Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for new I2C sensor SHT30 #150

Merged
merged 10 commits into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions lib/smooth/application/io/i2c/SHT30.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace smooth::application::sensor

constexpr const milliseconds command_delay_2ms(2);
constexpr const milliseconds non_clock_stretching_measurement_delay_16ms(16);
constexpr const int scl_timeout_7ms = 560000;
constexpr const int scl_timeout_7ms = 560000; // (560000 / 80MHz) = 0.007 = 7ms
constexpr const uint16_t repeatability_command[] = { 0x2C06, 0x2C0D, 0x2C10, 0x2400, 0x240B, 0x2416 };

constexpr const char* repeatability_name[] = { "MeasureHighRepeatabilityWithClockStretchingEnabled",
Expand Down Expand Up @@ -61,7 +61,7 @@ namespace smooth::application::sensor
std::copy(raw_data.begin(), raw_data.begin() + 3, temp_raw_data.begin());
std::copy(raw_data.begin() + 3, raw_data.end(), humd_raw_data.begin());

if (execute_crc_checking(temp_raw_data, 2) & execute_crc_checking(humd_raw_data, 2))
if (execute_crc_checking(temp_raw_data, 2) && execute_crc_checking(humd_raw_data, 2))
{
uint16_t raw_temp = static_cast<uint16_t>((raw_data[0] << 8) + raw_data[1]);
uint16_t raw_humd = static_cast<uint16_t>((raw_data[3] << 8) + raw_data[4]);
Expand All @@ -83,7 +83,7 @@ namespace smooth::application::sensor
bool res = false;
util::FixedBuffer<uint8_t, 3> raw_data{};

if (execute_status_read(raw_data) & execute_crc_checking(raw_data, 2))
if (execute_status_read(raw_data) && execute_crc_checking(raw_data, 2))
{
status = static_cast<uint16_t>((raw_data[0] << 8) + raw_data[1]);
res = true;
Expand Down Expand Up @@ -124,7 +124,7 @@ namespace smooth::application::sensor
// EnableMeasureHighRepeatabilityWithClockStretching it will be implemented using
// MeasureHighRepeatabilityWithClockStretchingDisabled
if ((mode == RepeatabilityMode::EnableMeasureMediumRepeatabilityWithClockStretching)
| (mode == RepeatabilityMode::EnableMeasureLowRepeatabilityWithClockStretching))
|| (mode == RepeatabilityMode::EnableMeasureLowRepeatabilityWithClockStretching))
{
use_clock_stretching = true;
}
Expand Down Expand Up @@ -266,8 +266,7 @@ namespace smooth::application::sensor
}
else
{
res = execute_repeatability_command();
res &= execute_read_block(raw_data);
res = execute_repeatability_command() && execute_read_block(raw_data);
}

if (!res)
Expand All @@ -281,8 +280,7 @@ namespace smooth::application::sensor
// Execute status read
bool SHT30::execute_status_read(FixedBufferBase<uint8_t>& raw_data)
{
auto res = execute_write_command(Command::ReadStatus);
res &= execute_read_block(raw_data);
auto res = execute_write_command(Command::ReadStatus) && execute_read_block(raw_data);

if (!res)
{
Expand Down
43 changes: 23 additions & 20 deletions lib/smooth/core/io/i2c/I2CMasterDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,21 @@ namespace smooth::core::io::i2c
// Write address and data
bool I2CMasterDevice::write(uint8_t address, std::vector<uint8_t>& data, bool expect_ack)
{
// Create a threadsafe command link
I2CCommandLink link(*this);

// Set the process name that will be used by log_error
set_process_name(write_tag);

// Set R/W bit to 0 for write.
auto write_address = static_cast<uint8_t>(address << 1);

auto res = i2c_master_start(link);
res |= i2c_master_write_byte(link, write_address, expect_ack);
res |= i2c_master_write(link, data.data(), data.size(), expect_ack);
res |= i2c_master_stop(link);
res |= i2c_master_cmd_begin(port, link, to_tick(timeout));
// Build the command link and execute the command link
auto res = i2c_master_start(link)
| i2c_master_write_byte(link, write_address, expect_ack)
| i2c_master_write(link, data.data(), data.size(), expect_ack)
| i2c_master_stop(link)
| i2c_master_cmd_begin(port, link, to_tick(timeout));

if (res != ESP_OK)
{
Expand Down Expand Up @@ -154,17 +157,14 @@ namespace smooth::core::io::i2c
// before changing so we can restore before returning from this function.
if (scl_timeout > 0)
{
//Log::info("I2C", "timeout = {}", scl_timeout);
PerMalmberg marked this conversation as resolved.
Show resolved Hide resolved
res |= i2c_get_timeout(port, &orig_scl_timeout);
res |= i2c_set_timeout(port, scl_timeout);
}

// Generate start condition
// Generate start condition, Write the slave address to slave, Write slave register address to slave
res |= i2c_master_start(link);

// Write the slave address to slave
res |= i2c_master_write_byte(link, write_address, true);

// Write slave register address to slave
res |= i2c_master_write(link, slave_reg.data(), slave_reg.size(), true);

// Generate another start condition or stop condition
Expand Down Expand Up @@ -276,13 +276,17 @@ namespace smooth::core::io::i2c
// Write the address of each possible device and see if an ACK is received or not.
for (uint8_t address = 2; address <= 127; ++address)
{
// Create a threadsafe command link
I2CCommandLink link(*this);

// Set R/W bit to 1 for read.
auto read_address = static_cast<uint8_t>(address << 1);

auto res = i2c_master_start(link);
res |= i2c_master_write_byte(link, read_address, true);
res |= i2c_master_stop(link);
res |= i2c_master_cmd_begin(port, link, to_tick(timeout));
// Build the command link and execute the command link
auto res = i2c_master_start(link)
| i2c_master_write_byte(link, read_address, true)
| i2c_master_stop(link)
| i2c_master_cmd_begin(port, link, to_tick(timeout));

if (res != ESP_OK)
{
Expand All @@ -300,31 +304,30 @@ namespace smooth::core::io::i2c
}

// Log the error
//void I2CMasterDevice::log_error(esp_err_t err, const char* msg)
void I2CMasterDevice::log_error(esp_err_t err, uint8_t address)
{
std::stringstream ss;
ss << "Error in - " << process_name << " - slave address: 0x" << std::hex << static_cast<int32_t>(address);

if (err == ESP_ERR_INVALID_ARG)
{
Log::error(log_tag, "{} - Parameter error", ss.str().c_str());
Log::error(log_tag, "{} - Parameter error", ss.str());
}
else if (err == ESP_FAIL)
{
Log::error(log_tag, "{} - Send command error, no ACK from slave", ss.str().c_str());
Log::error(log_tag, "{} - Send command error, no ACK from slave", ss.str());
}
else if (err == ESP_ERR_INVALID_STATE)
{
Log::error(log_tag, "{} - I2C driver not installed or not in master mode", ss.str().c_str());
Log::error(log_tag, "{} - I2C driver not installed or not in master mode", ss.str());
}
else if (err == ESP_ERR_TIMEOUT)
{
Log::error(log_tag, "{} - Operation timeout, bus busy", ss.str().c_str());
Log::error(log_tag, "{} - Operation timeout, bus busy", ss.str());
}
else if (err != ESP_OK)
{
Log::error(log_tag, "{} - unknown error: {}", ss.str().c_str(), err);
Log::error(log_tag, "{} - unknown error: {}", ss.str(), err);
}
}

Expand Down
30 changes: 15 additions & 15 deletions lib/smooth/include/smooth/core/io/i2c/I2CMasterDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ namespace smooth::core::io::i2c
bool write(uint8_t address, std::vector<uint8_t>& data, bool expect_ack = true);

/// Reads data from the 8 bit register of the slave with the provided address. This function DOES NOT
// support slave clock-stretching
/// support slave clock-stretching
/// \param address The slave address
/// \param slave_register The register to read from.
/// \param dest Where the data will be written to. The size of the buffer determines how many bytes to read.
/// \param use_restart_signal If true, uses a start-condition instead of a stop-condition after the slave
// address.
/// address.
/// \param end_with_nack If true, ends the transmission with a NACK instead of an ACK.
/// \return true on success, false on failure.
bool read(uint8_t address,
Expand All @@ -90,16 +90,17 @@ namespace smooth::core::io::i2c
bool end_with_nack = true);

/// Reads data from the 8 bit register of the slave with the provided address. This function supports slave
// clock-stretching
/// clock-stretching
/// \param address The slave address
/// \param slave_register The 16 bit register to read from.
/// \param dest Where the data will be written to. The size of the buffer determines how many bytes to read.
/// \param use_restart_signal If true, uses a start-condition instead of a stop-condition after the slave
// address.
/// address.
/// \param end_with_nack If true, ends the transmission with a NACK instead of an ACK.
/// \param scl_timeout Used to suppport slave clock-stretching. Slave must release SCL line within this
// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF (1,048,575)
// or 13ms. Negative numbers will be ignored.
/// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF
/// (1,048,575)
/// or 13ms. Negative numbers will be ignored.
/// \return true on success, false on failure.
bool read8(uint8_t address,
uint8_t slave_register,
Expand All @@ -109,16 +110,16 @@ namespace smooth::core::io::i2c
int scl_timeout = 0);

/// Reads data from the 16 bit register of the slave with the provided address. This function supports slave
// clock-stretching
/// clock-stretching
/// \param address The slave address
/// \param slave_register The 16 bit register to read from.
/// \param dest Where the data will be written to. The size of the buffer determines how many bytes to read.
/// \param use_restart_signal If true, uses a start-condition instead of a stop-condition after the slave
// address.
/// address.
/// \param end_with_nack If true, ends the transmission with a NACK instead of an ACK.
/// \param scl_timeout Used to suppport slave clock-stretching. Slave must release SCL line within this
// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF
// (1,048,575) or 13ms. Negative numbers will be ignored.
/// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF
/// (1,048,575) or 13ms. Negative numbers will be ignored.
/// \return true on success, false on failure.
bool read16(uint8_t address,
uint16_t slave_register,
Expand All @@ -128,7 +129,7 @@ namespace smooth::core::io::i2c
int scl_timeout = 0);

/// Reads a block of data from the slave with the provided address. This function DOES NOT support slave
// clock-stretching
/// clock-stretching
/// \param address The slave address
/// \param dest Where the data will be written to. The size of the buffer determines how many bytes to read.
/// \param end_with_nack If true, ends the transmission with a NACK instead of an ACK.
Expand All @@ -147,11 +148,11 @@ namespace smooth::core::io::i2c
/// \param slave_reg A FixedBuffer that hold the slave register address
/// \param dest Where the data will be written to. The size of the buffer determines how many bytes to read.
/// \param use_restart_signal If true, uses a start-condition instead of a stop-condition after the slave
// address.
/// address.
/// \param end_with_nack If true, ends the transmission with a NACK instead of an ACK.
/// \param scl_timeout Used to suppport slave clock-stretching. Slave must release SCL line within this
// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF
// (1,048,575) or 13ms. Negative numbers will be ignored.
/// time. Set to 0 to disable using slave clock-stretching. The maximum timeout value is 0xFFFFF
/// (1,048,575) or 13ms. Negative numbers will be ignored.
/// \return true on success, false on failure.
bool write_followed_by_read(I2CCommandLink& link,
uint8_t address,
Expand All @@ -164,7 +165,6 @@ namespace smooth::core::io::i2c
/// Log error
/// \param err The error type
/// \param msg The error message
//void log_error(esp_err_t err, const char* msg);
void log_error(esp_err_t err, uint8_t address);

/// Sets the name of the procees that is being executed
Expand Down