For Wire Hand

Dependencies:   mbed mbed-rtos EthernetInterface

fdc.h

Committer:
Masayoshi
Date:
2020-04-24
Revision:
0:88bfb16a6ad5

File content as of revision 0:88bfb16a6ad5:

/*-----------------------------------------------------------------
 * fdc.h
 */
// debug port
DigitalOut d19(p19);
DigitalOut d20(p20);
DigitalOut d21(p21);
DigitalOut d22(p22);
DigitalOut d23(p23);
DigitalOut d24(p24);
DigitalOut d25(p25);
DigitalOut d26(p26);

//static const char * DST_ADDRESS = "192.168.140.2";
//static const char * MY_ADDRESS  = "192.168.140.8";
//static const int DST_PORT = 6008;
//static const int MY_PORT  = 6008;
//static const char * NETMASK = "255.255.0.0";
//static const char * GATEWAY = "0.0.0.0";
 
//static const int USB_BAUDRATE = 9600;
 
static const uint8_t ADDR_I2C = 0xFF; //Address on FDC1004 for measurement register
static const uint8_t REG_FDC  = 0xA0; //int REG_FDC = 80; //Address on FDC1004 for measurement register b1010000
static const uint8_t REG_MUX  = 0xE0; //int REG_MEX =112; //Address on PCA9548 for measurement register b1110000
static char FDC_CONFIG[] = {0x08, 0x09, 0x0A, 0x0B};
static char FDC_MSB[]    = {0x00, 0x02, 0x04, 0x06};
static char FDC_LSB[]    = {0x01, 0x03, 0x05, 0x07};
 
static const int FDC_NUM1 = 2;
static const int FDC_NUM2 = 1;
static const int FDC_NUM = FDC_NUM1 + FDC_NUM2; //MUXに接続しているFDC1004の数、ch0から順に接続
//static const int NUM_AXES = 4;
static const int NUM_DEN = 4; // DENKYOKU
//static const int UDP_TX_SIZE = sizeof(float) * FDC_NUM * NUM_AXES;
 
//union UdpTx {
//  float data[FDC_NUM][NUM_AXES];
//  char bytes[4*FDC_NUM*NUM_AXES];
//};
 
//RawSerial pc(USBTX, USBRX);
//I2C i2c(p9, p10);
//DigitalOut led1(LED1);
 
/*static void setupUdp(UDPSocket& sock) {
    EthernetInterface eth;
 
    pc.printf("Setup UDP\r\n");
 
    eth.init(MY_ADDRESS, NETMASK, GATEWAY);
    pc.printf("eth.init()\r\n");
    eth.connect(15000);
    pc.printf("eth.connect()\r\n");
 
    const char *ip = eth.getIPAddress();
    pc.printf("IP: %s\r\n", ip ? ip : "No IP");
 
    sock.bind(MY_PORT);
    pc.printf("Port: %d\r\n", MY_PORT);
}*/
 
/* PCA9548を使ったch切替  */
static inline bool switchI2c(I2C *i2c, uint8_t ch) {
    bool ret = true;
    char cmd[1] = {1 << ch};
    int result = i2c->write(REG_MUX, cmd, 1, false);
    if (result != 0) { // Error
        //pc.printf("switchI2c error \r\n");
//ERROR
d22 = !d22;
//wait(0.2);
d22 = !d22;
        ret = false;
    }
    return ret;
}
 
/* FDC1004の設定をする関数  */
static inline bool initFdc(I2C *i2c){
    char cmd1[3] = {0x0C, 0x80, 0x00};
    char cmd2[1] = {ADDR_I2C};
    i2c->write(REG_FDC, cmd1, 3, false);
    i2c->write(REG_FDC, cmd2, 1, false); // DeviceIDの確認
 
    //idチェック 16,4 と出たらOK。
    char res[2];
    i2c->read(REG_FDC, res, 2);
 
    return res[0] == 16 && res[1] == 4;
}
 
static inline uint8_t highByte(uint16_t x) {
    return (x >> 8) & 0xFF;
}
 
static inline uint8_t lowByte(uint16_t x) {
    return (x >> 0) & 0xFF;
}
 
