Revision 0:5e0616a05642, committed 2015-12-24
- Comitter:
- marcusC
- Date:
- Thu Dec 24 05:25:32 2015 +0000
- Commit message:
- Commit the AM1805 library
Changed in this revision
diff -r 000000000000 -r 5e0616a05642 AM1805.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AM1805.cpp Thu Dec 24 05:25:32 2015 +0000
@@ -0,0 +1,607 @@
+/* AM1805 Sample code: external RTC module is used by host MCU */
+
+#include "mbed.h"
+#include "AM1805.h"
+
+#define I2C_SDA p28
+#define I2C_SCL p27
+#define AM1805_I2C_ADDRESS 0xD2
+/* Register Map */
+#define AM1805_REG_HUNDREDTHS 0x00
+#define AM1805_REG_ALM_HUN 0x08
+#define AM1805_REG_STATUS 0x0F
+#define AM1805_REG_CTRL1 0x10
+#define AM1805_REG_CTRL2 0x11
+#define AM1805_REG_INTMASK 0x12
+#define AM1805_REG_SLEEPCTRL 0x17
+#define AM1805_REG_TIM_CTRL 0x18
+#define AM1805_REG_CDTIM 0x19
+#define AM1805_REG_TIMINIT 0x1A
+#define AM1805_REG_WDT 0x1B
+#define AM1805_REG_OSCSTATUS 0x1D
+#define AM1805_REG_ID0 0x28
+#define AM1805_REG_EXTADDR_REG 0x3F
+/* Register Value */
+#define AM1805_VALUE_ID0 0x18
+
+#define AM1805_DEBUG 0
+
+I2C i2c(I2C_SDA, I2C_SCL);
+#if AM1805_DEBUG
+Serial pc(p13,p14);
+#endif
+
+static uint8_t get_extension_address(uint8_t address)
+{
+ uint8_t xadd;
+ char temp;
+
+ am1805_register_read(AM1805_REG_EXTADDR_REG, &temp, 1);
+ temp = temp & 0xC0;
+
+ if (address < 64) { xadd = 0x8; }
+ else if (address < 128) { xadd = 0x9; }
+ else if (address < 192) { xadd = 0xA; }
+ else { xadd = 0xB; }
+ return (xadd | temp);
+}
+
+/* Set one or more bits in the selected register, selected by 1's in the mask */
+static void setreg(char address, uint8_t mask)
+{
+ char temp;
+
+ am1805_register_read(address, &temp, 1);
+ temp |= mask;
+ am1805_register_write(address, temp);
+}
+
+/* Clear one or more bits in the selected register, selected by 1's in the mask */
+static void clrreg(char address, uint8_t mask)
+{
+ char temp;
+
+ am1805_register_read(address, &temp, 1);
+ temp &= ~mask;
+ am1805_register_write(address, temp);
+}
+
+static bool am1805_verify_product_id(void)
+{
+ char who_am_i[1];
+ am1805_register_read(AM1805_REG_ID0, &who_am_i[0], 1);
+#if AM1805_DEBUG
+ pc.printf("ID:%x\r\n",who_am_i[0]);
+#endif
+ if (who_am_i[0] != AM1805_VALUE_ID0)
+ return false;
+ else
+ return true;
+}
+
+bool am1805_init(void)
+{
+ bool transfer_succeeded = false;
+
+ i2c.frequency(400000);
+
+ /* Read and verify product ID */
+ transfer_succeeded = am1805_verify_product_id();
+
+ return transfer_succeeded;
+}
+
+void am1805_register_read(char register_address, char *destination, uint8_t number_of_bytes)
+{
+ i2c.write(AM1805_I2C_ADDRESS, ®ister_address, 1, 1);
+ i2c.read(AM1805_I2C_ADDRESS, destination, number_of_bytes);
+}
+
+void am1805_register_write(char register_address, uint8_t value)
+{
+ char tx_data[2];
+
+ tx_data[0] = register_address;
+ tx_data[1] = value;
+ i2c.write(AM1805_I2C_ADDRESS, tx_data, 2);
+
+}
+
+void am1805_burst_write(uint8_t *tx_data, uint8_t number_of_bytes)
+{
+ i2c.write(AM1805_I2C_ADDRESS, (char *)tx_data, number_of_bytes);
+}
+
+void am1805_config_input_interrupt(input_interrupt_t index_Interrupt)
+{
+ switch(index_Interrupt) {
+ case XT1_INTERRUPT:
+ /* Set input interrupt pin EX1T */
+ clrreg(AM1805_REG_STATUS,0x01); // Clear EX1
+ setreg(AM1805_REG_INTMASK,0x01); // Set EX1E
+ break;
+ case XT2_INTERRUPT:
+ /* Set input interrupt pin WDI */
+ clrreg(AM1805_REG_STATUS,0x02); // Clear EX2
+ setreg(AM1805_REG_INTMASK,0x02); // Set EX2E
+ break;
+ default:
+#if AM1805_DEBUG
+ pc.printf("Wrong Input Interrupt Index\r\n");
+#endif
+ break;
+ }
+}
+
+
+// Read a byte from local RAM
+uint8_t am1805_read_ram(uint8_t address)
+{
+ uint8_t xadd;
+ char temp;
+ uint8_t reg_ram = 0;
+
+ xadd = get_extension_address(address); // Calc XADDR value from address
+ am1805_register_write(AM1805_REG_EXTADDR_REG, xadd); // Load the XADDR register
+ reg_ram = (address & 0x3F) | 0x40; // Read the data
+ am1805_register_read(reg_ram, &temp, 1);
+#if AM1805_DEBUG
+ pc.printf("Read from addr:%x Data:%x\r\n",address,temp);
+#endif
+ return (uint8_t)temp;
+}
+
+// Write a byte to local RAM
+void am1805_write_ram(uint8_t address, uint8_t data)
+{
+ uint8_t xadd;
+ uint8_t reg_ram = 0;
+
+ xadd = get_extension_address(address); // Calc XADDR value from address
+ am1805_register_write(AM1805_REG_EXTADDR_REG, xadd); // Load the XADDR register
+ reg_ram = (address & 0x3F) | 0x40;
+ am1805_register_write(reg_ram, data); // Write the data
+}
+
+/*
+ * hundredth : 0 ~ 99
+ * second : 0 ~ 59
+ * minute : 0 ~ 59
+ * weekday : 0 ~ 6
+ * month : 1 ~ 12
+ * year : 0 ~ 99
+ * mode : 0 ~ 2
+ */
+void am1805_set_time(time_reg_struct_t time_regs)
+{
+ char temp;
+ uint8_t temp_buff[9];
+
+ /*
+ * Determine whether 12 or 24-hour timekeeping mode is being used
+ * and set the 1224 bit appropriately
+ */
+ if (time_regs.mode == 2) // 24-hour day
+ {
+ clrreg(AM1805_REG_CTRL1, 0x40);
+ }
+ else if (time_regs.mode == 1) // 12-hour day PM
+ {
+ time_regs.hour |= 0x20; // Set AM/PM
+ setreg(AM1805_REG_CTRL1, 0x40);
+ }
+ else // 12-hour day AM
+ {
+ setreg(AM1805_REG_CTRL1, 0x40);
+ }
+
+ /* Set the WRTC bit to enable counter writes. */
+ setreg(AM1805_REG_CTRL1, 0x01);
+
+ /* Set the correct century */
+ if (time_regs.century == 0)
+ {
+ clrreg(AM1805_REG_STATUS, 0x80);
+ }
+ else
+ {
+ setreg(AM1805_REG_STATUS, 0x80);
+ }
+
+ /* Write all of the time counters */
+ temp_buff[0] = AM1805_REG_HUNDREDTHS;
+ temp_buff[1] = time_regs.hundredth;
+ temp_buff[2] = time_regs.second;
+ temp_buff[3] = time_regs.minute;
+ temp_buff[4] = time_regs.hour;
+ temp_buff[5] = time_regs.date;
+ temp_buff[6] = time_regs.month;
+ temp_buff[7] = time_regs.year;
+ temp_buff[8] = time_regs.weekday;
+
+ /* Write the values to the AM18XX */
+ am1805_burst_write(temp_buff, sizeof(temp_buff));
+
+ /* Load the final value of the WRTC bit based on the value of protect */
+ am1805_register_read(AM1805_REG_CTRL1, &temp, 1);
+ temp &= 0x7E; // Clear the WRTC bit and the STOP bit
+ //temp_buff[1] |= (0x01 & (~protect)); // Invert the protect bit and update WRTC
+ am1805_register_write(AM1805_REG_CTRL1, temp);
+
+ return;
+}
+
+void am1805_get_time(time_reg_struct_t *time_regs)
+{
+ char temp_buff[8];
+ char time_mode;
+
+ /* Read the counters. */
+ am1805_register_read(AM1805_REG_HUNDREDTHS, temp_buff, 8);
+
+ time_regs->hundredth = temp_buff[0];
+ time_regs->second = temp_buff[1];
+ time_regs->minute = temp_buff[2];
+ time_regs->hour = temp_buff[3];
+ time_regs->date = temp_buff[4];
+ time_regs->month = temp_buff[5];
+ time_regs->year = temp_buff[6];
+ time_regs->weekday = temp_buff[7];
+
+ /* Get the current hours format mode 12:24 */
+ am1805_register_read(AM1805_REG_CTRL1, &time_mode, 1);
+ if ((time_mode & 0x40) == 0)
+ {
+ /* 24-hour mode. */
+ time_regs->mode = 2;
+ time_regs->hour = time_regs->hour & 0x3F; // Get tens:ones
+ }
+ else
+ {
+ /* 12-hour mode. Get PM:AM. */
+ time_regs->mode = (time_regs->hour & 0x20) ? 1 : 0; // PM : AM
+ time_regs->hour &= 0x1F; // Get tens:ones
+ }
+
+ time_regs->hundredth = temp_buff[0];
+ time_regs->second = temp_buff[1];
+ time_regs->minute = temp_buff[2];
+ time_regs->hour = temp_buff[3];
+ time_regs->date = temp_buff[4];
+ time_regs->month = temp_buff[5];
+ time_regs->year = temp_buff[6];
+ time_regs->weekday = temp_buff[7];
+
+#if AM1805_DEBUG
+ pc.printf("hundredth:%x\r\n",time_regs->hundredth);
+ pc.printf("second:%x\r\n",time_regs->second);
+ pc.printf("minute:%x\r\n",time_regs->minute);
+ pc.printf("hour:%x\r\n",time_regs->hour);
+ pc.printf("date:%x\r\n",time_regs->date);
+ pc.printf("month:%x\r\n",time_regs->month);
+ pc.printf("year:%x\r\n",time_regs->year);
+ pc.printf("weekday:%x\r\n",time_regs->weekday);
+#endif
+}
+
+void am1805_config_alarm(time_reg_struct_t time_regs, alarm_repeat_t repeat, interrupt_mode_t intmode, interrupt_pin_t pin)
+{
+ char temp;
+ uint8_t temp_buff[9];
+
+ /* Determine whether a 12-hour or a 24-hour time keeping mode is being used */
+ if (time_regs.mode == 1)
+ {
+ /* A 12-hour day PM */
+ time_regs.hour = time_regs.hour | 0x20; // Set AM/PM
+ }
+
+ /* Write all of the time counters */
+ temp_buff[0] = AM1805_REG_ALM_HUN;
+ temp_buff[1] = time_regs.hundredth;
+ temp_buff[2] = time_regs.second;
+ temp_buff[3] = time_regs.minute;
+ temp_buff[4] = time_regs.hour;
+ temp_buff[5] = time_regs.date;
+ temp_buff[6] = time_regs.month;
+ temp_buff[7] = time_regs.weekday;
+
+ clrreg(AM1805_REG_TIM_CTRL, 0x1C); // Clear the RPT field
+ clrreg(AM1805_REG_INTMASK, 0x64); // Clear the AIE bit and IM field
+ clrreg(AM1805_REG_STATUS, 0x04); // Clear the ALM flag
+
+ if (pin == PIN_FOUT_nIRQ)
+ {
+ /* Interrupt on FOUT/nIRQ */
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get the Control2 Register
+ temp = (temp & 0x03); // Extract the OUT1S field
+ if (temp != 0) // Not already selecting nIRQ
+ {
+ setreg(AM1805_REG_CTRL2, 0x03); // Set OUT1S to 3
+ }
+ }
+ if (pin == PIN_PSW_nIRQ2)
+ {
+ /* Interrupt on PSW/nIRQ2 */
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get the Control2 Register
+ temp &= 0x1C; // Extract the OUT2S field
+ if (temp != 0) // Not already selecting nIRQ
+ {
+ clrreg(AM1805_REG_CTRL2, 0x1C); // Clear OUT2S
+ setreg(AM1805_REG_CTRL2, 0x0C); // Set OUT2S to 3
+ }
+ }
+
+ if (repeat == ONCE_PER_10TH_SEC)
+ {
+ /* 10ths interrupt */
+ temp_buff[1] |= 0xF0;
+ repeat = ONCE_PER_SECOND; // Select correct RPT value
+ }
+ if (repeat == ONCE_PER_100TH_SEC)
+ {
+ /* 100ths interrupt */
+ temp_buff[1] = 0xFF;
+ repeat = ONCE_PER_SECOND; // Select correct RPT value
+ }
+ if (repeat != 0) // Don't initiate if repeat = 0
+ {
+ temp = (repeat << 2); // Set the RPT field to the value of repeat
+ setreg(AM1805_REG_TIM_CTRL, temp); // Was previously cleared
+ setreg(AM1805_REG_INTMASK, (intmode << 5)); // Set the alarm interrupt mode
+ setreg(AM1805_REG_INTMASK, 0x60); // Set the alarm interrupt mode
+ am1805_burst_write(temp_buff, 8); // Execute the burst write
+ setreg(AM1805_REG_INTMASK, 0x04); // Set the AIE bit
+ }
+ else
+ setreg(AM1805_REG_INTMASK, 0x60); // Set IM field to 0x3 (reset value) to minimize current draw
+
+ return;
+}
+
+void am1805_config_countdown_timer(count_down_range_t range, int32_t period, count_down_repeat_t repeat, interrupt_pin_t pin)
+{
+ uint8_t tm;
+ uint8_t trpt;
+ uint8_t tfs;
+ uint8_t te;
+ char temp;
+ char tctrl;
+ int32_t timer;
+ char oscmode;
+
+ /* 0 = XT, 1 = RC */
+ am1805_register_read(AM1805_REG_OSCSTATUS, &oscmode, 1);
+ oscmode = (oscmode & 0x10) ? 1 : 0;
+
+ /* disable count down timer */
+ if (pin == INTERNAL_FLAG)
+ {
+ te = 0;
+ }
+ else
+ {
+ te = 1;
+ if (repeat == SINGLE_LEVEL_INTERRUPT)
+ {
+ /* Level interrupt */
+ tm = 1; // Level
+ trpt = 0; // No repeat
+ if (range == PERIOD_US)
+ {
+ /* Microseconds */
+ if (oscmode == 0)
+ {
+ /* XT Mode */
+ if (period <= 62500) // Use 4K Hz
+ {
+ tfs = 0;
+ timer = (period * 4096);
+ timer = timer / 1000000;
+ timer = timer - 1;
+ }
+ else if (period <= 16384000) // Use 64 Hz
+ {
+ tfs = 1;
+ timer = (period * 64);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ else // Use 1 Hz
+ {
+ tfs = 2;
+ timer = period / 1000000;
+ timer = timer - 1;
+ }
+ }
+ else
+ {
+ /* RC Mode */
+ if (period <= 2000000) { // Use 128 Hz
+ tfs = 0;
+ timer = (period * 128);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ else if (period <= 4000000) { // Use 64 Hz
+ tfs = 1;
+ timer = (period * 64);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ else { // Use 1 Hz
+ tfs = 2;
+ timer = period / 1000000;
+ timer = timer - 1;
+ }
+ }
+ }
+ else
+ {
+ /* Seconds */
+ if (period <= 256)
+ {
+ /* Use 1 Hz */
+ tfs = 2;
+ timer = period - 1;
+ }
+ else
+ {
+ /* Use 1/60 Hz */
+ tfs = 3;
+ timer = period / 60;
+ timer = timer - 1;
+ }
+ }
+ }
+ else
+ {
+ /* Pulse interrupts */
+ tm = 0; // Pulse
+ trpt = repeat & 0x01; // Set up repeat
+ if (repeat < REPEAT_PLUSE_1_128_SEC)
+ {
+ tfs = 0;
+ if (oscmode == 0)
+ {
+ timer = (period * 4096);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ else
+ {
+ timer = (period * 128);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ }
+ else if (repeat < REPEAT_PLUSE_1_64_SEC)
+ {
+ tfs = 1;
+ timer = (period * 128);
+ timer /= 1000000;
+ timer = timer - 1;
+ }
+ else if (period <= 256)
+ {
+ /* Use 1 Hz */
+ tfs = 2;
+ timer = period - 1;
+ }
+ else
+ {
+ /* Use 1/60 Hz */
+ tfs = 3;
+ timer = period / 60;
+ timer = timer - 1;
+ }
+ }
+ }
+
+ am1805_register_read(AM1805_REG_TIM_CTRL, &tctrl, 1); // Get TCTRL, keep RPT, clear TE
+ tctrl = tctrl & 0x1C;
+ am1805_register_write(AM1805_REG_TIM_CTRL, tctrl);
+
+ tctrl = tctrl | (te * 0x80) | (tm * 0x40) | (trpt * 0x20) | tfs; // Merge the fields
+
+ if (pin == PIN_FOUT_nIRQ) // generate nTIRQ interrupt on FOUT/nIRQ (asserted low)
+ {
+ clrreg(AM1805_REG_CTRL2, 0x3); // Clear OUT1S
+ }
+ if (pin == PIN_PSW_nIRQ2) // generate nTIRQ interrupt on PSW/nIRQ2 (asserted low)
+ {
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get OUT2S
+ if ((temp & 0x1C) != 0)
+ {
+ temp = (temp & 0xE3) | 0x14; // If OUT2S != 0, set OUT2S to 5
+ }
+ am1805_register_write(AM1805_REG_CTRL2, temp); // Write back
+ }
+ if (pin != 0)
+ {
+ clrreg(AM1805_REG_STATUS,0x08); // Clear TIM
+ setreg(AM1805_REG_INTMASK,0x08); // Set TIE
+ am1805_register_write(AM1805_REG_CDTIM, timer); // Initialize the timer
+ am1805_register_write(AM1805_REG_TIMINIT, timer); // Initialize the timer repeat
+ am1805_register_write(AM1805_REG_TIM_CTRL, tctrl); // Start the timer
+ }
+
+ return ;
+}
+
+/** Parameter:
+ * timeout - minimum timeout period in 7.8 ms periods (0 to 7)
+ * mode - sleep mode (nRST modes not available in AM08xx)
+ * 0 => nRST is pulled low in sleep mode
+ * 1 => PSW/nIRQ2 is pulled high on a sleep
+ * 2 => nRST pulled low and PSW/nIRQ2 pulled high on sleep
+ * error ?returned value of the attempted sleep command
+ * 0 => sleep request accepted, sleep mode will be initiated in timeout seconds
+ * 1 => illegal input values
+ * 2 => sleep request declined, interrupt is currently pending
+ * 3 => sleep request declined, no sleep trigger interrupt enabled
+**/
+void am1805_set_sleep(uint8_t timeout, uint8_t mode)
+{
+ uint8_t slres = 0;
+ char temp = 0;
+
+#if AM1805_DEBUG
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get SLST bit (temp & 0x08)
+
+ if ( ( temp & 0x08 ) == 0)
+ {
+ pc.printf("Previous Sleep Failed\r\n");
+ } else {
+ pc.printf("Previous Sleep Successful\r\n");
+ }
+ clrreg(AM1805_REG_CTRL2,0x08); // Clear SLST
+
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get SLST bit (temp & 0x08)
+
+ if ( ( temp & 0x08 ) == 0)
+ {
+ pc.printf("Clear Succ\r\n");
+ } else {
+ pc.printf("Clear Fail\r\n");
+ }
+ clrreg(AM1805_REG_CTRL2,0x08); // Clear SLST
+#endif
+
+ if (mode > 0)
+ {
+ /* Sleep to PSW/nIRQ2 */
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Read OUT2S
+ temp = (temp & 0xE3) | 0x18; // MUST NOT WRITE OUT2S WITH 000
+ am1805_register_write(AM1805_REG_CTRL2, temp); // Write value to OUT2S
+ slres = 0;
+ }
+
+ temp = timeout | (slres << 6) | 0x80; // Assemble SLEEP register value
+ am1805_register_write(AM1805_REG_SLEEPCTRL, temp); // Write to the register
+
+#if AM1805_DEBUG
+ /* Determine if SLEEP was accepted */
+ am1805_register_read(AM1805_REG_CTRL2, &temp, 1); // Get SLP bit (temp & 0x80)
+
+ if ( ( temp & 0x80 ) == 0)
+ {
+ char reg_wdi_value = 0;
+ /* SLEEP did not happen - determine why and return reason. */
+ am1805_register_read(AM1805_REG_INTMASK, &temp, 1); // Get status register interrupt enables
+ am1805_register_read(AM1805_REG_WDT, ®_wdi_value, 1); // Get WDT register
+ if ((( temp & 0x0F ) == 0) & (((reg_wdi_value & 0x7C) == 0) || ((reg_wdi_value & 0x80) == 0x80)))
+ {
+ pc.printf("No trigger interrupts enabled\r\n");
+ }
+ else
+ {
+ pc.printf("Interrupt pending\r\n");
+ }
+ }
+ else
+ {
+ pc.printf("SLEEP request successful\r\n");
+ }
+#endif
+}
diff -r 000000000000 -r 5e0616a05642 AM1805.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AM1805.h Thu Dec 24 05:25:32 2015 +0000
@@ -0,0 +1,92 @@
+/* AM1805.h , AM1805 Sample code: external RTC module is used by host MCU */
+
+typedef struct
+{
+ uint8_t hundredth;
+ uint8_t second;
+ uint8_t minute;
+ uint8_t hour;
+ uint8_t date;
+ uint8_t weekday;
+ uint8_t month;
+ uint8_t year;
+ uint8_t century;
+ uint8_t mode;
+} time_reg_struct_t;
+
+typedef enum
+{
+ XT1_INTERRUPT = 0x01, /**< WDI input pin will generate XT1 interrupt */
+ XT2_INTERRUPT = 0x02 /**< EXTI input pin will generate XT2 interrupt */
+} input_interrupt_t;
+
+typedef enum
+{
+ DISABLE_ALARM = 0, /**< disable alarm */
+ ONCE_PER_YEAR = 1, /**< once per year */
+ ONCE_PER_MONTH = 2, /**< once per month */
+ ONCE_PER_WEEK = 3, /**< once per week */
+ ONCE_PER_DAY = 4, /**< once per day */
+ ONCE_PER_HOUR = 5, /**< once per hour */
+ ONCE_PER_MINUTE = 6, /**< once per minute */
+ ONCE_PER_SECOND = 7, /**< once per second */
+ ONCE_PER_10TH_SEC = 8, /**< once per 10th of a second */
+ ONCE_PER_100TH_SEC = 9 /**< once per 100th of a second */
+} alarm_repeat_t;
+
+typedef enum
+{
+ PERIOD_US = 0, /**< period in us */
+ PERIOD_SEC = 1 /**< period in seconds */
+} count_down_range_t;
+
+typedef enum
+{
+ SINGLE_LEVEL_INTERRUPT = 0, /**< single level interrupt */
+ REPEAT_PULSE_1_4096_SEC = 1, /**< a repeated pulsed interrupt, 1/4096 s (XT mode), 1/128 s (RC mode) (range must be 0) */
+ SINGLE_PULSE_1_4096_SEC = 2, /**< a single pulsed interrupt, 1/4096 s (XT mode), 1/128 s (RC mode) (range must be 0) */
+ REPEAT_PLUSE_1_128_SEC = 3, /**< a repeated pulsed interrupt, 1/128 s (range must be 0) */
+ SINGLE_PLUSE_1_128_SEC = 4, /**< a single pulsed interrupt, 1/128 s (range must be 0) */
+ REPEAT_PLUSE_1_64_SEC = 5, /**< a repeated pulsed interrupt, 1/64 s (range must be 1) */
+ SINGLE_PLUSE_1_64_SEC = 6 /**< a single pulsed interrupt, 1/64 s (range must be 1) */
+} count_down_repeat_t;
+
+typedef enum
+{
+ LEVEL_INTERRUPT = 0x00, /**< level interrupt */
+ PULSE_1_8192_SEC = 0x01, /**< pulse of 1/8192s (XT) or 1/128 s (RC) */
+ PULSE_1_64_SEC = 0x10, /**< pulse of 1/64 s */
+ PULSE_1_4_SEC = 0x11 /**< pulse of 1/4 s */
+} interrupt_mode_t;
+
+typedef enum
+{
+ INTERNAL_FLAG = 0, /**< internal flag only */
+ PIN_FOUT_nIRQ = 1, /**< generate the interrupt on FOUT/nIRQ */
+ PIN_PSW_nIRQ2 = 2, /**< generate the interrupt on PSW/nIRQ2 */
+ PIN_nTIRQ = 3 /**< generate the interrupt on nTIRQ (not apply to ALARM) */
+} interrupt_pin_t;
+
+bool am1805_init(void);
+
+void am1805_register_read(char register_address, char *destination, uint8_t number_of_bytes);
+
+void am1805_register_write(char register_address, uint8_t value);
+
+void am1805_burst_write(uint8_t *value, uint8_t number_of_bytes);
+
+uint8_t am1805_read_ram(uint8_t address);
+
+void am1805_write_ram(uint8_t address, uint8_t data);
+
+void am1805_config_input_interrupt(input_interrupt_t index_Interrupt);
+
+void am1805_set_time(time_reg_struct_t time_regs);
+
+void am1805_get_time(time_reg_struct_t *time_regs);
+
+void am1805_config_alarm(time_reg_struct_t time_regs, alarm_repeat_t repeat, interrupt_mode_t intmode, interrupt_pin_t pin);
+
+void am1805_config_countdown_timer(count_down_range_t range, int32_t period, count_down_repeat_t repeat, interrupt_pin_t pin);
+
+void am1805_set_sleep(uint8_t timeout, uint8_t mode);
\ No newline at end of file