/** ****************************************************************************** * @brief Write bytes to slave with specify register address where to * start write * @param Slave device address (7-bit right aligned) * @param Register address where to start write * @param Pointer to data byte array * @param Number of bytes to write * @retval Result status (SUCCESS or ERROR) ****************************************************************************** */ uint8_t i2c_write_multi_with_reg(uint8_t address, uint8_t reg, uint8_t* data, uint8_t len) { i2c_start(); if (i2c_check_status(MT_START) == ERROR) return ERROR; i2c_transmit((address << 1) | I2C_WRITE); if (i2c_check_status(MT_SLA_WRITE_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_transmit(reg); if (i2c_check_status(MT_DATA_TRANSMITTED_ACK) == ERROR) { i2c_stop(); return ERROR; } for (int i = 0; i < len; i++) { i2c_transmit(data[i]); if (i2c_check_status(MT_DATA_TRANSMITTED_ACK) == ERROR) { i2c_stop(); return ERROR; } } i2c_stop(); return SUCCESS; }
/** ****************************************************************************** * @brief Write byte to slave with specify register address * @param Slave device address (7-bit right aligned) * @param Register address * @param Data byte * @retval Result status (SUCCESS or ERROR) ****************************************************************************** */ uint8_t i2c_write_with_reg(uint8_t address, uint8_t reg, uint8_t data) { i2c_start(); if (i2c_check_status(MT_START) == ERROR) return ERROR; i2c_transmit((address << 1) | I2C_WRITE); if (i2c_check_status(MT_SLA_WRITE_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_transmit(reg); if (i2c_check_status(MT_DATA_TRANSMITTED_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_transmit(data); if (i2c_check_status(MT_DATA_TRANSMITTED_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_stop(); return SUCCESS; }
/** ****************************************************************************** * @brief Read bytes from slave with specify register address * @param Slave device address (7-bit right aligned) * @param Register address * @param Number of data bytes to read from slave * @param Pointer to data array byte to store data from slave * @retval Result status (SUCCESS or ERROR) ****************************************************************************** */ uint8_t i2c_read_multi_with_reg(uint8_t address, uint8_t reg, uint8_t len, uint8_t* data) { i2c_start(); if (i2c_check_status(MT_START) == ERROR) return ERROR; i2c_transmit((address << 1) | I2C_WRITE); if (i2c_check_status(MT_SLA_WRITE_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_transmit(reg); if (i2c_check_status(MT_DATA_TRANSMITTED_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_start(); if (i2c_check_status(MT_REP_START) == ERROR) return ERROR; i2c_transmit((address << 1) | I2C_READ); if (i2c_check_status(MT_SLA_READ_ACK) == ERROR) { i2c_stop(); return ERROR; } for (int i = 0; i < len; i++) { if (i == (len - 1)) { data[i] = i2c_receive_nack(); if (i2c_check_status(MT_DATA_RECEIVED_NACK) == ERROR) { i2c_stop(); return ERROR; } } else { data[i] = i2c_receive_ack(); if (i2c_check_status(MT_DATA_RECEIVED_ACK) == ERROR) { i2c_stop(); return ERROR; } } } i2c_stop(); return SUCCESS; }
/** ****************************************************************************** * @brief Check if I2C slave device is connected or not * @param Slave device address * @retval Connection status (SUCCESS or ERROR) ****************************************************************************** */ uint8_t i2c_is_device_connected(uint8_t address) { i2c_start(); if (i2c_check_status(MT_START) == ERROR) return ERROR; // Check device is connected or not // If connected, device will send ACK after // master transmit SLA+W or SLA+R i2c_transmit((address << 1) | I2C_WRITE); if (i2c_check_status(MT_SLA_WRITE_ACK) == ERROR) { i2c_stop(); return ERROR; } i2c_stop(); return SUCCESS; }
/** ****************************************************************************** * @brief Read byte from slave without specify register address * @param Slave device address (7-bit right aligned) * @param Pointer to data byte to store data from slave * @retval Result status (SUCCESS or ERROR) ****************************************************************************** */ uint8_t i2c_read_no_reg(uint8_t address, uint8_t* data) { i2c_start(); if (i2c_check_status(MT_START) == ERROR) return ERROR; i2c_transmit((address << 1) | I2C_READ); if (i2c_check_status(MT_SLA_READ_ACK) == ERROR) { i2c_stop(); return ERROR; } *data = i2c_receive_nack(); if (i2c_check_status(MT_DATA_RECEIVED_NACK) == ERROR) { i2c_stop(); return ERROR; } i2c_stop(); return SUCCESS; }
/******************************************************************************* * Function Name : i2c_open * Description : Open the I2C port communication * Input : - ClockSpeed: I2C clock frequency (<= 400000) * Output : None * Return : -1 if an error occurred *******************************************************************************/ int i2c_open(u32 ClockSpeed) { GPIO_InitTypeDef gpio_init_structure; I2C_InitTypeDef i2c_init_structure; #ifdef _I2C_AUTO_CHECK_STATUS /* Check for I2C bus status */ if (i2c_check_status() == -1) return(-1); #endif #ifdef _I2C_OS_SUPPORT /* Wait for the I2C mutex to become available */ sys_mut_wait(I2c_Mut, T_NO_TIMEOUT); #endif /* AHB peripheral clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* SCL-SDA GPIO */ gpio_init_structure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; gpio_init_structure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &gpio_init_structure); /* I2C configuration */ I2C_DeInit(I2C1); I2C_StructInit(&i2c_init_structure); i2c_init_structure.I2C_Ack = I2C_Ack_Enable; i2c_init_structure.I2C_ClockSpeed = I2C_MAX_CLOCK_SPEED(ClockSpeed); I2C_Init(I2C1, &i2c_init_structure); /* Enable I2C */ I2C_Cmd(I2C1, ENABLE); #ifdef _I2C_BUS_ERROR_RESET /* Reset system if bus is busy (happens if SDL or SDA is stuck low) */ if (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) NVIC_SystemReset(); #endif return(0); }