RV32 SoC DS UG
High-Perf RV32 SoC DS UG
RV64 SoC DS UG API and Examples
Embedded IDE UG
Loading...
Searching...
No Matches
DS3231.c
Go to the documentation of this file.
1
2// Copyright (C) 2013-2026 Efinix Inc. All rights reserved.
3// Full license header bsp/efinix/EfxSapphireSocRV64/include/LICENSE.MD
5
15
16#include <stdio.h>
17#include "bsp.h"
18#include "rtc/device/DS3231.h"
19
20/*----------------------------------------------------------------------------*/
21/* Register Definition */
22/*----------------------------------------------------------------------------*/
23
24/* --- Address: Timekeeping Register --- */
25#define RTC_SECONDS 0X00
26#define RTC_MINUTES 0X01
27#define RTC_HOURS 0X02
28#define RTC_WEEKDAYS 0X03
29#define RTC_DAYS 0X04
30#define RTC_MONTH 0X05
31#define RTC_YEAR 0X06
32
33/* --- Address: Control Status Register, Temp Reg --- */
34#define CONTROL_ADDR 0X0E
35#define STATUS_ADDR 0X0F
36#define AGING_ADDR 0X10
37#define MSB_TEMP 0X11
38#define LSB_TEMP 0X12
39
40/* --- Address: Timekeeping/ALARM in Each Register --- */
41#define SECONDS_DATA 0X7F
42#define MINUTES_DATA 0X7F
43#define _12HOURS_DATA 0X1F
44#define _24HOURS_DATA 0X3F
45#define DAYS_DATA 0XFF
46#define DATE_DATA 0X37
47#define MONTH_DATA 0X1F
48#define YEAR_DATA 0XFF
49
50
51/* -----------------------------------------------------------------------------*/
52/* RTC: Plug & Play Driver
53/* -----------------------------------------------------------------------------*/
55{
56 .applyConfig = DS3231_applyConfig,
57 .enableErrorInterrupt = DS3231_enableErrorInterrupt,
58 .getTime = DS3231_getTime,
59 .setTime = DS3231_setTime,
60 .setTimeSystem = DS3231_setTimeSystem,
61
62};
63
69
71
72 // Will drop I2C Transcation if Timeout.
74 return RTC_OK;
75}
76
78
79 LOG_INFO(DBG_MOD_RTC,"This is DS3231_getTime func!\n");
80 rtc_data_t *time = &rtc->current_time;
81 u8 get_data[9] = {0};
82
83 // Hardware Read
84 i2c_readData_b(rtc->inst, RTC_SECONDS, get_data, 7);
85 // Parsing
86 time->seconds = bcd2bin(get_data[RTC_SECONDS] & SECONDS_DATA);
87 time->minutes = bcd2bin(get_data[RTC_MINUTES] & MINUTES_DATA);
88 time->weekdays = bcd2bin(get_data[RTC_WEEKDAYS] & 0x07);
89 time->days = bcd2bin(get_data[RTC_DAYS] & 0x3F);
90 time->months = bcd2bin(get_data[RTC_MONTH] & 0x1F);
91 time->years = bcd2bin(get_data[RTC_YEAR]);
92
93 // Handle 12/24 Hour Logic (DS3231 Specific)
94 time->timesystem = (get_data[RTC_HOURS] & 0x40) >> 6;
95
96 if (time->timesystem == 1) {
97 // --- 12 Hour Mode ---
98 time->PM = (get_data[RTC_HOURS] & 0x20) >> 5;
99 time->hours = bcd2bin(get_data[RTC_HOURS] & 0x1F);
100 }
101 else {
102 // --- 24 Hour Mode ---
103 time->PM = 0; // Not applicable
104 time->hours = bcd2bin(get_data[RTC_HOURS] & 0x3F);
105 }
106 return RTC_OK;
107}
108
110 u8 buffer[1];
111 u8 current_mode_12h;
112
113 // DS3231 stores the mode flag in Bit 6 of this register
114 i2c_readData_b(rtc->inst, RTC_HOURS, buffer, 1);
115
116 // Extract Bit 6 (1 = 12h mode, 0 = 24h mode)
117 current_mode_12h = (buffer[0] & 0x40) >> 6;
118
119 // If already in the correct mode, do nothing
120 if (current_mode_12h == use_12hour_mode) {
121 return RTC_SKIP;
122 }
123
124 // 2. Perform the Conversion
125 u8 h_val;
126 u8 pm_flag = 0;
127 u8 new_reg_val;
128
129 if (use_12hour_mode) {
130 // In 24h mode, bits 0-5 are the value (0-23). Bit 6 is 0.
131 h_val = bcd2bin(buffer[0] & 0x3F);
132
133 if (h_val >= 12) {
134 pm_flag = 1;
135 if (h_val > 12) h_val -= 12; // 13:00 -> 1:00
136 } else {
137 pm_flag = 0;
138 if (h_val == 0) h_val = 12; // 00:00 -> 12:00 AM
139 }
140
141 new_reg_val = 0x40 | (pm_flag << 5) | bin2bcd(h_val);
142
143 }
144 else {
145 // In 12h mode: Bit 5 is PM, Bits 0-4 are Hour (1-12)
146 pm_flag = (buffer[0] & 0x20) >> 5;
147 h_val = bcd2bin(buffer[0] & 0x1F);
148
149 if (pm_flag) {
150 // PM Case: 12 PM -> 12, 1 PM -> 13
151 if (h_val < 12) h_val += 12;
152 } else {
153 // AM Case: 12 AM -> 00, 1 AM -> 1
154 if (h_val == 12) h_val = 0;
155 }
156 new_reg_val = bin2bcd(h_val);
157 }
158
159 // 3. Write Back
160 i2c_writeData_b(rtc->inst, RTC_HOURS, &new_reg_val, 1);
161 return RTC_OK;
162}
163
165 rtc_data_t *t = &rtc->current_time;
166 u8 buffer[1];
167
168 i2c_readData_b(rtc->inst, RTC_HOURS, buffer, 1);
169
170 // Make sure it is in 24hr timesystem!
171 // Check Bit 6 (0 = 24h, 1 = 12h). If it is 1, we must clear it.
172 if (buffer[0] & 0x40) {
173 buffer[0] &= ~0x40; // Clear Bit 6 to force 24h mode
174
175 i2c_setMux(rtc->inst, 0xF);
176 i2c_writeData_b(rtc->inst, RTC_HOURS, buffer, 1);
177 }
178
179 u8 set_data[7] = {
180 bin2bcd(t->seconds),
181 bin2bcd(t->minutes),
182 bin2bcd(t->hours), // 0-23 is now perfectly valid
183 bin2bcd(t->weekdays),
184 bin2bcd(t->days),
185 bin2bcd(t->months),
186 bin2bcd(t->years)
187 };
188 i2c_writeData_b(rtc->inst, RTC_SECONDS, set_data, 7);
189
190 return RTC_OK;
191}
192
193/************************************************************************************************************************/
#define RTC_YEAR
Definition DS3231.c:31
#define RTC_WEEKDAYS
Definition DS3231.c:28
#define RTC_SECONDS
Definition DS3231.c:25
#define RTC_DAYS
Definition DS3231.c:29
#define RTC_HOURS
Definition DS3231.c:27
#define SECONDS_DATA
Definition DS3231.c:41
#define RTC_MINUTES
Definition DS3231.c:26
#define RTC_MONTH
Definition DS3231.c:30
const rtc_api_t DS3231_driver
Definition DS3231.c:54
#define MINUTES_DATA
Definition DS3231.c:42
DS3231 Driver API definitions. This file provides data structures and APIs for controlling the DS3231...
Board Support Package API definitions.
#define LOG_INFO(mod, fmt,...)
Log an informational message (green).
Definition debug.h:233
#define DBG_MOD_RTC
Real-Time Clock driver.
Definition debug.h:144
rtc_status_t DS3231_getTime(rtc_instance_t *rtc)
Get time from DS3231 RTC.
Definition DS3231.c:77
rtc_status_t DS3231_applyConfig(rtc_instance_t *rtc)
Apply I2C + RTC configuration.
Definition DS3231.c:64
rtc_status_t DS3231_setTimeSystem(rtc_instance_t *rtc, u8 use_12hour_mode)
Set time system (12-hour or 24-hour) on DS3231 RTC.
Definition DS3231.c:109
rtc_status_t DS3231_enableErrorInterrupt(rtc_instance_t *rtc)
Enable error interrupt for DS3231 RTC.
Definition DS3231.c:70
rtc_status_t DS3231_setTime(rtc_instance_t *rtc)
Set time on DS3231 RTC.
Definition DS3231.c:164
@ I2C_INTERRUPT_DROP
Trigger Interrupt when DROP condition is sent.
Definition i2c.h:186
void i2c_setMux(i2c_instance_t *inst, const uint8_t cr)
Set I2C MUX control register.
Definition i2c.c:314
void i2c_writeData_b(i2c_instance_t *inst, u8 regAddr, u8 *data, u32 length)
Write data with an 8-bit register address over I2C and check rx ack for each transaction.
Definition i2c.c:224
void i2c_applyConfig(i2c_instance_t *inst)
Apply the software configuration to the hardware.
Definition i2c.c:83
void i2c_enableInterrupt(i2c_instance_t *inst, i2c_interrupt_t value)
Enables specific I2C interrupts.
Definition i2c.c:214
void i2c_readData_b(i2c_instance_t *inst, u8 regAddr, u8 *data, u32 length)
Read data with an 8-bit register address over I2C.
Definition i2c.c:258
rtc_status_t
RTC Status List.
Definition rtc.h:94
@ RTC_SKIP
Skip the function.
Definition rtc.h:98
@ RTC_OK
Successful Operation.
Definition rtc.h:95
struct rtc_instance rtc_instance_t
Forward declaration of RTC instance.
Definition rtc.h:115
RTC API structure.
Definition rtc.h:137
RTC time data structure.
Definition rtc.h:121
u8 hours
Hours (0-23 or 1-12).
Definition rtc.h:124
u8 timesystem
Time System (0 = 24-hour, 1 = 12-hour).
Definition rtc.h:126
u8 days
Day of the month (1-31).
Definition rtc.h:128
u8 minutes
Minutes (0-59).
Definition rtc.h:123
u8 years
Year (0-99).
Definition rtc.h:130
u8 seconds
Seconds (0-59).
Definition rtc.h:122
u8 PM
PM Indicator for 12-hour format (0 = AM, 1 = PM).
Definition rtc.h:125
u8 months
Month (1-12).
Definition rtc.h:129
u8 weekdays
Day of the week (1-7).
Definition rtc.h:127
rtc_data_t current_time
Current time data.
Definition rtc.h:156
i2c_instance_t * inst
Pointer to I2C instance.
Definition rtc.h:154
uint8_t u8
Definition type.h:30