/** \brief Read a Byte in blocking mode and set the status. * * \param dev_num bsp_dev_i2c_t: I2C dev num. * \param rx_data uint8_t*: The received byte. * \return bsp_status_t: status of the transfer. * */ bsp_status_t bsp_i2c_master_read_u8(bsp_dev_i2c_t dev_num, uint8_t* rx_data) { (void)dev_num; unsigned char data; int i; /* Read 8 bits */ data = 0; for(i = 0; i < 8; i++) { set_sda_float(); i2c_sw_delay(); set_scl_float(); i2c_sw_delay(); data <<= 1; if(get_sda()) data |= 1; set_scl_low(); i2c_sw_delay(); } *rx_data = data; /* Do not Send ACK / NACK because sent by bsp_i2c_read_ack() */ return BSP_OK; }
/** \brief Sends a Byte in blocking mode and set the status. * * \param dev_num bsp_dev_i2c_t: I2C dev num. * \param tx_data uint8_t: data to send. * \param tx_ack_flag bool*: TRUE means ACK, FALSE means NACK. * \return bsp_status_t: status of the transfer. * */ bsp_status_t bsp_i2c_master_write_u8(bsp_dev_i2c_t dev_num, uint8_t tx_data, bool* tx_ack_flag) { (void)dev_num; int i; unsigned char ack_val; /* Write 8 bits */ for(i = 0; i < 8; i++) { if(tx_data & 0x80) set_sda_float(); else set_sda_low(); i2c_sw_delay(); set_scl_float(); i2c_sw_delay(); set_scl_low(); tx_data <<= 1; } /* Read 1 bit ACK or NACK */ set_sda_float(); i2c_sw_delay(); set_scl_float(); i2c_sw_delay(); ack_val = get_sda(); set_scl_low(); i2c_sw_delay(); if(ack_val == 0) *tx_ack_flag = TRUE; else *tx_ack_flag = FALSE; return BSP_OK; }
static always_inline void twi_reset(void) { // make sure no sda/scl remains pulled up or down set_sda_to_input(); // deactivate internal pullup on sda/scl set_sda_low(); set_scl_to_input(); set_scl_low(); set_sda_to_output(); // release (set high) on sda/scl set_sda_high(); set_sda_to_input(); set_scl_to_output(); set_scl_high(); twi_reset_state(); }
/** \brief Write ACK or NACK at end of Read. * * \param dev_num bsp_dev_i2c_t: I2C dev num. * \param enable_ack bool: TRUE means ACK, FALSE means NACK. * \return void * */ void bsp_i2c_read_ack(bsp_dev_i2c_t dev_num, bool enable_ack) { (void)dev_num; /* Write 1 bit ACK or NACK */ if(enable_ack == TRUE) set_sda_low(); /* ACK */ else set_sda_float(); /* NACK */ i2c_sw_delay(); set_scl_float(); i2c_sw_delay(); set_scl_low(); }
/** \brief Sends START BIT in blocking mode and set the status. * * \param dev_num bsp_dev_i2c_t: I2C dev num. * \return bsp_status_t: status of the transfer. * */ bsp_status_t bsp_i2c_start(bsp_dev_i2c_t dev_num) { (void)dev_num; if(i2c_started == TRUE) { /* Re-Start condition */ set_sda_float(); i2c_sw_delay(); set_scl_float(); i2c_sw_delay(); } /* Generate START */ /* SDA & SCL are assumed to be floating = HIGH */ set_sda_low(); i2c_sw_delay(); set_scl_low(); i2c_started = TRUE; return BSP_OK; }