int8_t Magnetometer::begin()
{
    uint8_t buff[3];
    i2cAddr_ = HMC5833L_I2CADD;

    // Join the I2C bus as master
    WIRE.begin();

    // read the ID registers
    if (i2cReadBytes(HMC5833L_REG_IDA, buff, 3) != 0) 
        return HMC5833L_ERROR_I2CREAD;
    
    // compare the ID registers
    if (buff[0] != HMC5833L_REG_IDA_ID || buff[1] != HMC5833L_REG_IDB_ID
        || buff[2] != HMC5833L_REG_IDC_ID)
        return HMC5833L_ERROR_WRONG_ID;

    // set data rate speed to 30hz
    if (i2cWriteByte(HMC5833L_REG_CFGA, 0x14) != 0)
        return HMC5833L_ERROR_I2CWRITE;

    // set to continuous mode
    // single mode not supported by lib
    if (i2cWriteByte(HMC5833L_REG_MODE, 0) != 0)
        return HMC5833L_ERROR_I2CWRITE;

    // set default gain
    if (setGain(HMC5833L_GAIN_1090) != 0)
        return HMC5833L_ERROR_I2CWRITE;

    return 0;
}
void Accelerometer::readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address)
{
    setMemoryBank(bank);
    i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &address); // Set memory start address
    uint8_t chunkSize;
    for (uint16_t i = 0; i < dataSize;) {
        chunkSize = MPU6050_DMP_MEMORY_CHUNK_SIZE;
        if (i + chunkSize > dataSize)
            chunkSize = dataSize - i;
        if (chunkSize > 256 - address)
            chunkSize = 256 - address;

        i2cReadBytes(MPU6050_RA_MEM_R_W, chunkSize, data + i);

        i += chunkSize;
        address += chunkSize;

        if (i < dataSize) {
            if (address == 0)
                bank++;
            setMemoryBank(bank);
            i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &address); // Set Memory start address
        }
    }
}
bool Accelerometer::writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address, bool verify, bool useProgMem)
{
    setMemoryBank(bank);
    i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &address); // Set Memory start address
    uint8_t chunkSize;
    uint8_t *verifyBuffer = NULL;
    uint8_t *progBuffer = NULL;
    uint16_t i;
    uint8_t j;
    if (verify)
        verifyBuffer = (uint8_t *)malloc(MPU6050_DMP_MEMORY_CHUNK_SIZE);
    if (useProgMem)
        progBuffer = (uint8_t *)malloc(MPU6050_DMP_MEMORY_CHUNK_SIZE);
    for (i = 0; i < dataSize;) {
        chunkSize = MPU6050_DMP_MEMORY_CHUNK_SIZE;

        if (i + chunkSize > dataSize)
            chunkSize = dataSize - i;

        if (chunkSize > 256 - address)
            chunkSize = 256 - address;

        if (useProgMem)
            for (j = 0; j < chunkSize; j++)
                progBuffer[j] = pgm_read_byte(data + i + j);
        else
            progBuffer = (uint8_t *)data + i;

        i2cWriteBytes(MPU6050_RA_MEM_R_W, chunkSize, progBuffer);

        if (verify && verifyBuffer) {
            setMemoryBank(bank);
            i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &address); // Set memory start address
            i2cReadBytes(MPU6050_RA_MEM_R_W, chunkSize, verifyBuffer);
            if (memcmp(progBuffer, verifyBuffer, chunkSize) != 0) {
                free(verifyBuffer);
                if (useProgMem)
                    free(progBuffer);
                return false;
            }
        }

        i += chunkSize;
        address += chunkSize;

        if (i < dataSize) {
            if (address == 0)
                bank++;
            setMemoryBank(bank);
            i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &address); // Set memory start address
        }
    }
    if (verify)
        free(verifyBuffer);
    if (useProgMem)
        free(progBuffer);
    return true;
}
int8_t Accelerometer::i2cReadBits(uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data)
{
    uint8_t count, b;
    if ((count = i2cReadBytes(regAddr, 1, &b)) != 0) {
        uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
        b &= mask;
        b >>= (bitStart - length + 1);
        *data = b;
    }
uint16_t Accelerometer::getFIFOCount()
{
    i2cReadBytes(MPU6050_RA_FIFO_COUNTH, 2, buffer);
    uint16_t ret = (((uint16_t)buffer[0]) << 8) | buffer[1];
    if(ret == 1024)
    {
        resetFIFO();
        return 0;
    }
    else
        return ret;
}
Exemple #6
0
uint16_t SRF02::getRange(uint8_t cmd) {
    uint16_t range=0;
    uint8_t  data[4];
    bool     success=FALSE;
    
    if ( i2cWriteCmd(cmd) ) {
        usleep(PING_DELAY);
        success = i2cReadBytes( data, 255 );
    }
    if (!success) {
        fprintf(stderr, "[ERROR] SRF02::getRange(...) failed. %s\n", i2cErrorString);
    } else {
        range = WORD(data[2],data[3]);
    }
    return(range);
}
int8_t Magnetometer::readRaw(int16_t * x, int16_t * y, int16_t * z)
{
    if (i2cAddr_ == 0)
        return HMC5833L_ERROR_NOT_INITIALIZED;

    uint8_t data[6];

    if (i2cReadBytes(HMC5833L_REG_DATAXYZ, data, 6) != 0)
        return HMC5833L_ERROR_I2CREAD;

    conv2Byte2Signed16(data[1], data[0], x);
    conv2Byte2Signed16(data[3], data[2], z);
    conv2Byte2Signed16(data[5], data[4], y);

    if (*x == -4096 || *y == -4096 || *z == -4096)
        return HMC5833L_ERROR_GAINOVERFLOW;

    return 0;
}
void Accelerometer::getFIFOBytes(uint8_t *data, uint8_t length)
{
    i2cReadBytes(MPU6050_RA_FIFO_R_W, length, data);
}
uint8_t Accelerometer::getIntStatus()
{
    i2cReadBytes(MPU6050_RA_INT_STATUS, 1, buffer);
    return buffer[0];
}
Accelerometer::Accelerometer()
{
    m_i2cfd = open("/dev/i2c-1", O_RDWR);
    if(!m_i2cfd < 0)
        abort();
    if(ioctl(m_i2cfd, I2C_SLAVE, 0x68) < 0)
        abort();

    i2cWriteBits(MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, MPU6050_CLOCK_PLL_XGYRO); // Set Clock source
    i2cWriteBits(MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, MPU6050_GYRO_FS_250); // Full scale gyro range
    i2cWriteBits(MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, MPU6050_ACCEL_FS_2); // Full scale accel range
    i2cWriteBits(MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, 1, false); // Disable sleep mode

    i2cWriteBits(MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_DEVICE_RESET_BIT, 1, true); // Reset
    usleep(30000);
    i2cWriteBits(MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, 1, false); // Disable sleep mode
    setMemoryBank(0x10, true, true); // Get MPU hardware revision
    uint8_t value = 0x06; // Alright, this is dirty but a pointer to this value will be sent to every i2cWriteBytes...
    uint16_t value16; // Yeah... I know, I won't go to heaven but that's ok
    i2cWriteBytes(MPU6050_RA_MEM_START_ADDR, 1, &value); // Set memory start address
    i2cReadBytes(MPU6050_RA_MEM_R_W, 1, buffer); // Get hardware revision
    uint8_t hwRevision __attribute__((__unused__)) = buffer[0];
    setMemoryBank(0, false, false);

    i2cReadBits(MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OTP_BNK_VLD_BIT, 1, buffer);
    uint8_t otpValid __attribute__((__unused__)) = buffer[0]; // Check OTP bank validity

    i2cReadBits(MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer);
    int8_t xgOffset = buffer[0];
    i2cReadBits(MPU6050_RA_YG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer);
    int8_t ygOffset = buffer[0];
    i2cReadBits(MPU6050_RA_ZG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer);
    int8_t zgOffset = buffer[0];

    value = 0x7F; // Setup weird slave stuff
    i2cWriteBytes(MPU6050_RA_I2C_SLV0_ADDR, 1, &value);
    i2cWriteBits(MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, 1, false); // Disable I2C Master Mode
    value = 0x68;
    i2cWriteBytes(MPU6050_RA_I2C_SLV0_ADDR, 1, &value);
    i2cWriteBits(MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_RESET_BIT, 1, true); // Reset I2C Master
    usleep(20000);

    if (writeMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE, 0, 0, true, true)) { // Load DMP code into memory banks
        if (writeDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE, true)) { // Let's write the DMP configuration
            i2cWriteBits(MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, MPU6050_CLOCK_PLL_ZGYRO); // Set clock source
            value = 0x12;
            i2cWriteBytes(MPU6050_RA_INT_ENABLE, 1, &value); // Enable 0x12 interuption
            value = 4; // 1khz / (1 + 4) = 200 Hz
            i2cWriteBytes(MPU6050_RA_SMPLRT_DIV, 1, &value);
            i2cWriteBits(MPU6050_RA_CONFIG, MPU6050_CFG_EXT_SYNC_SET_BIT, MPU6050_CFG_EXT_SYNC_SET_LENGTH, MPU6050_EXT_SYNC_TEMP_OUT_L); // External Frame Sync
            i2cWriteBits(MPU6050_RA_CONFIG, MPU6050_CFG_DLPF_CFG_BIT, MPU6050_CFG_DLPF_CFG_LENGTH, MPU6050_DLPF_BW_42); // DLPF Mode
            i2cWriteBits(MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, MPU6050_GYRO_FS_2000); // Full scale gyro range
            value = 0x03;
            i2cWriteBytes(MPU6050_RA_DMP_CFG_1, 1, &value);
            value = 0x00;
            i2cWriteBytes(MPU6050_RA_DMP_CFG_2, 1, &value);

            // Setting X Y and Z gyro offsets to previous values
            i2cWriteBits(MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, xgOffset);
            i2cWriteBits(MPU6050_RA_YG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, ygOffset);
            i2cWriteBits(MPU6050_RA_ZG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, zgOffset);

            value16 = 0; // And gyro offsets users to 0
            i2cWriteWords(MPU6050_RA_XG_OFFS_USRH, 1, &value16);
            i2cWriteWords(MPU6050_RA_YG_OFFS_USRH, 1, &value16);
            i2cWriteWords(MPU6050_RA_ZG_OFFS_USRH, 1, &value16);

            // Memory update 1/7
            uint8_t dmpUpdate[16], j;
            uint16_t pos = 0;
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            //Memory update 2/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);
            resetFIFO();
            uint8_t fifoCount = getFIFOCount();
            uint8_t fifoBuffer[128];
            value = 2;
            i2cWriteBytes(MPU6050_RA_MOT_THR, 1, &value); // Motion threshold
            value = 156;
            i2cWriteBytes(MPU6050_RA_ZRMOT_THR, 1, &value); // Zero Motion threshold
            value = 80;
            i2cWriteBytes(MPU6050_RA_MOT_DUR, 1, &value); // Motion duration
            value = 0;
            i2cWriteBytes(MPU6050_RA_ZRMOT_DUR, 1, &value); // Zero Motion duration
            resetFIFO();
            setFIFOEnabled(true);
            setDMPEnabled(true);
            i2cWriteBits(MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_DMP_RESET_BIT, 1, true); // Reset DMP

            // Memory update 3/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            // Memory update 4/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            // Memory update 5/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);
            while ((fifoCount = getFIFOCount()) < 3);
            getFIFOBytes(fifoBuffer, fifoCount);
            uint8_t mpuIntStatus __attribute__((__unused__)) = getIntStatus();

            // Memory update 6/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);
            while ((fifoCount = getFIFOCount()) < 3);
            getFIFOBytes(fifoBuffer, fifoCount);
            mpuIntStatus = getIntStatus();

            // Memory update 7/7
            for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++)
                dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]);
            writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]);

            setDMPEnabled(false);
            dmpPacketSize = 42;
            resetFIFO();
            getIntStatus();
        } else
            abort();
    } else
        abort();

    i2cReadBits(MPU6050_RA_WHO_AM_I, MPU6050_WHO_AM_I_BIT, MPU6050_WHO_AM_I_LENGTH, buffer);
    if(buffer[0] != 0x34)
        abort();

    setDMPEnabled(true);
    zeroValues[0] = 0;
    zeroValues[1] = 0;
    zeroValues[2] = 0;
}
Exemple #11
0
bool SRF02::i2cReadBytes ( uint8_t *data ) {
    return(i2cReadBytes(data,1));
}