Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 41 additions & 0 deletions example/PPStest/PPStest.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Minimal test app making calls to PPS module in tight loop, printing state to Serial
// Used to verify stability of the I2C interface to the module.
#include <M5Unified.h>
#include "M5ModulePPS.h"

M5ModulePPS pps;

#define OUTPUT_VOLTAGE 5.0f
#define OUTPUT_CURRENT 5.0f

void setup()
{
M5.begin();
Serial.begin(1000000);

Serial.printf("Attempting to connect to PPS\n");

while (!pps.begin(&Wire, M5.In_I2C.getSDA(), M5.In_I2C.getSCL(), MODULE_POWER_ADDR, 400000U))
{
Serial.println("Connect error");
delay(100);
}

Serial.printf("PPS connected\n");

pps.setOutputVoltage(OUTPUT_VOLTAGE);
pps.setOutputCurrent(OUTPUT_CURRENT);
pps.setPowerEnable(true);
}

int cycle=0;
void loop()
{

float voltage_readback = pps.getReadbackVoltage();
float current_readback = pps.getReadbackCurrent();
float vin = pps.getVIN();
const char * modestr = ((pps.getMode() <= 1) ? "CV" : "CC");

Serial.printf("%d: Vin=%0.3fV Vout=%0.3fV Iout=%0.3fA Mode=%s\n",cycle++,vin,voltage_readback,current_readback,modestr);
}
35 changes: 30 additions & 5 deletions src/M5ModulePPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,40 @@ bool M5ModulePPS::begin(TwoWire *wire, uint8_t sda, uint8_t scl, uint8_t addr,
}
}

// If a second I2c transaction is made to the module, less than 100us after the end of the previous call we get NACK errors
// The underlying cause looks like an issue in the latest ESP-IF I2C library, but until that is fixed we need a workaround
// The below wrappers for the I2C functions ensure the minimum gap is enforced, with minimal performance impact even with
// tight looping to the PPS libraries. It allows applications to run indefinitely vs a few seconds (with the demo app on a
// Core2). Once the I2C library is fixed, simply remove the MIN_GAP definition to disable the workaround.
#define MIN_GAP 100

#ifdef MIN_GAP
#define I2C_ENTRY() {uint32_t gap=micros()-_micros;if(gap<MIN_GAP)delayMicroseconds(MIN_GAP-gap);}
#define I2C_EXIT() {_micros=micros();}
#else
#define I2C_ENTRY()
#define I2C_EXIT()
#endif

bool M5ModulePPS::writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
uint8_t length) {
bool rc=false;
I2C_ENTRY();

_wire->beginTransmission(addr);
_wire->write(reg);
_wire->write(buffer, length);
if (_wire->endTransmission() == 0) return true;
return false;
if (_wire->endTransmission() == 0) rc=true;

I2C_EXIT();
return rc;
}

bool M5ModulePPS::readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
uint8_t length) {
uint8_t length) {
bool rc=false;
I2C_ENTRY();

uint8_t index = 0;
_wire->beginTransmission(addr);
_wire->write(reg);
Expand All @@ -38,9 +61,11 @@ bool M5ModulePPS::readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
for (uint8_t i = 0; i < length; i++) {
buffer[index++] = _wire->read();
}
return true;
rc=true;
}
return false;

I2C_EXIT();
return rc;
}

void M5ModulePPS::float_to_bytes(float s, uint8_t *d) {
Expand Down
1 change: 1 addition & 0 deletions src/M5ModulePPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class M5ModulePPS {
uint8_t _sda;
uint8_t _scl;
uint32_t _speed;
uint32_t _micros;
bool writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length);
bool readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length);
void float_to_bytes(float s, uint8_t *d);
Expand Down