Skip to content

Commit

Permalink
[#143] I2cModule uses generated constants
Browse files Browse the repository at this point in the history
  • Loading branch information
susanw1 committed Nov 21, 2023
1 parent 642b0dd commit 1681351
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ class ArduinoZscriptBasicSetup {
#endif

#ifdef ZSCRIPT_HAVE_I2C_CHANNEL
if (Zscript::I2cChannel<ZscriptParams>::getNotifChannelPersistMaxLength() > notifPersistLength) {
notifPersistLength = Zscript::I2cChannel<ZscriptParams>::getNotifChannelPersistMaxLength();
if (Zscript::i2c_module::I2cChannel<ZscriptParams>::getNotifChannelPersistMaxLength() > notifPersistLength) {
notifPersistLength = Zscript::i2c_module::I2cChannel<ZscriptParams>::getNotifChannelPersistMaxLength();
}
#endif
#ifdef ZSCRIPT_HAVE_UART_CHANNEL
Expand All @@ -139,10 +139,10 @@ class ArduinoZscriptBasicSetup {
#endif
uint8_t i = 0;
#if defined(ZSCRIPT_HAVE_I2C_MODULE) || defined(ZSCRIPT_HAVE_I2C_CHANNEL)
Zscript::I2cModule<ZscriptParams>::setup();
Zscript::i2c_module::I2cModule<ZscriptParams>::setup();
#endif
#ifdef ZSCRIPT_HAVE_I2C_CHANNEL
channels[i++] = &Zscript::I2cModule<ZscriptParams>::channel;
channels[i++] = &Zscript::i2c_module::I2cModule<ZscriptParams>::channel;
#endif

#if defined(ZSCRIPT_HAVE_UART_MODULE) || defined(ZSCRIPT_HAVE_UART_CHANNEL)
Expand Down Expand Up @@ -170,7 +170,7 @@ class ArduinoZscriptBasicSetup {
#ifdef ZSCRIPT_SUPPORT_NOTIFICATIONS
uint8_t srcCount = 0;
#ifdef ZSCRIPT_I2C_SUPPORT_NOTIFICATIONS
notifSrcs[srcCount++] = &Zscript::I2cModule<ZscriptParams>::notifSrc;
notifSrcs[srcCount++] = &Zscript::i2c_module::I2cModule<ZscriptParams>::notifSrc;
#endif
#ifdef ZSCRIPT_PIN_SUPPORT_NOTIFICATIONS
notifSrcs[srcCount++] = &Zscript::pins_module::PinModule<ZscriptParams>::notificationSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@

namespace Zscript {

namespace i2c_module {

template<class ZP>
class I2cChannel;
}

}

#include "commands/I2cChannelInfo.hpp"
#include "commands/I2cChannelSetup.hpp"

Expand All @@ -59,19 +63,21 @@ class I2cChannel;
#endif

#define MODULE_EXISTS_005 EXISTENCE_MARKER_UTIL
#define MODULE_SWITCH_005 MODULE_SWITCH_UTIL(I2cModule<ZP>::execute)
#define MODULE_SWITCH_005 MODULE_SWITCH_UTIL(i2c_module::I2cModule<ZP>::execute)

#ifdef ZSCRIPT_I2C_SUPPORT_NOTIFICATIONS
# ifdef ZSCRIPT_SUPPORT_ADDRESSING
# define MODULE_ADDRESS_EXISTS_005 EXISTENCE_MARKER_UTIL
# define MODULE_ADDRESS_SWITCH_005 ADDRESS_SWITCH_UTIL(I2cModule<ZP>::address)
# define MODULE_ADDRESS_SWITCH_005 ADDRESS_SWITCH_UTIL(i2c_module::I2cModule<ZP>::address)
# endif
# define MODULE_NOTIFICATION_EXISTS_005 EXISTENCE_MARKER_UTIL
# define MODULE_NOTIFICATION_SWITCH_005 NOTIFICATION_SWITCH_UTIL(I2cModule<ZP>::notification)
# define MODULE_NOTIFICATION_SWITCH_005 NOTIFICATION_SWITCH_UTIL(i2c_module::I2cModule<ZP>::notification)
#endif

namespace Zscript {

namespace i2c_module {

template<class ZP>
class I2cModule : public ZscriptModule<ZP> {
#ifdef ZSCRIPT_I2C_SUPPORT_NOTIFICATIONS
Expand All @@ -88,7 +94,7 @@ class I2cModule : public ZscriptModule<ZP> {

public:
#ifdef ZSCRIPT_HAVE_I2C_CHANNEL
static I2cChannel<ZP> channel;
static I2cChannel <ZP> channel;
#endif


Expand Down Expand Up @@ -193,4 +199,6 @@ GenericCore::ZscriptNotificationSource<ZP> I2cModule<ZP>::notifSrc;
#endif
}

}

#endif /* SRC_MAIN_CPP_ARDUINO_I2C_MODULE_ZSCRIPTI2CMODULE_HPP_ */
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

namespace Zscript {

namespace i2c_module {

template<class ZP>
class I2cOutStream : public AbstractOutStream<ZP> {
public:
Expand Down Expand Up @@ -230,28 +232,6 @@ class I2cChannel : public ZscriptChannel<ZP> {
}
}
}

// void channelInfo(ZscriptCommandContext<ZP> ctx) {
// CommandOutStream<ZP> ctxOut = ctx.getOutStream();
// ctxOut.writeField('N', 0);
// ctxOut.writeField('M', 0x5);
// }
//
// void channelSetup(ZscriptCommandContext<ZP> ctx) {
// uint16_t addr;
// if (ctx.getField('A', &addr)) {
// if (addr >= 128) {
// ctx.status(ResponseStatus::VALUE_OUT_OF_RANGE);
// return;
// }
// out.setAddr((uint8_t) addr);
// }
// if (ctx.hasField('P')) {
// uint8_t index = this->parser.getChannelIndex();
// PersistenceSystem<ZP>::writeSection(PersistenceSystem<ZP>::getNotifChannelIdOffset(), 1, &index);
// }
// }

};

template<class ZP>
Expand All @@ -271,4 +251,6 @@ bool I2cChannel<ZP>::usingTmp = false;

}

}

#endif /* SRC_MAIN_CPP_ARDUINO_I2C_MODULE_CHANNELS_ZSCRIPTI2CCHANNEL_HPP_ */
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,26 @@
#define SRC_MAIN_CPP_ARDUINO_I2C_MODULE_COMMANDS_GENERALI2CACTION_HPP_

#include <zscript/modules/ZscriptCommand.hpp>
#include <net/zscript/model/modules/base/I2cModule.hpp>
#include <Wire.h>

#define COMMAND_EXISTS_0052 EXISTENCE_MARKER_UTIL
#define COMMAND_EXISTS_0053 EXISTENCE_MARKER_UTIL
#define COMMAND_EXISTS_0054 EXISTENCE_MARKER_UTIL

/**
* Handles the Send, Receive, and Send+Receive cases directly - they're pretty similar
*/
namespace Zscript {
template<class ZP>
class GeneralI2cAction {
static constexpr char ParamInterface__I = 'I';
static constexpr char ParamAddr__A = 'A';
static constexpr char ParamTenBit__T = 'T';
static constexpr char ParamRetries__R = 'R';
static constexpr char ParamReadLength__L = 'L';

static constexpr char RespRetries__R = 'R';
static constexpr char RespResultType__I = 'I';
static constexpr char RespResultType__OK = 0;
static constexpr char RespResultType__ADDRNACK = 2;
static constexpr char RespResultType__DATANACK = 3;
static constexpr char RespResultType__OTHER = 4;
namespace i2c_module {

template<class ZP>
class GeneralI2cAction: I2cSendReceive_CommandDefs {
public:
static constexpr uint8_t SEND_CODE = 0x02;
static constexpr uint8_t RECEIVE_CODE = 0x03;
static constexpr uint8_t SEND_RECEIVE_CODE = 0x04;
static constexpr uint8_t SEND_CODE = I2cSend_CommandDefs::CODE;
static constexpr uint8_t RECEIVE_CODE = I2cReceive_CommandDefs::CODE;
static constexpr uint8_t SEND_RECEIVE_CODE = I2cSendReceive_CommandDefs::CODE;

/** Note, SEND | RECEIVE == SEND_RECEIVE */
enum class ActionType : uint8_t {
Expand All @@ -45,11 +37,11 @@ class GeneralI2cAction {

static void executeSendReceive(ZscriptCommandContext<ZP> ctx, ActionType action) {
uint16_t address;
if (!ctx.getField(ParamAddr__A, &address)) {
if (!ctx.getField(ReqAddress__A, &address)) {
ctx.status(ResponseStatus::MISSING_KEY);
return;
}
if (ctx.hasField(ParamTenBit__T)) {
if (ctx.hasField(ReqTenBitMode__T)) {
ctx.status(ResponseStatus::EXECUTION_ERROR);
return;
}
Expand All @@ -60,22 +52,19 @@ class GeneralI2cAction {

CommandOutStream<ZP> out = ctx.getOutStream();

uint16_t requestedLength = ctx.getField(ParamReadLength__L, (uint16_t) 0);
uint16_t requestedLength = ctx.getField(ReqLength__L, (uint16_t) 0);
if (requestedLength > 32) {
ctx.status(ResponseStatus::DATA_TOO_LONG);
return;
}

// initial pass
uint16_t interface;
if (!ctx.getField(ParamInterface__I, &interface)) {
interface = 0;
} else if (interface > 0) {
ctx.status(ResponseStatus::VALUE_OUT_OF_RANGE);
if (!ctx.getReqdFieldCheckLimit(ReqInterface__I, 1, &interface)) {
return;
}

uint16_t retries = ctx.getField(ParamRetries__R, 5);
uint16_t retries = ctx.getField(ReqRetries__R, 5);
if (retries > 255) {
ctx.status(ResponseStatus::VALUE_OUT_OF_RANGE);
return;
Expand All @@ -94,44 +83,20 @@ class GeneralI2cAction {

uint8_t buffer[requestedLength];
switch ((ActionType) action) {
case ActionType::SEND:
Wire.beginTransmission((uint8_t) address);
if (ctx.getBigFieldSize() > 0) {
for (BigFieldBlockIterator<ZP> tbi = ctx.getBigField(); tbi.hasNext();) {
DataArrayWLeng16 data = tbi.nextContiguous();
Wire.write(data.data, data.length);
}
}
status = Wire.endTransmission();
break;
case ActionType::RECEIVE:
{
uint8_t len = Wire.requestFrom((uint8_t) address, (uint8_t) requestedLength);
if (len == 0) {
status = 2;
} else if (len != requestedLength) {
status = 4;
} else {
status = 0;
for (uint8_t i = 0; i < requestedLength; i++) {
buffer[i] = (uint8_t) Wire.read();
}
}
}
break;
case ActionType::SEND_RECEIVE:
Wire.beginTransmission((uint8_t) address);
if (ctx.getBigFieldSize() > 0) {
for (BigFieldBlockIterator<ZP> tbi = ctx.getBigField(); tbi.hasNext();) {
DataArrayWLeng16 data = tbi.nextContiguous();
Wire.write(data.data, data.length);
case ActionType::SEND:
Wire.beginTransmission((uint8_t) address);
if (ctx.getBigFieldSize() > 0) {
for (BigFieldBlockIterator<ZP> tbi = ctx.getBigField(); tbi.hasNext();) {
DataArrayWLeng16 data = tbi.nextContiguous();
Wire.write(data.data, data.length);
}
}
}
status = Wire.endTransmission(false);
if (status == 0) {
status = Wire.endTransmission();
break;
case ActionType::RECEIVE: {
uint8_t len = Wire.requestFrom((uint8_t) address, (uint8_t) requestedLength);
if (len == 0) {
status = 6;
status = 2;
} else if (len != requestedLength) {
status = 4;
} else {
Expand All @@ -140,52 +105,76 @@ class GeneralI2cAction {
buffer[i] = (uint8_t) Wire.read();
}
}
break;
}
break;
break;
case ActionType::SEND_RECEIVE:
Wire.beginTransmission((uint8_t) address);
if (ctx.getBigFieldSize() > 0) {
for (BigFieldBlockIterator<ZP> tbi = ctx.getBigField(); tbi.hasNext();) {
DataArrayWLeng16 data = tbi.nextContiguous();
Wire.write(data.data, data.length);
}
}
status = Wire.endTransmission(false);
if (status == 0) {
uint8_t len = Wire.requestFrom((uint8_t) address, (uint8_t) requestedLength);
if (len == 0) {
status = 6;
} else if (len != requestedLength) {
status = 4;
} else {
status = 0;
for (uint8_t i = 0; i < requestedLength; i++) {
buffer[i] = (uint8_t) Wire.read();
}
}
break;
}
break;
}

if (status == 0) {
infoValue = RespResultType__OK;
infoValue = RespResultInfo_Values::ok_value;
if (((uint8_t) action & (uint8_t) ActionType::RECEIVE) != 0) {
out.writeBigHex(buffer, requestedLength);
}
break;
} else if (status == 3) {
// abrupt failure during data send - don't retry, because its status is now unknown
infoValue = RespResultType__DATANACK;
infoValue = RespResultInfo_Values::dataNack_value;
ctx.status(ResponseStatus::COMMAND_DATA_NOT_TRANSMITTED);
break;
} else if (status == 5 || status == 4) {
if (recoverBusJam()) {
infoValue = RespResultType__OTHER;
infoValue = RespResultInfo_Values::other_value;
ctx.status(ResponseStatus::PERIPHERAL_JAM);
} else {
infoValue = RespResultType__OTHER;
infoValue = RespResultInfo_Values::other_value;
ctx.status(ResponseStatus::COMMAND_FAIL);
}
break;
} else if (status == 6 && action == ActionType::SEND_RECEIVE) {
infoValue = RespResultType__ADDRNACK;
infoValue = RespResultInfo_Values::addrNack_value;
ctx.status(ResponseStatus::COMMAND_NO_TARGET);
break;
} else if (attemptsDone < retries) {
// any other error, keep retrying. Beyond here, we must be at the end of all retries.
} else if (status == 2) {
infoValue = RespResultType__ADDRNACK;
infoValue = RespResultInfo_Values::addrNack_value;
ctx.status(ResponseStatus::COMMAND_NO_TARGET);
break;
} else {
infoValue = RespResultType__OTHER;
infoValue = RespResultInfo_Values::other_value;
ctx.status(ResponseStatus::COMMAND_FAIL);
break;
}

}
out.writeField(RespRetries__R, attemptsDone);
out.writeField(RespResultType__I, infoValue);
out.writeField(RespAttempts__R, attemptsDone);
out.writeField(RespResultInfo__I, infoValue);
return;
}

#ifdef ZSCRIPT_SUPPORT_ADDRESSING
static void executeAddressing(ZscriptAddressingContext<ZP> ctx) {
uint16_t interface;
Expand Down Expand Up @@ -249,7 +238,7 @@ class GeneralI2cAction {
pinMode(SDA, INPUT_PULLUP);
pinMode(SCL, INPUT_PULLUP);

if (digitalRead (SDA)) {
if (digitalRead(SDA)) {
if (!digitalRead(SCL)) {
Wire.begin();
return false;
Expand Down Expand Up @@ -279,4 +268,6 @@ class GeneralI2cAction {

}

}

#endif /* SRC_MAIN_CPP_ARDUINO_I2C_MODULE_COMMANDS_GENERALI2CACTION_HPP_ */
Loading

0 comments on commit 1681351

Please sign in to comment.