mirror of
https://github.com/utkumaden/esp-idf-ds3231.git
synced 2025-01-22 20:56:31 +01:00
Implement the entire driver.
This commit is contained in:
parent
34774a0786
commit
0d1a8e4252
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
idf_component_register(
|
||||
INCLUDE_DIRS "include"
|
||||
SRCS
|
||||
"source/io.c"
|
||||
"source/driver.c"
|
||||
)
|
89
include/ds3231.h
Normal file
89
include/ds3231.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef _ESP_IDF_DS3231_H_
|
||||
#define _ESP_IDF_DS3231_H_
|
||||
|
||||
#define DS3231_API
|
||||
|
||||
#include <driver/i2c.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct ds3231_t *ds3231_t;
|
||||
|
||||
typedef enum ds3231_alarmType_t
|
||||
{
|
||||
DS3231_ALARM1_PERSEC = 0,
|
||||
DS3231_ALARM1_S,
|
||||
DS3231_ALARM1_SM,
|
||||
DS3231_ALARM1_SMH,
|
||||
DS3231_ALARM1_SMHMD,
|
||||
DS3231_ALARM1_SMHWD,
|
||||
|
||||
DS3231_ALARM2_PREMIN = 0,
|
||||
DS3231_ALARM2_M,
|
||||
DS3231_ALARM2_MH,
|
||||
DS3231_ALARM2_MHMD,
|
||||
DS3231_ALARM2_MHWD
|
||||
} ds3231_alarmType_t;
|
||||
|
||||
typedef enum ds3231_rate_t
|
||||
{
|
||||
DS3231_RATE_1HZ = 0,
|
||||
DS3231_RATE_1024HZ = 1,
|
||||
DS3231_RATE_4096HZ = 2,
|
||||
DS3231_RATE_8192HZ = 3
|
||||
} ds3231_rate_t;
|
||||
|
||||
typedef enum ds3231_status_t
|
||||
{
|
||||
DS3231_STATUS_OSF = 1 << 7,
|
||||
DS3231_STATUS_BSY = 1 << 2,
|
||||
DS3231_STATUS_AL2 = 1 << 1,
|
||||
DS3231_STATUS_AL1 = 1 << 0,
|
||||
} ds3231_status_t;
|
||||
|
||||
DS3231_API ds3231_t ds3231_create(i2c_port_t port);
|
||||
|
||||
DS3231_API void ds3231_destroy(ds3231_t driver);
|
||||
|
||||
DS3231_API int ds3231_initialize(ds3231_t driver, int *opt_out_osf);
|
||||
|
||||
DS3231_API int ds3231_setSquareWaveOutput(ds3231_t driver, ds3231_rate_t rate, int battery_backed);
|
||||
|
||||
DS3231_API int ds3231_setInterrupt(ds3231_t driver, int alarm1, int alarm2);
|
||||
|
||||
DS3231_API int ds3231_getStatus(ds3231_t driver, ds3231_status_t *out_status);
|
||||
|
||||
DS3231_API int ds3231_getAgingOffset(ds3231_t driver, int8_t *out_offset);
|
||||
|
||||
DS3231_API int ds3231_setAgingOffset(ds3231_t driver, int8_t offset);
|
||||
|
||||
DS3231_API int ds3231_getTime(ds3231_t driver, struct tm *time);
|
||||
|
||||
DS3231_API int ds3231_setTime(ds3231_t driver, const struct tm *time);
|
||||
|
||||
DS3231_API int ds3231_setAlarm1(ds3231_t driver, ds3231_alarmType_t type, const struct tm *time);
|
||||
|
||||
DS3231_API int ds3231_setAlarm2(ds3231_t driver, ds3231_alarmType_t type, const struct tm *time);
|
||||
|
||||
DS3231_API int ds3231_beginTemperature(ds3231_t driver);
|
||||
|
||||
DS3231_API int ds3231_endTemperature(ds3231_t driver, int16_t *out_temperature);
|
||||
|
||||
inline static int ds3231_endTemperatureF(ds3231_t driver, float *out_temperature)
|
||||
{
|
||||
if (out_temperature == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16_t iTemp;
|
||||
if (ds3231_endTemperature(driver, &iTemp))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_temperature = (float)iTemp / 4.0f;
|
||||
}
|
||||
|
||||
#endif
|
426
source/driver.c
Normal file
426
source/driver.c
Normal file
@ -0,0 +1,426 @@
|
||||
#include "private.h"
|
||||
#include <errno.h>
|
||||
|
||||
#define F_INIT (1 << 0)
|
||||
|
||||
struct ds3231_t
|
||||
{
|
||||
int flags;
|
||||
i2c_port_t port;
|
||||
};
|
||||
|
||||
#define ASSERT_DRV() do { \
|
||||
if (driver == NULL || !(driver->flags & F_INIT)) { \
|
||||
errno = EINVAL; \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
DS3231_API ds3231_t ds3231_create(i2c_port_t port)
|
||||
{
|
||||
if (port > I2C_NUM_MAX)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ds3231_t driver = malloc(sizeof(struct ds3231_t));
|
||||
if (driver)
|
||||
{
|
||||
driver->flags = 0;
|
||||
driver->port = port;
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
DS3231_API void ds3231_destroy(ds3231_t driver)
|
||||
{
|
||||
free(driver);
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_initialize(ds3231_t driver, int *opt_out_osf)
|
||||
{
|
||||
if (driver == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read status regıister
|
||||
uint8_t status;
|
||||
if (ds3231_io_read(driver->port, DS3231_REGISTER_STATUS, &status, sizeof status))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (opt_out_osf)
|
||||
{
|
||||
*opt_out_osf = !!(status & DS3231_STATUS_OSF);
|
||||
}
|
||||
|
||||
driver->flags |= F_INIT;
|
||||
|
||||
int err;
|
||||
{
|
||||
// Wait until busy flag clears.
|
||||
ds3231_status_t status;
|
||||
while(!(err = ds3231_getStatus(driver, &status)) && (status & DS3231_STATUS_BSY))
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setSquareWaveOutput(ds3231_t driver, ds3231_rate_t rate, int battery_backed)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
uint8_t control = battery_backed ? DS3231_CONTROL_BBSQW : 0;
|
||||
switch (rate)
|
||||
{
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
case DS3231_RATE_1HZ:
|
||||
control |= DS3231_CONTROL_RS_1HZ;
|
||||
break;
|
||||
case DS3231_RATE_1024HZ:
|
||||
control |= DS3231_CONTROL_RS_1024HZ;
|
||||
break;
|
||||
case DS3231_RATE_4096HZ:
|
||||
control |= DS3231_CONTROL_RS_4096HZ;
|
||||
break;
|
||||
case DS3231_RATE_8192HZ:
|
||||
control |= DS3231_CONTROL_RS_8192HZ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_CONTROL, &control, sizeof control))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setInterrupt(ds3231_t driver, int alarm1, int alarm2)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
uint8_t control =
|
||||
DS3231_CONTROL_INTCN |
|
||||
alarm1 ? DS3231_CONTROL_A1IE : 0 |
|
||||
alarm2 ? DS3231_CONTROL_A2IE : 0;
|
||||
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_CONTROL, &control, sizeof control))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_getStatus(ds3231_t driver, ds3231_status_t *out_status)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (out_status == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ds3231_status_t rstatus;
|
||||
if (ds3231_io_read(driver->port, DS3231_REGISTER_STATUS, &rstatus, sizeof rstatus))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_status = (ds3231_status_t)rstatus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_getAgingOffset(ds3231_t driver, int8_t *out_offset)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (out_offset == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ds3231_io_read(driver->port, DS3231_REGISTER_OFFSET, out_offset, sizeof *out_offset))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setAgingOffset(ds3231_t driver, int8_t offset)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_OFFSET, &offset, sizeof offset))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline static void ds3231_fill_yday(struct tm *time)
|
||||
{
|
||||
time->tm_yday = time->tm_mday;
|
||||
switch(time->tm_mon)
|
||||
{
|
||||
case 0: // Jan
|
||||
break;
|
||||
case 1: // Feb
|
||||
time->tm_yday += 31; break;
|
||||
case 2: // Mar
|
||||
time->tm_yday += 59; break;
|
||||
case 3: // Apr
|
||||
time->tm_yday += 90; break;
|
||||
case 4: // May
|
||||
time->tm_yday += 120; break;
|
||||
case 5: // Jun
|
||||
time->tm_yday += 151; break;
|
||||
case 6: // Jul
|
||||
time->tm_yday += 181; break;
|
||||
case 7: // Aug
|
||||
time->tm_yday += 212; break;
|
||||
case 8: // Sep
|
||||
time->tm_yday += 243; break;
|
||||
case 9: // Oct
|
||||
time->tm_yday += 273; break;
|
||||
case 10: // Nov
|
||||
time->tm_yday += 304; break;
|
||||
case 11: // Dec
|
||||
time->tm_yday += 334; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((time->tm_year % 4) || (time->tm_year == 2100))
|
||||
{
|
||||
time->tm_yday -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_getTime(ds3231_t driver, struct tm *time)
|
||||
{
|
||||
uint8_t rtime[7];
|
||||
|
||||
ASSERT_DRV();
|
||||
|
||||
if (time == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ds3231_io_read(driver->port, DS3231_REGISTER_SECONDS, rtime, sizeof rtime))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
time->tm_sec = BCD_TO_DEC(rtime[0]);
|
||||
time->tm_min = BCD_TO_DEC(rtime[1]);
|
||||
if (rtime[2] & (1 << 6))
|
||||
{
|
||||
uint8_t bcd = DS3231_12_TO_24(rtime[2]);
|
||||
time->tm_hour = BCD_TO_DEC(bcd);
|
||||
}
|
||||
else
|
||||
{
|
||||
time->tm_hour = BCD_TO_DEC(rtime[2]);
|
||||
}
|
||||
time->tm_wday = rtime[3];
|
||||
time->tm_mday = BCD_TO_DEC(rtime[4]);
|
||||
time->tm_mon = BCD_TO_DEC((rtime[5] & 0x1F)) - 1;
|
||||
time->tm_year = 2000 + BCD_TO_DEC(rtime[6]) + ((rtime[5] & (1 << 7)) ? 100 : 0);
|
||||
ds3231_fill_yday(time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setTime(ds3231_t driver, const struct tm *time)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (time == NULL)
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t rtime[7];
|
||||
rtime[0] = DEC_TO_BCD(time->tm_sec);
|
||||
rtime[1] = DEC_TO_BCD(time->tm_min);
|
||||
rtime[2] = DEC_TO_BCD(time->tm_hour);
|
||||
rtime[3] = time->tm_wday;
|
||||
rtime[4] = DEC_TO_BCD(time->tm_mday);
|
||||
rtime[5] = DEC_TO_BCD(time->tm_mon + 1) + ((time->tm_year >= 2100) ? (1 << 7) : 0);
|
||||
rtime[6] = DEC_TO_BCD(time->tm_year % 100);
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_SECONDS, rtime, sizeof rtime))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setAlarm1(ds3231_t driver, ds3231_alarmType_t type, const struct tm *time)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (type > DS3231_ALARM1_SMHWD || time == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t rtime[4];
|
||||
rtime[0] = DEC_TO_BCD(time->tm_sec);
|
||||
rtime[1] = DEC_TO_BCD(time->tm_min);
|
||||
rtime[2] = DEC_TO_BCD(time->tm_hour);
|
||||
switch(type)
|
||||
{
|
||||
case DS3231_ALARM1_PERSEC:
|
||||
rtime[0] |= (1 << 7);
|
||||
case DS3231_ALARM1_S:
|
||||
rtime[1] |= (1 << 7);
|
||||
case DS3231_ALARM1_SM:
|
||||
rtime[2] |= (1 << 7);
|
||||
case DS3231_ALARM1_SMH:
|
||||
rtime[3] = (1 << 7);
|
||||
break;
|
||||
case DS3231_ALARM1_SMHWD: // Week day.
|
||||
rtime[3] = (1 << 6) | DEC_TO_BCD(time->tm_wday);
|
||||
break;
|
||||
case DS3231_ALARM1_SMHMD: // Month day.
|
||||
rtime[3] = DEC_TO_BCD(time->tm_mday);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_ALARM1_SECONDS, rtime, sizeof rtime))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_setAlarm2(ds3231_t driver, ds3231_alarmType_t type, const struct tm *time)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (type > DS3231_ALARM2_MHWD || time == NULL)
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t rtime[3];
|
||||
rtime[0] = DEC_TO_BCD(time->tm_min);
|
||||
rtime[1] = DEC_TO_BCD(time->tm_hour);
|
||||
switch(type)
|
||||
{
|
||||
case DS3231_ALARM2_PREMIN:
|
||||
rtime[0] |= (1 << 7);
|
||||
case DS3231_ALARM2_M:
|
||||
rtime[1] |= (1 << 7);
|
||||
case DS3231_ALARM2_MH:
|
||||
rtime[2] = (1 << 7);
|
||||
break;
|
||||
case DS3231_ALARM2_MHMD:
|
||||
rtime[2] = DEC_TO_BCD(time->tm_mday);
|
||||
break;
|
||||
case DS3231_ALARM2_MHWD:
|
||||
rtime[2] = (1 << 6) | DEC_TO_BCD(time->tm_wday);
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_ALARM2_MINUTES, rtime, sizeof rtime))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_beginTemperature(ds3231_t driver)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
uint8_t control;
|
||||
if (ds3231_io_read(driver->port, DS3231_REGISTER_CONTROL, &control, sizeof control))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
control |= DS3231_CONTROL_CONV;
|
||||
if (ds3231_io_write(driver->port, DS3231_REGISTER_CONTROL, &control, sizeof control))
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DS3231_API int ds3231_endTemperature(ds3231_t driver, int16_t *out_temperature)
|
||||
{
|
||||
ASSERT_DRV();
|
||||
|
||||
if (out_temperature == NULL)
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t status = 0xFF;
|
||||
uint8_t tempr[2];
|
||||
|
||||
while (
|
||||
!ds3231_io_read(driver->port, DS3231_REGISTER_CONTROL, &status, sizeof status) &&
|
||||
(status & DS3231_RSTATUS_BSY)
|
||||
)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
status = 0xFF;
|
||||
}
|
||||
|
||||
if (
|
||||
(status & DS3231_RSTATUS_BSY) ||
|
||||
ds3231_io_read(driver->port, DS3231_REGISTER_TEMP_H, tempr, sizeof tempr)
|
||||
)
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_temperature = (int16_t)((tempr[0] << 8) | (tempr[1]));
|
||||
*out_temperature >>= 6;
|
||||
|
||||
return 0;
|
||||
}
|
52
source/io.c
Normal file
52
source/io.c
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#include "private.h"
|
||||
#define DS3231_ADDR 0xD0
|
||||
|
||||
esp_err_t ds3231_io_read(i2c_port_t port, uint8_t addr, void *data, size_t sz)
|
||||
{
|
||||
i2c_cmd_handle_t cmd;
|
||||
esp_err_t retval;
|
||||
|
||||
if ((cmd = i2c_cmd_link_create()))
|
||||
{
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, DS3231_ADDR | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, DS3231_ADDR | I2C_MASTER_READ, true);
|
||||
i2c_master_read(cmd, data, sz, I2C_MASTER_LAST_NACK);
|
||||
|
||||
i2c_master_stop(cmd);
|
||||
|
||||
retval = i2c_master_cmd_begin(port, cmd, 20);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t ds3231_io_write(i2c_port_t port, uint8_t addr, const void *data, size_t sz)
|
||||
{
|
||||
i2c_cmd_handle_t cmd;
|
||||
esp_err_t retval;
|
||||
|
||||
if ((cmd = i2c_cmd_link_create()))
|
||||
{
|
||||
for (int i = 0; i < sz; ++ i)
|
||||
{
|
||||
i2c_master_start(cmd);
|
||||
i2c_master_write_byte(cmd, DS3231_ADDR | I2C_MASTER_WRITE, true);
|
||||
i2c_master_write_byte(cmd, addr, true);
|
||||
i2c_master_write_byte(cmd, ((uint8_t*)data)[i], true);
|
||||
}
|
||||
i2c_master_stop(cmd);
|
||||
|
||||
retval = i2c_master_cmd_begin(port, cmd, 20);
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
79
source/private.h
Normal file
79
source/private.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef _DS3231_PRIVATE_H_
|
||||
#define _DS3231_PRIVATE_H_
|
||||
|
||||
#include <ds3231.h>
|
||||
#include "registers.h"
|
||||
|
||||
#define BCD_TO_DEC(bcd) ((((bcd) >> 4) * 10) + (bcd & 0x0F))
|
||||
#define DEC_TO_BCD(dec) ((((dec) / 10) << 4) | (dec % 10))
|
||||
|
||||
inline static uint8_t DS3231_12_TO_24(uint8_t _12)
|
||||
{
|
||||
// This lookup table brought to you by maxim.
|
||||
// Thanks really thanks.
|
||||
switch (_12 & 0x3F)
|
||||
{
|
||||
default: return 0xFF;
|
||||
case 0x12: return 0x00;
|
||||
case 0x01: return 0x01;
|
||||
case 0x02: return 0x02;
|
||||
case 0x03: return 0x03;
|
||||
case 0x04: return 0x04;
|
||||
case 0x05: return 0x05;
|
||||
case 0x06: return 0x06;
|
||||
case 0x07: return 0x07;
|
||||
case 0x08: return 0x08;
|
||||
case 0x09: return 0x09;
|
||||
case 0x10: return 0x10;
|
||||
case 0x11: return 0x11;
|
||||
case 0x32: return 0x12;
|
||||
case 0x21: return 0x13;
|
||||
case 0x22: return 0x14;
|
||||
case 0x23: return 0x15;
|
||||
case 0x24: return 0x16;
|
||||
case 0x25: return 0x17;
|
||||
case 0x26: return 0x18;
|
||||
case 0x27: return 0x19;
|
||||
case 0x28: return 0x20;
|
||||
case 0x29: return 0x21;
|
||||
case 0x30: return 0x22;
|
||||
case 0x31: return 0x23;
|
||||
}
|
||||
}
|
||||
|
||||
inline static uint8_t DS3231_24_TO_12(uint8_t _24)
|
||||
{
|
||||
switch (_24 & 0x3F)
|
||||
{
|
||||
default: return 0xFF;
|
||||
case 0x00: return 0x12;
|
||||
case 0x01: return 0x01;
|
||||
case 0x02: return 0x02;
|
||||
case 0x03: return 0x03;
|
||||
case 0x04: return 0x04;
|
||||
case 0x05: return 0x05;
|
||||
case 0x06: return 0x06;
|
||||
case 0x07: return 0x07;
|
||||
case 0x08: return 0x08;
|
||||
case 0x09: return 0x09;
|
||||
case 0x10: return 0x10;
|
||||
case 0x11: return 0x11;
|
||||
case 0x12: return 0x32;
|
||||
case 0x13: return 0x21;
|
||||
case 0x14: return 0x22;
|
||||
case 0x15: return 0x23;
|
||||
case 0x16: return 0x24;
|
||||
case 0x17: return 0x25;
|
||||
case 0x18: return 0x26;
|
||||
case 0x19: return 0x27;
|
||||
case 0x20: return 0x28;
|
||||
case 0x21: return 0x29;
|
||||
case 0x22: return 0x30;
|
||||
case 0x23: return 0x31;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t ds3231_io_read(i2c_port_t port, uint8_t addr, void *data, size_t sz);
|
||||
esp_err_t ds3231_io_write(i2c_port_t port, uint8_t addr, const void *data, size_t sz);
|
||||
|
||||
#endif
|
48
source/registers.h
Normal file
48
source/registers.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef _DS3231_REGISTERS_H_
|
||||
#define _DS3231_REGISTERS_H_
|
||||
|
||||
#define DS3231_REGISTER_SECONDS (0x00)
|
||||
#define DS3231_REGISTER_MINUTES (0x01)
|
||||
#define DS3231_REGISTER_HOURS (0x02)
|
||||
#define DS3231_REGISTER_DAY (0x03)
|
||||
#define DS3231_REGISTER_DATE (0x04)
|
||||
#define DS3231_REGISTER_MONTH (0x05)
|
||||
#define DS3231_REGISTER_YEAR (0x06)
|
||||
#define DS3231_REGISTER_ALARM1_SECONDS (0x07)
|
||||
#define DS3231_REGISTER_ALARM1_MINUTES (0x08)
|
||||
#define DS3231_REGISTER_ALARM1_HOURS (0x09)
|
||||
#define DS3231_REGISTER_ALARM1_DAY_DATE (0x0A)
|
||||
#define DS3231_REGISTER_ALARM2_MINUTES (0x0B)
|
||||
#define DS3231_REGISTER_ALARM2_HOURS (0x0C)
|
||||
#define DS3231_REGISTER_ALARM2_DAY_DATE (0x0D)
|
||||
#define DS3231_REGISTER_CONTROL (0x0E)
|
||||
#define DS3231_REGISTER_STATUS (0x0F)
|
||||
#define DS3231_REGISTER_OFFSET (0x10)
|
||||
#define DS3231_REGISTER_TEMP_H (0x11)
|
||||
#define DS3231_REGISTER_TEMP_L (0x12)
|
||||
|
||||
#define DS3231_HOURS_12H_BIT (1 << 6)
|
||||
#define DS3231_DAY_DATE_BIT (1 << 6)
|
||||
#define DS3231_CENTURY_BIT (1 << 7)
|
||||
#define DS3231_ALARM_EN_BIT (1 << 7)
|
||||
|
||||
#define DS3231_CONTROL_EOSC (1 << 7)
|
||||
#define DS3231_CONTROL_BBSQW (1 << 6)
|
||||
#define DS3231_CONTROL_CONV (1 << 5)
|
||||
#define DS3231_CONTROL_RS_POS 3
|
||||
#define DS3231_CONTROL_RS_MASK (3 << DS3231_CONTROL_RS_POS)
|
||||
#define DS3231_CONTROL_RS_1HZ (0 << DS3231_CONTROL_RS_POS)
|
||||
#define DS3231_CONTROL_RS_1024HZ (1 << DS3231_CONTROL_RS_POS)
|
||||
#define DS3231_CONTROL_RS_4096HZ (2 << DS3231_CONTROL_RS_POS)
|
||||
#define DS3231_CONTROL_RS_8192HZ (3 << DS3231_CONTROL_RS_POS)
|
||||
#define DS3231_CONTROL_INTCN (1 << 2)
|
||||
#define DS3231_CONTROL_A2IE (1 << 1)
|
||||
#define DS3231_CONTROL_A1IE (1 << 0)
|
||||
|
||||
#define DS3231_RSTATUS_OSF (1 << 7)
|
||||
#define DS3231_RSTATUS_EN32KHZ (1 << 3)
|
||||
#define DS3231_RSTATUS_BSY (1 << 2)
|
||||
#define DS3231_RSTATUS_A2F (1 << 1)
|
||||
#define DS3231_RSTATUS_A1F (1 << 0)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user