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:
102
ext/e-ink/Waveshare.h
Normal file
102
ext/e-ink/Waveshare.h
Normal 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
255
ext/e-ink/Waveshare_4_2.h
Normal 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;
|
||||
}
|
||||
*/
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
|
||||
23
io/SoftI2C.h
23
io/SoftI2C.h
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include "../Platforms.h"
|
||||
#include "../Debug.h"
|
||||
|
||||
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O2")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user