diff --git a/os/hal/include/i2c.h b/os/hal/include/i2c.h index c46e7f096..ba7131c26 100644 --- a/os/hal/include/i2c.h +++ b/os/hal/include/i2c.h @@ -103,7 +103,7 @@ typedef enum { * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2ccallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); +typedef void (*i2ccallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); /** @@ -114,7 +114,7 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); * @param[in] i2cscfg pointer to the @p I2CSlaveConfig object triggering the * callback */ -typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg); +typedef void (*i2cerrorcallback_t)(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg); /** @@ -143,20 +143,8 @@ struct I2CSlaveConfig{ */ i2cerrorcallback_t id_err_callback; -// size_t txbytes; /*!< Number of bytes to transmitted. */ -// size_t rxbytes; /*!< Number of bytes to received. */ i2cblock_t *rxbuf; /*!< Pointer to receive buffer. */ i2cblock_t *txbuf; /*!< Pointer to transmit buffer.*/ - /** - * @brief Slave device address. - * @details Bits 0-9 contain slave device address. - * - * Bit 15 must be set to 1 if 10-bit addressing modes used. Otherwise - * keep it cleared. - * - * Bits 10-14 unused. - */ - uint16_t slave_addr; /* Status Change @p EventSource.*/ EventSource sevent; @@ -240,8 +228,8 @@ extern "C" { void i2cObjectInit(I2CDriver *i2cp); void i2cStart(I2CDriver *i2cp, const I2CConfig *config); void i2cStop(I2CDriver *i2cp); - void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t txbytes, size_t rxbytes); - void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t rxbytes); + void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, size_t txbytes, size_t rxbytes); + void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, size_t rxbytes); void i2cMasterStart(I2CDriver *i2cp); void i2cMasterStop(I2CDriver *i2cp); void i2cAddFlagsI(I2CDriver *i2cp, i2cflags_t mask); diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c index be7707796..729e14eb3 100644 --- a/os/hal/platforms/STM32/i2c_lld.c +++ b/os/hal/platforms/STM32/i2c_lld.c @@ -106,7 +106,7 @@ static void i2c_serve_event_interrupt(I2CDriver *i2cp) { /* Disable ITEVT In order to not have again a BTF IT */ dp->CR2 &= (uint16_t)~I2C_CR2_ITEVTEN; /* send restart and begin reading operations */ - i2c_lld_master_receive(i2cp, i2cp->rxbytes); + i2c_lld_master_receive(i2cp, i2cp->slave_addr, i2cp->rxbytes); } break; @@ -514,9 +514,16 @@ void i2c_lld_stop(I2CDriver *i2cp) { * @brief Transmits data ever the I2C bus as master. * * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbytes number of bytes to be transmited + * @param[in] rxbytes number of bytes to be received * */ -void i2c_lld_master_transmit(I2CDriver *i2cp, size_t txbytes, size_t rxbytes) { +void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, size_t txbytes, size_t rxbytes) { + i2cp->slave_addr = slave_addr; i2cp->txbytes = txbytes; i2cp->rxbytes = rxbytes; @@ -524,17 +531,17 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, size_t txbytes, size_t rxbytes) { i2cp->id_i2c->CR2 |= (I2C_CR2_ITERREN|I2C_CR2_ITEVTEN|I2C_CR2_ITBUFEN); i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - if(i2cp->id_slave_config->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 - i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr >>7) & 0x0006); + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); // add the header bits with LSB = 0 -> write i2cp->slave_addr1 |= 0xF0; // the remaining 8 bit of 10-bit address - i2cp->slave_addr2 = i2cp->id_slave_config->slave_addr & 0x00FF; + i2cp->slave_addr2 = slave_addr & 0x00FF; } else{ // LSB = 0 -> write - i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) & 0x00FE); + i2cp->slave_addr1 = ((slave_addr <<1) & 0x00FE); } i2cp->flags = 0; @@ -556,9 +563,16 @@ void i2c_lld_master_transmit(I2CDriver *i2cp, size_t txbytes, size_t rxbytes) { * @brief Receives data from the I2C bus. * * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbytes number of bytes to be transmited + * @param[in] rxbytes number of bytes to be received * */ -void i2c_lld_master_receive(I2CDriver *i2cp, size_t rxbytes){ +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, size_t rxbytes){ + i2cp->slave_addr = slave_addr; i2cp->rxbytes = rxbytes; // enable ERR, EVT & BUF ITs @@ -566,17 +580,17 @@ void i2c_lld_master_receive(I2CDriver *i2cp, size_t rxbytes){ i2cp->id_i2c->CR1 |= I2C_CR1_ACK; // acknowledge returned i2cp->id_i2c->CR1 &= ~I2C_CR1_POS; - if(i2cp->id_slave_config->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 - i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr >>7) & 0x0006); + i2cp->slave_addr1 = ((slave_addr >>7) & 0x0006); // add the header bits (the LSB -> 1 will be add to second i2cp->slave_addr1 |= 0xF0; // the remaining 8 bit of 10-bit address - i2cp->slave_addr2 = i2cp->id_slave_config->slave_addr & 0x00FF; + i2cp->slave_addr2 = slave_addr & 0x00FF; } else{ // LSB = 1 -> receive - i2cp->slave_addr1 = ((i2cp->id_slave_config->slave_addr <<1) | 0x01); + i2cp->slave_addr1 = ((slave_addr <<1) | 0x01); } i2cp->flags = I2C_FLG_MASTER_RECEIVER; diff --git a/os/hal/platforms/STM32/i2c_lld.h b/os/hal/platforms/STM32/i2c_lld.h index 83b4f7812..c3df51b07 100644 --- a/os/hal/platforms/STM32/i2c_lld.h +++ b/os/hal/platforms/STM32/i2c_lld.h @@ -161,17 +161,18 @@ struct I2CDriver{ /** * @brief Current slave configuration data. */ - I2CSlaveConfig *id_slave_config; + const I2CSlaveConfig *id_slave_config; - uint8_t slave_addr1; /*!< 7-bit address of the slave with r\w bit.*/ - uint8_t slave_addr2; /*!< used in 10-bit address mode. */ - - size_t rxbytes; - size_t txbytes; + size_t txbytes; /*!< Number of bytes to transmitted. */ + size_t rxbytes; /*!< Number of bytes to received. */ i2cflags_t errors; /*!< Error flags.*/ i2cflags_t flags; /*!< State flags.*/ + uint16_t slave_addr; /*!< Current slave address. */ + uint8_t slave_addr1; /*!< 7-bit address of the slave with r\w bit.*/ + uint8_t slave_addr2; /*!< Used in 10-bit address mode. */ + /*********** End of the mandatory fields. **********************************/ /** @@ -222,8 +223,8 @@ void i2c_lld_set_opmode(I2CDriver *i2cp); void i2c_lld_set_own_address(I2CDriver *i2cp); void i2c_lld_start(I2CDriver *i2cp); void i2c_lld_stop(I2CDriver *i2cp); -void i2c_lld_master_transmit(I2CDriver *i2cp, size_t txbytes, size_t rxbytes); -void i2c_lld_master_receive(I2CDriver *i2cp, size_t rxbytes); +void i2c_lld_master_transmit(I2CDriver *i2cp, uint16_t slave_addr, size_t txbytes, size_t rxbytes); +void i2c_lld_master_receive(I2CDriver *i2cp, uint16_t slave_addr, size_t rxbytes); #ifdef __cplusplus } diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c index dc48b9478..4e3f5e5b9 100644 --- a/os/hal/src/i2c.c +++ b/os/hal/src/i2c.c @@ -135,11 +135,17 @@ void i2cStop(I2CDriver *i2cp) { * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] i2cscfg pointer to the @p I2C slave config - * + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbytes number of bytes to be transmited + * @param[in] rxbytes number of bytes to be received */ -void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t txbytes, size_t rxbytes) { +void i2cMasterTransmit(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, size_t txbytes, size_t rxbytes) { chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ + (slave_addr != 0) &&\ (txbytes > 0) &&\ (i2cscfg->txbuf != NULL), "i2cMasterTransmit"); @@ -162,7 +168,7 @@ void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t txbytes, "i2cMasterTransmit(), #1", "not ready"); i2cp->id_state = I2C_ACTIVE; - i2c_lld_master_transmit(i2cp, txbytes, rxbytes); + i2c_lld_master_transmit(i2cp, slave_addr, txbytes, rxbytes); _i2c_wait_s(i2cp); #if !I2C_USE_WAIT i2c_lld_wait_bus_free(i2cp); @@ -177,11 +183,16 @@ void i2cMasterTransmit(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t txbytes, * * @param[in] i2cp pointer to the @p I2CDriver object * @param[in] i2cscfg pointer to the @p I2C slave config - * + * @param[in] slave_addr Slave device address. Bits 0-9 contain slave + * device address. Bit 15 must be set to 1 if 10-bit + * addressing modes used. Otherwise keep it cleared. + * Bits 10-14 unused. + * @param[in] txbytes number of bytes to be transmited */ -void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t rxbytes){ +void i2cMasterReceive(I2CDriver *i2cp, const I2CSlaveConfig *i2cscfg, uint16_t slave_addr, size_t rxbytes){ chDbgCheck((i2cp != NULL) && (i2cscfg != NULL) &&\ + (slave_addr != 0) &&\ (rxbytes > 0) && \ (i2cscfg->rxbuf != NULL), "i2cMasterReceive"); @@ -204,7 +215,7 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t rxbytes){ "i2cMasterReceive(), #1", "not ready"); i2cp->id_state = I2C_ACTIVE; - i2c_lld_master_receive(i2cp, rxbytes); + i2c_lld_master_receive(i2cp, slave_addr, rxbytes); _i2c_wait_s(i2cp); #if !I2C_USE_WAIT i2c_lld_wait_bus_free(i2cp); @@ -215,6 +226,7 @@ void i2cMasterReceive(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg, size_t rxbytes){ } +// FIXME: I do not know what this function must do. And can not test it //uint16_t i2cSMBusAlertResponse(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg) { // // i2cMasterReceive(i2cp, i2cscfg); diff --git a/testhal/STM32/I2C/lis3.c b/testhal/STM32/I2C/lis3.c index a4eb40603..00bb712a1 100644 --- a/testhal/STM32/I2C/lis3.c +++ b/testhal/STM32/I2C/lis3.c @@ -26,20 +26,6 @@ static void i2c_lis3_error_cb(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){ while(TRUE); } -// Accelerometer lis3lv02dq config -static I2CSlaveConfig lis3 = { - NULL, - i2c_lis3_error_cb, - accel_rx_data, - accel_tx_data, - 0b0011101, - {NULL}, -}; - - - - - /** * This treading need for convenient realize * "read through write" process. @@ -53,7 +39,7 @@ static msg_t I2CAccelThread(void *arg) { int16_t acceleration_y = 0; int16_t acceleration_z = 0; - I2CDriver *i2cp; + I2CSlaveConfig *i2cscfg; msg_t msg; while (TRUE) { @@ -65,30 +51,42 @@ static msg_t I2CAccelThread(void *arg) { chSysUnlock(); /***************** Perform processing here. ***************************/ - i2cp = (I2CDriver *)msg; + i2cscfg = (I2CSlaveConfig *)msg; /* collect measured data */ - acceleration_x = lis3.rxbuf[0] + (lis3.rxbuf[1] << 8); - acceleration_y = lis3.rxbuf[2] + (lis3.rxbuf[3] << 8); - acceleration_z = lis3.rxbuf[4] + (lis3.rxbuf[5] << 8); + acceleration_x = i2cscfg->rxbuf[0] + (i2cscfg->rxbuf[1] << 8); + acceleration_y = i2cscfg->rxbuf[2] + (i2cscfg->rxbuf[3] << 8); + acceleration_z = i2cscfg->rxbuf[4] + (i2cscfg->rxbuf[5] << 8); } return 0; } - - /* This callback raise up when transfer finished */ static void i2c_lis3_cb(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){ - (void) i2cscfg; - + (void) i2cp; // only wake up processing thread if (i2c_accel_tp != NULL) { - i2c_accel_tp->p_msg = (msg_t)i2cp; + i2c_accel_tp->p_msg = (msg_t)i2cscfg; chSchReadyI(i2c_accel_tp); i2c_accel_tp = NULL; } } + +// Accelerometer lis3lv02dq config +static const I2CSlaveConfig lis3 = { + i2c_lis3_cb, + i2c_lis3_error_cb, + accel_rx_data, + accel_tx_data, + {NULL}, +}; + + +#define lis3_addr 0b0011101 + + + /** * Init function. Here we will also start personal serving thread. */ @@ -105,8 +103,8 @@ int init_lis3(void){ while (i2c_accel_tp == NULL) chThdSleepMilliseconds(1); -#define RXBYTES 0 //set to 0 because we need only transmit #define TXBYTES 4 +#define RXBYTES 0 //set to 0 because we need only transmit /* configure accelerometer */ lis3.txbuf[0] = ACCEL_CTRL_REG1 | AUTO_INCREMENT_BIT; // register address @@ -115,9 +113,8 @@ int init_lis3(void){ lis3.txbuf[3] = 0b00000000; /* sending */ - i2cMasterTransmit(&I2CD1, &lis3, TXBYTES, RXBYTES); + i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, TXBYTES, RXBYTES); chThdSleepMilliseconds(1); - lis3.id_callback = i2c_lis3_cb; #undef RXBYTES #undef TXBYTES @@ -133,7 +130,7 @@ void request_acceleration_data(void){ #define TXBYTES 1 lis3.txbuf[0] = ACCEL_OUT_DATA | AUTO_INCREMENT_BIT; // register address i2cAcquireBus(&I2CD1); - i2cMasterTransmit(&I2CD1, &lis3, TXBYTES, RXBYTES); + i2cMasterTransmit(&I2CD1, &lis3, lis3_addr, TXBYTES, RXBYTES); i2cReleaseBus(&I2CD1); #undef RXBYTES #undef TXBYTES diff --git a/testhal/STM32/I2C/max1236.c b/testhal/STM32/I2C/max1236.c index 80e477170..ed9d12ca6 100644 --- a/testhal/STM32/I2C/max1236.c +++ b/testhal/STM32/I2C/max1236.c @@ -39,15 +39,15 @@ static void i2c_max1236_cb(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){ // ADC maxim MAX1236 config -static I2CSlaveConfig max1236 = { - NULL, +static const I2CSlaveConfig max1236 = { + i2c_max1236_cb, i2c_max1236_error_cb, max1236_rx_data, max1236_tx_data, - 0b0110100, {NULL}, }; +#define max1236_addr 0b0110100 /** * Initilization routine. See datasheet on page 13 to understand @@ -63,12 +63,10 @@ void init_max1236(void){ // transmit out 2 bytes i2cAcquireBus(&I2CD2); - i2cMasterTransmit(&I2CD2, &max1236, TXBYTES, RXBYTES); + i2cMasterTransmit(&I2CD2, &max1236, max1236_addr, TXBYTES, RXBYTES); while(I2CD2.id_state != I2C_READY){ chThdSleepMilliseconds(1); } - /* now add pointer to callback function */ - max1236.id_callback = i2c_max1236_cb; i2cReleaseBus(&I2CD2); #undef RXBYTES #undef TXBYTES @@ -81,7 +79,7 @@ void read_max1236(void){ #define RXBYTES 8 i2cAcquireBus(&I2CD2); - i2cMasterReceive(&I2CD2, &max1236, RXBYTES); + i2cMasterReceive(&I2CD2, &max1236, max1236_addr, RXBYTES); i2cReleaseBus(&I2CD2); #undef RXBYTES #undef TXBYTES diff --git a/testhal/STM32/I2C/tmp75.c b/testhal/STM32/I2C/tmp75.c index e5f502e23..6744fe325 100644 --- a/testhal/STM32/I2C/tmp75.c +++ b/testhal/STM32/I2C/tmp75.c @@ -34,22 +34,23 @@ static void i2c_tmp75_cb(I2CDriver *i2cp, I2CSlaveConfig *i2cscfg){ } // Fill TMP75 config. -static I2CSlaveConfig tmp75 = { +static const I2CSlaveConfig tmp75 = { i2c_tmp75_cb, i2c_tmp75_error_cb, tmp75_rx_data, tmp75_tx_data, - 0b1001000, {NULL}, }; +#define tmp75_addr 0b1001000 + /* This is main function. */ void request_temperature(void){ #define TXBYTES 0 // set to zero because we need only reading #define RXBYTES 2 // we need to read 2 bytes i2cAcquireBus(&I2CD2); - i2cMasterReceive(&I2CD2, &tmp75, RXBYTES); + i2cMasterReceive(&I2CD2, &tmp75, tmp75_addr, RXBYTES); i2cReleaseBus(&I2CD2); }