I2C. Driver looks working, but sometimes hangs up. I don't know, my big project cause troubles in it, or driver cause troubles in my project.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3116 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
barthess 2011-07-03 18:02:55 +00:00
parent af0e40079d
commit ccb28114da
9 changed files with 179 additions and 71 deletions

View File

@ -165,9 +165,9 @@ struct I2CSlaveConfig{
* @notapi * @notapi
*/ */
#define _i2c_wait_s(i2cp) { \ #define _i2c_wait_s(i2cp) { \
chDbgAssert((i2cp)->id_thread == NULL, \ chDbgAssert((i2cp)->id_thread == NULL, \
"_i2c_wait(), #1", "already waiting"); \ "_i2c_wait(), #1", "already waiting"); \
(i2cp)->id_thread = chThdSelf(); \ (i2cp)->id_thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \ chSchGoSleepS(THD_STATE_SUSPENDED); \
} }
@ -179,9 +179,9 @@ struct I2CSlaveConfig{
* @notapi * @notapi
*/ */
#define _i2c_wakeup_isr(i2cp) { \ #define _i2c_wakeup_isr(i2cp) { \
if ((i2cp)->id_thread != NULL) { \ if ((i2cp)->id_thread != NULL) { \
Thread *tp = (i2cp)->id_thread; \ Thread *tp = (i2cp)->id_thread; \
(i2cp)->id_thread = NULL; \ (i2cp)->id_thread = NULL; \
chSysLockFromIsr(); \ chSysLockFromIsr(); \
chSchReadyI(tp); \ chSchReadyI(tp); \
chSysUnlockFromIsr(); \ chSysUnlockFromIsr(); \
@ -218,6 +218,31 @@ struct I2CSlaveConfig{
_i2c_wakeup_isr(i2cp); \ _i2c_wakeup_isr(i2cp); \
} }
/**
* @brief Error ISR code.
* @details This code handles the portable part of the ISR code:
* - Error callback invocation.
* - Waiting thread wakeup, if any.
* - Driver state transitions.
*
* @note This macro is meant to be used in the low level drivers
* implementation only.
*
* @param[in] i2cp pointer to the @p I2CDriver object
*
* @notapi
*/
#define _i2c_isr_err_code(i2cp, i2cscfg) { \
(i2cp)->id_state = I2C_COMPLETE; \
if(((i2cp)->id_slave_config)->id_err_callback) { \
((i2cp)->id_slave_config)->id_err_callback(i2cp, i2cscfg); \
if((i2cp)->id_state == I2C_COMPLETE) \
(i2cp)->id_state = I2C_READY; \
} \
else \
(i2cp)->id_state = I2C_READY; \
_i2c_wakeup_isr(i2cp); \
}
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */

View File

@ -94,20 +94,20 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) {
} }
break; break;
case I2C_EV8_2_MASTER_BYTE_TRANSMITTED: case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
/* Disable ITEVT In order to not have again a BTF IT */
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
/* if nothing to read then generate stop */ /* if nothing to read then generate stop */
if (i2cp->rxbytes == 0){ if (i2cp->rxbytes == 0){
dp->CR1 |= I2C_CR1_STOP; dp->CR1 |= I2C_CR1_STOP;
/* Disable ITEVT In order to not have again a BTF IT */
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
/* Portable I2C ISR code defined in the high level driver, /* Portable I2C ISR code defined in the high level driver,
* note, it is a macro.*/ * note, it is a macro.*/
_i2c_isr_code(i2cp, i2cp->id_slave_config); _i2c_isr_code(i2cp, i2cp->id_slave_config);
} }
else{ else{
/* Disable ITEVT In order to not have again a BTF IT */
dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN;
/* send restart and begin reading operations */ /* send restart and begin reading operations */
i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbuf, i2cp->rxbytes); chSysLockFromIsr();
i2c_lld_master_transceive(i2cp);
chSysUnlockFromIsr();
} }
break; break;
@ -242,10 +242,10 @@ static void i2c_serve_error_interrupt(I2CDriver *i2cp) {
if(flags != I2CD_NO_ERROR) { if(flags != I2CD_NO_ERROR) {
/* send communication end signal */ /* send communication end signal */
_i2c_isr_code(i2cp, i2cp->id_slave_config);
chSysLockFromIsr(); chSysLockFromIsr();
i2cAddFlagsI(i2cp, flags); i2cAddFlagsI(i2cp, flags);
chSysUnlockFromIsr(); chSysUnlockFromIsr();
_i2c_isr_err_code(i2cp, i2cp->id_slave_config);
} }
} }
@ -539,10 +539,6 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
i2cp->txbuf = txbuf; i2cp->txbuf = txbuf;
i2cp->rxbuf = rxbuf; i2cp->rxbuf = rxbuf;
/* enable ERR, EVT & BUF ITs */
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
if(slave_addr & 0x8000){/* 10-bit mode used */ if(slave_addr & 0x8000){/* 10-bit mode used */
/* add the two msb of 10-bit address to the header */ /* add the two msb of 10-bit address to the header */
i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006);
@ -568,9 +564,18 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) // while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
// ; // ;
//#endif /* I2C_USE_WAIT */ //#endif /* I2C_USE_WAIT */
uint32_t timeout = 0xfffff;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
; uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
;
/* is timeout overflows? */
chDbgAssert(timeout < I2C_START_TIMEOUT,
"i2c_lld_master_transmit(), #1", "time is out");
/* enable ERR, EVT & BUF ITs */
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
} }
@ -593,11 +598,6 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
i2cp->rxbytes = rxbytes; i2cp->rxbytes = rxbytes;
i2cp->rxbuf = rxbuf; i2cp->rxbuf = rxbuf;
/* enable ERR, EVT & BUF ITs */
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
if(slave_addr & 0x8000){/* 10-bit mode used */ if(slave_addr & 0x8000){/* 10-bit mode used */
/* add the two msb of 10-bit address to the header */ /* add the two msb of 10-bit address to the header */
i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006);
@ -633,9 +633,62 @@ void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--) // while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
// ; // ;
//#endif /* I2C_USE_WAIT */ //#endif /* I2C_USE_WAIT */
uint32_t timeout = 0xfffff;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
; uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
;
/* is timeout overflows? */
chDbgAssert(timeout < I2C_START_TIMEOUT,
"i2c_lld_master_receive(), #1", "time is out");
/* enable ERR, EVT & BUF ITs */
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
}
void i2c_lld_master_transceive(I2CDriver *i2cp){
i2cp->flags = I2C_FLG_MASTER_RECEIVER;
i2cp->errors = 0;
i2cp->slave_addr1 |= 0x01;
/* Only one byte to be received */
if(i2cp->rxbytes == 1) {
i2cp->flags |= I2C_FLG_1BTR;
}
/* Only two bytes to be received */
else if(i2cp->rxbytes == 2) {
i2cp->flags |= I2C_FLG_2BTR;
i2cp->id_i2c->CR1 |= I2C_CR1_POS; /* Acknowledge Position */
}
i2cp->id_i2c->CR1 |= I2C_CR1_START; /* send start bit */
//#if !I2C_USE_WAIT
// /* Wait until the START condition is generated on the bus:
// * the START bit is cleared by hardware */
// uint32_t timeout = 0xfffff;
// while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
// ;
//#endif /* I2C_USE_WAIT */
uint32_t timeout = I2C_START_TIMEOUT;
while((i2cp->id_i2c->CR1 & I2C_CR1_START) && timeout--)
;
/* is timeout overflows? */
chDbgAssert(timeout < I2C_START_TIMEOUT,
"i2c_lld_master_receive(), #1", "time is out");
/* enable ERR, EVT & BUF ITs */
i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN);
i2cp->id_i2c->CR1 |= I2C_CR1_ACK; /* acknowledge returned */
i2cp->id_i2c->CR1 &= ~I2C_CR1_POS;
} }

