RTC library for Max31341/2 devices

Fork of max3134x by Mahir Ozturk

Files at this revision

API Documentation at this revision

Comitter:
Mahir Ozturk
Date:
Wed Apr 10 17:28:15 2019 +0300
Commit message:
Initial commit

Changed in this revision

Max31341.cpp Show annotated file Show diff for this revision Revisions of this file
Max31341.h Show annotated file Show diff for this revision Revisions of this file
Max31341_regs.h Show annotated file Show diff for this revision Revisions of this file
Max31342.cpp Show annotated file Show diff for this revision Revisions of this file
Max31342.h Show annotated file Show diff for this revision Revisions of this file
Max31342_regs.h Show annotated file Show diff for this revision Revisions of this file
RtcBase.cpp Show annotated file Show diff for this revision Revisions of this file
RtcBase.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 1efa49a69ff8 Max31341.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31341.cpp	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright (C) 2018 Maxim Integrated Products, Inc., All rights Reserved.
+*
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* 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 MAXIM INTEGRATED 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.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+#include "Max31341.h"
+
+const RtcBase::regmap_t Max31341::regmap = {
+	/*.config_reg1         = */MAX31341_REG_CONFIG_REG1_ADDR,
+	/*.config_reg2         = */MAX31341_REG_CONFIG_REG2_ADDR,
+	/*.int_ploarity_config = */MAX31341_REG_INT_POLARITY_CONFIG_ADDR,
+	/*.timer_config        = */MAX31341_REG_TIMER_CONFIG_ADDR,
+	/*.int_en_reg          = */MAX31341_REG_INT_EN_REG_ADDR,
+	/*.int_status_reg      = */MAX31341_REG_INT_STATUS_REG_ADDR,
+	/*.seconds             = */MAX31341_REG_SECONDS_ADDR,
+	/*.minutes             = */MAX31341_REG_MINUTES_ADDR,
+	/*.hours               = */MAX31341_REG_HOURS_ADDR,
+	/*.day                 = */MAX31341_REG_DAY_ADDR,
+	/*.date                = */MAX31341_REG_DATE_ADDR,
+	/*.month               = */MAX31341_REG_MONTH_ADDR,
+	/*.year                = */MAX31341_REG_YEAR_ADDR,
+	/*.alm1_sec            = */MAX31341_REG_ALM1_SEC_ADDR,
+	/*.alm1_min            = */MAX31341_REG_ALM1_MIN_ADDR,
+	/*.alm1_hrs            = */MAX31341_REG_ALM1_HRS_ADDR,
+	/*.alm1day_date        = */MAX31341_REG_ALM1DAY_DATE_ADDR,
+	/*.alm1_mon            = */RtcBase::REG_NOT_AVAILABLE,
+	/*.alm1_year           = */RtcBase::REG_NOT_AVAILABLE,
+	/*.alm2_min            = */MAX31341_REG_ALM2_MIN_ADDR,
+	/*.alm2_hrs            = */MAX31341_REG_ALM2_HRS_ADDR,
+	/*.alm2day_date        = */MAX31341_REG_ALM2DAY_DATE_ADDR,
+	/*.timer_count         = */MAX31341_REG_TIMER_COUNT_ADDR,
+	/*.timer_init          = */MAX31341_REG_TIMER_INIT_ADDR,
+	/*.ram_start           = */MAX31341_REG_RAM_START_ADDR,
+	/*.ram_end             = */MAX31341_REG_RAM_END_ADDR,
+	/*.pwr_mgmt_reg        = */MAX31341_REG_PWR_MGMT_REG_ADDR,
+	/*.trickle_reg         = */MAX31341_REG_TRICKLE_REG_ADDR,
+	/*.clock_sync_delay    = */MAX31341_REG_CLOCK_SYNC_REG,
+};
+
diff -r 000000000000 -r 1efa49a69ff8 Max31341.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31341.h	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright (C) 2018 Maxim Integrated Products, Inc., All rights Reserved.
+*
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* 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 MAXIM INTEGRATED 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.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+#include "RtcBase.h"
+#include "Max31341_regs.h"
+
+#ifndef MAX31341_H_
+#define MAX31341_H_
+
+class Max31341 : public RtcBase {
+public:
+	Max31341(I2C *i2c, PinName inta_pin = NC, PinName intb_pin = NC) : RtcBase(&regmap, i2c, inta_pin, intb_pin) {}
+private:
+	static const regmap_t regmap;
+};
+
+#endif /* MAX31341_H_ */
diff -r 000000000000 -r 1efa49a69ff8 Max31341_regs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31341_regs.h	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * 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 MAXIM INTEGRATED 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.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#ifndef MAX31341_REGS_H_
+#define MAX31341_REGS_H_
+
+enum max31341_register_address {
+	MAX31341_REG_CONFIG_REG1_ADDR		= 0x00,
+	MAX31341_REG_CONFIG_REG2_ADDR		= 0x01,
+	MAX31341_REG_INT_POLARITY_CONFIG_ADDR	= 0x02,
+	MAX31341_REG_TIMER_CONFIG_ADDR		= 0x03,
+	MAX31341_REG_INT_EN_REG_ADDR		= 0x04,
+	MAX31341_REG_INT_STATUS_REG_ADDR	= 0x05,
+	MAX31341_REG_SECONDS_ADDR			= 0x06,
+	MAX31341_REG_MINUTES_ADDR			= 0x07,
+	MAX31341_REG_HOURS_ADDR				= 0x08,
+	MAX31341_REG_DAY_ADDR				= 0x09,
+	MAX31341_REG_DATE_ADDR				= 0x0A,
+	MAX31341_REG_MONTH_ADDR				= 0x0B,
+	MAX31341_REG_YEAR_ADDR				= 0x0C,
+	MAX31341_REG_ALM1_SEC_ADDR			= 0x0D,
+	MAX31341_REG_ALM1_MIN_ADDR			= 0x0E,
+	MAX31341_REG_ALM1_HRS_ADDR			= 0x0F,
+	MAX31341_REG_ALM1DAY_DATE_ADDR		= 0x10,
+	MAX31341_REG_ALM2_MIN_ADDR			= 0x11,
+	MAX31341_REG_ALM2_HRS_ADDR			= 0x12,
+	MAX31341_REG_ALM2DAY_DATE_ADDR		= 0x13,
+	MAX31341_REG_TIMER_COUNT_ADDR		= 0x14,
+	MAX31341_REG_TIMER_INIT_ADDR		= 0x15,
+	MAX31341_REG_RAM_START_ADDR			= 0x16,
+	MAX31341_REG_RAM_END_ADDR			= 0x55,
+	MAX31341_REG_PWR_MGMT_REG_ADDR		= 0x56,
+	MAX31341_REG_TRICKLE_REG_ADDR		= 0x57,
+	MAX31341_REG_CLOCK_SYNC_REG			= 0x58,
+	MAX31341_REG_END,
+};
+
+#endif /* MAX31341_REGS_H_ */
diff -r 000000000000 -r 1efa49a69ff8 Max31342.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31342.cpp	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright (C) 2018 Maxim Integrated Products, Inc., All rights Reserved.
+*
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* 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 MAXIM INTEGRATED 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.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+#include "Max31342.h"
+
+const RtcBase::regmap_t Max31342::regmap = {
+	/*.config_reg1         = */MAX31342_REG_CONFIG_REG1_ADDR,
+	/*.config_reg2         = */MAX31342_REG_CONFIG_REG2_ADDR,
+	/*.int_ploarity_config = */RtcBase::REG_NOT_AVAILABLE,
+	/*.timer_config        = */MAX31342_REG_TIMER_CONFIG_ADDR,
+	/*.int_en_reg          = */MAX31342_REG_INT_EN_REG_ADDR,
+	/*.int_status_reg      = */MAX31342_REG_INT_STATUS_REG_ADDR,
+	/*.seconds             = */MAX31342_REG_SECONDS_ADDR,
+	/*.minutes             = */MAX31342_REG_MINUTES_ADDR,
+	/*.hours               = */MAX31342_REG_HOURS_ADDR,
+	/*.day                 = */MAX31342_REG_DAY_ADDR,
+	/*.date                = */MAX31342_REG_DATE_ADDR,
+	/*.month               = */MAX31342_REG_MONTH_ADDR,
+	/*.year                = */MAX31342_REG_YEAR_ADDR,
+	/*.alm1_sec            = */MAX31342_REG_ALM1_SEC_ADDR,
+	/*.alm1_min            = */MAX31342_REG_ALM1_MIN_ADDR,
+	/*.alm1_hrs            = */MAX31342_REG_ALM1_HRS_ADDR,
+	/*.alm1day_date        = */MAX31342_REG_ALM1DAY_DATE_ADDR,
+	/*.alm1_mon            = */MAX31342_REG_ALM1_MON_ADDR,
+	/*.alm1_year           = */MAX31342_REG_ALM1_YEAR_ADDR,
+	/*.alm2_min            = */MAX31342_REG_ALM2_MIN_ADDR,
+	/*.alm2_hrs            = */MAX31342_REG_ALM2_HRS_ADDR,
+	/*.alm2day_date        = */MAX31342_REG_ALM2DAY_DATE_ADDR,
+	/*.timer_count         = */MAX31342_REG_TIMER_COUNT_ADDR,
+	/*.timer_init          = */MAX31342_REG_TIMER_INIT_ADDR,
+	/*.ram_start           = */RtcBase::REG_NOT_AVAILABLE,
+	/*.ram_end             = */RtcBase::REG_NOT_AVAILABLE,
+	/*.pwr_mgmt_reg        = */RtcBase::REG_NOT_AVAILABLE,
+	/*.trickle_reg         = */RtcBase::REG_NOT_AVAILABLE,
+	/*.clock_sync_delay    = */MAX31342_REG_CLOCK_SYNC_REG,
+};
+
diff -r 000000000000 -r 1efa49a69ff8 Max31342.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31342.h	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright (C) 2018 Maxim Integrated Products, Inc., All rights Reserved.
+*
+* This software is protected by copyright laws of the United States and
+* of foreign countries. This material may also be protected by patent laws
+* and technology transfer regulations of the United States and of foreign
+* countries. This software is furnished under a license agreement and/or a
+* nondisclosure agreement and may only be used or reproduced in accordance
+* with the terms of those agreements. Dissemination of this information to
+* any party or parties not specified in the license agreement and/or
+* nondisclosure agreement is expressly prohibited.
+*
+* 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 MAXIM INTEGRATED 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.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************
+*/
+#include "RtcBase.h"
+#include "Max31342_regs.h"
+
+#ifndef MAX31342_H_
+#define MAX31342_H_
+
+class Max31342 : public RtcBase {
+public:
+	Max31342(I2C *i2c, PinName inta_pin = NC, PinName intb_pin = NC) : RtcBase(&regmap, i2c, inta_pin, intb_pin) {}
+private:
+	static const regmap_t regmap;
+};
+
+#endif /* MAX31342_H_ */
diff -r 000000000000 -r 1efa49a69ff8 Max31342_regs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Max31342_regs.h	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * 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 MAXIM INTEGRATED 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.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#ifndef MAX31342_REGS_H_
+#define MAX31342_REGS_H_
+
+enum max31342_register_address {
+	MAX31342_REG_CONFIG_REG1_ADDR		= 0x00,
+	MAX31342_REG_CONFIG_REG2_ADDR		= 0x01,
+	MAX31342_REG_SLEEP_CONFIG_ADDR		= 0x02,
+	MAX31342_REG_TIMER_CONFIG_ADDR		= 0x03,
+	MAX31342_REG_INT_EN_REG_ADDR		= 0x04,
+	MAX31342_REG_INT_STATUS_REG_ADDR	= 0x05,
+	MAX31342_REG_SECONDS_ADDR			= 0x06,
+	MAX31342_REG_MINUTES_ADDR			= 0x07,
+	MAX31342_REG_HOURS_ADDR				= 0x08,
+	MAX31342_REG_DAY_ADDR				= 0x09,
+	MAX31342_REG_DATE_ADDR				= 0x0A,
+	MAX31342_REG_MONTH_ADDR				= 0x0B,
+	MAX31342_REG_YEAR_ADDR				= 0x0C,
+	MAX31342_REG_ALM1_SEC_ADDR			= 0x0D,
+	MAX31342_REG_ALM1_MIN_ADDR			= 0x0E,
+	MAX31342_REG_ALM1_HRS_ADDR			= 0x0F,
+	MAX31342_REG_ALM1DAY_DATE_ADDR		= 0x10,
+	MAX31342_REG_ALM1_MON_ADDR			= 0x11,
+	MAX31342_REG_ALM1_YEAR_ADDR			= 0x12,
+	MAX31342_REG_ALM2_MIN_ADDR			= 0x13,
+	MAX31342_REG_ALM2_HRS_ADDR			= 0x14,
+	MAX31342_REG_ALM2DAY_DATE_ADDR		= 0x15,
+	MAX31342_REG_TIMER_COUNT_ADDR		= 0x16,
+	MAX31342_REG_TIMER_INIT_ADDR		= 0x17,
+	MAX31342_REG_CLOCK_SYNC_REG			= 0x58,
+	MAX31342_REG_END,
+ };
+
+#endif /* MAX31342_REGS_H_ */
diff -r 000000000000 -r 1efa49a69ff8 RtcBase.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RtcBase.cpp	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,1181 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * 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 MAXIM INTEGRATED 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.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#include "RtcBase.h"
+
+#define pr_err(fmt, ...) if(1) printf(fmt " (%s:%d)\r\n", ## __VA_ARGS__, __func__, __LINE__)
+#define pr_debug(fmt, ...) if(0) printf(fmt " (%s:%d)\r\n", ## __VA_ARGS__, __func__, __LINE__)
+
+#define BCD2BIN(val) (((val) & 15) + ((val) >> 4) * 10)
+#define BIN2BCD(val) ((((val) / 10) << 4) + (val) % 10)
+
+#define POST_INTR_WORK_SIGNAL_ID			0x1
+
+RtcBase::RtcBase(const regmap_t *regmap, I2C *i2c, PinName inta_pin = NC, PinName intb_pin = NC)
+{
+	if (i2c == NULL) {
+		pr_err("i2c object is invalid!");
+		while (1);
+	}
+	i2c_handler = i2c;
+
+	this->regmap = regmap;
+
+	sw_reset_release();
+
+	rtc_start();
+
+	irq_disable_all();
+
+	post_intr_work_thread = new Thread();
+
+	post_intr_work_thread->start(Callback<void()>(this, &RtcBase::post_interrupt_work));
+
+	if (inta_pin != NC) {
+		this->inta_pin = new InterruptIn(inta_pin);
+
+		this->inta_pin->fall(Callback<void()>(this, &RtcBase::interrupt_handler));
+
+		this->inta_pin->enable_irq();
+	} else {
+		this->inta_pin = NULL;
+	}
+
+	if (intb_pin != NC) {
+		this->intb_pin = new InterruptIn(intb_pin);
+
+		this->intb_pin->fall(Callback<void()>(this, &RtcBase::interrupt_handler));
+
+		this->intb_pin->enable_irq();
+	} else {
+		this->intb_pin = NULL;
+	}
+}
+
+RtcBase::~RtcBase()
+{
+	if (post_intr_work_thread) {
+		delete post_intr_work_thread;
+	}
+
+	if (inta_pin) {
+		delete inta_pin;
+	}
+
+	if (intb_pin) {
+		delete intb_pin;
+	}
+}
+
+int RtcBase::read_register(uint8_t reg, uint8_t *value, uint8_t len)
+{
+	int ret;
+
+	if (value == NULL) {
+		pr_err("value is invalid!");
+		return -1;
+	}
+
+	ret = i2c_handler->write(MAX3134X_I2C_W, (const char *) &reg, 1, true);
+	if (ret != 0) {
+		pr_err("i2c write failed with %d!", ret);
+		return -1;
+	}
+
+	ret = i2c_handler->read(MAX3134X_I2C_R, (char *) value, len, false);
+	if (ret < 0) {
+		pr_err("i2c read failed with %d!", ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::write_register(uint8_t reg, const uint8_t *value, uint8_t len)
+{
+	int ret;
+	uint8_t *buffer;
+
+	if (value == NULL) {
+		pr_err("value is invalid!");
+		return -1;
+	}
+
+	buffer = new uint8_t[1 + len];
+	buffer[0] = reg;
+
+	memcpy(&buffer[1], value, len);
+
+	ret = i2c_handler->write(MAX3134X_I2C_W, (const char *)buffer, 1 + len);
+	if (ret != 0) {
+		pr_err("i2c write failed with %d!", ret);
+	}
+
+	delete[] buffer;
+
+	return ret;
+}
+
+int RtcBase::rtc_regs_to_time(struct tm *time, const rtc_time_regs_t *regs)
+{
+	/* tm_sec seconds [0,61] */
+	time->tm_sec = BCD2BIN(regs->seconds.bcd.value);
+
+	/* tm_min minutes [0,59] */
+	time->tm_min = BCD2BIN(regs->minutes.bcd.value);
+
+	/* tm_hour hour [0,23] */
+	time->tm_hour = BCD2BIN(regs->hours.bcd.value);
+
+	/* tm_wday day of week [0,6] (Sunday = 0) */
+	time->tm_wday = BCD2BIN(regs->day.bcd.value) - 1;
+
+	/* tm_mday day of month [1,31] */
+	time->tm_mday = BCD2BIN(regs->date.bcd.value);
+
+	/* tm_mon month of year [0,11] */
+	time->tm_mon = BCD2BIN(regs->month.bcd.value) - 1;
+
+	/* tm_year years since 2000 */
+	if (regs->month.bits.century) {
+		time->tm_year = BCD2BIN(regs->year.bcd.value) + 200;
+	} else {
+		time->tm_year = BCD2BIN(regs->year.bcd.value) + 100;
+	}
+
+	/* tm_yday day of year [0,365] */
+	time->tm_yday = 0; /* TODO */
+
+	/* tm_isdst daylight savings flag */
+	time->tm_isdst = 0; /* TODO */
+
+	return 0;
+}
+
+int RtcBase::time_to_rtc_regs(rtc_time_regs_t *regs, const struct tm *time)
+{
+	/*********************************************************
+	 * +----------+------+---------------------------+-------+
+	 * | Member   | Type | Meaning                   | Range |
+	 * +----------+------+---------------------------+-------+
+	 * | tm_sec   | int  | seconds after the minute  | 0-61* |
+	 * | tm_min   | int  | minutes after the hour    | 0-59  |
+	 * | tm_hour  | int  | hours since midnight      | 0-23  |
+	 * | tm_mday  | int  | day of the month          | 1-31  |
+	 * | tm_mon   | int  | months since January      | 0-11  |
+	 * | tm_year  | int  | years since 1900          |       |
+	 * | tm_wday  | int  | days since Sunday         | 0-6   |
+	 * | tm_yday  | int  | days since January 1      | 0-365 |
+	 * | tm_isdst | int  | Daylight Saving Time flag |       |
+	 * +----------+------+---------------------------+-------+
+	 * * tm_sec is generally 0-59. The extra range is to accommodate for leap
+	 *   seconds in certain systems.
+	 *********************************************************/
+	regs->seconds.bcd.value = BIN2BCD(time->tm_sec);
+
+	regs->minutes.bcd.value = BIN2BCD(time->tm_min);
+
+	regs->hours.bcd.value= BIN2BCD(time->tm_hour);
+
+	regs->day.bcd.value = BIN2BCD(time->tm_wday + 1);
+
+	regs->date.bcd.value = BIN2BCD(time->tm_mday);
+
+	regs->month.bcd.value = BIN2BCD(time->tm_mon + 1);
+
+	if (time->tm_year >= 200) {
+		regs->month.bits.century = 1;
+		regs->year.bcd.value = BIN2BCD(time->tm_year - 200);
+	} else if (time->tm_year >= 100) {
+		regs->month.bits.century = 0;
+		regs->year.bcd.value = BIN2BCD(time->tm_year - 100);
+	} else {
+		pr_err("Invalid set date!");
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::get_time(struct tm *time)
+{
+	rtc_time_regs_t time_regs;
+
+	if (time == NULL) {
+		pr_err("rtc_ctime is invalid!");
+		return -1;
+	}
+
+	if (read_register(regmap->seconds, (uint8_t *) &time_regs,
+			sizeof(time_regs)) < 0) {
+		pr_err("read time registers failed!");
+		return -1;
+	}
+
+	return rtc_regs_to_time(time, &time_regs);
+}
+
+int RtcBase::set_rtc_time()
+{
+	config_reg2_t reg;
+
+	/* Toggle Set_RTC bit to set RTC date */
+
+	if (read_register(regmap->config_reg2, (uint8_t *)&reg, 1) < 0) {
+		pr_err("read time registers failed!");
+		return -1;
+	}
+
+	reg.bits.set_rtc = CONFIG_REG2_SET_RTC_RTCPRGM;
+	if (write_register(regmap->config_reg2, (uint8_t *)&reg, 1) < 0) {
+		pr_err("write config2 register failed!");
+		return -1;
+	}
+
+	/* SET_RTC bit should be kept high at least 10ms */
+	ThisThread::sleep_for(10);
+
+	reg.bits.set_rtc = CONFIG_REG2_SET_RTC_RTCRUN;
+	if (write_register(regmap->config_reg2, (uint8_t *)&reg, 1) < 0) {
+		pr_err("write config2 register failed!");
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::set_time(const struct tm *time)
+{
+	rtc_time_regs_t time_regs;
+
+	if (time == NULL) {
+		pr_err("rtc_ctime is invalid!");
+		return -1;
+	}
+
+	time_to_rtc_regs(&time_regs, time);
+
+	if (write_register(regmap->seconds, (const uint8_t *) &time_regs,
+			sizeof(time_regs)) < 0) {
+		pr_err("read time registers failed!");
+		return -1;
+	}
+
+	return set_rtc_time();
+}
+
+int RtcBase::nvram_write(const uint8_t *buffer, int offset, int length)
+{
+	int totlen;
+
+	if (regmap->ram_start == REG_NOT_AVAILABLE) {
+		pr_err("Device does not have NVRAM!");
+		return -1;
+	}
+
+	totlen = regmap->ram_end - regmap->ram_start + 1;
+
+	if ((offset + length) > totlen) {
+		return -1;
+	}
+
+	if (length == 0) {
+		return 0;
+	}
+
+	if (write_register(regmap->ram_start + offset, buffer, length) < 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::nvram_read(uint8_t *buffer, int offset, int length)
+{
+	int totlen;
+
+	if (regmap->ram_start == REG_NOT_AVAILABLE) {
+		pr_err("Device does not have NVRAM!");
+		return -1;
+	}
+
+	totlen = regmap->ram_end - regmap->ram_start + 1;
+
+	if ((offset + length) > totlen) {
+		return -1;
+	}
+
+	if (length == 0) {
+		return -1;
+	}
+
+	if (read_register(regmap->ram_start + offset, buffer, length) < 0) {
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::nvram_size()
+{
+	if ((regmap->ram_start == REG_NOT_AVAILABLE) ||
+			(regmap->ram_end == REG_NOT_AVAILABLE)) {
+		return 0;
+	}
+
+	return regmap->ram_end - regmap->ram_start + 1;
+}
+
+int RtcBase::time_to_alarm_regs(alarm_regs_t &regs, const struct tm *alarm_time)
+{
+	regs.sec.bcd.value = BIN2BCD(alarm_time->tm_sec);
+	regs.min.bcd.value = BIN2BCD(alarm_time->tm_min);
+	regs.hrs.bcd.value = BIN2BCD(alarm_time->tm_hour);
+
+	if (regs.day_date.bits.dy_dt == 0) {
+		/* Date match */
+		regs.day_date.bcd_date.value = BIN2BCD(alarm_time->tm_mday);
+	} else {
+		/* Day match */
+		regs.day_date.bcd_day.value = BIN2BCD(alarm_time->tm_wday);
+	}
+	regs.mon.bcd.value = BIN2BCD(alarm_time->tm_mon);
+
+	return 0;
+}
+
+int RtcBase::alarm_regs_to_time(struct tm *alarm_time, const alarm_regs_t *regs)
+{
+	alarm_time->tm_sec = BCD2BIN(regs->sec.bcd.value);
+	alarm_time->tm_min = BCD2BIN(regs->min.bcd.value);
+	alarm_time->tm_hour = BCD2BIN(regs->hrs.bcd.value);
+
+	if (regs->day_date.bits.dy_dt == 0) { /* date */
+		alarm_time->tm_mday = BCD2BIN(regs->day_date.bcd_date.value);
+	} else { /* day */
+		alarm_time->tm_wday = BCD2BIN(regs->day_date.bcd_day.value);
+	}
+
+	if (regmap->alm1_mon != REG_NOT_AVAILABLE) {
+		alarm_time->tm_mon = BCD2BIN(regs->mon.bcd.value) - 1;
+	}
+
+	if (regmap->alm1_year != REG_NOT_AVAILABLE) {
+		alarm_time->tm_year = BCD2BIN(regs->year.bcd.value) + 100;	/* XXX no century bit */
+	}
+
+	return 0;
+}
+
+int RtcBase::set_alarm_period(alarm_no_t alarm_no, alarm_regs_t &regs, alarm_period_t period)
+{
+	regs.sec.bits.a1m1 = 1;
+	regs.min.bits.a1m2 = 1;
+	regs.hrs.bits.a1m3 = 1;
+	regs.day_date.bits.a1m4 = 1;
+	regs.mon.bits.a1m5 = 1;
+	regs.mon.bits.a1m6 = 1;
+	regs.day_date.bits.dy_dt = 1;
+
+	switch (period) {
+	case ALARM_PERIOD_ONETIME:
+		if ((alarm_no == ALARM2) || (regmap->alm1_year == REG_NOT_AVAILABLE)) { /* not supported! */
+			return -1;
+		}
+		regs.mon.bits.a1m6 = 0;
+	case ALARM_PERIOD_YEARLY:
+		if ((alarm_no == ALARM2) || (regmap->alm1_mon == REG_NOT_AVAILABLE)) { /* not supported! */
+			return -1;
+		}
+		regs.mon.bits.a1m5 = 0;
+	case ALARM_PERIOD_MONTHLY:
+		regs.day_date.bits.dy_dt = 0;
+	case ALARM_PERIOD_WEEKLY:
+		regs.day_date.bits.a1m4 = 0;
+	case ALARM_PERIOD_DAILY:
+		regs.hrs.bits.a1m3 = 0;
+	case ALARM_PERIOD_HOURLY:
+		regs.min.bits.a1m2 = 0;
+	case ALARM_PERIOD_EVERYMINUTE:
+		regs.sec.bits.a1m1 = 0;
+	case ALARM_PERIOD_EVERYSECOND:
+		if ((alarm_no == ALARM2) && (period == ALARM_PERIOD_EVERYSECOND)) {
+			return -1; /* Alarm2 does not support "once per second" alarm*/
+		}
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+int RtcBase::set_alarm_regs(alarm_no_t alarm_no, const alarm_regs_t *regs)
+{
+	uint8_t *ptr_regs = (uint8_t *)regs;
+	uint8_t off = 0;
+	uint8_t dev_ba;
+	uint8_t len = sizeof(alarm_regs_t);
+
+	if (alarm_no == ALARM1) {
+		dev_ba = regmap->alm1_sec;
+		if (regmap->alm1_mon == REG_NOT_AVAILABLE) len -= 2; /* discard mon & year registers */
+	} else {
+		dev_ba = regmap->alm2_min;
+		off = 1;	/* starts from min register */
+		len -= 3;	/* discard min, mon & sec registers */
+	}
+
+	return write_register(dev_ba, &ptr_regs[off], len);
+}
+
+int RtcBase::get_alarm_regs(alarm_no_t alarm_no, alarm_regs_t *regs)
+{
+	uint8_t *ptr_regs = (uint8_t *)regs;
+	uint8_t off = 0;
+	uint8_t dev_ba;
+	uint8_t len = sizeof(alarm_regs_t);
+
+	if (alarm_no == ALARM1) {
+		dev_ba = regmap->alm1_sec;
+		if (regmap->alm1_mon == REG_NOT_AVAILABLE) len -= 2; /* discard mon & year registers */
+	} else {
+		regs->sec.raw = 0;	/* zeroise second register for alarm2 */
+		dev_ba = regmap->alm2_min;
+		off = 1;	/* starts from min register (no sec register) */
+		len -= 2;	/* discard mon & sec registers */
+	}
+
+	return read_register(dev_ba, &ptr_regs[off], len);
+}
+
+int RtcBase::set_alarm(alarm_no_t alarm_no, const struct tm *alarm_time, alarm_period_t period)
+{
+	int ret;
+	alarm_regs_t regs;
+
+	ret = set_alarm_period(alarm_no, regs, period);
+	if (ret) {
+		return ret;
+	}
+
+	/* Convert time structure to alarm registers */
+	ret = time_to_alarm_regs(regs, alarm_time);
+	if (ret) {
+		return ret;
+	}
+
+	ret = set_alarm_regs(alarm_no, &regs);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::get_alarm(alarm_no_t alarm_no, struct tm *alarm_time, alarm_period_t *period, bool *is_enabled)
+{
+	int ret;
+	alarm_regs_t regs;
+	uint8_t reg;
+
+	ret = get_alarm_regs(alarm_no, &regs);
+	if (ret) {
+		return ret;
+	}
+
+	/* Convert alarm registers to time structure */
+	ret = alarm_regs_to_time(alarm_time, &regs);
+	if (ret) {
+		return ret;
+	}
+
+	*period = (alarm_no == ALARM1) ? ALARM_PERIOD_EVERYSECOND : ALARM_PERIOD_EVERYMINUTE;
+
+	if ((alarm_no == ALARM1) && (regs.sec.bits.a1m1 == 0)) *period = ALARM_PERIOD_EVERYMINUTE;
+	if (regs.min.bits.a1m2 == 0) *period = ALARM_PERIOD_HOURLY;
+	if (regs.hrs.bits.a1m3 == 0) *period = ALARM_PERIOD_DAILY;
+	if (regs.day_date.bits.a1m4 == 0) *period = ALARM_PERIOD_WEEKLY;
+	if (regs.day_date.bits.dy_dt == 0) *period = ALARM_PERIOD_MONTHLY;
+	if ((alarm_no == ALARM1) && (regmap->alm1_mon != REG_NOT_AVAILABLE) && (regs.mon.bits.a1m5 == 0)) *period = ALARM_PERIOD_YEARLY;
+	if ((alarm_no == ALARM1) && (regmap->alm1_mon != REG_NOT_AVAILABLE) && (regs.mon.bits.a1m6 == 0)) *period = ALARM_PERIOD_ONETIME;
+
+	ret = read_register(regmap->int_en_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	if (alarm_no == ALARM1) {
+		*is_enabled = (reg & (1 << INTR_ID_ALARM1)) != 0;
+	} else {
+		*is_enabled = (reg & (1 << INTR_ID_ALARM2)) != 0;
+	}
+
+	return 0;
+}
+
+int RtcBase::set_power_mgmt_mode(power_mgmt_mode_t mode)
+{
+	int ret;
+	pwr_mgmt_reg_t reg;
+
+	if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) {
+		pr_err("Device does not support power mgmt!");
+		return -1;
+	}
+
+	ret = read_register(regmap->pwr_mgmt_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.d_mode = mode;
+
+	ret = write_register(regmap->pwr_mgmt_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::comparator_threshold_level(comp_thresh_t th)
+{
+	int ret;
+	config_reg2_t reg;
+
+	if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) {
+		pr_err("Device does not support analog comparator!");
+		return -1;
+	}
+
+	ret = read_register(regmap->config_reg2, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.bref = th;
+
+	ret = write_register(regmap->config_reg2, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::supply_select(power_mgmt_supply_t supply)
+{
+	int ret;
+	pwr_mgmt_reg_t reg;
+
+	if (regmap->pwr_mgmt_reg == REG_NOT_AVAILABLE) {
+		pr_err("Device does not support power mgmt!");
+		return -1;
+	}
+
+	ret = read_register(regmap->pwr_mgmt_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	switch (supply) {
+	case POW_MGMT_SUPPLY_SEL_VCC:
+		reg.bits.d_man_sel = 1;
+		reg.bits.d_vback_sel = 0;
+		break;
+	case POW_MGMT_SUPPLY_SEL_AIN:
+		reg.bits.d_man_sel = 1;
+		reg.bits.d_vback_sel = 1;
+		break;
+	case POW_MGMT_SUPPLY_SEL_AUTO:
+	default:
+		reg.bits.d_man_sel = 0;
+		break;
+	}
+
+	ret = write_register(regmap->pwr_mgmt_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::trickle_charger_enable(trickle_charger_ohm_t res, bool diode)
+{
+	int ret;
+	struct {
+		unsigned char ohm      : 2;
+		unsigned char diode    : 1;
+		unsigned char schottky : 1;
+		unsigned char          : 4;
+	} reg;
+
+	if (regmap->trickle_reg == REG_NOT_AVAILABLE) { /* trickle charger not supported! */
+		pr_err("Device does not support trickle charger!");
+		return -1;
+	}
+
+	reg.ohm = res;
+
+	reg.diode = (diode) ? 1 : 0;
+
+	reg.schottky = 1; /* always enabled */
+
+	ret = write_register(regmap->trickle_reg, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::trickle_charger_disable()
+{
+	int ret;
+	uint8_t reg;
+
+	if (regmap->trickle_reg == REG_NOT_AVAILABLE) { /* trickle charger not supported! */
+		pr_err("Device does not support trickle charger!");
+		return -1;
+	}
+
+	reg = 0;
+
+	ret = write_register(regmap->trickle_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+
+int RtcBase::set_output_square_wave_frequency(square_wave_out_freq_t freq)
+{
+	int ret;
+	config_reg1_t reg;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.rs = freq;
+
+	ret = write_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::set_clock_sync_delay(sync_delay_t delay)
+{
+	int ret;
+	clock_sync_reg_t reg;
+
+	ret = read_register(regmap->clock_sync_delay, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.sync_delay = delay;
+
+	ret = write_register(regmap->clock_sync_delay, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::set_clkin_frequency(clkin_freq_t freq)
+{
+	int ret;
+	config_reg1_t reg;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.clksel = freq;
+
+	ret = write_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	if (freq == CLKIN_FREQ_1HZ) {
+		ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_1SEC);
+	} else {
+		ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_100MS);
+	}
+
+	return ret;
+}
+
+int RtcBase::configure_intb_clkout_pin(config_intb_clkout_pin_t sel)
+{
+	int ret;
+	config_reg1_t reg;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.intcn = (sel == CONFIGURE_PIN_AS_INTB) ? 1 : 0;
+
+	ret = write_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::configure_inta_clkin_pin(config_inta_clkin_pin_t sel)
+{
+	int ret;
+	config_reg1_t reg;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.eclk = (sel == CONFIGURE_PIN_AS_CLKIN) ? 1 : 0;
+
+	ret = write_register(regmap->config_reg1, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	if (sel == CONFIGURE_PIN_AS_CLKIN) {
+		/* Default synchronization delay for external clock mode */
+		ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_1SEC);
+	} else {
+		/* Synchronization delay for internal oscillator mode */
+		ret = set_clock_sync_delay(SYNC_DLY_LESS_THAN_20MS);
+	}
+
+	return ret;
+}
+
+int RtcBase::timer_init(uint8_t value, bool repeat, timer_freq_t freq)
+{
+	int ret;
+	timer_config_t reg_cfg;
+
+	ret = read_register(regmap->timer_config, (uint8_t *)&reg_cfg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg_cfg.bits.te = 0; /* timer is reset */
+	reg_cfg.bits.tpause = 1; /* timer is paused */
+	reg_cfg.bits.trpt = repeat ? 1 : 0;	/* Timer repeat mode */
+	reg_cfg.bits.tfs = freq;	/* Timer frequency */
+
+	ret = write_register(regmap->timer_config, (uint8_t *)&reg_cfg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	ret = write_register(regmap->timer_init, (uint8_t *)&value, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+uint8_t RtcBase::timer_get()
+{
+	int ret;
+	uint8_t reg;
+
+	ret = read_register(regmap->timer_count, (uint8_t *)&reg, 1);
+	if (ret) {
+		return (uint8_t) - 1;
+	}
+
+	return reg;
+}
+
+int RtcBase::timer_start()
+{
+	int ret;
+	timer_config_t reg;
+
+	ret = read_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.te = 1;
+	reg.bits.tpause = 0;
+
+	ret = write_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::timer_pause()
+{
+	int ret;
+	timer_config_t reg;
+
+	ret = read_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.te = 1;
+	reg.bits.tpause = 1;
+
+	ret = write_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::timer_continue()
+{
+	int ret;
+	timer_config_t reg;
+
+	ret = read_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.te = 1;
+	reg.bits.tpause = 0;
+
+	ret = write_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::timer_stop()
+{
+	int ret;
+	timer_config_t reg;
+
+	ret = read_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.te = 0;
+	reg.bits.tpause = 1;
+
+	ret = write_register(regmap->timer_config, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::data_retention_mode_config(int state)
+{
+	int ret;
+	config_reg1_t cfg1;
+	config_reg2_t cfg2;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *)&cfg1, 1);
+	if (ret) {
+		return ret;
+	}
+
+	ret = read_register(regmap->config_reg2, (uint8_t *)&cfg2, 1);
+	if (ret) {
+		return ret;
+	}
+
+	if (state) {
+		cfg1.bits.osconz = 1;
+		cfg2.bits.data_reten = 1;
+	} else {
+		cfg1.bits.osconz = 0;
+		cfg2.bits.data_reten = 0;
+	}
+
+	ret = write_register(regmap->config_reg1, (uint8_t *)&cfg1, 1);
+	if (ret) {
+		return ret;
+	}
+
+	ret = write_register(regmap->config_reg2, (uint8_t *)&cfg2, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::data_retention_mode_enter()
+{
+	return data_retention_mode_config(1);
+}
+
+int RtcBase::data_retention_mode_exit()
+{
+	return data_retention_mode_config(0);
+}
+
+int RtcBase::i2c_timeout_config(int enable)
+{
+	int ret;
+	config_reg2_t reg;
+
+	ret = read_register(regmap->config_reg2, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg.bits.i2c_timeout = (enable) ? 1 : 0;
+
+	ret = write_register(regmap->config_reg2, (uint8_t *)&reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::i2c_timeout_enable()
+{
+	return i2c_timeout_config(1);
+}
+
+int RtcBase::i2c_timeout_disable()
+{
+	return i2c_timeout_config(0);
+}
+
+int RtcBase::irq_enable(intr_id_t id)
+{
+	int ret;
+	uint8_t reg;
+
+	ret = read_register(regmap->int_en_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg |= (1 << id);
+
+	ret = write_register(regmap->int_en_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::irq_disable(intr_id_t id)
+{
+	int ret;
+	uint8_t reg;
+
+	ret = read_register(regmap->int_en_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	reg &= ~(1 << id);
+
+	ret = write_register(regmap->int_en_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::irq_disable_all()
+{
+	int ret;
+	uint8_t reg = 0;
+
+	ret = write_register(regmap->int_en_reg, &reg, 1);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+void RtcBase::set_intr_handler(intr_id_t id, interrupt_handler_function func, void *cb)
+{
+	interrupt_handler_list[id].func = func;
+	interrupt_handler_list[id].cb = cb;
+}
+
+void RtcBase::post_interrupt_work()
+{
+	int ret;
+	uint8_t reg, inten, mask;
+
+
+	while (true) {
+		Thread::signal_wait(POST_INTR_WORK_SIGNAL_ID);
+
+		ret = read_register(regmap->int_status_reg, &reg, 1);
+		if (ret) {
+			pr_err("Read interrupt status register failed!");
+		}
+
+		ret = read_register(regmap->int_en_reg, &inten, 1);
+		if (ret) {
+			pr_err("Read interrupt enable register failed!");
+		}
+
+		for (int i = 0; i < INTR_ID_END; i++) {
+			mask = (1 << i);
+			if ((reg & mask) && (inten & mask)) {
+				if (interrupt_handler_list[i].func != NULL) {
+					interrupt_handler_list[i].func(interrupt_handler_list[i].cb);
+				}
+			}
+		}
+	}
+}
+
+void RtcBase::interrupt_handler()
+{
+	post_intr_work_thread->signal_set(POST_INTR_WORK_SIGNAL_ID);
+}
+
+int RtcBase::sw_reset_assert()
+{
+	int ret;
+	config_reg1_t config_reg1;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	config_reg1.bits.swrstn = 0;	/* Put device in reset state */
+
+	ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::sw_reset_release()
+{
+	int ret;
+	config_reg1_t config_reg1;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	config_reg1.bits.swrstn = 1;	/* Remove device from reset state */
+
+	ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::rtc_start()
+{
+	int ret;
+	config_reg1_t config_reg1;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	config_reg1.bits.osconz = 0;	/* Enable the oscillator */
+
+	ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	return 0;
+}
+
+int RtcBase::rtc_stop()
+{
+	int ret;
+	config_reg1_t config_reg1;
+
+	ret = read_register(regmap->config_reg1, (uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	config_reg1.bits.osconz = 1;	/* Disable the oscillator */
+
+	ret = write_register(regmap->config_reg1, (const uint8_t *) &config_reg1, 1);
+	if (ret < 0) {
+		pr_err("read_register failed!");
+		return ret;
+	}
+
+	return 0;
+}
diff -r 000000000000 -r 1efa49a69ff8 RtcBase.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RtcBase.h	Wed Apr 10 17:28:15 2019 +0300
@@ -0,0 +1,866 @@
+/*******************************************************************************
+ * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * 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 MAXIM INTEGRATED 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.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
+
+#ifndef RTCBASE_H_
+#define RTCBASE_H_
+
+#include "mbed.h"
+#include <ctime>
+
+
+/**
+ * @brief	RTC base driver class for Maxim Max3134x RTC series.
+ */
+class RtcBase
+{
+public:
+	/**
+	* @brief	Mode of the comparator
+	*/
+	typedef enum {
+		POW_MGMT_MODE_COMPARATOR,		/**< Comparator */
+		POW_MGMT_MODE_POWER_MANAGEMENT,	/**< Power Management / Trickle Charger Mode */
+	} power_mgmt_mode_t;
+
+	/**
+	* @brief	Analog comparator threshold voltage
+	*/
+	typedef enum {
+		COMP_THRESH_1V4,	/**< 1.4V */
+		COMP_THRESH_1V6,	/**< 1.6V */
+		COMP_THRESH_1V8,	/**< 1.8V */
+		COMP_THRESH_2V0,	/**< 2.0V */
+	} comp_thresh_t;
+
+	/**
+	* @brief	Supply voltage select.
+	*/
+	typedef enum {
+		POW_MGMT_SUPPLY_SEL_AUTO,	/**< Circuit decides whether to use VCC or VBACKUP */
+		POW_MGMT_SUPPLY_SEL_VCC,	/**< Use VCC as supply */
+		POW_MGMT_SUPPLY_SEL_AIN,	/**< Use AIN as supply */
+	} power_mgmt_supply_t;
+
+	/**
+	* @brief	Selection of charging path's resistor value
+	*/
+	typedef enum {
+		TRICKLE_CHARGER_3K5,	/**< 3500 Ohm */
+		TRICKLE_CHARGER_3K5_2,	/**< 3500 Ohm */
+		TRICKLE_CHARGER_7K,		/**< 7000 Ohm */
+		TRICKLE_CHARGER_13K,	/**< 13000 Ohm */
+	} trickle_charger_ohm_t;
+
+	/**
+	* @brief	Timer frequency selection
+	*/
+	typedef enum {
+		TIMER_FREQ_1024HZ,	/**< 1024Hz */
+		TIMER_FREQ_256HZ,	/**< 256Hz */
+		TIMER_FREQ_64HZ,	/**< 64Hz */
+		TIMER_FREQ_16HZ,	/**< 16Hz */
+	} timer_freq_t;
+
+	/**
+	* @brief	CLKIN frequency selection
+	*/
+	typedef enum {
+		CLKIN_FREQ_1HZ,		/**< 1Hz*/
+		CLKIN_FREQ_50HZ,	/**< 50Hz */
+		CLKIN_FREQ_60HZ,	/**< 60Hz */
+		CLKIN_FREQ_32HZ768,	/**< 32.768Hz */
+	} clkin_freq_t;
+
+	/**
+	* @brief	Square wave output frequency selection on CLKOUT pin
+	*/
+	typedef enum {
+		SQUARE_WAVE_OUT_FREQ_1HZ,		/**< 1Hz */
+		SQUARE_WAVE_OUT_FREQ_4096HZ,	/**< 4.098kHz */
+		SQUARE_WAVE_OUT_FREQ_8192HZ,	/**< 8.192kHz */
+		SQUARE_WAVE_OUT_FREQ_32768HZ,	/**< 32.768kHz */
+	} square_wave_out_freq_t;
+
+	/**
+	* @brief	Selection of interrupt ids
+	*/
+	typedef enum {
+		INTR_ID_ALARM1,		/**< Alarm1 flag */
+		INTR_ID_ALARM2,		/**< Alarm2 flag */
+		INTR_ID_TIMER,		/**< Timer interrupt flag */
+		INTR_ID_RESERVED,
+		INTR_ID_EXTERNAL,	/**< External interrupt flag for DIN1 */
+		INTR_ID_ANALOG,		/**< Analog Interrupt flag / Power fail flag  */
+		INTR_ID_OSF,		/**< Oscillator stop flag */
+		INTR_ID_LOS,		/**< Loss of signal */
+		INTR_ID_END,
+	} intr_id_t;
+
+
+	/**
+	* @brief	Alarm number selection
+	*/
+	typedef enum {
+		ALARM1,	/**< Alarm number 1 */
+		ALARM2,	/**< Alarm number 2 */
+	} alarm_no_t;
+
+	/**
+	* @brief	Alarm periodicity selection
+	*/
+	typedef enum {
+		ALARM_PERIOD_EVERYSECOND,	/**< Once per second */
+		ALARM_PERIOD_EVERYMINUTE,	/**< Second match / Once per minute */
+		ALARM_PERIOD_HOURLY,		/**< Second and Minute match */
+		ALARM_PERIOD_DAILY,			/**< Hour, Minute and Second match*/
+		ALARM_PERIOD_WEEKLY,		/**< Day and Time match */
+		ALARM_PERIOD_MONTHLY,		/**< Date and Time match */
+		ALARM_PERIOD_YEARLY,		/**< Month, Date and Time match (Max31342 only) */
+		ALARM_PERIOD_ONETIME,		/**< Year, Month, Date and Time match (Max31342 only) */
+	} alarm_period_t;
+
+	/**
+	* @brief	Selection of INTA/CLKIN pin function
+	*/
+	typedef enum {
+		CONFIGURE_PIN_AS_INTA,	/**< Configure pin as interrupt out */
+		CONFIGURE_PIN_AS_CLKIN,	/**< Configure pin as external clock in  */
+	} config_inta_clkin_pin_t;
+
+	/**
+	* @brief	Selection of INTB/CLKOUT pin function
+	*/
+	typedef enum {
+		CONFIGURE_PIN_AS_CLKOUT,	/**< Output is square wave */
+		CONFIGURE_PIN_AS_INTB,		/**< Output is interrupt */
+	} config_intb_clkout_pin_t;
+
+	/**
+	 * @brief	Selection of sync delay
+	 */
+	typedef enum {
+		SYNC_DLY_LESS_THAN_1SEC = 0,	/**<  Sync delay less than 1 second, recommended for external 1Hz clock */
+		SYNC_DLY_LESS_THAN_100MS,		/**<  Sync delay less than 100 msec, recommended for external 50Hz/60Hz/32KHz clock */
+		SYNC_DLY_LESS_THAN_20MS,		/**<  Sync delay less than 20 msec, recommended for internal clock */
+	} sync_delay_t;
+
+	typedef enum {
+		TTS_INTERNAL_1SEC = 0,
+		TTS_INTERNAL_2SEC,
+		TTS_INTERNAL_4SEC,
+		TTS_INTERNAL_16SEC,
+		TTS_INTERNAL_32SEC,
+		TTS_INTERNAL_64SEC,
+		TTS_INTERNAL_128SEC,
+	} ttsint_t;
+
+	/**
+	* @brief	Function pointer type to interrupt handler function
+	*/
+	typedef void (*interrupt_handler_function)(void *);
+
+	/**
+	* @brief		Read from a register.
+	*
+	* @param[in]	reg Address of a register to be read.
+	* @param[out]	value Pointer to save result value.
+	* @param[in]	len Size of result to be read.
+	*
+	* @returns		0 on success, negative error code on failure.
+	*/
+	int read_register(uint8_t reg, uint8_t *value, uint8_t len);
+
+	/**
+	* @brief		Write to a register.
+	*
+	* @param[in]	reg Address of a register to be written.
+	* @param[out]	value Pointer of value to be written to register.
+	* @param[in]	len Size of result to be written.
+	*
+	* @returns		0 on success, negative error code on failure.
+	*/
+	int write_register(uint8_t reg, const uint8_t *value, uint8_t len);
+
+	/**
+	* @brief		Read time info from RTC.
+	*
+	* @param[out]	rtc_time Time info from RTC.
+	*
+	* @returns		0 on success, negative error code on failure.
+	*/
+	int get_time(struct tm *rtc_ctime);
+
+	/**
+	* @brief		Set time info to RTC.
+	*
+	* @param[in]	rtc_time Time info to be written to RTC.
+	*
+	* @returns		0 on success, negative error code on failure.
+	*/
+	int set_time(const struct tm *rtc_ctime);
+
+	/**
+	* @brief		Non-volatile memory write
+	*
+	* @param[out]	buffer Pointer to the data to be written
+	* @param[in]	offset Offset of location in NVRAM
+	* @param[in]	length Number of bytes to write
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int nvram_write(const uint8_t *buffer, int offset, int length);
+
+	/**
+	* @brief		Non-volatile memory read
+	*
+	* @param[in]	buffer Buffer to read in to
+	* @param[in]	offset Offset of location in NVRAM
+	* @param[in]	length Number of bytes to read
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int nvram_read(uint8_t *buffer, int offset, int length);
+
+	/**
+	* @brief		NVRAM size of the part
+	*
+	* @return		0 if part does not have a NVRAM, otherwise returns size
+	*/
+	int nvram_size();
+
+	/**
+	* @brief		Set an alarm condition
+	*
+	* @param[in]	alarm_no Alarm number, ALARM1 or ALARM2
+	* @param[in]	alarm_time Pointer to alarm time to be set
+	* @param[in]	period Alarm periodicity, one of ALARM_PERIOD_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int set_alarm(alarm_no_t alarm_no, const struct tm *alarm_time, alarm_period_t period);
+
+	/**
+	* @brief		Get alarm data & time
+	*
+	* @param[in]	alarm_no Alarm number, ALARM1 or ALARM2
+	* @param[out]	alarm_time Pointer to alarm time to be filled in
+	* @param[out]	period Pointer to the period of alarm, one of ALARM_PERIOD_*
+	* @param[out]	is_enabled Pointer to the state of alarm
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int get_alarm(alarm_no_t alarm_no, struct tm *alarm_time, alarm_period_t *period, bool *is_enabled);
+
+	/**
+	* @brief		Select power management mode of operation
+	*
+	* @param[in]	mode Mode selection, one of COMP_MODE_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int set_power_mgmt_mode(power_mgmt_mode_t mode);
+
+	/**
+	* @brief		Set comparator threshold
+	*
+	* @param[in]	th Set Analog Comparator Threshold level, one of COMP_THRESH_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int comparator_threshold_level(comp_thresh_t th);
+
+	/**
+	* @brief		Select device power source
+	*
+	* @param[in]	supply Supply selection, one of POW_MGMT_SUPPLY_SEL_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int supply_select(power_mgmt_supply_t supply);
+
+	/**
+	* @brief		Configure trickle charger charging path, also enable it
+	*
+	* @param[in]	res Value of resister
+	* @param[in]	diode Enable diode
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int trickle_charger_enable(trickle_charger_ohm_t res, bool diode);
+
+	/**
+	* @brief		Disable trickle charger
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int trickle_charger_disable();
+
+	/**
+	* @brief		Select square wave output frequency selection
+	*
+	* @param[in]	freq Clock frequency, one of CLKOUT_FREQ_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int set_output_square_wave_frequency(square_wave_out_freq_t freq);
+
+	/**
+	* @brief		Select external clock input frequency
+	*
+	* @param[in]	freq Clock frequency, one of CLKIN_FREQ_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int set_clkin_frequency(clkin_freq_t freq);
+
+	/**
+	* @brief		Select direction of INTB/CLKOUT pin
+	*
+	* @param[in]	sel Pin function, one of CONFIGURE_PIN_B3_AS_INTB or CONFIGURE_PIN_B3_AS_CLKOUT
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int configure_intb_clkout_pin(config_intb_clkout_pin_t sel);
+
+	/**
+	* @brief		Select direction of INTA/CLKIN pin
+	*
+	* @param[in]	sel Pin function, one of CONFIGURE_PIN_B3_AS_INTA or CONFIGURE_PIN_B3_AS_CLKIN
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int configure_inta_clkin_pin(config_inta_clkin_pin_t sel);
+
+	/**
+	* @brief		Initialize timer
+	*
+	* @param[in]	value Timer initial value
+	* @param[in]	repeat Timer repeat mode enable/disable
+	* @param[in]	freq Timer frequency, one of TIMER_FREQ_*
+	* @param[in]	mode Timer mode, 0 or 1
+	*
+	* @return		0 on success, error code on failure
+	*
+	* @note			\p mode controls the countdown timer interrupt function
+	* along with \p repeat.
+	* 	Pulse interrupt when \p mode = 0, irrespective of \p repeat (true or false)
+	* 	Pulse interrupt when \p mode = 1 and \p repeat = true
+	* 	Level interrupt when \p mode = 1 and \p repeat = false
+	*/
+	int timer_init(uint8_t value, bool repeat, timer_freq_t freq);
+
+	/**
+	* @brief	Read timer value
+	*
+	* @return	0 on success, error code on failure
+	*/
+	uint8_t timer_get();
+
+	/**
+	* @brief	Enable timer
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int timer_start();
+
+	/**
+	* @brief	Pause timer, timer value is preserved
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int timer_pause();
+
+	/**
+	* @brief	Start timer from the paused value
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int timer_continue();
+
+	/**
+	* @brief	Disable timer
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int timer_stop();
+
+	/**
+	* @brief	Put device into data retention mode
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int data_retention_mode_enter();
+
+	/**
+	* @brief	Remove device from data retention mode
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int data_retention_mode_exit();
+
+	/**
+	* @brief	Enable I2C bus timeout mechanism
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int i2c_timeout_enable();
+
+	/**
+	* @brief	Disable I2C bus timeout mechanism
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int i2c_timeout_disable();
+
+	/**
+	* @brief		Enable interrupt
+	*
+	* @param[in]	id Interrupt id, one of INTR_ID_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int irq_enable(intr_id_t id);
+
+	/**
+	* @brief		Disable interrupt
+	*
+	* @param[in]	id Interrupt id, one of INTR_ID_*
+	*
+	* @return		0 on success, error code on failure
+	*/
+	int irq_disable(intr_id_t id);
+
+	/**
+	* @brief	Disable all interrupts
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int irq_disable_all();
+
+	/**
+	* @brief		Set interrupt handler for a specific interrupt id
+	*
+	* @param[in]	id Interrupt id, one of INTR_ID_*
+	* @param[in]	func Interrupt handler function
+	* @param[in]	cb Interrupt handler data
+	*/
+	void set_intr_handler(intr_id_t id, interrupt_handler_function func, void *cb);
+
+	/**
+	* @brief	Put device into reset state
+	*
+	* @return 	0 on success, error code on failure
+	*/
+	int sw_reset_assert();
+
+	/**
+	* @brief	Release device from state state
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int sw_reset_release();
+
+	/**
+	* @brief	Enable the RTC oscillator
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int rtc_start();
+
+	/**
+	* @brief	Disable the RTC oscillator
+	*
+	* @return	0 on success, error code on failure
+	*/
+	int rtc_stop();
+
+	/**
+	* @brief	Base class destructor.
+	*/
+	~RtcBase();
+
+protected:
+	typedef struct {
+		uint8_t config_reg1;
+		uint8_t config_reg2;
+		uint8_t int_ploarity_config;
+		uint8_t timer_config;
+		uint8_t int_en_reg;
+		uint8_t int_status_reg;
+		uint8_t seconds;
+		uint8_t minutes;
+		uint8_t hours;
+		uint8_t day;
+		uint8_t date;
+		uint8_t month;
+		uint8_t year;
+		uint8_t alm1_sec;
+		uint8_t alm1_min;
+		uint8_t alm1_hrs;
+		uint8_t alm1day_date;
+		uint8_t alm1_mon;
+		uint8_t alm1_year;
+		uint8_t alm2_min;
+		uint8_t alm2_hrs;
+		uint8_t alm2day_date;
+		uint8_t timer_count;
+		uint8_t timer_init;
+		uint8_t ram_start;
+		uint8_t ram_end;
+		uint8_t pwr_mgmt_reg;
+		uint8_t trickle_reg;
+		uint8_t clock_sync_delay;
+		uint8_t temp_msb;
+		uint8_t temp_lsb;
+		uint8_t ts_config;
+	} regmap_t;
+
+	typedef struct {
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char seconds : 4;	/**< RTC seconds value. */
+				unsigned char sec_10  : 3;	/**< RTC seconds in multiples of 10 */
+				unsigned char         : 1;
+			} bits;
+			struct {
+				unsigned char value   : 7;
+				unsigned char         : 1;
+			} bcd;
+		} seconds;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char minutes : 4;	/**< RTC minutes value */
+				unsigned char min_10  : 3;	/**< RTC minutes in multiples of 10 */
+				unsigned char         : 1;
+			} bits;
+			struct {
+				unsigned char value   : 7;
+				unsigned char         : 1;
+			} bcd;
+		} minutes;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char hour       : 4;	/**< RTC hours value */
+				unsigned char hr_10      : 2;	/**< RTC hours in multiples of 10 */
+				unsigned char            : 2;
+			} bits;
+			struct {
+				unsigned char value      : 6;
+				unsigned char            : 2;
+			} bcd;
+		} hours;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char day : 3;	/**< RTC days */
+				unsigned char     : 5;
+			} bits;
+			struct {
+				unsigned char value : 3;
+				unsigned char       : 5;
+			} bcd;
+		} day;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char date    : 4;	/**< RTC date */
+				unsigned char date_10 : 2;	/**< RTC date in multiples of 10 */
+				unsigned char         : 2;
+			} bits;
+			struct {
+				unsigned char value   : 6;
+				unsigned char         : 2;
+			} bcd;
+		} date;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char month    : 4;	/**< RTC months */
+				unsigned char month_10 : 1;	/**< RTC month in multiples of 10 */
+				unsigned char          : 2;
+				unsigned char century  : 1;	/**< Century bit */
+			} bits;
+			struct {
+				unsigned char value   : 5;
+				unsigned char         : 3;
+			} bcd;
+		} month;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char year    : 4;	/**< RTC years */
+				unsigned char year_10 : 4;	/**< RTC year multiples of 10 */
+			} bits;
+			struct {
+				unsigned char value   : 8;
+			} bcd;
+		} year;
+	} rtc_time_regs_t;
+
+	typedef struct {
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char seconds : 4;	/**< Alarm1 seconds */
+				unsigned char sec_10  : 3;	/**< Alarm1 seconds in multiples of 10 */
+				unsigned char a1m1    : 1;	/**< Alarm1 mask bit for minutes */
+			} bits;
+			struct {
+				unsigned char value   : 7;
+				unsigned char         : 1;
+			} bcd;
+		} sec;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char minutes : 4;	/**< Alarm1 minutes */
+				unsigned char min_10  : 3;	/**< Alarm1 minutes in multiples of 10 */
+				unsigned char a1m2    : 1;	/**< Alarm1 mask bit for minutes */
+			} bits;
+			struct {
+				unsigned char value   : 7;
+				unsigned char         : 1;
+			} bcd;
+		} min;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char hour       : 4;	/**< Alarm1 hours */
+				unsigned char hr_10      : 2;	/**< Alarm1 hours in multiples of 10 */
+				unsigned char            : 1;
+				unsigned char a1m3       : 1;	/**< Alarm1 mask bit for hours */
+			} bits;
+			struct {
+				unsigned char value      : 6;
+				unsigned char            : 2;
+			} bcd;
+		} hrs;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char day_date : 4;	/**< Alarm1 day/date */
+				unsigned char date_10  : 2;	/**< Alarm1 date in multiples of 10 */
+				unsigned char dy_dt    : 1;
+				unsigned char a1m4     : 1;	/**< Alarm1 mask bit for day/date */
+			} bits;
+			struct {
+				unsigned char value   : 3;
+				unsigned char         : 5;
+			} bcd_day;
+			struct {
+				unsigned char value   : 6;
+				unsigned char         : 2;
+			} bcd_date;
+		} day_date;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char month    : 4;	/**< Alarm1 months */
+				unsigned char month_10 : 1;	/**< Alarm1 months in multiples of 10 */
+				unsigned char          : 1;
+				unsigned char a1m6     : 1;	/**< Alarm1 mask bit for year */
+				unsigned char a1m5     : 1;	/**< Alarm1 mask bit for month */
+			} bits;
+			struct {
+				unsigned char value   : 5;
+				unsigned char         : 3;
+			} bcd;
+		} mon;
+
+		union {
+			unsigned char raw;
+			struct {
+				unsigned char year    : 4;	/* Alarm1 years */
+				unsigned char year_10 : 4;	/* Alarm1 multiples of 10 */
+			} bits;
+			struct {
+				unsigned char value   : 8;
+			} bcd;
+		} year;
+	} alarm_regs_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char swrstn : 1;	/**< Software reset */
+			unsigned char rs     : 2;	/**< Square wave output frequency selection on CLKOUT pin */
+			unsigned char osconz : 1;	/**< Oscillator is on when set to 0. Oscillator is off when set to 1. */
+			unsigned char clksel : 2;	/**< Selects the CLKIN frequency */
+			unsigned char intcn  : 1;	/**< Interrupt control bit. Selects the direction of INTB/CLKOUT */
+			unsigned char eclk   : 1;	/**< Enable external clock input */
+		} bits;
+	} config_reg1_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char             : 1;
+			unsigned char set_rtc     : 1;	/**< Set RTC */
+			unsigned char rd_rtc      : 1;	/**< Read RTC. */
+			unsigned char i2c_timeout : 1;	/**< I2C timeout Enable */
+			unsigned char bref        : 2;	/**< BREF sets the analog comparator threshold voltage. */
+			unsigned char data_reten  : 1;	/**< Sets the circuit into data retention mode. */
+			unsigned char             : 1;
+		} bits;
+	} config_reg2_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char tfs    : 2;	/**< Timer frequency selection */
+			unsigned char trpt   : 1;	/**< Timer repeat mode. It controls the timer interrupt function along with TM. */
+			unsigned char        : 1;
+			unsigned char te     : 1;	/**< Timer enable */
+			unsigned char tpause : 1;	/**< Timer Pause.*/
+			unsigned char        : 2;
+		} bits;
+	} timer_config_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char d_mode      : 2;	/**< Sets the mode of the comparator to one of the two following: comparator mode, and power management mode/trickle charger mode. */
+			unsigned char d_man_sel   : 1;	/**< Default low. When this bit is low, input control block decides which supply to use. When this bit is high, user can manually select whether to use V<sub>CC</sub> or VBACKUP as supply. */
+			unsigned char d_vback_sel : 1;	/**< : Default low. When this bit is low, and D_MANUAL_SEL is high, V<sub>CC</sub> is switched to supply. When this bit is high, and D_MANUAL_SEL is high, V<sub>BACKUP</sub> is switched to supply. */
+			unsigned char             : 4;
+		} bits;
+	} pwr_mgmt_reg_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char sync_delay : 2; /* Sync delay to take for the internal countdown chain to reset after the rising edge of Set_RTC */
+			unsigned char            : 6;
+		} bits;
+	} clock_sync_reg_t;
+
+	typedef union {
+		unsigned char raw;
+		struct {
+			unsigned char automode    : 1;	/**< Automatic mode of temperature measurement. This mode is valid only when ONESHOTMODE=0. */
+			unsigned char oneshotmode : 1;	/**< One-shot user requested temp measurement in real-time. AUTOMODE must be 0 in one-shot measurement mode. */
+			unsigned char ttint       : 3;	/**< Set temp measurement interval to specified time for auto mode */
+			unsigned char             : 3;
+		} bits;
+	} ts_config_t;
+
+	static const uint8_t REG_NOT_AVAILABLE = 0xFF;
+
+	/**
+	* @brief	Base class constructor.
+	*
+	* @param[in]	regmap Pointer to device register mappings.
+	* @param[in]	i2c Pointer to I2C bus object for this device.
+	* @param[in]	inta_pin MCU's pin number that device's INTA pin connected
+	* @param[in]	intb_pin MCU's pin number that device's INTB pin connected
+	*/
+	RtcBase(const regmap_t *regmap, I2C *i2c, PinName inta_pin, PinName intb_pin);
+
+private:
+	/* PRIVATE TYPE DECLARATIONS */
+
+	/* PRIVATE VARIABLE DECLARATIONS */
+	I2C *i2c_handler;
+	InterruptIn *inta_pin;
+	InterruptIn *intb_pin;
+	const regmap_t *regmap;
+
+	/* PRIVATE CONSTANT VARIABLE DECLARATIONS */
+	static const uint8_t I2C_WRITE = 0;
+	static const uint8_t I2C_READ = 1;
+	static const uint8_t MAX3134X_I2C_ADDRESS = 0x69;
+	static const uint8_t MAX3134X_I2C_W = ((MAX3134X_I2C_ADDRESS << 1) | I2C_WRITE);
+	static const uint8_t MAX3134X_I2C_R = ((MAX3134X_I2C_ADDRESS << 1) | I2C_READ);
+
+	enum config_reg2_set_rtc {
+		CONFIG_REG2_SET_RTC_RTCRUN = 0,	/**< Setting this bit to zero doesn't allow to write into the RTC */
+		CONFIG_REG2_SET_RTC_RTCPRGM,	/**< This bit must be set to one, before writing into the RTC. i.e to set the initial time for the RTC this bit must be high. */
+	};
+
+	/* PRIVATE FUNCTION DECLARATIONS */
+	void interrupt_handler();
+
+	void (RtcBase::*funcptr)(void);
+
+	void post_interrupt_work();
+
+	Thread *post_intr_work_thread;
+
+	struct handler {
+		void (*func)(void *);
+		void *cb;
+	};
+
+	handler interrupt_handler_list[INTR_ID_END];
+
+	int tm_hour_to_rtc_hr12(int hours, bool *is_am);
+
+	int rtc_hr12_to_tm_hour(int hours, bool is_am);
+
+	int rtc_regs_to_time(struct tm *time, const rtc_time_regs_t *regs);
+
+	int time_to_rtc_regs(rtc_time_regs_t *regs, const struct tm *time);
+
+	int set_alarm_regs(alarm_no_t alarm_no, const alarm_regs_t *regs);
+
+	int get_alarm_regs(alarm_no_t alarm_no, alarm_regs_t *regs);
+
+	int time_to_alarm_regs(alarm_regs_t &regs, const struct tm *alarm_time);
+
+	int alarm_regs_to_time(struct tm *alarm_time, const alarm_regs_t *regs);
+
+	int set_alarm_period(alarm_no_t alarm_no, alarm_regs_t &regs, alarm_period_t period);
+
+	int set_rtc_time();
+
+	int data_retention_mode_config(int state);
+
+	int i2c_timeout_config(int enable);
+
+	int set_clock_sync_delay(sync_delay_t delay);
+};
+
+#endif /* RTCBASE_H_ */