fixed some issue with SoftI2C not working (missing delay)

added code for a waveshare eInk
refactored some old code to match with the new SoftI2C
This commit is contained in:
2020-10-18 10:49:59 +02:00
parent 9c94faa24d
commit ac74587ee7
7 changed files with 426 additions and 44 deletions

102
ext/e-ink/Waveshare.h Normal file
View File

@@ -0,0 +1,102 @@
#ifndef E_INK_WAVESHARE
#define E_INK_WAVESHARE
#include <cstdint>
#include "../../Debug.h"
/**
* base-class for Waveshare SPI E-Ink displays
* subclasses for every display type implement the actual methods
*/
template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class Waveshare {
static constexpr const char* NAME = "E-Ink";
SPI& spi;
public:
Waveshare(SPI& spi) : spi(spi) {
debugMod4(NAME, "ctor() CS:%d BUSY:%d RST:%d DC:%d", PIN_CS, PIN_BUSY, PIN_RST, PIN_DC);
MyGPIO::setInput(PIN_BUSY);
MyGPIO::setOutput(PIN_RST);
MyGPIO::setOutput(PIN_DC);
MyGPIO::setOutput(PIN_CS);
}
protected:
void reset() {
debugMod(NAME, "reset()");
MyGPIO::clear(PIN_RST);
usleep(200*1000);
MyGPIO::set(PIN_RST);
usleep(200*1000);
}
void sendCommand(uint8_t command) {
MyGPIO::clear(PIN_DC);
transfer(command);
}
void sendData(uint8_t data) {
MyGPIO::set(PIN_DC);
transfer(data);
}
void transfer(uint8_t data) {
MyGPIO::clear(PIN_CS); // select
spi.writeByte(data);
MyGPIO::clear(PIN_CS); // unselect
}
void waitUntilIdle() {
debugMod(NAME, "waitUntilIdle()");
while(MyGPIO::get(PIN_BUSY) == 0) {usleep(200*1000);}
debugMod(NAME, "OK");
}
void lut(uint8_t c, uint8_t l, const uint8_t* p) {
sendCommand(c);
for (int i = 0; i < l; i++, p++) {
sendData(*p);
}
}
void send1(uint8_t cmd, uint8_t v1) {
sendCommand(cmd);
sendData(v1);
}
void send2(uint8_t cmd, uint8_t v1, uint8_t v2) {
sendCommand(cmd);
sendData(v1);
sendData(v2);
}
void send3(uint8_t cmd, uint8_t v1, uint8_t v2, uint8_t v3) {
sendCommand(cmd);
sendData(v1);
sendData(v2);
sendData(v3);
}
void send4(uint8_t cmd, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4) {
sendCommand(cmd);
sendData(v1);
sendData(v2);
sendData(v3);
sendData(v4);
}
void send5(uint8_t cmd, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5) {
sendCommand(cmd);
sendData(v1);
sendData(v2);
sendData(v3);
sendData(v4);
sendData(v5);
}
};
#endif // E_INK_WAVESHARE

255
ext/e-ink/Waveshare_4_2.h Normal file
View File

