remove i2c mutex (now done in arduino-esp v2)

This commit is contained in:
cyberman54 2022-03-05 13:30:34 +01:00
parent cbca3ebb90
commit c9c4f2e714
7 changed files with 186 additions and 285 deletions

View File

@ -30,11 +30,6 @@
// length of display buffer for lmic event messages // length of display buffer for lmic event messages
#define LMIC_EVENTMSG_LEN 17 #define LMIC_EVENTMSG_LEN 17
// I2C bus access control
#define I2C_MUTEX_LOCK() \
(xSemaphoreTake(I2Caccess, pdMS_TO_TICKS(DISPLAYREFRESH_MS)) == pdTRUE)
#define I2C_MUTEX_UNLOCK() (xSemaphoreGive(I2Caccess))
// pseudo system halt function, useful to prevent writeloops to NVRAM // pseudo system halt function, useful to prevent writeloops to NVRAM
#ifndef _ASSERT #ifndef _ASSERT
#define _ASSERT(cond) \ #define _ASSERT(cond) \

View File

@ -52,9 +52,6 @@ int bme_init(void) {
int rc = 0; int rc = 0;
#ifdef HAS_BME680 #ifdef HAS_BME680
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
Wire.begin(HAS_BME680); Wire.begin(HAS_BME680);
iaqSensor.begin(BME680_ADDR, Wire); iaqSensor.begin(BME680_ADDR, Wire);
@ -69,25 +66,14 @@ int bme_init(void) {
rc = checkIaqSensorStatus(); rc = checkIaqSensorStatus();
} else
ESP_LOGE(TAG, "I2c bus busy - BME680 initialization error");
#elif defined HAS_BME280 #elif defined HAS_BME280
if (I2C_MUTEX_LOCK()) {
rc = bme.begin(BME280_ADDR); rc = bme.begin(BME280_ADDR);
} else
ESP_LOGE(TAG, "I2c bus busy - BME280 initialization error");
#elif defined HAS_BMP180 #elif defined HAS_BMP180
if (I2C_MUTEX_LOCK()) {
// Wire.begin(21, 22); // Wire.begin(21, 22);
rc = bmp.begin(); rc = bmp.begin();
} else
ESP_LOGE(TAG, "I2c bus busy - BMP180 initialization error");
#endif #endif
I2C_MUTEX_UNLOCK(); // release i2c bus access
if (rc) if (rc)
bmecycler.attach(BMECYCLE, setBMEIRQ); // start cyclic data transmit bmecycler.attach(BMECYCLE, setBMEIRQ); // start cyclic data transmit
return rc; return rc;
@ -123,8 +109,7 @@ int checkIaqSensorStatus(void) {
// store current BME sensor data in struct // store current BME sensor data in struct
void bme_storedata(bmeStatus_t *bme_store) { void bme_storedata(bmeStatus_t *bme_store) {
if ((cfg.payloadmask & MEMS_DATA) && if (cfg.payloadmask & MEMS_DATA)
(I2C_MUTEX_LOCK())) { // block i2c bus access
#ifdef HAS_BME680 #ifdef HAS_BME680
if (iaqSensor.run()) { // if new data is available if (iaqSensor.run()) { // if new data is available
@ -154,9 +139,6 @@ void bme_storedata(bmeStatus_t *bme_store) {
bme_store->iaq = 0; // IAQ feature not present with BME280 bme_store->iaq = 0; // IAQ feature not present with BME280
#endif #endif
I2C_MUTEX_UNLOCK(); // release i2c bus access
}
} // bme_storedata() } // bme_storedata()
#ifdef HAS_BME680 #ifdef HAS_BME680

View File

@ -90,13 +90,6 @@ void dp_setup(int contrast) {
void dp_init(bool verbose) { void dp_init(bool verbose) {
#if (HAS_DISPLAY) == 1 // i2c
// block i2c bus access
if (!I2C_MUTEX_LOCK())
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
else {
#endif
dp_setup(DISPLAYCONTRAST); dp_setup(DISPLAYCONTRAST);
if (verbose) { if (verbose) {
@ -122,8 +115,7 @@ void dp_init(bool verbose) {
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
dp_println(); dp_println();
dp_printf("%dMB %s Flash", spi_flash_get_chip_size() / (1024 * 1024), dp_printf("%dMB %s Flash", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext.");
: "ext.");
// give user some time to read or take picture // give user some time to read or take picture
dp_dump(displaybuf); dp_dump(displaybuf);
@ -165,11 +157,6 @@ void dp_init(bool verbose) {
dp_power(cfg.screenon); // set display off if disabled dp_power(cfg.screenon); // set display off if disabled
#if (HAS_DISPLAY) == 1 // i2c
I2C_MUTEX_UNLOCK(); // release i2c bus access
} // mutex
#endif
} // dp_init } // dp_init
void dp_refresh(bool nextPage) { void dp_refresh(bool nextPage) {
@ -182,10 +169,6 @@ void dp_refresh(bool nextPage) {
if (!DisplayIsOn && (DisplayIsOn == cfg.screenon)) if (!DisplayIsOn && (DisplayIsOn == cfg.screenon))
return; return;
// block i2c bus access
if (!I2C_MUTEX_LOCK())
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
else {
// set display on/off according to current device configuration // set display on/off according to current device configuration
if (DisplayIsOn != cfg.screenon) { if (DisplayIsOn != cfg.screenon) {
DisplayIsOn = cfg.screenon; DisplayIsOn = cfg.screenon;
@ -202,9 +185,6 @@ void dp_refresh(bool nextPage) {
dp_drawPage(nextPage); dp_drawPage(nextPage);
I2C_MUTEX_UNLOCK(); // release i2c bus access
} // mutex
} // refreshDisplay() } // refreshDisplay()
void dp_drawPage(bool nextpage) { void dp_drawPage(bool nextpage) {
@ -600,14 +580,8 @@ void dp_power(uint8_t screenon) {
void dp_shutdown(void) { void dp_shutdown(void) {
#if (HAS_DISPLAY) == 1 #if (HAS_DISPLAY) == 1
// block i2c bus access
if (!I2C_MUTEX_LOCK())
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
else {
obdPower(&ssoled, false); obdPower(&ssoled, false);
delay(DISPLAYREFRESH_MS / 1000 * 1.1); delay(DISPLAYREFRESH_MS / 1000 * 1.1);
I2C_MUTEX_UNLOCK(); // release i2c bus access
}
#elif (HAS_DISPLAY) == 2 #elif (HAS_DISPLAY) == 2
// to come // to come
#endif #endif

View File

@ -12,7 +12,7 @@ void i2c_init(void) {
Wire.begin(); Wire.begin();
} }
//void i2c_deinit(void) { Wire.end(); } // void i2c_deinit(void) { Wire.end(); }
void i2c_deinit(void) { Wire.~TwoWire(); } void i2c_deinit(void) { Wire.~TwoWire(); }
void i2c_scan(void) { void i2c_scan(void) {
@ -49,9 +49,6 @@ void i2c_scan(void) {
ESP_LOGI(TAG, "Starting I2C bus scan..."); ESP_LOGI(TAG, "Starting I2C bus scan...");
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
memset(&bbi2c, 0, sizeof(bbi2c)); memset(&bbi2c, 0, sizeof(bbi2c));
bbi2c.bWire = 0; bbi2c.bWire = 0;
bbi2c.iSDA = MY_DISPLAY_SDA; bbi2c.iSDA = MY_DISPLAY_SDA;
@ -83,15 +80,10 @@ void i2c_scan(void) {
} // for i } // for i
ESP_LOGI(TAG, "%u I2C device(s) found", iCount); ESP_LOGI(TAG, "%u I2C device(s) found", iCount);
} }
I2C_MUTEX_UNLOCK(); // release i2c bus access
} else
ESP_LOGE(TAG, "I2C bus busy - scan error");
} }
// mutexed functions for i2c r/w access // functions for i2c r/w access, mutexing is done by Wire.cpp
int i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) { int i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
if (I2C_MUTEX_LOCK()) {
uint8_t ret = 0; uint8_t ret = 0;
Wire.beginTransmission(addr); Wire.beginTransmission(addr);
@ -109,17 +101,11 @@ int i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
data[index++] = Wire.read(); data[index++] = Wire.read();
} }
finish: finish:
I2C_MUTEX_UNLOCK(); // release i2c bus access return ret ? ret : 0xFF;
return ret;
} else {
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
return 0xFF;
}
} }
int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) { int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
if (I2C_MUTEX_LOCK()) {
uint8_t ret = 0; uint8_t ret = 0;
Wire.beginTransmission(addr); Wire.beginTransmission(addr);
@ -129,10 +115,5 @@ int i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
} }
ret = Wire.endTransmission(); ret = Wire.endTransmission();
I2C_MUTEX_UNLOCK(); // release i2c bus access
return ret ? ret : 0xFF; return ret ? ret : 0xFF;
} else {
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", _seconds());
return 0xFF;
}
} }

View File

@ -87,11 +87,6 @@ void setup() {
char features[100] = ""; char features[100] = "";
// create some semaphores for syncing / mutexing tasks
I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus
_ASSERT(I2Caccess != NULL);
I2C_MUTEX_UNLOCK();
// disable brownout detection // disable brownout detection
#ifdef DISABLE_BROWNOUT #ifdef DISABLE_BROWNOUT
// register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4

View File

@ -10,8 +10,6 @@ RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface
// initialize RTC // initialize RTC
uint8_t rtc_init(void) { uint8_t rtc_init(void) {
if (I2C_MUTEX_LOCK()) { // block i2c bus access
Wire.begin(HAS_RTC); Wire.begin(HAS_RTC);
Rtc.Begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL); Rtc.Begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL);
@ -36,41 +34,37 @@ uint8_t rtc_init(void) {
} }
#endif #endif
I2C_MUTEX_UNLOCK(); // release i2c bus access
ESP_LOGI(TAG, "RTC initialized"); ESP_LOGI(TAG, "RTC initialized");
return 1; // success return 1; // success
} else {
ESP_LOGE(TAG, "RTC initialization error, I2C bus busy"); // failure
return 0; // failure // return 0
}
} // rtc_init() } // rtc_init()
uint8_t set_rtctime(time_t t) { // t is sec epoch time uint8_t set_rtctime(time_t t) { // t is sec epoch time
if (I2C_MUTEX_LOCK()) {
#ifdef RTC_INT // sync rtc 1Hz pulse on top of second #ifdef RTC_INT // sync rtc 1Hz pulse on top of second
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start
#endif #endif
Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000 Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
I2C_MUTEX_UNLOCK();
ESP_LOGI(TAG, "RTC time synced"); ESP_LOGI(TAG, "RTC time synced");
return 1; // success return 1; // success
} else {
ESP_LOGE(TAG, "RTC set time failure"); // failure
return 0; // failure // return 0
}
} // set_rtctime() } // set_rtctime()
time_t get_rtctime(uint16_t *msec) { time_t get_rtctime(uint16_t *msec) {
time_t t = 0; time_t t = 0;
*msec = 0; *msec = 0;
if (I2C_MUTEX_LOCK()) {
if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) { if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) {
RtcDateTime tt = Rtc.GetDateTime(); RtcDateTime tt = Rtc.GetDateTime();
t = tt.Epoch32Time(); // sec2000 -> epoch t = tt.Epoch32Time(); // sec2000 -> epoch
} }
I2C_MUTEX_UNLOCK();
#ifdef RTC_INT #ifdef RTC_INT
// adjust time to top of next second by waiting TimePulseTick to flip // adjust time to top of next second by waiting TimePulseTick to flip
bool lastTick = TimePulseTick; bool lastTick = TimePulseTick;
@ -79,19 +73,12 @@ time_t get_rtctime(uint16_t *msec) {
t++; t++;
#endif #endif
return t; return t;
} else {
ESP_LOGE(TAG, "RTC get time failure");
return 0; // failure
}
} // get_rtctime() } // get_rtctime()
float get_rtctemp(void) { float get_rtctemp(void) {
if (I2C_MUTEX_LOCK()) {
RtcTemperature temp = Rtc.GetTemperature(); RtcTemperature temp = Rtc.GetTemperature();
I2C_MUTEX_UNLOCK();
return temp.AsFloatDegC(); return temp.AsFloatDegC();
}
return 0;
} // get_rtctemp() } // get_rtctemp()
#endif // HAS_RTC #endif // HAS_RTC

View File

@ -63,8 +63,7 @@ void calibrateTime(void) {
} // calibrateTime() } // calibrateTime()
// set system time (UTC), calibrate RTC and RTC_INT pps // set system time (UTC), calibrate RTC and RTC_INT pps
bool setMyTime(uint32_t t_sec, uint16_t t_msec, bool setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource) {
timesource_t mytimesource) {
struct timeval tv = {0}; struct timeval tv = {0};
@ -141,22 +140,12 @@ uint8_t timepulse_init() {
// if we have, use pulse from on board RTC chip as time base for calendar time // if we have, use pulse from on board RTC chip as time base for calendar time
#if defined RTC_INT #if defined RTC_INT
// setup external rtc 1Hz clock pulse // setup external rtc 1Hz clock pulse
if (I2C_MUTEX_LOCK()) {
Rtc.SetSquareWavePinClockFrequency(DS3231SquareWaveClock_1Hz); Rtc.SetSquareWavePinClockFrequency(DS3231SquareWaveClock_1Hz);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock);
I2C_MUTEX_UNLOCK();
pinMode(RTC_INT, INPUT_PULLUP); pinMode(RTC_INT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(RTC_INT), CLOCKIRQ, FALLING); attachInterrupt(digitalPinToInterrupt(RTC_INT), CLOCKIRQ, FALLING);
ESP_LOGI(TAG, "Timepulse: external (RTC)"); ESP_LOGI(TAG, "Timepulse: external (RTC)");
return 1; // success
} else {
ESP_LOGE(TAG, "RTC initialization error, I2C bus busy");
return 0; // failure
}
return 1; // success
#else #else
// use ESP32 hardware timer as time base for calendar time // use ESP32 hardware timer as time base for calendar time
ppsIRQ = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec ppsIRQ = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec
@ -164,8 +153,6 @@ uint8_t timepulse_init() {
timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, false); timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, false);
timerAlarmEnable(ppsIRQ); timerAlarmEnable(ppsIRQ);
ESP_LOGI(TAG, "Timepulse: internal (ESP32 hardware timer)"); ESP_LOGI(TAG, "Timepulse: internal (ESP32 hardware timer)");
return 1; // success
#endif #endif
// start cyclic time sync // start cyclic time sync