Skip to content

Commit a0076cc

Browse files
authored
Merge pull request #173 from adafruit/i2c-init
Add I2C Device Initialization
2 parents 55e67ce + c30d605 commit a0076cc

File tree

8 files changed

+544
-212
lines changed

8 files changed

+544
-212
lines changed

src/Wippersnapper.cpp

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,12 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
560560
is_success = false;
561561
}
562562

563-
// Pack I2CResponse message
563+
// Fill I2CResponse
564564
msgi2cResponse.which_payload =
565565
wippersnapper_signal_v1_I2CRequest_req_i2c_init_tag;
566566
msgi2cResponse.payload.resp_i2c_init.is_initialized = is_success;
567567

568-
// Encode I2CResponse message
568+
// Encode I2CResponse
569569
if (!encodeI2CResponse(&msgi2cResponse)) {
570570
return false;
571571
}
@@ -602,15 +602,14 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
602602
WS_DEBUG_PRINT("\t# of addresses found on bus: ");
603603
WS_DEBUG_PRINTLN(scanResp.addresses_found_count);
604604

605-
// Pack I2CResponse
605+
// Fill I2CResponse
606606
msgi2cResponse.which_payload =
607607
wippersnapper_signal_v1_I2CResponse_resp_i2c_scan_tag;
608608
memcpy(msgi2cResponse.payload.resp_i2c_scan.addresses_found,
609609
scanResp.addresses_found, sizeof(scanResp.addresses_found));
610610
msgi2cResponse.payload.resp_i2c_scan.addresses_found_count =
611611
scanResp.addresses_found_count;
612-
613-
// Encode I2C Response
612+
// Encode I2CResponse
614613
if (!encodeI2CResponse(&msgi2cResponse)) {
615614
return false;
616615
}
@@ -626,30 +625,57 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
626625
WS_DEBUG_PRINTLN("ERROR: Could not decode I2CDeviceInitRequest message.");
627626
return false; // fail out if we can't decode
628627
}
629-
// Attach device to I2C port
630-
bool deviceInitSuccess = false;
628+
629+
// Create response
630+
msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero;
631+
msgi2cResponse.which_payload =
632+
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag;
633+
634+
// Initialize device and fill response
631635
if (msgI2CDeviceInitRequest.i2c_port_number == 0 &&
632636
WS._i2cPort0->isInitialized() == true) {
633-
deviceInitSuccess =
634-
WS._i2cPort0->attachI2CDevice(&msgI2CDeviceInitRequest);
637+
msgi2cResponse.payload.resp_i2c_device_init.is_success =
638+
WS._i2cPort0->initI2CDevice(&msgI2CDeviceInitRequest);
635639
} else if (msgI2CDeviceInitRequest.i2c_port_number == 1 &&
636640
WS._i2cPort1->isInitialized() == true) {
637-
deviceInitSuccess =
638-
WS._i2cPort1->attachI2CDevice(&msgI2CDeviceInitRequest);
641+
msgi2cResponse.payload.resp_i2c_device_init.is_success =
642+
WS._i2cPort1->initI2CDevice(&msgI2CDeviceInitRequest);
639643
}
640-
// Create response
644+
645+
// Encode response
646+
if (!encodeI2CResponse(&msgi2cResponse)) {
647+
return false;
648+
}
649+
650+
} else if (field->tag ==
651+
wippersnapper_signal_v1_I2CRequest_req_i2c_device_deinit_tag) {
652+
WS_DEBUG_PRINTLN("NEW COMMAND: I2C Device De-init");
653+
// Decode stream into an I2CDeviceDeinitRequest
654+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest msgI2CDeviceDeinitRequest =
655+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest_init_zero;
656+
// Decode stream into struct, msgI2CDeviceDeinitRequest
657+
if (!pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceDeinitRequest_fields,
658+
&msgI2CDeviceDeinitRequest)) {
659+
WS_DEBUG_PRINTLN(
660+
"ERROR: Could not decode I2CDeviceDeinitRequest message.");
661+
return false; // fail out if we can't decode
662+
}
663+
664+
// Empty I2C response to fill out
641665
msgi2cResponse = wippersnapper_signal_v1_I2CResponse_init_zero;
642666
msgi2cResponse.which_payload =
643-
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_init_tag;
644-
msgi2cResponse.payload.resp_i2c_device_init.is_success = deviceInitSuccess;
645-
// Encode message
646-
memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing));
647-
pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing,
648-
sizeof(WS._buffer_outgoing));
649-
if (!pb_encode(&ostream, wippersnapper_signal_v1_I2CResponse_fields,
650-
&msgi2cResponse)) {
651-
WS_DEBUG_PRINTLN("ERROR: Unable to encode I2C response message");
652-
return false; // fail out if we cant encode
667+
wippersnapper_signal_v1_I2CResponse_resp_i2c_device_deinit_tag;
668+
669+
// Delete device from I2C bus
670+
if (msgI2CDeviceDeinitRequest.i2c_port_number == 0 &&
671+
WS._i2cPort0->isInitialized() == true) {
672+
msgi2cResponse.payload.resp_i2c_device_deinit.is_success =
673+
WS._i2cPort0->deinitI2CDevice(&msgI2CDeviceDeinitRequest);
674+
}
675+
676+
// Encode response
677+
if (!encodeI2CResponse(&msgi2cResponse)) {
678+
return false;
653679
}
654680
} else {
655681
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
@@ -1492,7 +1518,6 @@ ws_status_t Wippersnapper::run() {
14921518
WS._mqtt->processPackets(10);
14931519
feedWDT();
14941520

1495-
// TODO: Loop thru components
14961521
// Process digital inputs, digitalGPIO module
14971522
WS._digitalGPIO->processDigitalInputs();
14981523
feedWDT();
@@ -1501,5 +1526,9 @@ ws_status_t Wippersnapper::run() {
15011526
WS._analogIO->processAnalogInputs();
15021527
feedWDT();
15031528

1529+
// Process I2C sensor events
1530+
// WS._i2cPort0->update();
1531+
// feedWDT();
1532+
15041533
return WS_NET_CONNECTED; // TODO: Make this funcn void!
15051534
}

src/Wippersnapper.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@
5656

5757
// Uncomment the following use the staging IO server //
5858
//#define USE_STAGING ///< Use Adafruit IO staging
59-
// certificate #define IO_MQTT_SERVER "io.adafruit.us" ///< Adafruit IO MQTT
60-
// Server
61-
59+
// certificate
6260
#define IO_MQTT_SERVER "io.adafruit.com" ///< Adafruit IO MQTT Server
6361
//(Production)
6462

@@ -71,7 +69,7 @@
7169
#endif
7270

7371
#define WS_VERSION \
74-
"1.0.0-beta.14" ///< WipperSnapper app. version (semver-formatted)
72+
"1.0.0-beta.15" ///< WipperSnapper app. version (semver-formatted)
7573

7674
// Reserved Adafruit IO MQTT topics
7775
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic

src/components/i2c/WipperSnapper_I2C.cpp

Lines changed: 109 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -113,49 +113,125 @@ WipperSnapper_Component_I2C::scanAddresses() {
113113

114114
/*******************************************************************************/
115115
/*!
116-
@brief Initializes I2C device driver and attaches its object to the "bus"
116+
@brief Initializes I2C device driver.
117117
@param msgDeviceInitReq
118118
A decoded I2CDevice initialization request message.
119119
@returns True if I2C device is initialized and attached, False otherwise.
120120
*/
121121
/*******************************************************************************/
122-
bool WipperSnapper_Component_I2C::attachI2CDevice(
122+
bool WipperSnapper_Component_I2C::initI2CDevice(
123123
wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq) {
124-
bool attachSuccess = false;
125-
// Determine which sensor-specific callback to utilize
126124

127-
// AHTX0 Sensor
125+
uint16_t i2cAddress = (uint16_t)msgDeviceInitReq->i2c_address;
126+
// Determine which sensor-specific callback to utilize
128127
if (msgDeviceInitReq->has_aht_init) {
129-
// TODO: Implement handling in future release
130-
/* uint16_t addr = (uint16_t)msgDeviceInitReq->aht_init.address;
131-
WS_DEBUG_PRINTLN("Requesting to initialize AHTx sensor");
132-
WS_DEBUG_PRINT("\tSensor Addr: ");
133-
WS_DEBUG_PRINTLN(addr, HEX);
134-
WS_DEBUG_PRINT("\tTemperature sensor enabled? ");
135-
WS_DEBUG_PRINTLN(msgDeviceInitReq->aht_init.enable_temperature);
136-
WS_DEBUG_PRINT("\tHumidity sensor enabled? ");
137-
WS_DEBUG_PRINTLN(msgDeviceInitReq->aht_init.enable_humidity);
138-
139-
// TODO: Create I2C Driver using the an AHT driver sub-class!
140-
I2C_Driver *aht = new I2C_Driver(addr, this->_i2c);
141-
// Attempt to initialize the sensor driver
142-
if (!aht->initAHTX0()) {
143-
attachSuccess = false;
144-
return attachSuccess;
145-
}
146-
// Initialize device-specific sensors
147-
if (msgDeviceInitReq->aht_init.enable_temperature == true) {
148-
aht->enableAHTX0Temperature();
149-
}
150-
if (msgDeviceInitReq->aht_init.enable_humidity == true) {
151-
aht->enableAHTX0Humidity();
152-
}
153-
// Push to vector for sensor drivers
154-
activeDrivers.push_back(aht); */
155-
attachSuccess = true;
128+
// Initialize new AHTX0 sensor
129+
_ahtx0 = new WipperSnapper_I2C_Driver_AHTX0(this->_i2c, i2cAddress);
130+
131+
// Did we initialize successfully?
132+
if (!_ahtx0->getInitialized()) {
133+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize AHTX0 chip!");
134+
return false;
135+
}
136+
WS_DEBUG_PRINTLN("AHTX0 Initialized Successfully!");
137+
138+
// Configure AHTX0 sensor
139+
if (msgDeviceInitReq->aht_init.enable_temperature) {
140+
_ahtx0->enableTemperatureSensor();
141+
_ahtx0->setTemperatureSensorPeriod(
142+
msgDeviceInitReq->aht_init.period_temperature);
143+
WS_DEBUG_PRINTLN("Enabled AHTX0 Temperature Sensor, [Returns every: ");
144+
WS_DEBUG_PRINT(msgDeviceInitReq->aht_init.period_temperature);
145+
WS_DEBUG_PRINTLN("seconds]");
146+
}
147+
if (msgDeviceInitReq->aht_init.enable_humidity) {
148+
_ahtx0->enableHumiditySensor();
149+
_ahtx0->setHumiditySensorPeriod(
150+
msgDeviceInitReq->aht_init.period_humidity);
151+
WS_DEBUG_PRINTLN("Enabled AHTX0 Humidity Sensor, [Returns every: ");
152+
WS_DEBUG_PRINT(msgDeviceInitReq->aht_init.period_humidity);
153+
WS_DEBUG_PRINTLN("seconds]");
154+
}
155+
drivers.push_back(_ahtx0);
156156
} else {
157157
WS_DEBUG_PRINTLN("ERROR: Sensor not found")
158158
}
159159
WS_DEBUG_PRINTLN("Successfully initialized AHTX0 sensor!");
160-
return attachSuccess;
160+
return true;
161+
}
162+
163+
/*******************************************************************************/
164+
/*!
165+
@brief Updates the properties of an I2C device driver.
166+
@param msgDeviceUpdateReq
167+
A decoded I2CDeviceUpdateRequest.
168+
@returns True if I2C device is was successfully updated, False otherwise.
169+
*/
170+
/*******************************************************************************/
171+
bool WipperSnapper_Component_I2C::updateI2CDevice(
172+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceUpdateReq) {
173+
// TODO!! //
174+
}
175+
176+
/*******************************************************************************/
177+
/*!
178+
@brief Deinitializes an I2C device driver.
179+
@param msgDeviceDeinitReq
180+
A decoded I2CDeviceDeinitRequest.
181+
@returns True if I2C device is found and de-initialized, False otherwise.
182+
*/
183+
/*******************************************************************************/
184+
bool WipperSnapper_Component_I2C::deinitI2CDevice(
185+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq) {
186+
uint16_t deviceAddr = (uint16_t)msgDeviceDeinitReq->i2c_address;
187+
// Loop thru vector of drivers
188+
for (int i = 0; i < drivers.size(); i++) {
189+
if (drivers[i]->getSensorAddress() == deviceAddr) {
190+
// Check driver type
191+
if (drivers[i]->getDriverType() == AHTX0) {
192+
// Should we delete the driver entirely, or just update?
193+
if ((msgDeviceDeinitReq->aht.disable_temperature &&
194+
drivers[i]->getHumidSensorPeriod() == -1L) ||
195+
(msgDeviceDeinitReq->aht.disable_humidity &&
196+
drivers[i]->getTempSensorPeriod() == -1L) ||
197+
(msgDeviceDeinitReq->aht.disable_temperature &&
198+
msgDeviceDeinitReq->aht.disable_humidity)) {
199+
// delete the driver and remove from list so we dont attempt to
200+
// update() it
201+
delete _ahtx0;
202+
drivers.erase(drivers.begin() + i);
203+
return true;
204+
WS_DEBUG_PRINTLN("AHTX0 Deleted");
205+
}
206+
207+
// Disable the device's temperature sensor
208+
else if (msgDeviceDeinitReq->aht.disable_temperature) {
209+
drivers[i]->disableTemperatureSensor();
210+
return true;
211+
WS_DEBUG_PRINTLN("AHTX0 Temperature Sensor Disabled");
212+
}
213+
214+
// Disable the device's humidity sensor
215+
else if (msgDeviceDeinitReq->aht.disable_humidity) {
216+
drivers[i]->disableHumiditySensor();
217+
WS_DEBUG_PRINTLN("AHTX0 Humidity Sensor Disabled");
218+
return true;
219+
}
220+
} else {
221+
WS_DEBUG_PRINTLN("ERROR: Driver type unspecified");
222+
}
223+
}
224+
}
225+
// Driver was not erased or not found
226+
return false;
227+
}
228+
229+
/*******************************************************************************/
230+
/*!
231+
@brief Queries all I2C device drivers for new values. Fills and sends an
232+
I2CSensorEvent with the sensor event data.
233+
*/
234+
/*******************************************************************************/
235+
void WipperSnapper_Component_I2C::update() {
236+
// TODO
161237
}

src/components/i2c/WipperSnapper_I2C.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
#include "Wippersnapper.h"
2020
#include <Wire.h>
2121

22-
#include "drivers/I2C_Driver.h"
22+
#include "drivers/WipperSnapper_I2C_Driver.h"
23+
#include "drivers/WipperSnapper_I2C_Driver_AHTX0.h"
2324

2425
// forward decl.
2526
class Wippersnapper;
26-
class I2C_Driver;
2727

2828
/**************************************************************************/
2929
/*!
@@ -35,16 +35,27 @@ class WipperSnapper_Component_I2C {
3535
WipperSnapper_Component_I2C(
3636
wippersnapper_i2c_v1_I2CBusInitRequest *msgInitRequest);
3737
~WipperSnapper_Component_I2C();
38+
bool isInitialized();
39+
3840
wippersnapper_i2c_v1_I2CBusScanResponse scanAddresses();
3941
bool
40-
attachI2CDevice(wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq);
41-
bool isInitialized();
42+
initI2CDevice(wippersnapper_i2c_v1_I2CDeviceInitRequest *msgDeviceInitReq);
43+
// TODO: Update Implementation
44+
// THIS NEEDS AN UPDATE REQUEST
45+
bool updateI2CDevice(
46+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceUpdateReq);
47+
bool deinitI2CDevice(
48+
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq);
49+
50+
void update();
4251

4352
private:
4453
bool _isInit;
4554
int32_t _portNum;
46-
TwoWire *_i2c = NULL;
47-
std::vector<I2C_Driver *> activeDrivers;
55+
TwoWire *_i2c = nullptr;
56+
std::vector<WipperSnapper_I2C_Driver *> drivers;
57+
// Sensor drivers
58+
WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr;
4859
};
4960
extern Wippersnapper WS;
5061

0 commit comments

Comments
 (0)