@@ -0,0 +1,255 @@
#include "Waveshare.h"
template <int PIN_CS, int PIN_BUSY, int PIN_RST, int PIN_DC, typename SPI> class Waveshare_4_2 : public Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI> {
static constexpr const char* NAME = "E-Ink 4.2\"";
public:
enum class Mode {
BLACK_WHITE,
BLACK_WHITE_RED,
};
public:
Waveshare_4_2(SPI& spi) : Waveshare<PIN_CS, PIN_BUSY, PIN_RST, PIN_DC, SPI>(spi) {
}
public:
struct Window {
uint16_t x1; // must be multiple of 8
uint16_t y1;
uint16_t w; // must be multiple of 8
uint16_t h;
Window(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) : x1(x1), y1(y1), w(w), h(h) {}
};
void setWindow(Window& win) {
this->sendCommand(0x90);
this->sendData((win.x1) >> 8);
this->sendData((win.x1) >> 0);
this->sendData((win.x1+win.w-1) >> 8);
this->sendData((win.x1+win.w-1) >> 0);
this->sendData(win.y1 >> 8);
this->sendData(win.y1 >> 0);
this->sendData((win.y1+win.h-1) >> 8);
this->sendData((win.y1+win.h-1) >> 0);
this->sendData(0x0); // 0 = refresh only the window, 1 = refresh everything??
}
void enableWindow() {
this->sendCommand(0x91);
}
void disableWindow() {
this->sendCommand(0x92);
}
void init(Mode mode) {
debugMod(NAME, "init()");
this->reset();
this->send3(0x06, 0x17, 0x17, 0x17); // BOOSTER_SOFT_START
this->sendCommand(0x04); // POWER_ON
this->waitUntilIdle();
uint8_t cfg = 0x0F;
if (mode == Mode::BLACK_WHITE) {cfg |= (1<<4);}
this->send1(0x00, cfg); // PANEL_SETTING
this->send1(0x50, 0xF7); // VCOM_AND_DATA_INTERVAL_SETTING
//this->sendCommand(0x10);//DATA_START_TRANSMISSION_1
//usleep(10*1000);
debugMod(NAME, "init() complete");
}
void loadBlack(const uint8_t* black) {
this->sendCommand(0x10);
if (black) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(black[i]));}
} else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);}
}
this->sendCommand(0x11);
}
void loadRed(const uint8_t* red) {
this->sendCommand(0x13);
if (red) {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~reverse(red[i]));}
} else {
for (int i = 0; i < 400*300/8; ++i) {this->sendData(~0x00);}
}
this->sendCommand(0x11);
}
static uint8_t reverse(uint8_t a) {
return
((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
void show() {
debugMod(NAME, "refresh");
this->sendCommand(0x12);//DISPLAY_REFRESH
usleep(100*1000);
this->waitUntilIdle();
debugMod(NAME, "refresh done");
debugMod(NAME, "sleep");
this->send1(0x50, 0x17);//VCOM_AND_DATA_INTERVAL_SETTING
this->send1(0x82, 0x00);//VCM_DC_SETTING_REGISTER, to solve Vcom drop
this->send4(0x01, 0x02, 0x00, 0x00, 0x00);//POWER_SETTING
this->waitUntilIdle();
this->sendCommand(0x02);//POWER_OFF
debugMod(NAME, "sleep done");
}
private:
unsigned char lut_dc_4in2[44] = {
0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x17, 0x00, 0x00,
0x02, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R21H
unsigned char lut_ww_4in2[42] = {
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R22H r
unsigned char lut_bw_4in2[42] = {
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R24H b
unsigned char lut_bb_4in2[42] = {
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R23H w
unsigned char lut_wb_4in2[42] = {
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
};
/*
int EPD_Init_4in2()
{
EPD_Reset();
EPD_SendCommand(0x01);//POWER_SETTING
EPD_SendData(0x03); // VDS_EN, VDG_EN
EPD_SendData(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
EPD_SendData(0x2F); // VDH
EPD_SendData(0x2F); // VDL
EPD_SendData(0xFF); // VDHR
EPD_Send_3(0x06, 0x17, 0x17, 0x17);//BOOSTER_SOFT_START
EPD_SendCommand(0x04);//POWER_ON
EPD_WaitUntilIdle();
EPD_Send_2(0x00, 0xBF, 0x0B);//PANEL_SETTING: // KW-BF KWR-AF BWROTP 0f
EPD_Send_1(0x30, 0x3C);//PLL_CONTROL: 3A 100HZ, 29 150Hz, 39 200HZ, 31 171HZ
EPD_Send_4(0x61, 1, 144, 1, 44);// RESOLUTION_SETTING: HI(W), LO(W), HI(H), LO(H)
EPD_Send_1(0x82, 0x12);// VCM_DC_SETTING
EPD_Send_1(0x50, 0x97);// VCOM_AND_DATA_INTERVAL_SETTING: VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
EPD_lut(0x20,44,&lut_dc_4in2[0]);// LUT_FOR_VCOM
EPD_lut(0x21,42,&lut_ww_4in2[0]);// LUT_WHITE_TO_WHITE
EPD_lut(0x22,42,&lut_bw_4in2[0]);// LUT_BLACK_TO_WHITE
EPD_lut(0x23,42,&lut_wb_4in2[0]);// LUT_WHITE_TO_BLACK
EPD_lut(0x24,42,&lut_bb_4in2[0]);// LUT_BLACK_TO_BLACK
EPD_SendCommand(0x10);//DATA_START_TRANSMISSION_1
delay(2);
for(int i = 0; i < 400*300; i++)EPD_SendData(0xFF);//Red channel
EPD_SendCommand(0x13);//DATA_START_TRANSMISSION_2
delay(2);
return 0;
}
unsigned char lut_dc_4in2b[] =
{
0x00, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x17, 0x17, 0x00, 0x00,
0x02, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0E, 0x0E, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R21H
unsigned char lut_ww_4in2b[] =
{
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R22H r
unsigned char lut_bw_4in2b[] =
{
0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x40, 0x0A,
0x01, 0x00, 0x00, 0x01, 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R24H b
unsigned char lut_bb_4in2b[] =
{
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//R23H w
unsigned char lut_wb_4in2b[] =
{
0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 0x80, 0x0A,
0x01, 0x00, 0x00, 0x01, 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
int EPD_Init_4in2b()
{
EPD_Reset();
EPD_Send_3(0x06,0x17,0x17,0x17);//BOOSTER_SOFT_START
EPD_SendCommand(0x04);//POWER_ON
EPD_WaitUntilIdle();
EPD_Send_1(0x00, 0x0F);//PANEL_SETTING
EPD_Send_1(0x50,0xF7);// VCOM_AND_DATA_INTERVAL_SETTING
EPD_SendCommand(0x10);//DATA_START_TRANSMISSION_1
delay(2);
return 0;
}
*/

View File

@@ -169,6 +169,9 @@ public:
// set output power to 17 dBm
setTxPower(17);
// we use explicit header mode for RX/TX
explicitHeaderMode();
// put in standby mode
idle();
@@ -351,9 +354,9 @@ public:
if (isTransmitting()) {return 0;}
// put in standby mode
idle();
//idle();
explicitHeaderMode();
//explicitHeaderMode();
// reset FIFO address and payload length
writeRegister(REG_FIFO_ADDR_PTR, 0);
@@ -412,7 +415,7 @@ public:
uint8_t irqFlags = readRegister(REG_IRQ_FLAGS);
explicitHeaderMode();
//explicitHeaderMode();
// clear all current IRQ flags
writeRegister(REG_IRQ_FLAGS, irqFlags);

View File

@@ -73,7 +73,7 @@ private:
// read all 24 calibration bytes for temperature and pressure
uint8_t b1[24];
readRegister(REG_DIG_T1, b1, 24);
i2c.readReg(ADDR7, REG_DIG_T1, 24, b1);
cal.dig_T1 = (b1[1] << 8) | b1[0];
cal.dig_T2 = (b1[3] << 8) | b1[2];
@@ -90,8 +90,8 @@ private:
cal.dig_P9 = (b1[23] << 8) | b1[22];
// humidity
readRegister(0xA1, &cal.dig_H1, 1);
readRegister(0xE1, b1, 7);
i2c.readReg(ADDR7, 0xA1, 1, &cal.dig_H1);
i2c.readReg(ADDR7, 0xE1, 7, b1);
cal.dig_H2 = (b1[1] << 8) | b1[0];
cal.dig_H3 = b1[3];
cal.dig_H4 = (b1[3] << 4) | (b1[4] & 0b000001111);
@@ -101,9 +101,9 @@ private:
//os_printf("calib temp: %d %d %d\n", cal.dig_T1, cal.dig_T2, cal.dig_T3);
//os_printf("calib pres: %d %d %d %d %d %d %d %d %d\n", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9);
//os_printf("calib humi: %d %d %d %d %d %d\n", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6);
debugMod3(NAME, "calTemp: %d %d %d", cal.dig_T1, cal.dig_T2, cal.dig_T3);
debugMod9(NAME, "calPres: %d %d %d %d %d %d %d %d %d", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9);
debugMod6(NAME, "calHumi: %d %d %d %d %d %d", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6);
//debugMod3(NAME, "calTemp: %d %d %d", cal.dig_T1, cal.dig_T2, cal.dig_T3);
//debugMod9(NAME, "calPres: %d %d %d %d %d %d %d %d %d", cal.dig_P1, cal.dig_P2, cal.dig_P3, cal.dig_P4, cal.dig_P5, cal.dig_P6, cal.dig_P7, cal.dig_P8, cal.dig_P9);
//debugMod6(NAME, "calHumi: %d %d %d %d %d %d", cal.dig_H1, cal.dig_H2, cal.dig_H3, cal.dig_H4, cal.dig_H5, cal.dig_H6);
}
@@ -115,8 +115,8 @@ private:
const uint8_t cfgMode = 0b11;
const uint8_t cfg1 = (cfgHumi << 1);
const uint8_t cfg2 = (cfgTemp << 5) | (cfgPres << 2) | (cfgMode << 0);
writeRegister(REG_CTRL1, &cfg1, 1);
writeRegister(REG_CTRL2, &cfg2, 1);
i2c.writeReg(ADDR7, REG_CTRL1, 1, &cfg1);
i2c.writeReg(ADDR7, REG_CTRL2, 1, &cfg2);
}
@@ -133,7 +133,7 @@ public:
uint8_t getStatus() {
uint8_t res[1];
readRegister(REG_STATUS, res, 1);
i2c.readReg(ADDR7, REG_STATUS, 1, res);
//os_printf("Status: %d \n", res[0]);
return 0;
}
@@ -141,58 +141,59 @@ public:
/** get current pressure in hPa */
float getPressure() {
uint8_t res[3];
readRegister(REG_PRESSURE, res, 3);
i2c.readReg(ADDR7, REG_PRESSURE, 3, res);
//os_printf("res: %d - %d - %d \n", res[0], res[1], res[2]);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const uint32_t pres = BME280_compensate_P_int64(tmp);
const float presF = pres / 256.0f / 100.0f; // convert from Q24.8 to float and from Pa to hPa
const uint32_t p0 = pres / 256;
const uint32_t p1 = (uint32_t) presF;
const uint32_t p2 = (presF - p1) * 100000;
debugMod4(NAME, "[pres] ADC: %d -> %d Pa | %d.%d hPa", tmp, p0, p1,p2);
//const uint32_t p0 = pres / 256;
//const uint32_t p1 = (uint32_t) presF;
//const uint32_t p2 = (presF - p1) * 100000;
//debugMod4(NAME, "[pres] ADC: %d -> %d Pa | %d.%d hPa", tmp, p0, p1,p2);
return presF;
}
float getTemperature() {
uint8_t res[3];
readRegister(REG_TEMPERATURE, res, 3);
i2c.readReg(ADDR7, REG_TEMPERATURE, 3, res);
//os_printf("res: %d - %d - %d \n", res[0], res[1], res[2]);
const uint32_t tmp = ((res[0] << 16) | (res[1] << 8) | (res[2] << 0)) >> 4;
const int32_t temp = BME280_compensate_T_int32(tmp);
const float tempF = temp / 100.0f;
debugMod2(NAME, "[temp] ADC: %d -> %d", tmp, temp);
//debugMod2(NAME, "[temp] ADC: %d -> %d", tmp, temp);
return tempF;
}
float getHumidity() {
uint8_t res[2];
readRegister(REG_HUMIDITY, res, 2);
i2c.readReg(ADDR7, REG_HUMIDITY, 2, res);
//os_printf("res: %d - %d \n", res[0], res[1]);
const uint32_t tmp = (res[0] << 8) | (res[1] << 0);
const int32_t humi = bme280_compensate_H_int32(tmp);
const float humiF = humi / 1024.0f;
const uint16_t h0 = humi / 1024;
const uint16_t h1 = (uint16_t) humiF;
const uint16_t h2 = (humiF - humi) * 10000;
debugMod4(NAME, "[humi] ADC: %d -> %d -> %d.%d %%", tmp, h0, h1,h2);
//const uint16_t h0 = humi / 1024;
//const uint16_t h1 = (uint16_t) humiF;
//const uint16_t h2 = (humiF - humi) * 10000;
//debugMod4(NAME, "[humi] ADC: %d -> %d -> %d.%d %%", tmp, h0, h1,h2);
return humiF;
}
/*
bool readRegister(const uint8_t addr, uint8_t* dst, const uint8_t len) {
bool ok;
// address the slave in write mode and select the first register to read
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n"); return false;}
if (!ok) {printf("failed start write\n"); return false;}
ok = i2c.writeByteAndCheck(addr);
if (!ok) {os_printf("failed to select register %d\n", addr); return false;}
if (!ok) {printf("failed to select register %d\n", addr); return false;}
//i2c::stop();
// address the slave in read mode and read [len] registers
ok = i2c.startRead(ADDR7);
if (!ok) {os_printf("failed start read\n"); return 0;}
if (!ok) {printf("failed start read\n"); return 0;}
i2c.readBytes(dst, len);
// done
@@ -207,11 +208,11 @@ public:
// address the slave in write mode and select the first register to read
ok = i2c.startWrite(ADDR7);
if (!ok) {os_printf("failed start write\n"); return false;}
if (!ok) {printf("failed start write\n"); return false;}
ok = i2c.writeByteAndCheck(addr);
if (!ok) {os_printf("failed to select register %d\n", addr); return false;}
if (!ok) {printf("failed to select register %d\n", addr); return false;}
ok = i2c.writeBytesAndCheck(src, len);
if (!ok) {os_printf("failed to write register contents \n"); return false;}
if (!ok) {printf("failed to write register contents \n"); return false;}
// done
i2c.stop();
@@ -219,7 +220,7 @@ public:
}
*/
private:

View File

@@ -3,7 +3,7 @@
#include "../../io/SoftI2C.h"
class DS3231 {
template <typename I2C> class DS3231 {
static constexpr uint8_t ADDR7 = 0x68;
@@ -11,11 +11,17 @@ class DS3231 {
static constexpr uint8_t REG_MINUTES = 0x01;
static constexpr uint8_t REG_HOURS = 0x02;
I2C& i2c;
public:
DS3231(I2C& i2c) : i2c(i2c) {
;
}
bool isPresent() {
return i2c::query(ADDR7);
//return i2c::query(ADDR7);
return i2c.query(ADDR7);
}
struct Time {
@@ -37,7 +43,7 @@ public:
Res get() {
uint8_t buf[8];
readRegister(0x00, buf, 8);
i2c.readReg(ADDR7, 0x00, 8, buf);
Res res;
@@ -49,8 +55,8 @@ public:
res.date.m = (((buf[5] & 0b00010000)>>4)*10) + (buf[5] & 0b1111);
res.date.y = (((buf[6] & 0b11110000)>>4)*10) + (buf[6] & 0b1111);
os_printf("%d %d %d \n", res.time.h, res.time.m, res.time.s);
os_printf("%d %d %d \n", res.date.d, res.date.m, res.date.y);
printf("%d %d %d \n", res.time.h, res.time.m, res.time.s);
printf("%d %d %d \n", res.date.d, res.date.m, res.date.y);
return res;
@@ -62,7 +68,7 @@ public:
buf[0] = ((s/10)<<4) + (s % 10);
buf[1] = ((m/10)<<4) + (m % 10);
buf[2] = ((h/10)<<4) + (h % 10);
writeRegister(0x00, buf, 3);
i2c.writeReg(ADDR7, 0x00, 3, buf);
}
@@ -72,12 +78,13 @@ public:
buf[0] = ((d/10)<<4) + (d % 10);
buf[1] = ((m/10)<<4) + (m % 10);
buf[2] = ((y/10)<<4) + (y % 10);
writeRegister(0x04, buf, 3);
i2c.writeReg(ADDR7, 0x04, 3, buf);
}
private:
/*
bool readRegister(const uint8_t addr, uint8_t* dst, const uint8_t len) {
bool ok;
@@ -118,6 +125,7 @@ private:
return true;
}
*/
};

View File

@@ -15,6 +15,7 @@ template <int PIN_SDA, int PIN_SCL, bool fast> class SoftI2C {
inline void sdaDirIn() {MyGPIO::setInput(PIN_SDA);}
inline void sclDirOut() {MyGPIO::setOutput(PIN_SCL);}
inline void sclDirIn() {MyGPIO::setInput(PIN_SCL);}
inline void sdaHi() {MyGPIO::set(PIN_SDA);}
inline void sdaLo() {MyGPIO::clear(PIN_SDA);}
@@ -29,7 +30,7 @@ template <int PIN_SDA, int PIN_SCL, bool fast> class SoftI2C {
__asm__ __volatile__("nop");
}
} else {
for (uint16_t i = 0; i < 1024; ++i) {
for (uint16_t i = 0; i < 2048; ++i) {
__asm__ __volatile__("nop");
}
}
@@ -92,7 +93,8 @@ public:
waitLong();
sdaHi();
sdaDirIn(); // free the bus
sdaDirIn(); // free the bus
sclDirIn(); // TESTING. free the bus
waitLong();
@@ -147,6 +149,17 @@ public:
stop();
return ok;
}
inline void queryAll() {
debugMod(NAME, "queryAll()")
for (uint8_t i = 0; i < 128; ++i) {
if (query(i)) {
debugMod1(NAME, "found %d", i)
}
waitLong();
if (i%16 == 0) {vTaskDelay(100 / portTICK_PERIOD_MS);}
}
}
@@ -166,14 +179,14 @@ public:
// select register(s) to read
ok = startWrite(addr);
if (!ok) {debugMod(NAME, "failed start write(1)"); return false;}
if (!ok) {debugMod(NAME, "failed start read(1)"); return false;}
ok = writeByteAndCheck(reg);
if (!ok) {debugMod(NAME, "failed select register"); return false;}
stop();
// read register(s)
ok = startRead(addr);
if (!ok) {debugMod(NAME, "failed start write(2)"); return false;}
if (!ok) {debugMod(NAME, "failed start read(2)"); return false;}
readBytes(dst, len);
stop();
@@ -215,6 +228,7 @@ private:
inline void _writeBit(const bool out) {
//sdaDirOut(); // switch to output mode
if(out) {sdaHi();} else {sdaLo();} // apply data
waitShort(); // wait for data to settle. IMPORTANT!
sclHi(); // clock pulse
waitShort();
sclLo();
@@ -254,6 +268,7 @@ private:
inline bool _readAck() {
sdaDirIn(); // switch to input mode
const uint8_t res = _readBit();
//printf("%d\n", res);
return res == 0; // ACK when input pulled low
}

View File

@@ -5,8 +5,6 @@
#include "../Platforms.h"
#include "../Debug.h"
#pragma GCC push_options
#pragma GCC optimize ("O2")