Skip to content

Commit

Permalink
Add support for setting and reading alarm (#4)
Browse files Browse the repository at this point in the history
struct tm out = {0};
struct tm in = {0};

out.tm_min = 30;
out.tm_hour = 12;
out.tm_mday = BM8563_ALARM_DISABLE;
out.tm_wday = BM8563_ALARM_DISABLE;

bm8563_ioctl(&bm, BM8563_ALARM_SET, &out);
...
bm8563_ioctl(&bm, BM8563_ALARM_READ, &in);
  • Loading branch information
tuupola authored Jun 4, 2020
1 parent 0ebcde2 commit e51fc97
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file, in reverse
## [0.5.0](https://github.com/tuupola/bm8563/compare/0.4.0...master) - unreleased

### Added
- Support for reading and writing alarms ([#4](https://github.com/tuupola/bm8563/pull/4)).
- Support for low voltage warnings ([#3](https://github.com/tuupola/bm8563/pull/3)).

## 0.4.0 - 2020-20-05
Expand Down
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,52 @@ bm8563_init(&bm);
bm8563_write(&bm, &rtc);
```
## Set RTC alarm
```c
#include <time.h>
#include "bm8563.h"
#include "user_i2c.h"
struct tm rtc_alarm;
bm8563_t bm;
/* Add pointers to user provided functions. */
bm.read = &user_i2c_read;
bm.write = &user_i2c_write;
bm8563_init(&bm);
/* Add alarm every day at 21:30. */
rtc_alarm.tm_min = 30;
rtc_alarm.tm_hour = 21;
rtc_alarm.tm_mday = BM8563_ALARM_NONE;
rtc_alarm.tm_wday = BM8563_ALARM_NONE;
bm8563_ioctl(&bm, BM8563_ALARM_SET, &rtc_alarm);
```

## Read RTC alarm

```c
#include <time.h>

#include "bm8563.h"
#include "user_i2c.h"

struct tm rtc_alarm;
bm8563_t bm;

/* Add pointers to user provided functions. */
bm.read = &user_i2c_read;
bm.write = &user_i2c_write;

bm8563_init(&bm);

bm8563_ioctl(&bm, BM8563_ALARM_READ, &rtc_alarm);
```
## License
The MIT License (MIT). Please see [License File](LICENSE.txt) for more information.
103 changes: 103 additions & 0 deletions bm8563.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,109 @@ bm8563_err_t bm8563_write(const bm8563_t *bm, const struct tm *time)
return bm->write(bm->handle, BM8563_ADDRESS, BM8563_SECONDS, buffer, BM8563_TIME_SIZE);
}


bm8563_err_t bm8563_ioctl(const bm8563_t *bm, int16_t command, void *argument)
{
uint8_t reg = command >> 8;
uint8_t buffer[BM8563_ALARM_SIZE] = {0};
uint8_t status;
struct tm *time;

switch (command) {
case BM8563_ALARM_SET:
time = (struct tm *)argument;

/* 0..59 */
if (BM8563_ALARM_NONE == time->tm_min) {
buffer[0] = 0x00;
} else {
buffer[0] = decimal2bcd(time->tm_min);
buffer[0] |= BM8563_ALARM_ENABLE;
}

/* 0..23 */
if (BM8563_ALARM_NONE == time->tm_hour) {
buffer[1] = 0x00;
} else {
buffer[1] = decimal2bcd(time->tm_hour);
buffer[1] &= 0b00111111;
buffer[1] |= BM8563_ALARM_ENABLE;
}

/* 1..31 */
if (BM8563_ALARM_NONE == time->tm_mday) {
buffer[2] = 0x00;
} else {
buffer[2] = decimal2bcd(time->tm_mday);
buffer[2] &= 0b00111111;
buffer[2] |= BM8563_ALARM_ENABLE;
}

/* 0..6 */
if (BM8563_ALARM_NONE == time->tm_mday) {
buffer[3] = 0x00;
} else {
buffer[3] = decimal2bcd(time->tm_wday);
buffer[3] &= 0b00000111;
buffer[3] |= BM8563_ALARM_ENABLE;
}

return bm->write(
bm->handle, BM8563_ADDRESS, reg, buffer, BM8563_ALARM_SIZE
);

break;

case BM8563_ALARM_READ:
time = (struct tm *)argument;

/* 0..59 */
status = bm->read(
bm->handle, BM8563_ADDRESS, reg, buffer, BM8563_ALARM_SIZE
);

if (BM8563_OK != status) {
return status;
}

if (BM8563_ALARM_ENABLE & buffer[0]) {
buffer[0] &= 0b01111111;
time->tm_min = bcd2decimal(buffer[0]);
} else {
time->tm_min = BM8563_ALARM_NONE;
}

/* 0..23 */
if (BM8563_ALARM_ENABLE & buffer[1]) {
buffer[1] &= 0b00111111;
time->tm_hour = bcd2decimal(buffer[1]);
} else {
time->tm_hour = BM8563_ALARM_NONE;
}

/* 1..31 */
if (BM8563_ALARM_ENABLE & buffer[2]) {
buffer[2] &= 0b00111111;
time->tm_mday = bcd2decimal(buffer[2]);
} else {
time->tm_mday = BM8563_ALARM_NONE;
}

/* 0..6 */
if (BM8563_ALARM_ENABLE & buffer[3]) {
buffer[3] &= 0b00000111;
time->tm_wday = bcd2decimal(buffer[3]);
} else {
time->tm_wday = BM8563_ALARM_NONE;
}

return BM8563_OK;
break;
}

return BM8563_ERROR_NOTTY;
}

bm8563_err_t bm8563_close(const bm8563_t *bm)
{
return BM8563_OK;
Expand Down
23 changes: 23 additions & 0 deletions bm8563.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,15 @@ extern "C" {

#define BM8563_ADDRESS (0x51)
#define BM8563_CONTROL_STATUS_1 (0x00)
#define BM8563_TESTC (0b00001000)
#define BM8563_STOP (0b00100000)
#define BM8563_TEST1 (0b10000000)
#define BM8563_CONTROL_STATUS_2 (0x01)
#define BM8563_TIE (0b00000001)
#define BM8563_AIE (0b00000010)
#define BM8563_TF (0b00000100)
#define BM8563_AF (0b00001000)
#define BM8563_TI_TP (0b00010000)
#define BM8563_SECONDS (0x02)
#define BM8563_MINUTES (0x03)
#define BM8563_HOURS (0x04)
Expand All @@ -54,6 +62,20 @@ extern "C" {
#define BM8563_TIME_SIZE (0x07)
#define BM8563_CENTURY_BIT (0b10000000)

#define BM8563_MINUTE_ALARM (0x09)
#define BM8563_HOUR_ALARM (0x0a)
#define BM8563_DAY_ALARM (0x0b)
#define BM8563_WEEKDAY_ALARM (0x0c)
#define BM8563_ALARM_ENABLE (0b10000000)
#define BM8563_ALARM_NONE (0xff)
#define BM8563_ALARM_SIZE (0x04)

/* IOCTL commands */
#define BM8563_ALARM_SET (0x0900)
#define BM8563_ALARM_READ (0x0901)

/* Status codes. */
#define BM8563_ERROR_NOTTY (-1)
#define BM8563_OK (0x00)
#define BM8563_ERR_LOW_VOLTAGE (0x80)

Expand All @@ -69,6 +91,7 @@ typedef int32_t bm8563_err_t;
bm8563_err_t bm8563_init(const bm8563_t *bm);
bm8563_err_t bm8563_read(const bm8563_t *bm, struct tm *time);
bm8563_err_t bm8563_write(const bm8563_t *bm, const struct tm *time);
bm8563_err_t bm8563_ioctl(const bm8563_t *bm, int16_t command, void *buffer);
bm8563_err_t bm8563_close(const bm8563_t *bm);

#ifdef __cplusplus
Expand Down

0 comments on commit e51fc97

Please sign in to comment.