View File

@ -13,6 +13,7 @@
/*===========================================================================*/ /*===========================================================================*/
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
#define I2C_START_TIMEOUT 0xFFFF
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
@ -233,6 +234,7 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr,
uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes); uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes);
void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr,
uint8_t *rxbuf, size_t rxbytes); uint8_t *rxbuf, size_t rxbytes);
void i2c_lld_master_transceive(I2CDriver *i2cp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -165,15 +165,18 @@ void i2cMasterTransmit(I2CDriver *i2cp,
/* init slave config field in driver */ /* init slave config field in driver */
i2cp->id_slave_config = i2cscfg; i2cp->id_slave_config = i2cscfg;
//#if I2C_USE_WAIT #if I2C_USE_WAIT
// i2c_lld_wait_bus_free(i2cp); i2c_lld_wait_bus_free(i2cp);
// if(i2c_lld_bus_is_busy(i2cp)) { if(i2c_lld_bus_is_busy(i2cp)) {
//#ifdef PRINTTRACE #ifdef PRINTTRACE
// print("I2C Bus busy!\n"); print("I2C Bus busy!\n");
//#endif return;
// return; #else
// }; /* the time is out */
//#endif chDbgAssert(FALSE, "i2cMasterTransmit(), #1", "time is out");
#endif
};
#endif
chSysLock(); chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY, chDbgAssert(i2cp->id_state == I2C_READY,
@ -211,15 +214,18 @@ void i2cMasterReceive(I2CDriver *i2cp,
/* init slave config field in driver */ /* init slave config field in driver */
i2cp->id_slave_config = i2cscfg; i2cp->id_slave_config = i2cscfg;
//#if I2C_USE_WAIT #if I2C_USE_WAIT
// i2c_lld_wait_bus_free(i2cp); i2c_lld_wait_bus_free(i2cp);
// if(i2c_lld_bus_is_busy(i2cp)) { if(i2c_lld_bus_is_busy(i2cp)) {
//#ifdef PRINTTRACE #ifdef PRINTTRACE
// print("I2C Bus busy!\n"); print("I2C Bus busy!\n");
//#endif return;
// return; #else
// }; /* the time is out */
//#endif chDbgAssert(FALSE, "i2cMasterReceive(), #1", "time is out");
#endif
};
#endif
chSysLock(); chSysLock();
chDbgAssert(i2cp->id_state == I2C_READY, chDbgAssert(i2cp->id_state == I2C_READY,

View File

@ -173,6 +173,14 @@
/* I2C driver related settings. */ /* I2C driver related settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(I2C_USE_WAIT) || defined(__DOXYGEN__)
#define I2C_USE_WAIT TRUE
#endif
/** /**
* @brief Enables the mutual exclusion APIs on the I2C bus. * @brief Enables the mutual exclusion APIs on the I2C bus.
*/ */

View File

@ -54,9 +54,9 @@ static msg_t I2CAccelThread(void *arg) {
i2cscfg = (I2CSlaveConfig *)msg; i2cscfg = (I2CSlaveConfig *)msg;
/* collect measured data */ /* collect measured data */
acceleration_x = i2cscfg->rxbuf[0] + (i2cscfg->rxbuf[1] << 8); acceleration_x = accel_rx_data[0] + (accel_rx_data[1] << 8);
acceleration_y = i2cscfg->rxbuf[2] + (i2cscfg->rxbuf[3] << 8); acceleration_y = accel_rx_data[2] + (accel_rx_data[3] << 8);
acceleration_z = i2cscfg->rxbuf[4] + (i2cscfg->rxbuf[5] << 8); acceleration_z = accel_rx_data[4] + (accel_rx_data[5] << 8);
} }
return 0; return 0;
} }
@ -77,8 +77,6 @@ static void i2c_lis3_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
static const I2CSlaveConfig lis3 = { static const I2CSlaveConfig lis3 = {
i2c_lis3_cb, i2c_lis3_cb,
i2c_lis3_error_cb, i2c_lis3_error_cb,
accel_rx_data,
accel_tx_data,
}; };
@ -106,13 +104,13 @@ int init_lis3(void){
#define RXBYTES 0 /* set to 0 because we need only transmit */ #define RXBYTES 0 /* set to 0 because we need only transmit */
/* configure accelerometer */ /* configure accelerometer */
lis3.txbuf[0] = ACCEL_CTRL_REG1 | AUTO_INCREMENT_BIT; /* register address */ accel_tx_data[0] = ACCEL_CTRL_REG1 | AUTO_INCREMENT_BIT; /* register address */
lis3.txbuf[1] = 0b11100111; accel_tx_data[1] = 0b11100111;
lis3.txbuf[2] = 0b01000001; accel_tx_data[2] = 0b01000001;
lis3.txbuf[3] = 0b00000000; accel_tx_data[3] = 0b00000000;
/* sending */ /* sending */
i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, TXBYTES, RXBYTES); i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, accel_tx_data, TXBYTES, accel_rx_data, RXBYTES);
chThdSleepMilliseconds(1); chThdSleepMilliseconds(1);
#undef RXBYTES #undef RXBYTES
@ -127,9 +125,9 @@ int init_lis3(void){
void request_acceleration_data(void){ void request_acceleration_data(void){
#define RXBYTES 6 #define RXBYTES 6
#define TXBYTES 1 #define TXBYTES 1
lis3.txbuf[0] = ACCEL_OUT_DATA | AUTO_INCREMENT_BIT; // register address accel_tx_data[0] = ACCEL_OUT_DATA | AUTO_INCREMENT_BIT; // register address
i2cAcquireBus(&I2CD1); i2cAcquireBus(&I2CD1);
i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, TXBYTES, RXBYTES); i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, accel_tx_data, TXBYTES, accel_rx_data, RXBYTES);
i2cReleaseBus(&I2CD1); i2cReleaseBus(&I2CD1);
#undef RXBYTES #undef RXBYTES
#undef TXBYTES #undef TXBYTES

View File

@ -29,6 +29,23 @@
/*
* Red LEDs blinker thread, times are in milliseconds.
*/
static WORKING_AREA(BlinkWA, 128);
static msg_t Blink(void *arg) {
(void)arg;
while (TRUE) {
palClearPad(IOPORT3, GPIOC_LED);
chThdSleepMilliseconds(500);
palSetPad(IOPORT3, GPIOC_LED);
chThdSleepMilliseconds(500);
}
return 0;
}
/* Temperature polling thread */ /* Temperature polling thread */
static WORKING_AREA(PollTmp75ThreadWA, 128); static WORKING_AREA(PollTmp75ThreadWA, 128);
static msg_t PollTmp75Thread(void *arg) { static msg_t PollTmp75Thread(void *arg) {
@ -110,6 +127,8 @@ int main(void) {
PollAccelThread, PollAccelThread,
NULL); NULL);
/* Creates the blinker thread. */
chThdCreateStatic(BlinkWA, sizeof(BlinkWA), LOWPRIO, Blink, NULL);
/* main loop that do nothing */ /* main loop that do nothing */
while (TRUE) { while (TRUE) {

View File

@ -29,11 +29,12 @@ static void i2c_max1236_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg)
/* This callback raise up when transfer finished */ /* This callback raise up when transfer finished */
static void i2c_max1236_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){ static void i2c_max1236_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
(void)*i2cp; (void)*i2cp;
(void)*i2cscfg;
/* get ADC data */ /* get ADC data */
ch1 = ((i2cscfg->rxbuf[0] & 0xF) << 8) + i2cscfg->rxbuf[1]; ch1 = ((max1236_rx_data[0] & 0xF) << 8) + max1236_rx_data[1];
ch2 = ((i2cscfg->rxbuf[2] & 0xF) << 8) + i2cscfg->rxbuf[3]; ch2 = ((max1236_rx_data[2] & 0xF) << 8) + max1236_rx_data[3];
ch3 = ((i2cscfg->rxbuf[4] & 0xF) << 8) + i2cscfg->rxbuf[5]; ch3 = ((max1236_rx_data[4] & 0xF) << 8) + max1236_rx_data[5];
ch4 = ((i2cscfg->rxbuf[6] & 0xF) << 8) + i2cscfg->rxbuf[7]; ch4 = ((max1236_rx_data[6] & 0xF) << 8) + max1236_rx_data[7];
} }
@ -42,8 +43,6 @@ static void i2c_max1236_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
static const I2CSlaveConfig max1236 = { static const I2CSlaveConfig max1236 = {
i2c_max1236_cb, i2c_max1236_cb,
i2c_max1236_error_cb, i2c_max1236_error_cb,
max1236_rx_data,
max1236_tx_data,
}; };
#define max1236_addr 0b0110100 #define max1236_addr 0b0110100
@ -56,13 +55,13 @@ void init_max1236(void){
/* this data we must send via IC to setup ADC */ /* this data we must send via IC to setup ADC */
#define RXBYTES 0 #define RXBYTES 0
#define TXBYTES 2 #define TXBYTES 2
max1236.txbuf[0] = 0b10000011; /* config register content. Consult datasheet */ max1236_tx_data[0] = 0b10000011; /* config register content. Consult datasheet */
max1236.txbuf[1] = 0b00000111; /* config register content. Consult datasheet */ max1236_tx_data[1] = 0b00000111; /* config register content. Consult datasheet */
/* transmit out 2 bytes */ /* transmit out 2 bytes */
i2cAcquireBus(&I2CD2); i2cAcquireBus(&I2CD2);
i2cMasterTransmit(&I2CD2, &max1236, max1236_addr, TXBYTES, RXBYTES); i2cMasterTransmit(&I2CD2, &max1236, max1236_addr, max1236_tx_data, TXBYTES, max1236_rx_data, RXBYTES);
while(I2CD2.id_state != I2C_READY){ while(I2CD2.id_state != I2C_READY){
chThdSleepMilliseconds(1); chThdSleepMilliseconds(1);
} }
@ -78,7 +77,7 @@ void read_max1236(void){
#define RXBYTES 8 #define RXBYTES 8
i2cAcquireBus(&I2CD2); i2cAcquireBus(&I2CD2);
i2cMasterReceive(&I2CD2, &max1236, max1236_addr, RXBYTES); i2cMasterReceive(&I2CD2, &max1236, max1236_addr, max1236_rx_data, RXBYTES);
i2cReleaseBus(&I2CD2); i2cReleaseBus(&I2CD2);
#undef RXBYTES #undef RXBYTES
#undef TXBYTES #undef TXBYTES

View File

@ -14,7 +14,6 @@
/* input buffer */ /* input buffer */
static i2cblock_t tmp75_rx_data[TMP75_RX_DEPTH]; static i2cblock_t tmp75_rx_data[TMP75_RX_DEPTH];
static i2cblock_t tmp75_tx_data[TMP75_TX_DEPTH];
/* temperature value */ /* temperature value */
static int16_t temperature = 0; static int16_t temperature = 0;
@ -29,16 +28,15 @@ static void i2c_tmp75_error_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
/* This callback raise up when transfer finished */ /* This callback raise up when transfer finished */
static void i2c_tmp75_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){ static void i2c_tmp75_cb(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg){
(void)*i2cp; (void)*i2cp;
(void)*i2cscfg;
/* store temperature value */ /* store temperature value */
temperature = (i2cscfg->rxbuf[0] << 8) + i2cscfg->rxbuf[1]; temperature = (tmp75_rx_data[0] << 8) + tmp75_rx_data[1];
} }
/* Fill TMP75 config. */ /* Fill TMP75 config. */
static const I2CSlaveConfig tmp75 = { static const I2CSlaveConfig tmp75 = {
i2c_tmp75_cb, i2c_tmp75_cb,
i2c_tmp75_error_cb, i2c_tmp75_error_cb,
tmp75_rx_data,
tmp75_tx_data,
}; };
#define tmp75_addr 0b1001000 #define tmp75_addr 0b1001000
@ -49,7 +47,7 @@ void request_temperature(void){
#define RXBYTES 2 /* we need to read 2 bytes */ #define RXBYTES 2 /* we need to read 2 bytes */
i2cAcquireBus(&I2CD2); i2cAcquireBus(&I2CD2);
i2cMasterReceive(&I2CD2, &tmp75, tmp75_addr, RXBYTES); i2cMasterReceive(&I2CD2, &tmp75, tmp75_addr, tmp75_rx_data, RXBYTES);
i2cReleaseBus(&I2CD2); i2cReleaseBus(&I2CD2);
} }