/** * Copyright (c) 2015 - present LibDriver All rights reserved * * The MIT License (MIT) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * @file driver_ds3231.c * @brief driver ds3231 source file * @version 2.0.0 * @author Shifeng Li * @date 2021-03-15 * *

history

* *
Date Version Author Description *
2021/03/15 2.0 Shifeng Li format the code *
2020/11/30 1.0 Shifeng Li first upload *
*/ #include "driver_ds3231.h" /** * @brief chip information definition */ #define CHIP_NAME "Maxim Integrated DS3231" /**< chip name */ #define MANUFACTURER_NAME "Maxim Integrated" /**< manufacturer name */ #define SUPPLY_VOLTAGE_MIN 2.3f /**< chip min supply voltage */ #define SUPPLY_VOLTAGE_MAX 5.5f /**< chip max supply voltage */ #define MAX_CURRENT 0.65f /**< chip max current */ #define TEMPERATURE_MIN -40.0f /**< chip min operating temperature */ #define TEMPERATURE_MAX 85.0f /**< chip max operating temperature */ #define DRIVER_VERSION 2000 /**< driver version */ /** * @brief chip register definition */ #define DS3231_REG_SECOND 0x00 /**< second register */ #define DS3231_REG_MINUTE 0x01 /**< minute register */ #define DS3231_REG_HOUR 0x02 /**< hour register */ #define DS3231_REG_WEEK 0x03 /**< week register */ #define DS3231_REG_DATE 0x04 /**< date register */ #define DS3231_REG_MONTH 0x05 /**< month register */ #define DS3231_REG_YEAR 0x06 /**< year register */ #define DS3231_REG_ALARM1_SECOND 0x07 /**< alarm1 second register */ #define DS3231_REG_ALARM1_MINUTE 0x08 /**< alarm1 minute register */ #define DS3231_REG_ALARM1_HOUR 0x09 /**< alarm1 hour register */ #define DS3231_REG_ALARM1_WEEK 0x0A /**< alarm1 week register */ #define DS3231_REG_ALARM2_MINUTE 0x0B /**< alarm2 minute register */ #define DS3231_REG_ALARM2_HOUR 0x0C /**< alarm2 hour register */ #define DS3231_REG_ALARM2_WEEK 0x0D /**< alarm2 week register */ #define DS3231_REG_CONTROL 0x0E /**< control register */ #define DS3231_REG_STATUS 0x0F /**< status register */ #define DS3231_REG_XTAL 0x10 /**< xtal register */ #define DS3231_REG_TEMPERATUREH 0x11 /**< temperature high register */ #define DS3231_REG_TEMPERATUREL 0x12 /**< temperature low register */ /** * @brief chip address definition */ #define DS3231_ADDRESS 0x68 /**< iic device address */ /** * @brief write one byte * @param[in] *handle points to a ds3231 handle structure * @param[in] reg is the iic register address * @param[in] data is the write data * @return status code * - 0 success * - 1 write failed * @note none */ static uint8_t a_ds3231_iic_write(ds3231_handle_t *handle, uint8_t reg, uint8_t data) { if (handle->iic_write(DS3231_ADDRESS, reg, &data, 1) != 0) /* write data */ { return 1; /* return error */ } else { return 0; /* success return 0 */ } } /** * @brief read multiple bytes * @param[in] *handle points to a ds3231 handle structure * @param[in] reg is the iic register address * @param[out] *buf points to a data buffer * @param[in] len is the data buffer length * @return status code * - 0 success * - 1 read failed * @note none */ static uint8_t a_ds3231_iic_multiple_read(ds3231_handle_t *handle, uint8_t reg, uint8_t *buf, uint8_t len) { if (handle->iic_read(DS3231_ADDRESS, reg, buf, len) != 0) /* read data */ { return 1; /* return error */ } else { /* success return 0 */ return 0; } } /** * @brief hex to bcd * @param[in] val is the hex data * @return bcd data * @note none */ static uint8_t a_ds3231_hex2bcd(uint8_t val) { uint8_t i, j, k; i = val / 10; /* get tens place */ j = val % 10; /* get ones place */ k = j + (i << 4); /* set bcd */ return k; /* return bcd */ } /** * @brief bcd to hex * @param[in] val is the bcd data * @return hex data * @note none */ static uint8_t a_ds3231_bcd2hex(uint8_t val) { uint8_t temp; temp = val & 0x0F; /* get ones place */ val = (val >> 4) & 0x0F; /* get tens place */ val = val * 10; /* set tens place */ temp = temp + val; /* get hex */ return temp; /* return hex */ } /** * @brief set the current time * @param[in] *handle points to a ds3231 handle structure * @param[in] *t points to a time structure * @return status code * - 0 success * - 1 set time failed * - 2 handle or time is NULL * - 3 handle is not initialized * - 4 time is invalid * @note none */ uint8_t ds3231_set_time(ds3231_handle_t *handle, ds3231_time_t *t) { uint8_t res; uint8_t reg; uint8_t century; uint16_t year; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { if ((t->year < 1990) || (t->year > 2190)) /* check year */ { handle->debug_print("ds3231: year can't be over 2190 or less than 1990.\n"); /* year can't be over 2190 or less than 1990 */ return 4; /* return error */ } if ((t->month == 0) || (t->month > 12)) /* check month */ { handle->debug_print("ds3231: month can't be zero or over than 12.\n"); /* month can't be zero or over than 12 */ return 4; /* return error */ } if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 4; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 4; /* return error */ } if ((t->hour < 1) || (t->hour > 12)) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 12 or less 1.\n"); /* hour can't be over than 12 or less 1 */ return 4; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 4; /* return error */ } if (t->second > 59) /* check second */ { handle->debug_print("ds3231: second can't be over than 59.\n"); /* second can't be over than 59 */ return 4; /* return error */ } } else if (t->format == DS3231_FORMAT_24H) /* if 24H */ { if ((t->year < 1990) || (t->year > 2190)) /* check year */ { handle->debug_print("ds3231: year can't be over 2190 or less than 1990.\n"); /* year can't be over 2190 or less than 1990 */ return 4; /* return error */ } if ((t->month == 0) || (t->month > 12)) /* check month */ { handle->debug_print("ds3231: month can't be zero or over than 12.\n"); /* month can't be zero or over than 12 */ return 4; /* return error */ } if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 4; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 4; /* return error */ } if (t->hour > 23) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 23.\n"); /* hour can't be over than 23 */ return 4; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 4; /* return error */ } if (t->second > 59) /* check second */ { handle->debug_print("ds3231: second can't be over than 59.\n"); /* second can't be over than 59 */ return 4; /* return error */ } } else { handle->debug_print("ds3231: format is invalid.\n"); /* format is invalid */ return 4; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_SECOND, a_ds3231_hex2bcd(t->second)); /* write second */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write second failed.\n"); /* write second failed */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_MINUTE, a_ds3231_hex2bcd(t->minute)); /* write minute */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write minute failed.\n"); /* write minute failed */ return 1; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { reg = (uint8_t)((1 << 6) | (t->am_pm << 5) | a_ds3231_hex2bcd(t->hour)); /* set hour in 12H */ } else /* if 24H */ { reg = (0 << 6) | a_ds3231_hex2bcd(t->hour); /* set hour in 24H */ } res = a_ds3231_iic_write(handle, DS3231_REG_HOUR, reg); /* write hour */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write hour failed.\n"); /* write hour failed */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_WEEK, a_ds3231_hex2bcd(t->week)); /* write week */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write week failed.\n"); /* write week failed */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_DATE, a_ds3231_hex2bcd(t->date)); /* write data */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write date failed.\n"); /* write date failed */ return 1; /* return error */ } year = t->year - 1990; /* year -1990 */ if (year >= 100) /* check year */ { century = 1; /* set century */ year -= 100; /* year -= 100 */ } else { century = 0; /* set century 0 */ } res = a_ds3231_iic_write(handle, DS3231_REG_MONTH, a_ds3231_hex2bcd(t->month) | (century << 7)); /* write month and century */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write century and month failed.\n"); /* write century and month failed */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_YEAR, a_ds3231_hex2bcd((uint8_t)year)); /* write year */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write year failed.\n"); /* write year failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the current time * @param[in] *handle points to a ds3231 handle structure * @param[out] *t points to a time structure * @return status code * - 0 success * - 1 get time failed * - 2 handle or time is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_time(ds3231_handle_t *handle, ds3231_time_t *t) { uint8_t res; uint8_t buf[7]; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } memset(buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */ res = a_ds3231_iic_multiple_read(handle, DS3231_REG_SECOND, (uint8_t *)buf, 7); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: multiple read failed.\n"); /* multiple read failed */ return 1; /* return error */ } t->year = a_ds3231_bcd2hex(buf[6]) + 1990 + ((buf[5] >> 7) & 0x01) * 100; /* get year */ t->month = a_ds3231_bcd2hex(buf[5]&0x1F); /* get month */ t->week = a_ds3231_bcd2hex(buf[3]); /* get week */ t->date = a_ds3231_bcd2hex(buf[4]); /* get date */ t->am_pm = (ds3231_am_pm_t)((buf[2] >> 5) & 0x01); /* get am pm */ t->format = (ds3231_format_t)((buf[2] >> 6) & 0x01); /* get format */ if (t->format == DS3231_FORMAT_12H) /* if 12H */ { t->hour = a_ds3231_bcd2hex(buf[2] & 0x1F); /* get hour */ } else { t->hour = a_ds3231_bcd2hex(buf[2] & 0x3F); /* get hour */ } t->minute = a_ds3231_bcd2hex(buf[1]); /* get minute */ t->second = a_ds3231_bcd2hex(buf[0]); /* get second */ return 0; /* success return 0 */ } /** * @brief set the alarm1 time * @param[in] *handle points to a ds3231 handle structure * @param[in] *t points to a time structure * @param[in] mode is the alarm1 interrupt mode * @return status code * - 0 success * - 1 set alarm1 failed * - 2 handle or time is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_alarm1(ds3231_handle_t *handle, ds3231_time_t *t, ds3231_alarm1_mode_t mode) { uint8_t res; uint8_t reg; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 1; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 1; /* return error */ } if ((t->hour < 1) || (t->hour > 12)) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 12 or less 1.\n"); /* hour can't be over than 12 or less 1 */ return 1; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 1; /* return error */ } if (t->second > 59) /* check second */ { handle->debug_print("ds3231: second can't be over than 59.\n"); /* second can't be over than 59 */ return 1; /* return error */ } } else if (t->format == DS3231_FORMAT_24H) /* if 24H */ { if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 1; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 1; /* return error */ } if (t->hour > 23) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 23.\n"); /* hour can't be over than 23 */ return 1; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 1; /* return error */ } if (t->second > 59) /* check second */ { handle->debug_print("ds3231: second can't be over than 59.\n"); /* second can't be over than 59 */ return 1; /* return error */ } } else { handle->debug_print("ds3231: format is invalid.\n"); /* format is invalid */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM1_SECOND, a_ds3231_hex2bcd(t->second) | ((mode & 0x01) << 7)); /* write second */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm1 second failed.\n"); /* write alarm1 second failed */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM1_MINUTE, a_ds3231_hex2bcd(t->minute) | (((mode >> 1) & 0x01) << 7)); /* write minute */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm1 minute failed.\n"); /* write alarm1 minute failed */ return 1; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { reg = (uint8_t)((((mode >> 2) & 0x01) << 7) | (1 << 6) | (t->am_pm << 5) | a_ds3231_hex2bcd(t->hour)); /* set hour in 12H */ } else /* if 24H */ { reg = (((mode >> 2) & 0x01) << 7) | a_ds3231_hex2bcd(t->hour); /* set hour in 24H */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM1_HOUR, reg); /* write hour */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm1 hour failed.\n"); /* write alarm1 hour failed */ return 1; /* return error */ } if (mode >= DS3231_ALARM1_MODE_WEEK_HOUR_MINUTE_SECOND_MATCH) /* if week */ { reg = (((mode >> 3) & 0x01) << 7) | (1 << 6) | a_ds3231_hex2bcd(t->week); /* set data in week */ } else /* if day */ { reg = (((mode >> 3) & 0x01) << 7) | a_ds3231_hex2bcd(t->date); /* set data in date */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM1_WEEK, reg); /* write week */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm1 week failed.\n"); /* write alarm1 week failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the alarm1 time * @param[in] *handle points to a ds3231 handle structure * @param[out] *t points to a time structure * @param[out] *mode points to an alarm1 interrupt mode buffer * @return status code * - 0 success * - 1 get alarm1 failed * - 2 handle or time is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_alarm1(ds3231_handle_t *handle, ds3231_time_t *t, ds3231_alarm1_mode_t *mode) { uint8_t res; uint8_t buf[4]; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } memset(buf, 0, sizeof(uint8_t) * 4); /* clear the buffer */ res = a_ds3231_iic_multiple_read(handle, DS3231_REG_ALARM1_SECOND, (uint8_t *)buf, 4); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: multiple read failed.\n"); /* multiple read failed */ return 1; /* return error */ } t->year = 0; /* get year */ t->month = 0; /* get month */ if (((buf[3] >> 6) & 0x01) != 0) /* if week */ { t->week = a_ds3231_bcd2hex(buf[3] & 0x0F); /* get week */ t->date = 0; /* get data */ } else /* if data */ { t->week = 0; /* get week */ t->date = a_ds3231_bcd2hex(buf[3] & 0x3F); /* get data */ } t->am_pm = (ds3231_am_pm_t)((buf[2] >> 5) & 0x01); /* get am pm */ t->format = (ds3231_format_t)((buf[2] >> 6) & 0x01); /* get format */ if (t->format == DS3231_FORMAT_12H) /* if 12H */ { t->hour = a_ds3231_bcd2hex(buf[2]&0x1F); /* get hour */ } else /* if 24H */ { t->hour = a_ds3231_bcd2hex(buf[2]&0x3F); /* get hour */ } t->minute = a_ds3231_bcd2hex(buf[1] & 0x7F); /* get minute */ t->second = a_ds3231_bcd2hex(buf[0] & 0x7F); /* get second */ *mode = (ds3231_alarm1_mode_t)(((buf[0]>>7)&0x01)<<0 | ((buf[1]>>7)&0x01)<<1 | ((buf[2]>>7)&0x01)<<2 | ((buf[3]>>7)&0x01)<<3 | ((buf[3] >> 6)&0x01)<<4 ); /* get mode */ return 0; /* success return 0 */ } /** * @brief set the alarm2 time * @param[in] *handle points to a ds3231 handle structure * @param[in] *t points to a time structure * @param[in] mode is the alarm2 interrupt mode * @return status code * - 0 success * - 1 set alarm2 failed * - 2 handle or time is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_alarm2(ds3231_handle_t *handle, ds3231_time_t *t, ds3231_alarm2_mode_t mode) { uint8_t res; uint8_t reg; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 1; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 1; /* return error */ } if ((t->hour < 1) || (t->hour > 12)) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 12 or less 1.\n"); /* hour can't be over than 12 or less 1 */ return 1; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 1; /* return error */ } } else if (t->format == DS3231_FORMAT_24H) /* if 24H */ { if ((t->week == 0) || (t->week > 7)) /* check week */ { handle->debug_print("ds3231: week can't be zero or over than 7.\n"); /* week can't be zero or over than 7 */ return 1; /* return error */ } if ((t->date == 0) || (t->date > 31)) /* check data */ { handle->debug_print("ds3231: date can't be zero or over than 31.\n"); /* date can't be zero or over than 31 */ return 1; /* return error */ } if (t->hour > 23) /* check hour */ { handle->debug_print("ds3231: hour can't be over than 23.\n"); /* hour can't be over than 23 */ return 1; /* return error */ } if (t->minute > 59) /* check minute */ { handle->debug_print("ds3231: minute can't be over than 59.\n"); /* minute can't be over than 59 */ return 1; /* return error */ } } else { handle->debug_print("ds3231: format is invalid.\n"); /* format is invalid */ return 1; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM2_MINUTE, a_ds3231_hex2bcd(t->minute) | (((mode >> 0) & 0x01) << 7)); /* write minute */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm2 minute failed.\n"); /* write alarm2 minute failed */ return 1; /* return error */ } if (t->format == DS3231_FORMAT_12H) /* if 12H */ { reg = (uint8_t)((((mode >> 1) & 0x01) << 7) | (1 << 6) | (t->am_pm << 5) | a_ds3231_hex2bcd(t->hour)); /* set hour in 12H */ } else /* if 24H */ { reg = (((mode >> 1) & 0x01) << 7) | a_ds3231_hex2bcd(t->hour); /* set hour in 24H */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM2_HOUR, reg); /* write hour */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm2 hour failed.\n"); /* write alarm2 hour failed */ return 1; /* return error */ } if (mode >= (uint8_t)DS3231_ALARM1_MODE_WEEK_HOUR_MINUTE_SECOND_MATCH) /* if week */ { reg = (((mode >> 2) & 0x01) << 7) | (1 << 6) | a_ds3231_hex2bcd(t->week); /* set data in week */ } else /* if day */ { reg = (((mode >> 2) & 0x01) << 7) | a_ds3231_hex2bcd(t->date); /* set data in date */ } res = a_ds3231_iic_write(handle, DS3231_REG_ALARM2_WEEK, reg); /* write week */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write alarm2 week failed.\n"); /* write alarm2 week failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the alarm2 time * @param[in] *handle points to a ds3231 handle structure * @param[out] *t points to a time structure * @param[out] *mode points to an alarm2 interrupt mode buffer * @return status code * - 0 success * - 1 get alarm2 failed * - 2 handle or time is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_alarm2(ds3231_handle_t *handle, ds3231_time_t *t, ds3231_alarm2_mode_t *mode) { uint8_t res; uint8_t buf[3]; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (t == NULL) /* check time */ { handle->debug_print("ds3231: time is null.\n"); /* time is null */ return 2; /* return error */ } memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */ res = a_ds3231_iic_multiple_read(handle, DS3231_REG_ALARM2_MINUTE, (uint8_t *)buf, 3); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: multiple read failed.\n"); /* multiple read failed */ return 1; /* return error */ } t->year = 0; /* get year */ t->month = 0; /* get month */ if (((buf[2] >> 6) & 0x01) != 0) /* if week */ { t->week = a_ds3231_bcd2hex(buf[2] & 0x0F); /* get week */ t->date = 0; /* get data */ } else /* if data */ { t->week = 0; /* get week */ t->date = a_ds3231_bcd2hex(buf[2] & 0x3F); /* get data */ } t->am_pm = (ds3231_am_pm_t)((buf[1] >> 5) & 0x01); /* get am pm */ t->format = (ds3231_format_t)((buf[1] >> 6) & 0x01); /* get format */ if (t->format == DS3231_FORMAT_12H) /* if 12H */ { t->hour = a_ds3231_bcd2hex(buf[1]&0x1F); /* get hour */ } else /* if 24H */ { t->hour = a_ds3231_bcd2hex(buf[1]&0x3F); /* get hour */ } t->minute = a_ds3231_bcd2hex(buf[0] & 0x7F); /* get minute */ t->second = 0; /* get second */ *mode = (ds3231_alarm2_mode_t)(((buf[0]>>7)&0x01)<<0 | ((buf[1]>>7)&0x01)<<1 | ((buf[2]>>7)&0x01)<<2 | ((buf[2]>>6)&0x01)<<4); /* get mode */ return 0; /* success return 0 */ } /** * @brief enable or disable the oscillator * @param[in] *handle points to a ds3231 handle structure * @param[in] enable is a bool value * @return status code * - 0 success * - 1 set oscillator failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_oscillator(ds3231_handle_t *handle, ds3231_bool_t enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } prev &= ~ (1 << 7); /* clear config */ prev |= (!enable) << 7; /* set enable */ res = a_ds3231_iic_write(handle, DS3231_REG_CONTROL, prev); /* write control */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write control failed.\n"); /* write control failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the chip oscillator status * @param[in] *handle points to a ds3231 handle structure * @param[out] *enable points to a bool value buffer * @return status code * - 0 success * - 1 get oscillator failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_oscillator(ds3231_handle_t *handle, ds3231_bool_t *enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } *enable = (ds3231_bool_t)(!((prev >> 7) & 0x01)); /* get enable */ return 0; /* success return 0 */ } /** * @brief enable or disable the alarm interrupt * @param[in] *handle points to a ds3231 handle structure * @param[in] alarm is the alarm number * @param[in] enable is a bool value * @return status code * - 0 success * - 1 set alarm interrupt failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_alarm_interrupt(ds3231_handle_t *handle, ds3231_alarm_t alarm, ds3231_bool_t enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } prev &= ~(1 << alarm); /* clear config */ prev |= enable << alarm; /* set enable */ res = a_ds3231_iic_write(handle, DS3231_REG_CONTROL, prev); /* write control */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write control failed.\n"); /* write control failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the alarm interrupt status * @param[in] *handle points to a ds3231 handle structure * @param[in] alarm is the alarm number * @param[out] *enable points to a bool value buffer * @return status code * - 0 success * - 1 get alarm interrupt failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_alarm_interrupt(ds3231_handle_t *handle, ds3231_alarm_t alarm, ds3231_bool_t *enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } *enable = (ds3231_bool_t)((prev >> alarm) & 0x01); /* get enable */ return 0; /* success return 0 */ } /** * @brief set the chip pin function * @param[in] *handle points to a ds3231 handle structure * @param[in] pin is the pin's function * @return status code * - 0 success * - 1 set pin failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_pin(ds3231_handle_t *handle, ds3231_pin_t pin) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } prev &= ~(1 << 2); /* clear config */ prev |= pin << 2; /* set pin */ res = a_ds3231_iic_write(handle, DS3231_REG_CONTROL, prev); /* write control */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write control failed.\n"); /* write control failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the chip pin function * @param[in] *handle points to a ds3231 handle structure * @param[out] *pin points to a pin's function buffer * @return status code * - 0 success * - 1 get pin failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_pin(ds3231_handle_t *handle, ds3231_pin_t *pin) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } *pin = (ds3231_pin_t)((prev >> 2) & 0x01); /* get pin */ return 0; /* success return 0 */ } /** * @brief enable or disable the square wave output * @param[in] *handle points to a ds3231 handle structure * @param[in] enable is a bool value * @return status code * - 0 success * - 1 set square wave failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_square_wave(ds3231_handle_t *handle, ds3231_bool_t enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } prev &= ~(1 << 6); /* clear config */ prev |= enable << 6; /* set enable */ res = a_ds3231_iic_write(handle, DS3231_REG_CONTROL, prev); /* write control */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write control failed.\n"); /* write control failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the square wave output status * @param[in] *handle points to a ds3231 handle structure * @param[out] *enable points to a bool value buffer * @return status code * - 0 success * - 1 get square wave failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_square_wave(ds3231_handle_t *handle, ds3231_bool_t *enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } *enable = (ds3231_bool_t)((prev >> 6) & 0x01); /* get enable */ return 0; /* success return 0 */ } /** * @brief get the chip temperature * @param[in] *handle points to a ds3231 handle structure * @param[out] *raw points to a raw temperature buffer * @param[out] *s points to a converted temperature buffer * @return status code * - 0 success * - 1 get temperature failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_temperature(ds3231_handle_t *handle, int16_t *raw, float *s) { uint8_t res; uint8_t prev; uint32_t times; uint8_t buf[2]; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } memset(buf, 0, sizeof(uint8_t) * 2); /* clear the buffer */ res = a_ds3231_iic_multiple_read(handle, DS3231_REG_CONTROL, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read control failed.\n"); /* read control failed */ return 1; /* return error */ } prev &= ~(1 << 5); /* clear config */ prev |= 1 << 5; /* set enable */ res = a_ds3231_iic_write(handle, DS3231_REG_CONTROL, prev); /* write control */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write control failed.\n"); /* write control failed */ return 1; /* return error */ } times = 500; /* set 5s */ while (times != 0) /* check times */ { handle->delay_ms(10); /* delay 10 ms */ res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* read status */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } if (((prev >> 2) & 0x01) == 0) /* check result */ { break; /* break */ } times--; /* times-- */ } if (times == 0) /* if zero */ { handle->debug_print("ds3231: read timeout.\n"); /* read timeout */ return 1; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_TEMPERATUREH, (uint8_t *)buf, 2); /* read temperature */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read temperature failed.\n"); /* read temperature failed */ return 1; /* return error */ } *raw = (int16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set raw temperature */ *raw = (*raw) >> 6; /* right shift */ if (((*raw) & 0x0200) != 0) /* set negative value */ { *raw = (*raw) | 0xFC00U; /* set negative part */ } *s = (float)(*raw) * 0.25f; /* set converted temperature */ return 0; /* success return 0 */ } /** * @brief get the chip status * @param[in] *handle points to a ds3231 handle structure * @param[out] *status points to a chip status buffer * @return status code * - 0 success * - 1 get status failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_status(ds3231_handle_t *handle, uint8_t *status) { uint8_t res; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)status, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief set the chip aging offset * @param[in] *handle points to a ds3231 handle structure * @param[in] offset is time aging offset * @return status code * - 0 success * - 1 set aging offset failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_aging_offset(ds3231_handle_t *handle, int8_t offset) { uint8_t res; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_write(handle, DS3231_REG_XTAL, offset); /* write offset */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write offset failed.\n"); /* write offset failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the chip aging offset * @param[in] *handle points to a ds3231 handle structure * @param[out] *offset points to a time aging offset buffer * @return status code * - 0 success * - 1 get aging offset failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_aging_offset(ds3231_handle_t *handle, int8_t *offset) { uint8_t res; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_XTAL, (uint8_t *)offset, 1); /* read offset */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read offset failed.\n"); /* read offset failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief convert a aging offset value to a register raw data * @param[in] *handle points to a ds3231 handle structure * @param[in] offset is a converted aging offset value * @param[out] *reg points to a register raw buffer * @return status code * - 0 success * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_aging_offset_convert_to_register(ds3231_handle_t *handle, float offset, int8_t *reg) { if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } *reg = (int8_t)(offset / 0.12f); /* convert real data to register data */ return 0; /* success return 0 */ } /** * @brief convert a register raw data to a converted aging offset data * @param[in] *handle points to a ds3231 handle structure * @param[in] reg is the register raw data * @param[out] *offset points to a converted aging offset buffer * @return status code * - 0 success * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_aging_offset_convert_to_data(ds3231_handle_t *handle, int8_t reg, float *offset) { if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } *offset = (float)(reg) * 0.12f; /* convert raw data to real data */ return 0; /* success return 0 */ } /** * @brief irq handler * @param[in] *handle points to a ds3231 handle structure * @return status code * - 0 success * - 1 run failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_irq_handler(ds3231_handle_t *handle) { uint8_t res, prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } /* if oscillator stop */ if ((prev & DS3231_STATUS_ALARM_2) != 0) /* if alarm 2 */ { if (handle->receive_callback != NULL) /* if receive callback */ { handle->receive_callback(DS3231_STATUS_ALARM_2); /* run callback */ } } if ((prev & DS3231_STATUS_ALARM_1) != 0) /* if alarm 1 */ { if (handle->receive_callback != NULL) /* if receive callback */ { handle->receive_callback(DS3231_STATUS_ALARM_1); /* run callback */ } } return 0; /* success return 0 */ } /** * @brief initialize the chip * @param[in] *handle points to a ds3231 handle structure * @return status code * - 0 success * - 1 iic initialization failed * - 2 handle is NULL * - 3 linked functions is NULL * @note none */ uint8_t ds3231_init(ds3231_handle_t *handle) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->debug_print == NULL) /* check debug_print */ { return 3; /* return error */ } if (handle->iic_init == NULL) /* check iic_init */ { handle->debug_print("ds3231: iic_init is null.\n"); /* iic_init is null */ return 3; /* return error */ } if (handle->iic_deinit == NULL) /* check iic_deinit */ { handle->debug_print("ds3231: iic_deinit is null.\n"); /* iic_deinit is null */ return 3; /* return error */ } if (handle->iic_write == NULL) /* check iic_write */ { handle->debug_print("ds3231: iic_write is null.\n"); /* iic_write is null */ return 3; /* return error */ } if (handle->iic_read == NULL) /* check iic_read */ { handle->debug_print("ds3231: iic_read is null.\n"); /* iic_read is null */ return 3; /* return error */ } if (handle->delay_ms == NULL) /* check delay_ms */ { handle->debug_print("ds3231: delay_ms is null.\n"); /* delay_ms is null */ return 3; /* return error */ } if (handle->receive_callback == NULL) /* check receive_callback */ { handle->debug_print("ds3231: receive_callback is null.\n"); /* receive_callback is null */ return 3; /* return error */ } if (handle->iic_init() != 0) /* iic init */ { handle->debug_print("ds3231: iic init failed.\n"); /* iic init failed */ return 1; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ (void)handle->iic_deinit(); /* iic deinit */ return 1; /* return error */ } prev &= ~(1 << 7); /* clear config */ res = a_ds3231_iic_write(handle, DS3231_REG_STATUS, prev); /* write status */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write status failed.\n"); /* write status failed */ (void)handle->iic_deinit(); /* iic deinit */ return 1; /* return error */ } handle->inited = 1; /* flag finish initialization */ return 0; /* success return 0 */ } /** * @brief close the chip * @param[in] *handle points to a ds3231 handle structure * @return status code * - 0 success * - 1 iic deinit failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_deinit(ds3231_handle_t *handle) { if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (handle->iic_deinit() != 0) /* iic deinit */ { handle->debug_print("ds3231: iic deinit failed.\n"); /* iic deinit failed */ return 1; /* return error */ } handle->inited = 0; /* flag close */ return 0; /* success return 0 */ } /** * @brief clear the alarm flag * @param[in] *handle points to a ds3231 handle structure * @param[in] alarm is the alarm number * @return status code * - 0 success * - 1 alarm clear failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_alarm_clear(ds3231_handle_t *handle, ds3231_alarm_t alarm) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* multiple_read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } prev &= ~(1 << alarm); /* clear config */ res = a_ds3231_iic_write(handle, DS3231_REG_STATUS, prev); /* write status */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write status failed.\n"); /* write status failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief enable or disable the 32KHz output * @param[in] *handle points to a ds3231 handle structure * @param[in] enable is a bool value * @return status code * - 0 success * - 1 set 32khz output failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_32khz_output(ds3231_handle_t *handle, ds3231_bool_t enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } prev &= ~(1 << 3); /* clear config */ prev |= enable << 3; /* set enable */ res = a_ds3231_iic_write(handle, DS3231_REG_STATUS, prev); /* write status */ if (res != 0) /* check result */ { handle->debug_print("ds3231: write status failed.\n"); /* write status failed */ return 1; /* return error */ } return 0; /* success return 0 */ } /** * @brief get the 32KHz output status * @param[in] *handle points to a ds3231 handle structure * @param[out] *enable points to a bool value buffer * @return status code * - 0 success * - 1 get 32khz output failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_32khz_output(ds3231_handle_t *handle, ds3231_bool_t *enable) { uint8_t res; uint8_t prev; if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } res = a_ds3231_iic_multiple_read(handle, DS3231_REG_STATUS, (uint8_t *)&prev, 1); /* multiple read */ if (res != 0) /* check result */ { handle->debug_print("ds3231: read status failed.\n"); /* read status failed */ return 1; /* return error */ } *enable = (ds3231_bool_t)((prev >> 3) & 0x01); /* get enable */ return 0; /* success return 0 */ } /** * @brief set the chip register * @param[in] *handle points to a ds3231 handle structure * @param[in] reg is the iic register address * @param[in] *buf points to a data buffer * @param[in] len is the data buffer length * @return status code * - 0 success * - 1 write failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_set_reg(ds3231_handle_t *handle, uint8_t reg, uint8_t *buf, uint16_t len) { if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (handle->iic_write(DS3231_ADDRESS, reg, buf, len) != 0) /* write data */ { return 1; /* return error */ } else { return 0; /* success return 0 */ } } /** * @brief get the chip register * @param[in] *handle points to a ds3231 handle structure * @param[in] reg is the iic register address * @param[out] *buf points to a data buffer * @param[in] len is the data buffer length * @return status code * - 0 success * - 1 read failed * - 2 handle is NULL * - 3 handle is not initialized * @note none */ uint8_t ds3231_get_reg(ds3231_handle_t *handle, uint8_t reg, uint8_t *buf, uint16_t len) { if (handle == NULL) /* check handle */ { return 2; /* return error */ } if (handle->inited != 1) /* check handle initialization */ { return 3; /* return error */ } if (handle->iic_read(DS3231_ADDRESS, reg, buf, len) != 0) /* read data */ { return 1; /* return error */ } else { return 0; /* success return 0 */ } } /** * @brief get chip's information * @param[out] *info points to a ds3231 info structure * @return status code * - 0 success * - 2 handle is NULL * @note none */ uint8_t ds3231_info(ds3231_info_t *info) { if (info == NULL) /* check handle */ { return 2; /* return error */ } memset(info, 0, sizeof(ds3231_info_t)); /* initialize ds3231 info structure */ strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */ strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */ strncpy(info->interface, "IIC", 8); /* copy interface name */ info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */ info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */ info->max_current_ma = MAX_CURRENT; /* set maximum current */ info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */ info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */ info->driver_version = DRIVER_VERSION; /* set driver version */ return 0; /* success return 0 */ }