mirror of
https://github.com/randybb/esphome-configs.git
synced 2026-01-02 19:47:29 +01:00
have fun
This commit is contained in:
24
components/bm8563/__init__.py
Normal file
24
components/bm8563/__init__.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID, CONF_SLEEP_DURATION
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
|
||||
CONF_I2C_ADDR = 0x51
|
||||
|
||||
bm8563 = cg.esphome_ns.namespace('bm8563')
|
||||
BM8563 = bm8563.class_('BM8563', cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(BM8563),
|
||||
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_seconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(CONF_I2C_ADDR))
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
if CONF_SLEEP_DURATION in config:
|
||||
cg.add(var.set_sleep_duration(config[CONF_SLEEP_DURATION]))
|
||||
yield cg.register_component(var, config)
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
|
||||
242
components/bm8563/bm8563.cpp
Normal file
242
components/bm8563/bm8563.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/components/i2c/i2c_bus.h"
|
||||
#include "bm8563.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace bm8563 {
|
||||
|
||||
static const char *TAG = "bm8563.sensor";
|
||||
|
||||
void BM8563::setup(){
|
||||
this->write_byte_16(0,0);
|
||||
this->setupComplete = true;
|
||||
if (this->sleep_duration_.has_value()) {
|
||||
SetAlarmIRQ(*this->sleep_duration_);
|
||||
}
|
||||
}
|
||||
|
||||
void BM8563::loop(){
|
||||
// if(!this->setupComplete){
|
||||
// return;
|
||||
// }
|
||||
// BM8563_TimeTypeDef BM8563_TimeStruct;
|
||||
// getTime(&BM8563_TimeStruct);
|
||||
// this->publish_state(BM8563_TimeStruct.seconds);
|
||||
}
|
||||
|
||||
void BM8563::dump_config(){
|
||||
ESP_LOGCONFIG(TAG, "BM8563:");
|
||||
ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
|
||||
ESP_LOGCONFIG(TAG, " setupComplete: %s", this->setupComplete ? "true" : "false");
|
||||
if (this->sleep_duration_.has_value()) {
|
||||
uint32_t duration = *this->sleep_duration_;
|
||||
ESP_LOGCONFIG(TAG, " Sleep Duration: %u ms", duration);
|
||||
}
|
||||
}
|
||||
|
||||
void BM8563::set_sleep_duration(uint32_t time_s) {
|
||||
this->sleep_duration_ = uint64_t(time_s);
|
||||
if (this->sleep_duration_.has_value()) {
|
||||
SetAlarmIRQ(*this->sleep_duration_);
|
||||
}
|
||||
}
|
||||
|
||||
bool BM8563::getVoltLow() {
|
||||
uint8_t data = ReadReg(0x02);
|
||||
return data & 0x80; // RTCC_VLSEC_MASK
|
||||
}
|
||||
|
||||
uint8_t BM8563::bcd2ToByte(uint8_t value) {
|
||||
uint8_t tmp = 0;
|
||||
tmp = ((uint8_t)(value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
|
||||
return (tmp + (value & (uint8_t)0x0F));
|
||||
}
|
||||
|
||||
uint8_t BM8563::byteToBcd2(uint8_t value) {
|
||||
uint8_t bcdhigh = 0;
|
||||
|
||||
while (value >= 10) {
|
||||
bcdhigh++;
|
||||
value -= 10;
|
||||
}
|
||||
|
||||
return ((uint8_t)(bcdhigh << 4) | value);
|
||||
}
|
||||
|
||||
void BM8563::getTime(BM8563_TimeTypeDef* BM8563_TimeStruct) {
|
||||
uint8_t buf[3] = {0};
|
||||
|
||||
this->read_register(0x02, buf, 3);
|
||||
|
||||
BM8563_TimeStruct->seconds = bcd2ToByte(buf[0] & 0x7f);
|
||||
BM8563_TimeStruct->minutes = bcd2ToByte(buf[1] & 0x7f);
|
||||
BM8563_TimeStruct->hours = bcd2ToByte(buf[2] & 0x3f);
|
||||
}
|
||||
|
||||
void BM8563::setTime(BM8563_TimeTypeDef* BM8563_TimeStruct) {
|
||||
if (BM8563_TimeStruct == NULL) {
|
||||
return;
|
||||
}
|
||||
uint8_t buf[3] = {byteToBcd2(BM8563_TimeStruct->seconds), byteToBcd2(BM8563_TimeStruct->minutes), byteToBcd2(BM8563_TimeStruct->hours)};
|
||||
|
||||
this->write_register(0x02, buf, 3);
|
||||
}
|
||||
|
||||
void BM8563::getDate(BM8563_DateTypeDef* BM8563_DateStruct) {
|
||||
uint8_t buf[4] = {0};
|
||||
this->read_register(0x05, buf, 4);
|
||||
|
||||
BM8563_DateStruct->date = bcd2ToByte(buf[0] & 0x3f);
|
||||
BM8563_DateStruct->weekDay = bcd2ToByte(buf[1] & 0x07);
|
||||
BM8563_DateStruct->month = bcd2ToByte(buf[2] & 0x1f);
|
||||
|
||||
if (buf[2] & 0x80) {
|
||||
BM8563_DateStruct->year = 1900 + bcd2ToByte(buf[3] & 0xff);
|
||||
} else {
|
||||
BM8563_DateStruct->year = 2000 + bcd2ToByte(buf[3] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
void BM8563::setDate(BM8563_DateTypeDef* BM8563_DateStruct) {
|
||||
if (BM8563_DateStruct == NULL) {
|
||||
return;
|
||||
}
|
||||
uint8_t buf[4] = {byteToBcd2(BM8563_DateStruct->date), byteToBcd2(BM8563_DateStruct->weekDay), 0, byteToBcd2((uint8_t)(BM8563_DateStruct->year % 100))};
|
||||
|
||||
|
||||
if (BM8563_DateStruct->year < 2000) {
|
||||
buf[3] = byteToBcd2(BM8563_DateStruct->month) | 0x80;
|
||||
} else {
|
||||
buf[3] = byteToBcd2(BM8563_DateStruct->month) | 0x00;
|
||||
}
|
||||
|
||||
this->write_register(0x05, buf, 4);
|
||||
}
|
||||
|
||||
void BM8563::WriteReg(uint8_t reg, uint8_t data) {
|
||||
this->write_byte(reg, data);
|
||||
}
|
||||
|
||||
uint8_t BM8563::ReadReg(uint8_t reg) {
|
||||
uint8_t data;
|
||||
this->read_register(reg, &data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
int BM8563::SetAlarmIRQ(int afterSeconds) {
|
||||
uint8_t reg_value = 0;
|
||||
reg_value = ReadReg(0x01);
|
||||
|
||||
if (afterSeconds < 0) {
|
||||
reg_value &= ~(1 << 0);
|
||||
WriteReg(0x01, reg_value);
|
||||
reg_value = 0x03;
|
||||
WriteReg(0x0E, reg_value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t type_value = 2;
|
||||
uint8_t div = 1;
|
||||
if (afterSeconds > 255) {
|
||||
div = 60;
|
||||
type_value = 0x83;
|
||||
} else {
|
||||
type_value = 0x82;
|
||||
}
|
||||
|
||||
afterSeconds = (afterSeconds / div) & 0xFF;
|
||||
WriteReg(0x0F, afterSeconds);
|
||||
WriteReg(0x0E, type_value);
|
||||
|
||||
reg_value |= (1 << 0);
|
||||
reg_value &= ~(1 << 7);
|
||||
WriteReg(0x01, reg_value);
|
||||
return afterSeconds * div;
|
||||
}
|
||||
|
||||
int BM8563::SetAlarmIRQ(const BM8563_TimeTypeDef &BM8563_TimeStruct) {
|
||||
uint8_t irq_enable = false;
|
||||
uint8_t out_buf[4] = {0x80, 0x80, 0x80, 0x80};
|
||||
|
||||
if (BM8563_TimeStruct.minutes >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[0] = byteToBcd2(BM8563_TimeStruct.minutes) & 0x7f;
|
||||
}
|
||||
|
||||
if (BM8563_TimeStruct.hours >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[1] = byteToBcd2(BM8563_TimeStruct.hours) & 0x3f;
|
||||
}
|
||||
|
||||
out_buf[2] = 0x00;
|
||||
out_buf[3] = 0x00;
|
||||
|
||||
uint8_t reg_value = ReadReg(0x01);
|
||||
|
||||
if (irq_enable) {
|
||||
reg_value |= (1 << 1);
|
||||
} else {
|
||||
reg_value &= ~(1 << 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
WriteReg(0x09 + i, out_buf[i]);
|
||||
}
|
||||
WriteReg(0x01, reg_value);
|
||||
|
||||
return irq_enable ? 1 : 0;
|
||||
}
|
||||
|
||||
int BM8563::SetAlarmIRQ(const BM8563_DateTypeDef &BM8563_DateStruct, const BM8563_TimeTypeDef &BM8563_TimeStruct) {
|
||||
uint8_t irq_enable = false;
|
||||
uint8_t out_buf[4] = {0x80, 0x80, 0x80, 0x80};
|
||||
|
||||
if (BM8563_TimeStruct.minutes >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[0] = byteToBcd2(BM8563_TimeStruct.minutes) & 0x7f;
|
||||
}
|
||||
|
||||
if (BM8563_TimeStruct.hours >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[1] = byteToBcd2(BM8563_TimeStruct.hours) & 0x3f;
|
||||
}
|
||||
|
||||
if (BM8563_DateStruct.date >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[2] = byteToBcd2(BM8563_DateStruct.date) & 0x3f;
|
||||
}
|
||||
|
||||
if (BM8563_DateStruct.weekDay >= 0) {
|
||||
irq_enable = true;
|
||||
out_buf[3] = byteToBcd2(BM8563_DateStruct.weekDay) & 0x07;
|
||||
}
|
||||
|
||||
uint8_t reg_value = ReadReg(0x01);
|
||||
|
||||
if (irq_enable) {
|
||||
reg_value |= (1 << 1);
|
||||
} else {
|
||||
reg_value &= ~(1 << 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
WriteReg(0x09 + i, out_buf[i]);
|
||||
}
|
||||
WriteReg(0x01, reg_value);
|
||||
|
||||
return irq_enable ? 1 : 0;
|
||||
}
|
||||
|
||||
void BM8563::clearIRQ() {
|
||||
uint8_t data = ReadReg(0x01);
|
||||
WriteReg(0x01, data & 0xf3);
|
||||
}
|
||||
|
||||
void BM8563::disableIRQ() {
|
||||
clearIRQ();
|
||||
uint8_t data = ReadReg(0x01);
|
||||
WriteReg(0x01, data & 0xfC);
|
||||
}
|
||||
|
||||
} // namespace bm8563
|
||||
} // namespace esphome
|
||||
62
components/bm8563/bm8563.h
Normal file
62
components/bm8563/bm8563.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
|
||||
|
||||
namespace esphome {
|
||||
namespace bm8563 {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int8_t hours;
|
||||
int8_t minutes;
|
||||
int8_t seconds;
|
||||
} BM8563_TimeTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int8_t weekDay;
|
||||
int8_t month;
|
||||
int8_t date;
|
||||
int16_t year;
|
||||
} BM8563_DateTypeDef;
|
||||
|
||||
class BM8563 : public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
void dump_config() override;
|
||||
|
||||
void set_sleep_duration(uint32_t time_ms);
|
||||
|
||||
bool getVoltLow();
|
||||
|
||||
void getTime(BM8563_TimeTypeDef* BM8563_TimeStruct);
|
||||
void getDate(BM8563_DateTypeDef* BM8563_DateStruct);
|
||||
|
||||
void setTime(BM8563_TimeTypeDef* BM8563_TimeStruct);
|
||||
void setDate(BM8563_DateTypeDef* BM8563_DateStruct);
|
||||
|
||||
int SetAlarmIRQ(int afterSeconds);
|
||||
int SetAlarmIRQ(const BM8563_TimeTypeDef &BM8563_TimeStruct);
|
||||
int SetAlarmIRQ(const BM8563_DateTypeDef &BM8563_DateStruct, const BM8563_TimeTypeDef &BM8563_TimeStruct);
|
||||
|
||||
void clearIRQ();
|
||||
void disableIRQ();
|
||||
|
||||
void WriteReg(uint8_t reg, uint8_t data);
|
||||
uint8_t ReadReg(uint8_t reg);
|
||||
|
||||
private:
|
||||
uint8_t bcd2ToByte(uint8_t value);
|
||||
uint8_t byteToBcd2(uint8_t value);
|
||||
|
||||
uint8_t trdata[7];
|
||||
optional<uint64_t> sleep_duration_;
|
||||
bool setupComplete;
|
||||
};
|
||||
|
||||
} // namespace bm8563
|
||||
} // namespace esphome
|
||||
Reference in New Issue
Block a user