static inline void config(I2C *i2c, int rate, int (&capdac)[NUM_DEN]){
    // rate設定 1:100S/s, 2:200S/s, 3:400S/s
 
    uint16_t conf_fdc, conf_meas;
 
    // conf_fdc 測定頻度と使うチャンネルを設定
    conf_fdc = (rate << 10) + (1 << 8) + (0b1111 << 4);
    char cmd[3] = {0x0C, highByte(conf_fdc), lowByte(conf_fdc)};
    i2c->write(REG_FDC, cmd, 3, false);
 
    // conf_meas CAPDACの設定
    for(int i=0; i<4;i++){
        if(capdac[i] >= 0){
            conf_meas = (i << 13) + (0b100 << 10) + (capdac[i] << 5);
        } else if (capdac[i] == -1){
            conf_meas = (i << 13) + (0b111 << 10);
        }
        cmd[0] = FDC_CONFIG[i];
        cmd[1] = highByte(conf_meas);
        cmd[2] = lowByte(conf_meas);
        int result = i2c->write(REG_FDC, cmd, 3, false);
    }
}
 
static inline int readRegister(I2C *i2c, char address) {
    char cmd[1] = {address};
    char res[2];
 
    i2c->write(REG_FDC, cmd, 1, true); // no stop
    i2c->read (REG_FDC, res, 2);
    return (int)((int)res[0] << 8) | res[1];
}
 
static inline int readMeas(I2C *i2c, int i) {
    int msb = readRegister(i2c, FDC_MSB[i]);
    return (msb << 8);
}
 
static inline void senseCapacitance(I2C *i2c, float (&c)[NUM_DEN], int (&capdac)[NUM_DEN]){
    for (int i=0; i<NUM_DEN; i++) {
        c[i] = ((float)readMeas(i2c, i)/0x80000);
        if (c[i] >= 16) {
            c[i] -= 32;
        }
        if (capdac[i] > 0) {
            c[i] += float(capdac[i]) * 3.125f / 0x80000;
        }
    }
}
 
// TODO リファクタリング後の関数(senseCapacitance)が、元の関数と同じ値になるか要検証
/*static void senseCapacitance_orig(float (&c)[NUM_AXES], int (&capdac)[NUM_AXES]){
  unsigned int mbb1, mbb2, mbb3; // variables to store 16-bit unsigned integers
  char res1[2];
  char res2[1];
 
  for(int i=0; i<NUM_AXES; i++){
    i2c.write(REG_FDC, FDC_MSB + i, 1, true);
    i2c.read(REG_FDC, res1, 2);
 
    i2c.write(REG_FDC, FDC_LSB + i, 1, true);
    i2c.read(REG_FDC, res2, 1);
 
    // Below are the calculations to take the 24-bit measurement and convert into capacitance for MEAS1
    // * From datasheet: p.16 Section 8.6.1.1 shows the formula (all we need to do is shift the 24-bit value right by 19)
    // ** Shifting by 19 takes a 24 bit number and makes it a 5 bit number with 19 bits after the decimal point
    mbb1 = res1[0] * 256 + res1[1]; // Puts 16 most significant bits into one integer for left sensor measurement
    mbb2 = mbb1 >> 11; // Sets mbb2 to the 5 bits that exist before the decimal point pFの整数部分5bit
    mbb3 = 0b0000011111111111 & mbb1; // Sets mbb3 to the 11 bits that exist after the decimal point pFの小数点以下の11bit
 
    c[i] = (float)mbb2 + (float)mbb3 / 2048 + (float)res2[0] / 524288; // 単位pF
    if (capdac[i] > 0) {
      c[i] += float(capdac[i]) * float(3.125); //CAPDACによるoffset追加
    }
  }
}*/
 
/*static void displayValues(float (&values)[FDC_NUM][NUM_AXES]) {
    for (int j=0; j<FDC_NUM; j++) {
        for(int i=0; i<NUM_AXES; i++) {
            pc.printf("|%5.2f|", values[j][i]);
        }
    }
    pc.printf("\r\n");
}*/