From cb232ea55e112939e065a853291f589bfc1a95f2 Mon Sep 17 00:00:00 2001 From: Ea-r-th <39779954+Ea-r-th@users.noreply.github.com> Date: Thu, 18 Sep 2025 01:19:03 -0700 Subject: [PATCH] I2C tested, main file now contains rough sample for use with DHT20 --- SHAL/Include/Core/SHAL_CORE.h | 29 ++++++++++++++++-- SHAL/Src/Core/SHAL_CORE.cpp | 20 ------------ SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp | 37 ++++++++++++++-------- SHAL/Src/main.cpp | 46 ++++++++++++++++------------ 4 files changed, 77 insertions(+), 55 deletions(-) diff --git a/SHAL/Include/Core/SHAL_CORE.h b/SHAL/Include/Core/SHAL_CORE.h index 9abbb29..c891dda 100644 --- a/SHAL/Include/Core/SHAL_CORE.h +++ b/SHAL/Include/Core/SHAL_CORE.h @@ -24,6 +24,13 @@ void SHAL_init(); typedef bool (*condition_fn_t)(void); +#define SHAL_WAIT_FOR_CONDITION_US(cond, timeout_us) \ + SHAL_wait_for_condition_us([&](){ return (cond); }, (timeout_us)) + +#define SHAL_WAIT_FOR_CONDITION_MS(cond, timeout_ms) \ + SHAL_wait_for_condition_ms([&](){ return (cond); }, (timeout_ms)) + + //Currently configures systick to count down in microseconds void systick_init(); @@ -33,9 +40,27 @@ void SHAL_delay_us(uint32_t us); void SHAL_delay_ms(uint32_t ms); -bool SHAL_wait_for_condition_us(condition_fn_t condition, uint32_t timeout_us); +template +bool SHAL_wait_for_condition_us(Condition cond, uint32_t timeout_us) { + while (timeout_us--) { + if (cond()) { + return true; // success + } + SHAL_delay_us(1); + } + return false; // timeout +} -bool SHAL_wait_for_condition_ms(condition_fn_t condition, uint32_t timeout_ms); +template +bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) { + while (timeout_ms--) { + if (cond()) { + return true; // success + } + SHAL_delay_ms(1); + } + return false; // timeout +} //--------------------------------------------------------- diff --git a/SHAL/Src/Core/SHAL_CORE.cpp b/SHAL/Src/Core/SHAL_CORE.cpp index 6f44eb2..8f46a8f 100644 --- a/SHAL/Src/Core/SHAL_CORE.cpp +++ b/SHAL/Src/Core/SHAL_CORE.cpp @@ -40,23 +40,3 @@ void SHAL_delay_ms(uint32_t ms){ SHAL_delay_us(1000); } } - -bool SHAL_wait_for_condition_us(condition_fn_t condition, uint32_t timeout_us){ - while (timeout_us--) { - if (condition()) { - return true; // Condition met - } - SHAL_delay_us(1); // Wait 1 µs - } - return false; // Timeout -} - -bool SHAL_wait_for_condition_ms(condition_fn_t condition, uint32_t timeout_ms){ - while (timeout_ms--) { - if (condition()) { - return true; // Condition met - } - SHAL_delay_ms(1); // Wait 1 µs - } - return false; // Timeout -} \ No newline at end of file diff --git a/SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp b/SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp index a6db22e..b8ea899 100644 --- a/SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp +++ b/SHAL/Src/Peripheral/I2C/SHAL_I2C.cpp @@ -65,13 +65,12 @@ void SHAL_I2C::setClockConfig(uint32_t configuration) { void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen) { - SHAL_UART2.sendString("Beginning of writeread\r\n"); - - volatile I2C_TypeDef* I2CPeripheral = getI2CPair(m_I2CPair).I2CReg; - //Wait for I2C bus - while (I2CPeripheral->ISR & I2C_ISR_BUSY); + if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_BUSY) == 0, 100)){ + SHAL_UART2.sendString("I2C timed out waiting for not busy\r\n"); + return; + } //Write phase if (writeLen > 0) { @@ -79,12 +78,18 @@ void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t wri I2CPeripheral->CR2 = (addr << 1) | (writeLen << I2C_CR2_NBYTES_Pos) | I2C_CR2_START; for (size_t i = 0; i < writeLen; i++) { - while(!(I2CPeripheral->ISR & I2C_ISR_TXIS)); //TX ready + if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TXIS) != 0, 100)){ + SHAL_UART2.sendString("I2C timed out waiting for TX\r\n"); + return; + } I2CPeripheral->TXDR = writeData[i]; } //Wait until transfer complete - while (!(I2CPeripheral->ISR & I2C_ISR_TC)); + if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TC) != 0, 100)){ + SHAL_UART2.sendString("I2C timed out waiting for TC\r\n"); + return; + } } //Read phase @@ -92,18 +97,24 @@ void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t wri SHAL_UART2.sendString("Read initiated\r\n"); - I2CPeripheral->CR2 = (addr << 1) | - I2C_CR2_RD_WRN | - (readLen << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | I2C_CR2_AUTOEND; + I2CPeripheral->CR2 &= ~(I2C_CR2_NBYTES | I2C_CR2_SADD | I2C_CR2_RD_WRN); + I2CPeripheral->CR2 |= (addr << 1) | + I2C_CR2_RD_WRN | + (readLen << I2C_CR2_NBYTES_Pos) | + I2C_CR2_START | I2C_CR2_AUTOEND; for (size_t i = 0; i < readLen; i++) { - while (!(I2CPeripheral->ISR & I2C_ISR_RXNE)); //RX ready + if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_RXNE) != 0 , 100)){ + SHAL_UART2.sendString("I2C timed out waiting for RXNE\r\n"); + return; + } SHAL_UART2.sendString("Read byte"); readData[i] = static_cast(I2CPeripheral->RXDR); } } - SHAL_UART2.sendString("\r\n"); + else{ + I2CPeripheral->CR2 |= I2C_CR2_STOP; + } } void SHAL_I2C::masterWrite(uint8_t addr, const uint8_t *writeData, uint8_t writeLen) { diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index 0db2e09..db71ff0 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -1,6 +1,7 @@ #include "SHAL.h" #include "stm32f0xx.h" +#include void c3Interrupt(){ SHAL_UART2.sendString("Begin\r\n"); @@ -8,35 +9,36 @@ void c3Interrupt(){ uint8_t cmd[3] = {0xAC, 0x33, 0x00}; SHAL_I2C1.masterWrite(0x38, cmd, 3); - SHAL_UART2.sendString("Hello\r\n"); - SHAL_delay_ms(100); - uint8_t buffer[7] = {0}; - - SHAL_UART2.sendString("Buffer created?\r\n"); + uint8_t dht_buf[7] = {0}; //Read 7 bytes (status + 5 data + CRC) - SHAL_I2C1.masterRead(0x38, buffer, 7); - - SHAL_UART2.sendString("Read complete\r\n"); + SHAL_I2C1.masterRead(0x38, dht_buf, 7); //Parse humidity (20 bits) - uint32_t rawHumidity = ((uint32_t)buffer[1] << 12) | - ((uint32_t)buffer[2] << 4) | - ((uint32_t)buffer[3] >> 4); + uint32_t rawHumidity = ((uint32_t)dht_buf[1] << 12) | + ((uint32_t)dht_buf[2] << 4) | + ((uint32_t)dht_buf[3] >> 4); - // Parse temperature (20 bits) - uint32_t rawTemp = (((uint32_t)buffer[3] & 0x0F) << 16) | - ((uint32_t)buffer[4] << 8) | - ((uint32_t)buffer[5]); + uint32_t rawTemp = (((uint32_t)dht_buf[3] & 0x0F) << 16) | + ((uint32_t)dht_buf[4] << 8) | + ((uint32_t)dht_buf[5]); - float humidity = (rawHumidity * 100.0f) / 1048576.0f; // 2^20 = 1048576 - float temperature = (rawTemp * 200.0f) / 1048576.0f - 50.0f; + // Use 64-bit intermediate to avoid overflow + uint32_t hum_hundredths = (uint32_t)(((uint64_t)rawHumidity * 10000ULL) >> 20); + int32_t temp_hundredths = (int32_t)((((uint64_t)rawTemp * 20000ULL) >> 20) - 5000); - char buf[64]; - sprintf(buf, "Temp: %.2f C, Hum: %.2f %%\r\n", temperature, humidity); - SHAL_UART2.sendString(buf); + char out[80]; + sprintf(out, "rawH=0x%05lX rawT=0x%05lX\r\n", + (unsigned long)rawHumidity, (unsigned long)rawTemp); + SHAL_UART2.sendString(out); + + // print as X.YY + sprintf(out, "Temp: %ld.%02ld C, Hum: %ld.%02ld %%\r\n", + (long)(temp_hundredths / 100), (long)(abs(temp_hundredths % 100)), + (long)(hum_hundredths / 100), (long)(hum_hundredths % 100)); + SHAL_UART2.sendString(out); } void tim2Handler(){ @@ -77,6 +79,10 @@ int main() { sprintf(statusString, "Status = 0x%02X\r\n", status); SHAL_UART2.sendString(statusString); + + SHAL_delay_ms(10); + + c3Interrupt(); //End setup while (true) {