Esempio n. 1
0
ITG3200::ITG3200(uint8_t range) {
    readI2C(GYRADDR, 0x00, 1, gBuffer);   // Who am I?
    
    #ifdef DEBUG
        Serial.print("ITG-3200 ID = ");
        Serial.println((int) gBuffer[0]);
    #endif

    // Configure ITG-3200
    // Refer to DS Section 8: Register Description.
    sendI2C(GYRADDR, 0x15, 0x18);   // 00011000 -- Sample rate divider is 24(+1), so 40 Hz

    // Set Range
    readI2C(GYRADDR, 0x16, 1, gBuffer);
    gBuffer[1] = range;
    gBuffer[1] = (gBuffer[1] << 3);   // See DS.
    gBuffer[0] |= gBuffer[1];
    sendI2C(GYRADDR, 0x16, gBuffer[0]);

    #ifdef DEBUG
        Serial.println("ITG-3200 configured!");
    #endif

    // Zero buffer.
    for (int i=0; i<READ_SIZE; i++) {
        gBuffer[i] = 0;
    }
}
Esempio n. 2
0
int main()
{
	i2cBus = open("/dev/i2c-1", O_RDWR);
	if (i2cBus <= 0)
	{
		printf("Error opening the i2c bus\n");
		return -1;
	}

	selectI2CDevice(ACCEL_BUS_ADDRESS);

//	writeI2C(CTRL_REG5_XM, 0xf0);
//	writeI2C(CTRL_REG6_XM, 0x60);
//	writeI2C(CTRL_REG7_XM, 0);

	writeI2C(0x2D, 0x08); // enable accel

	while(1)
	{
		short block[3];
		readI2C(ACCEL_X, 2, (unsigned char*)&block[0]);
		readI2C(ACCEL_Y, 2, (unsigned char*)&block[1]);
		readI2C(ACCEL_Z, 2, (unsigned char*)&block[2]);
		printf("gyro reads: %d,%d,%d\n", (int)block[0], (int)block[1], (int)block[2]);
	}
	return 0;
}
Esempio n. 3
0
int EM2874Device::getDeviceID()
{
	uint8_t buf[2], tuner_reg;
	// ROMで判断
	writeReg(EM28XX_REG_I2C_CLK, 0x42);
	buf[0] = 0; buf[1] = 0x6a;	writeI2C(EEPROM_ADDR, 2, buf, false);
	if(!readI2C (EEPROM_ADDR, 2, buf, true))
		return -1;

	if(buf[0] == 0x3b && buf[1] == 0x00)
		return 2;

	// Tuner Regで判断
	writeReg(EM28XX_REG_I2C_CLK, 0x44);
	buf[0] = 0xfe; buf[1] = 0;	writeI2C(DEMOD_ADDR, 2, buf, true);
	tuner_reg = 0x0;
	writeI2C(TUNER_ADDR, 1, &tuner_reg, false);
	readI2C (TUNER_ADDR, 1, &tuner_reg, true);

	buf[0] = 0xfe; buf[1] = 1;	writeI2C(DEMOD_ADDR, 2, buf, true);

	if(tuner_reg == 0x84)	// TDA18271HD
		return 1;

	return 2;
}
Esempio n. 4
0
int read2I2C(unsigned char addr) {
  	unsigned char val_high, val_low;
    startI2C(addr, I2C_READ);
    val_high = readI2C(1);
  	val_low = readI2C(0);
    stopI2C();
  	return ((unsigned int)val_high << 8L) | val_low;
}
Esempio n. 5
0
ITG3200::ITG3200() {
	spn("Init ITG-3200 starting...");


    readI2C(GYRADDR, 0x00, 1, buffer);   // Who am I?

    sp("ITG-3200 ID = ");
    spln((int) buffer[0]);

    readI2C(GYRADDR, 0x15, 2, buffer);

    // Sample rate divider is 1 + 1 = 2, so 1000 Hz / 2 = 500 Hz
    buffer[0] = 1;

    // Set FS_SEL = 3 as recommended on DS p. 24.
    // Set DLPF_CFG = 3. This signifies a 1 kHz internal sample rate with a 42
    // Hz LPF bandwidth, which should be low enough to filter out the motor
    // vibrations.
    buffer[1] = (3 << 3) | 3;   // FS_SEL is on bits 4 and 3.

    writeI2C(GYRADDR, 0x15, 2, buffer);

    // Set to use X gyro as clock reference as recommended on DS p. 27.
    buffer[0] = 1;
    writeI2C(GYRADDR, 0x3e, 1, buffer);


    spln("ITG-3200 configured!");

    // Zero buffer.
    for (int i=0; i<6; i++) {
        buffer[i] = 0;
    }

    // Low-pass filter.
    #ifdef GYRO_LPF_DEPTH
    lpfIndex = 0;
    for (int i=0; i<3; i++)
        for (int j=0; j<GYRO_LPF_DEPTH; j++)
            lpfVal[i][j] = 0;
    #endif // GYRO_LPF_DEPTH

    for (int i=0; i<3; i++) {
        gZero[i] = 0;
        gVec[i] = 0;
        angle[i] = 0;
    }
    calibrated = false;
}
Esempio n. 6
0
int read1I2C(unsigned char addr) {
    unsigned char val;

    startI2C(addr, I2C_READ);
    val = readI2C(0);
    return val;
}
Esempio n. 7
0
IOReturn
IOI2CDriveBayGPIO::readModifyWriteI2C(
	UInt8		subAddr,
	UInt8		value,
	UInt8		mask)
{
	IOReturn	status;
	UInt32		clientKey;
	UInt8		data;

	if (kIOReturnSuccess == (status = lockI2CBus(&clientKey)))
	{
		if (kIOReturnSuccess != (status = readI2C(subAddr, &data, 1, clientKey)))
		{
			DLOG("IOI2CDriveBayGPIO@%lx::rmw read S:0x%x error: 0x%08x\n", getI2CAddress(), subAddr, status);
		}
		else
		{
			// Apply mask and value
			data = ((data & ~mask) | (value & mask));

			if (kIOReturnSuccess != (status = writeI2C(subAddr, &data, 1, clientKey)))
			{
				DLOG("IOI2CDriveBayGPIO@%lx::rmw write S:0x%x error: 0x%08x\n", getI2CAddress(), subAddr, status);
			}
		}
		unlockI2CBus(clientKey);
	}

	return status;
}
Esempio n. 8
0
// AppleLM87::getReading
IOReturn AppleLM8x::getReading(UInt32 subAddress, SInt32 *value)
{
    IOReturn status;
    UInt8 data;
    
    if (systemIsRestarting == TRUE)
        return kIOReturnOffline;

    status = openI2C(kLM8xBus);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::getReading(0x%x) failed to open I2C bus.\n", kLM8xAddr<<1);
        return status;
    }

    status = readI2C((UInt8)subAddress, (UInt8 *) &data, 1);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::getReading(0x%x) readI2C failed.\n", kLM8xAddr<<1);
        closeI2C();
        return status;
    }
	
	closeI2C();

	*value = (SInt32)data;

	return kIOReturnSuccess;
}
Esempio n. 9
0
void setActiveMMA8451Q (unsigned int state) {
	unsigned char ctl1[] = {0x2A, 0x00};
	writeI2C(0x1c, ctl1, 1, 0); //0x2E 0100 0000  40
	readI2C(0x1c, &(ctl1[1]) , 1, 1);
	if(state) ctl1[1] |= 0x01;
	else ctl1[1] &= 0xFE;
	writeI2C(0x1c,ctl1, 2, 1);
}
Esempio n. 10
0
void setOutputBit(unsigned char state){
    unsigned char temp;
    readI2C(SlaveAddress,CTRL_REG1,&temp,1);
    if(state)
        temp &= ~CTRL_REG1_FREAD; 
    else
        temp |= CTRL_REG1_FREAD;
    writeI2C(SlaveAddress,CTRL_REG1,&temp,1);
}
Esempio n. 11
0
void executeMMA8451Q(unsigned char* buffer, unsigned int length) {
	enableI2C(12);
	setPwrBusStatus(PM_SYSPWR, PM_ENABLE);
	initMMA8451Q();
	attachInterrupt(mma8451qVector, 1,6, 1);
	setActiveMMA8451Q(1);
	LPM3;
	detachInterrupt(1,6);
	unsigned char statreg[2] = {0x00, 0x01};
	writeI2C(0x1c, statreg, 1, 0);
	readI2C(0x1c, statreg , 1, 1);
	writeI2C(0x1c, statreg+1, 1, 0);
	readI2C(0x1c, buffer , 96, 1);
	setActiveMMA8451Q(0);
	disableI2C();
	setPwrBusStatus(PM_SYSPWR, PM_DISABLE);
	return;
}
Esempio n. 12
0
Vector getOrientation()
{
	if (i2cBus > 0)
	{
		short block[3];
        	readI2C(ACCEL_X, 2, (unsigned char*)&block[0]);
       	 	readI2C(ACCEL_Y, 2, (unsigned char*)&block[1]);
        	readI2C(ACCEL_Z, 2, (unsigned char*)&block[2]);

	        float smoothingFactor = 10;
		static Vector vDown(0,0,0);
        	vDown.x = ((vDown.x*smoothingFactor) + (float)block[0]/255.0f) / (smoothingFactor+1);
        	vDown.y = ((vDown.y*smoothingFactor) + (float)block[1]/255.0f) / (smoothingFactor+1);
		vDown.z = ((vDown.z*smoothingFactor) + (float)block[2]/255.0f) / (smoothingFactor+1);

		return vDown;
	}
	return Vector(0,1,0);
}
Esempio n. 13
0
void ITG3200::poll() {
    readI2C(GYRADDR, 0x1d, 6, buffer);

    // Shift high byte to be high 8 bits and append with low byte.
    gRaw[0] = -((buffer[2] << 8) | buffer[3]);   // Tricopter X axis is chip Y axis.
    gRaw[1] = -((buffer[0] << 8) | buffer[1]);   // Tricopter Y axis is chip X axis.
    gRaw[2] = -((buffer[4] << 8) | buffer[5]);   // Z axis is same.

    if (calibrated) {
        // Apply calibration values.
        for (int i=0; i<3; i++) {
            gRaw[i] -= gZero[i];
        }

        // Low-pass filter.
        #ifdef GYRO_LPF_DEPTH
        for (int i=0; i<3; i++) {
            lpfVal[i][lpfIndex] = gRaw[i] / GYRO_LPF_DEPTH;

            gRaw[i] = 0;
            for (int j=0; j<GYRO_LPF_DEPTH; j++) {
                gRaw[i] += lpfVal[i][(lpfIndex + j) % GYRO_LPF_DEPTH];
            }
        }
        lpfIndex = (lpfIndex + 1) % GYRO_LPF_DEPTH;   // Increment index by 1 and loop back from GYRO_LPF_DEPTH.
        #endif // GYRO_LPF_DEPTH
    }

    //sp("G( ");
    //for (int i=0; i<3; i++) {
    //    sp(gRaw[i]);
    //    sp(" ");
    //}
    //spln(")");

    // Read gyro temperature (DS p. 7).
    //readI2C(GYRADDR, TEMP_OUT, 2, buffer);
    //temp = 35 + (((buffer[0] << 8) | buffer[1]) + 13200)/280.0;

    // Convert raw gyro output values to rad/s.
    // Output: [0x0000 -- 0x7fff] = [     0 -- 32767]
    //         [0x8000 -- 0xffff] = [-32768 --    -1]
    // Range: [-2000, 2000] deg/s
    // Scale factor: 14.375 LSB / (deg/s)
    for (int i=0; i<3; i++) {
        gVec[i] = (float) gRaw[i] / 14.375 * PI/180;
    }

    //sp("G( ");
    //for (int i=0; i<3; i++) {
    //    sp(gVec[i]);
    //    sp(" ");
    //}
    //spln(")");
}
Esempio n. 14
0
IOReturn AppleLM8x::saveRegisters()
{
    IOReturn status;

    DLOG("AppleLM8x::saveRegisters(0x%x) entered.\n", kLM8xAddr<<1);

    status = openI2C(kLM8xBus);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::saveRegisters(0x%x) failed to open I2C bus.\n", kLM8xAddr<<1);
        return status;
    }

    status = readI2C((UInt8)kChannelModeRegister, (UInt8 *)&savedRegisters.ChannelMode, 1);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::saveRegisters(0x%x) readI2C failed.\n", kLM8xAddr<<1);
        closeI2C();
        return status;
    }

    status = readI2C((UInt8)kConfReg1, (UInt8 *)&savedRegisters.Configuration1, 1);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::saveRegisters(0x%x) readI2C failed.\n", kLM8xAddr<<1);
        closeI2C();
        return status;
    }

    status = readI2C((UInt8)kConfReg2, (UInt8 *)&savedRegisters.Configuration2, 1);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::saveRegisters(0x%x) readI2C failed.\n", kLM8xAddr<<1);
        closeI2C();
        return status;
    }

    closeI2C();

    return status;
}
Esempio n. 15
0
IOReturn
IOI2CLM6x::getRemoteTemperature	(
									SInt32*				temperature
								)
{
    UInt8							rawDataMsb;
    UInt8							rawDataLsb;
    IOReturn						status = kIOReturnSuccess;

	require_success( ( status = readI2C( kLM6xReg_RemoteTemperatureMSB, &rawDataMsb, 1 ) ), IOI2CLM6x_getRemoteTemperature_readI2CErr1 );
	require_success( ( status = readI2C( kLM6xReg_RemoteTemperatureLSB, &rawDataLsb, 1 ) ), IOI2CLM6x_getRemoteTemperature_readI2CErr2 );

	// Remote temperature data is represented by a 11-bit, two's complement word with 
	// an LSB equal to 0.125C.  The data format is a left justified 16-bit word available in
	// two 8-bit registers.

	*temperature = ( ( ( ( SInt8 ) rawDataMsb ) << 16 ) | ( rawDataLsb << 8 ) );

IOI2CLM6x_getRemoteTemperature_readI2CErr2:
IOI2CLM6x_getRemoteTemperature_readI2CErr1:
	return( status );
}
Esempio n. 16
0
uint16_t getGyroSample(uint16_t index, uint8_t *array){
	startI2C(MPU9150ADDR, WRITE);
		writeI2C(0x43);
	stopI2C();
	startI2C(MPU9150ADDR, READ);
		for(uint8_t k=0; k<6; k++){
			if(index > 54-1) break;
			uint8_t ackType = (k < (6-1))? ACK : NACK ;
			array[index++] = readI2C(ackType);
		}
	stopI2C();
	return index;
}
Esempio n. 17
0
//=========================================
//功能:初始化MMA8451
//输入:无
//输出:无
//返回:无
//=========================================
void Init_MMA8452(void)
{
    unsigned char temp;
    
    //设置休眠
    MMA845x_Standby();
    
    /* 设置采样频率为100Hz */
    MMA845x_Output_Data_Rates(Output_Data_Rates_400);
    
    setOutput_8Bit;
    
    readI2C(SlaveAddress,CTRL_REG4,&temp,1);
    temp |= CTRL_REG4_INT_EN_DRDY;
    writeI2C(SlaveAddress,CTRL_REG4,&temp,1);
    
    readI2C(SlaveAddress,CTRL_REG5,&temp,1);
    temp |= CTRL_REG5_INT_CFG_DRDY;
    writeI2C(SlaveAddress,CTRL_REG5,&temp,1);
    
    /* 将设备切换到主动模式 */
    MMA845x_Active();
}
Esempio n. 18
0
bool EepromDev::loadFromDevice(void)
{
    bool ret_value = false;
    int fd;
    if (openDevice(fd)) {
        ret_value = readI2C(fd, 0, &data_, sizeof(data_));
        ::close(fd);
    }

    if (!isValidData())
        loadFromDefaults();

    /* Update v1 to v2 */
    if (data_.version == 1) {
        data_.features |= feature_eepromoops;

        data_.eepromoops_offset = 4096;
        data_.eepromoops_length = 61440;

        data_.eeprom_size = 65536;
        data_.page_size = 128;

        if (data_.features & feature_retina) {
            data_.lvds1.frequency = 148500000;
            data_.lvds1.hactive = 1920;
            data_.lvds1.vactive = 1080;
            data_.lvds1.hback_porch = 148;
            data_.lvds1.hfront_porch = 88;
            data_.lvds1.hsync_len = 44;
            data_.lvds1.vback_porch = 36;
            data_.lvds1.vfront_porch = 4;
            data_.lvds1.vsync_len = 5;
            data_.lvds1.flags = vsync_polarity | hsync_polarity
                              | data_width_8bit | mapping_jeida
                              | dual_channel | channel_present;

            data_.lvds2.flags = channel_present;
        }

        if (data_.features & feature_hdmi) {
            /* Pull HDMI settings from e.g. EDID */
            data_.hdmi.flags = channel_present | ignore_settings
                             | data_width_8bit;
        }

        data_.version = 2;
    }

    return ret_value;
}
Esempio n. 19
0
IOReturn IOI2CDriveBayGPIO::callPlatformFunction(
	const OSSymbol *functionName,
	bool waitForFunction,
	void *param1, void *param2,
	void *param3, void *param4)
{
	const char	*functionNameStr;
	UInt8		data;
	IOReturn	status;

	if (functionName == 0)
		return kIOReturnBadArgument;

	functionNameStr = functionName->getCStringNoCopy();

	if (0 == strcmp(functionNameStr, kSymGPIOParentWriteGPIO))
	{
		return readModifyWriteI2C(k9554OutputPort, (UInt8)(UInt32)param2, (UInt8)(UInt32)param3);
	}
	else
	if (0 == strcmp(functionNameStr, kSymGPIOParentReadGPIO))
	{
		if (kIOReturnSuccess == (status = readI2C(k9554InputPort, &data, 1)))
			*(UInt32 *)param2 = (UInt32)data;
		return status;
	}
	else // GPIO interrupt client API...
	if (0 == strcmp(functionNameStr, kSymGPIOParentRegister))
		return registerGPIOClient((UInt32)param1, (GPIOEventHandler)param3, (IOService*)param4, true);
	else
	if (0 == strcmp(functionNameStr, kSymGPIOParentUnregister))
		return registerGPIOClient((UInt32)param1, (GPIOEventHandler)0, (IOService*)0, false);
	else
	if (0 == strcmp(functionNameStr, kSymGPIOParentEvtEnable))
		return enableGPIOClient((UInt32)param1, true);
	else
	if (0 == strcmp(functionNameStr, kSymGPIOParentEvtDisable))
		return enableGPIOClient((UInt32)param1, false);
	else
	if (0 == strcmp(functionNameStr, kSymGPIOParentIntCapable))
	{
		*((UInt32 *)param1) = 1;
		return kIOReturnSuccess;
	}

	return super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4);
}
Esempio n. 20
0
IOReturn
IOI2CLM6x::getLocalTemperature	(
									SInt32*				temperature
								)
{
    IOReturn						status = kIOReturnSuccess;
    UInt8							rawData;

	require_success( ( status = readI2C( kLM6xReg_LocalTemperature, &rawData, 1 ) ), IOI2CLM6x_getLocalTemperature_readI2CErr );

	// Local temperature data is represented by a 8-bit, two's complement word with 
	// an LSB equal to 1.0C.  We need to shift it into a 16.16 format.

	*temperature = ( ( ( SInt8 ) rawData ) << 16 );

IOI2CLM6x_getLocalTemperature_readI2CErr:
	return( status );
}
Esempio n. 21
0
void ITG3200::Poll() {
    readI2C(GYRADDR, REGADDR, READ_SIZE, gBuffer);

    gRaw[0] = ((gBuffer[0] << 8) | gBuffer[1]);   // Shift high byte to be high 8 bits and append with low byte.
    gRaw[1] = ((gBuffer[2] << 8) | gBuffer[3]);
    gRaw[2] = ((gBuffer[4] << 8) | gBuffer[5]);

    for (int i=0; i<3; i++) {   // Convert raw values to a nice -1 to 1 range.
        float tmp;
        if (gRaw[i] >= 0x8000)   // If zero to negative rot. vel.: 2^16-1 to 2^15...
            tmp = -((signed) (0xFFFF - gRaw[i]));   // ...subtract from 2^16-1.
        gVal[i] = tmp/0x8000;   // Divide by maximum magnitude.
    }

    #ifdef DEBUG
        Serial.print("GX: "); Serial.print(gVal[0]);
        Serial.print("   GY: "); Serial.print(gVal[1]);
        Serial.print("   GZ: "); Serial.println(gVal[2]);
    #endif
}
Esempio n. 22
0
void BMA180::poll() {
    // Read data.
    readI2C(ACCADDR, 0x02, 6, buffer);

    // Store 14 bits of data (thus the division by 4 at the end).
    aRaw[0] = ((buffer[3] << 8) | (buffer[2] & ~0x03)) / 4;   // Tricopter X axis is chip Y axis.
    aRaw[1] = ((buffer[1] << 8) | (buffer[0] & ~0x03)) / 4;   // Tricopter Y axis is chip X axis.
    aRaw[2] = ((buffer[5] << 8) | (buffer[4] & ~0x03)) / 4;   // Z axis is same.

    // Low-pass filter.
    #ifdef ACC_LPF_DEPTH
    for (int i=0; i<3; i++) {
        lpfVal[i][lpfIndex] = aRaw[i] / ACC_LPF_DEPTH;

        aRaw[i] = 0;
        for (int j=0; j<ACC_LPF_DEPTH; j++) {
            aRaw[i] += lpfVal[i][(lpfIndex + j) % ACC_LPF_DEPTH];
        }
    }
    lpfIndex = (lpfIndex + 1) % ACC_LPF_DEPTH;   // Increment index by 1 and loop back from ACC_LPF_DEPTH.
    #endif // ACC_LPF_DEPTH

    // Read accelerometer temperature.
    //readI2C(ACCADDR, 0x08, 1, buffer);
    //temp = -40 + 0.5 * buffer[0];   // 0.5 K/LSB

    // Convert raw values to multiples of gravitational acceleration.
    // Output: [0x1fff -- 0x0000] = [-8191 --    0]
    //         [0x3fff -- 0x2000] = [    1 -- 8192]
    // ADC resolution varies depending on setup. See DS p. 27 or the
    // constructor of this class.
    for (int i=0; i<3; i++) {
        aVec[i] = (float) (aRaw[i] / res);
    }

    // TODO: Decide if this is worth the extra computational cost and define
    // offsets and gains in globals.h.
    aVec[0] = (aVec[0] + 0.0345) / 1.0365;
    aVec[1] = (aVec[1] - 0.0100) / 1.0300;
    aVec[2] = (aVec[2] + 0.0185) / 1.0285;
}
Esempio n. 23
0
//=========================================
//功能:连续读出MMA8452内部加速度数据,地址范围0x01~0x06
//输入:无
//输出:无
//返回:无
//=========================================
void Multiple_Read_MMA8452(void)
{   
    /*uchar i;
    
    while(I2C_SR3_BUSY);          //检测总线是否空闲
    I2C_CR2_START = 1;            //产生起始信号
    while(!I2C_SR1_SB);           //查询起始位是否已发送
    
    I2C_DR = SlaveAddress;         //发送写地址,写DR将清除I2C_SR1_SB待验证
    while(!I2C_SR1_ADDR);		  //查询地址是否发送	
    i = I2C_SR1;
    i = I2C_SR3;               //清除I2C_SR1_ADDR
    
    I2C_DR = 0x01;                //写数据
    while(!(I2C_SR1&0x84)); 
    
    I2C_CR2_START = 1;            //产生起始信号
    while(!I2C_SR1_SB);
    
    I2C_DR = SlaveAddress+1;        //发送写地址,写DR将清除I2C_SR1_SB待验证
    while(!I2C_SR1_ADDR);		   //查询地址是否发送	
    i = I2C_SR1;
    i = I2C_SR3;                //清除I2C_SR1_ADDR
    
    for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
    {
    if (i == 5){ //设置关闭应答
    I2C_CR2_ACK = 0;
    I2C_CR2_STOP = 1;
}
    while(!(I2C_SR1&0x40));
    BUF[i] =I2C_DR;          
}
    
    I2C_CR2_ACK = 1;  //开启应答*/
    
    readI2C(SlaveAddress,0x01,BUF,6);
    
}
Esempio n. 24
0
//______________________________________________________________________________________
int  			readI2C(_i2c *p, char* dBuffer, int length) {
static
int				nrpt=3;
int				to=__time__+25;

					if(p) {
						p->nrx=length;
						if(dBuffer[1])
							writeI2C(p,dBuffer,2);
						else
							writeI2C(p,dBuffer,1);
						while(p->nrx && __time__< to)
							_proc_loop();
						if(p->nrx) {
							Reset_I2C(p);
							if(--nrpt)
								return	readI2C(p, dBuffer, length);
						}
						nrpt=3;
						memcpy(dBuffer,p->rxbuf,length);
						if(p->nrx) {
							return(0);
						}
					} else
						while(length--)
								dBuffer[length]=0;
						_CLEAR_ERROR(pfm,PFM_I2C_ERR);
						if(_DBG(pfm,_DBG_I2C_RX)) {
							_io *io=_stdio(__dbug);
							int i;
							__print(":%04d",__time__ % 10000);
							for(i=0;i<length;++i)
								__print(" %02X",p->rxbuf[i]);
							__print("\r\n>");
							_stdio(io);
						}
						return(-1);
}
Esempio n. 25
0
IOReturn IOI2CMaxim1631::getTemp( UInt32 maximReg /* unused */, SInt32 * temp )
{
IOReturn	status;
union
{
	UInt16		aShort;
	UInt8		aByte[2];
} readBuffer;

	// get the temperature.
	//	this is done by issuing a COMBINED (default for readI2C) I2C request, with
	//	'kReadCurrentTemp' as the "sub-addr' and reading 2 bytes, since the current
	//	temp register is 16 bits.

	if (kIOReturnSuccess == (status = readI2C( kReadCurrentTemp, &readBuffer.aByte[0], 2 )))
	{
		// temperature register format:
		//
		//	MS byte:  1/sign, 7 integer
		//	LS byte:  4/fraction, 4/zero
		
		// format the 16.16 fixed point temperature and return it
		// ( the 0xFFFFF000 allows for the propagation of the sign bit,
		//   which could happen in the case of a very cold room inlet temperature )

		*temp = ( ( ( ( SInt16 ) readBuffer.aShort ) << 8 ) & 0xFFFFF000 );
	
		//DLog( "IOI2CMaxim1631::getTemp - raw data = 0x%04X, returning %08lX\n",
		//					i2cBuffer.aShort,   *temp );
	}
	else
	{
		IOLog( "IOI2CMaxim1631::getTemp - unable to read temperature (status = 0x%08X)\n", status );
		*temp = 0x7FFFFFFF;	// pass back very large positive number - will probably set off warning`
	}

	return status;
}
Esempio n. 26
0
IOReturn
IOI2CDevice::readI2C(
	UInt32	subAddress,
	UInt8	*data,
	UInt32	count,
	UInt32	clientKey,
	UInt32	mode,
	UInt32	retries,
	UInt32	timeout_uS,
	UInt32	options)
{
	IOI2CCommand cmd = {0};

	cmd.command = kI2CCommand_Read;
	cmd.mode = mode;
	cmd.subAddress = subAddress;
	cmd.count = count;
	cmd.buffer = data;
	cmd.retries = retries;
	cmd.timeout_uS = timeout_uS;
	cmd.options = options;

	return readI2C(&cmd, clientKey);
}
Esempio n. 27
0
IOReturn AppleLM8x::initHW(IOService *provider)
{
    IOReturn status;
    UInt8 cfgReg = 0;
    UInt8 attempts = 0;

    DLOG("AppleLM8x::initHW(0x%x) entered.\n", kLM8xAddr<<1);

    status = openI2C(kLM8xBus);
    if(status != kIOReturnSuccess)
    {
        DLOG("AppleLM8x::initHW(0x%x) failed to open I2C bus.\n", kLM8xAddr<<1);
        return status;
    }
 
	// Attempt to start LM87 by setting bit 0 in Configuration Register 1.  If we detect the RESET
	// bit, then make a second attempt.
	for ( ; attempts < 2; attempts++ )
	{
		// Read Configuration Register 1
		status = readI2C((UInt8)kConfReg1, (UInt8 *) &cfgReg, 1);
		if(status != kIOReturnSuccess)
		{
			DLOG("AppleLM8x::initHW(0x%x) readI2C failed.\n", kLM8xAddr<<1);
			break;
		}

		DLOG("AppleLM8x::readI2C(0x%x) retrieved data = 0x%x\n", kLM8xAddr<<1, cfgReg);    

		// If we detect RESET, wait at least 45ms for it to clear.
		if ( cfgReg & kConfRegRESET )
		{
			IOSleep(50);
			status = kIOReturnError;
		}

		if(status != kIOReturnSuccess)
		{
			IOLog("AppleLM8x::initHW(0x%x) readI2C detected RESET bit.\n", kLM8xAddr<<1);
		}

		// Start monitoring operations
		cfgReg = 0x1;

		// Failure of this write operation is fatal
		status = writeI2C((UInt8)kConfReg1, (UInt8 *)&cfgReg, 1);

		// Read Configuration Register 1
		status = readI2C((UInt8)kConfReg1, (UInt8 *) &cfgReg, 1);
		if(status != kIOReturnSuccess)
		{
			DLOG("AppleLM8x::initHW(0x%x) readI2C failed.\n", kLM8xAddr<<1);
			break;
		}
	
		if ( cfgReg == kConfRegStart )
		{
			break;
		}
		else
		{
			IOLog("AppleLM8x::readI2C(0x%x) retrieved configuration register 1 = 0x%x\n", kLM8xAddr<<1, cfgReg);    
		}
	}

    closeI2C();

    return status;
}
Esempio n. 28
0
bool IOI2CDriveBayGPIO::start(IOService *provider)
{
	IOReturn				status;
	OSData					*data;
	mach_timespec_t			timeout;

	DLOG("IOI2CDriveBayGPIO::start\n");

	// Get our "reg" property.. I2C address.
	if (0 == (data = OSDynamicCast(OSData, provider->getProperty("reg"))))
	{
		DLOG("IOI2CDriveBayGPIO::start -- no reg property\n");
		return false;
	}
	fReg = *((UInt32 *)data->getBytesNoCopy());

	// Find the PCA9554M node. It provides our interrupt source...
	timeout.tv_sec = 30;
	timeout.tv_nsec = 0;
	if (0 == (fPCA9554M = waitForService(serviceMatching("IOI2CDriveBayMGPIO"), &timeout)))
	{
		DLOG("IOI2CDriveBayGPIO::start -- timeout waiting for IOI2CDriveBayMGPIO\n");
		return false;
	}

	fConfigReg = 0xFF;		// default to all input pins
	fPolarityReg = 0x00;	// no polarity inversion

	// find out how to program the config register
	if (data = OSDynamicCast(OSData, provider->getProperty("config-reg")))
		fConfigReg = (UInt8)*((UInt32 *)data->getBytesNoCopy());

	// find out how to program the polarity register
	if (data = OSDynamicCast(OSData, provider->getProperty("polarity-reg")))
		fPolarityReg = (UInt8)*((UInt32 *)data->getBytesNoCopy());

	DLOG("IOI2CDriveBayGPIO(%x)::start fConfigReg = %02x fPolarityReg = %02x\n", (int)fReg, fConfigReg, fPolarityReg);

	// allocate my lock
	fClientLock = IOLockAlloc();

	// Register with the combined PCA9554M
	DLOG("IOI2CDriveBayGPIO(%x)::start - register9554MInterruptClient\n", (int)fReg);
	if (kIOReturnSuccess != (status = fPCA9554M->callPlatformFunction("register9554MInterruptClient", false,
				(void *)fReg, (void *)&sProcess9554MInterrupt, (void *)this, (void *)true)))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start failed to register (%x)\n", (int)fReg, (int)status);
		return false;
	}

	// Start IOI2C services...
	if (false == super::start(provider))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start -- super::start returned error\n", (int)fReg);
		return false;
	}

	super::callPlatformFunction("IOI2CSetDebugFlags", false, (void *)kStateFlags_kprintf, (void *)true, (void *)NULL, (void *)NULL);

	if (kIOReturnSuccess != readI2C(k9554OutputPort, &fOutputReg, 1))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start -- super::start returned error\n", (int)fReg);
		freeI2CResources();
		return false;
	}

	// start matching on children
	publishChildren(provider);
	registerService();

	DLOG("IOI2CDriveBayGPIO@%lx::start succeeded\n", getI2CAddress());

	return true;
}
Esempio n. 29
0
bool IOI2CMaxim1631::start( IOService *nub )
{
IOReturn	status;
UInt8		configReg, cmdByte;

	DLOG("IOI2CMaxim1631::start - entered\n");

	if (false == super::start(nub))
	{
		DLOG( "IOI2CMaxim1631::start - super::start failed.  Exiting...\n" );
		return false;
	}

	if (!fGetSensorValueSym)
		fGetSensorValueSym = OSSymbol::withCString("getSensorValue");

	// According to the I2C gurus, accessing the config register is done by a COMBINED mode
	// (default for readI2C) I2C access with the 'kAccessConfigurationByte' command as the
	// "sub-addr" value.

	if (kIOReturnSuccess != (status = readI2C( kAccessConfigurationByte, &configReg, 1 )))
	{
		IOLog("IOI2CMaxim1631@%lx::start unable to read config reg\n", getI2CAddress());
		freeI2CResources();
		return false;
	}
	DLOG( "IOI2CMaxim1631::start - read config register- value = 0x%02X\n", configReg );
	if ( (configReg & 0x01) != 0 )	// not in continuous conversion mode (bit 0 == 1 is 1SHOT mode)
	{
		IOLog( "IOI2CMaxim1631::start - Note: not in continuous conversion mode. Setting mode.\n" );
		// should we also be setting the resolution bits here? -- bg
		configReg &= ~0x01;	// set 1SHOT bit to zero for continuous conversion mode
		// to write to the config register, you perform a Standard SubAddr I2C transaction
		// (which is the default mode for writeI2C()), specifying 'kAccessConfigurationByte'
		// command as the sub-addr.
		if ( kIOReturnSuccess != ( status = writeI2C( kAccessConfigurationByte, &configReg, 1 )) )
		{
			IOLog( "IOI2CMaxim1631::start - unable to turn off 1SHOT mode! Cannot provide temperature values.\n" );
			freeI2CResources();
			return false;
		}
	}

	// Tell the sensor to go into continuous temp. conversion mode.
	//	Talked to the I2C gurus and according to the diagram for the interface diagram
	//	for issuing the 'kStartConvertT' command, one needs to issue a Standard I2C write
	//	transaction.  The data buffer contains one (1) byte, which is the command byte,
	//	and we override the default "mode" so that IOI2CFamily issues the correct type
	//	of transaction. [rdar://problem/4118773]

	cmdByte = kStartConvertT;
	if ( kIOReturnSuccess != ( status = writeI2C( 0 /* no subaddr */, &cmdByte, 1, kIOI2C_CLIENT_KEY_DEFAULT, kI2CMode_Standard ) ) )
	{
		IOLog( "IOI2CMaxim1631::start - unable to start sensor (status = 0x%08X)\n", status );
	}

	// tell the world i'm here
	registerService();

	// Publish any child nubs under the max1631 node...
	publishChildren(nub);

	return(true);
}
Esempio n. 30
0
BMA180::BMA180() {
    readI2C(ACCADDR, 0x00, 1, buffer);

    sp("BMA180 ID = ");
    spln((int) buffer[0]);

    // Set ee_w bit
    readI2C(ACCADDR, CTRLREG0, 1, buffer);
    buffer[0] |= 0x10;   // Bitwise OR operator to set ee_w bit.
    writeI2C(ACCADDR, CTRLREG0, 1, buffer);   // Have to set ee_w to write any other registers.

    // Set range.
    readI2C(ACCADDR, OLSB1, 1, buffer);
    buffer[0] &= (~0x0e);   // Clear old ACC_RANGE bits.
    buffer[0] |= (ACC_RANGE << 1);   // Need to shift left one bit; refer to DS p. 21.
    writeI2C(ACCADDR, OLSB1, 1, buffer);   // Write new ACC_RANGE data, keep other bits the same.

    // Set ADC resolution (DS p. 8).
    res = 8000;   // == 1/0.000125         // [   -1,   1] g
    if      (ACC_RANGE == 1) res /= 1.5;   // [ -1.5, 1.5] g
    else if (ACC_RANGE == 2) res /= 2;     // [   -2,   2] g
    else if (ACC_RANGE == 3) res /= 3;     // [   -3,   3] g
    else if (ACC_RANGE == 4) res /= 4;     // [   -4,   4] g
    else if (ACC_RANGE == 5) res /= 8;     // [   -8,   8] g
    else if (ACC_RANGE == 6) res /= 16;    // [  -16,  16] g

    // Set bandwidth.
    //     ACC_BW  bandwidth (Hz)
    //          0              10
    //          1              20
    //          2              40
    //          3              75
    //          4             150
    //          5             300
    //          6             600
    //          7            1200
    readI2C(ACCADDR, BWTCS, 1, buffer);
    buffer[0] &= (~0xf0);   // Clear bandwidth bits <7:4>.
    buffer[0] |= (ACC_BW << 4);   // Need to shift left four bits; refer to DS p. 21.
    writeI2C(ACCADDR, BWTCS, 1, buffer);   // Keep tcs<3:0> in BWTCS, but write new ACC_BW.

    // Set mode_config to 0x01 (ultra low noise mode, DS p. 28).
    //readI2C(ACCADDR, 0x30, 1, buffer);
    //buffer[0] &= (~0x03);   // Clear mode_config bits <1:0>.
    //buffer[0] |= 0x01;
    //writeI2C(ACCADDR, 0x30, 1, buffer);

    spln("BMA180 configured!");

    for (int i=0; i<3; i++) {
        aRaw[i] = 0;
        aVec[i] = 0;
    }

    // Zero buffer.
    for (int i=0; i<6; i++) {
        buffer[i] = 0;
    }

    // Low-pass filter.
    #ifdef ACC_LPF_DEPTH
    lpfIndex = 0;
    for (int i=0; i<3; i++)
        for (int j=0; j<ACC_LPF_DEPTH; j++)
            lpfVal[i][j] = 0;
    #endif // ACC_LPF_DEPTH
}