Sapphire SoC DS Sapphire SoC UG Sapphire HP SoC DS Sapphire HP SoC UG RISC-V Embedded IDE UG Board Support Package
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 .getTime = DS3231_getTime,
57 .setTime = DS3231_setTime,
58 .setTimeSystem = DS3231_setTimeSystem,
59
60};
61
63
64 LOG_INFO(DBG_MOD_RTC,"This is DS3231_getTime func!\n");
65 rtc_data_t *time = &rtc->current_time;
66 u8 get_data[9] = {0};
67
68 // Hardware Read
69 i2c_readData_b(rtc->inst, RTC_SECONDS, get_data, 7);
70 // Parsing
71 time->seconds = bcd2bin(get_data[RTC_SECONDS] & SECONDS_DATA);
72 time->minutes = bcd2bin(get_data[RTC_MINUTES] & MINUTES_DATA);
73 time->weekdays = bcd2bin(get_data[RTC_WEEKDAYS] & 0x07);
74 time->days = bcd2bin(get_data[RTC_DAYS] & 0x3F);
75 time->months = bcd2bin(get_data[RTC_MONTH] & 0x1F);
76 time->years = bcd2bin(get_data[RTC_YEAR]);
77
78 // Handle 12/24 Hour Logic (DS3231 Specific)
79 time->timesystem = (get_data[RTC_HOURS] & 0x40) >> 6;
80
81 if (time->timesystem == 1) {
82 // --- 12 Hour Mode ---
83 time->PM = (get_data[RTC_HOURS] & 0x20) >> 5;
84 time->hours = bcd2bin(get_data[RTC_HOURS] & 0x1F);
85 }
86 else {
87 // --- 24 Hour Mode ---
88 time->PM = 0; // Not applicable
89 time->hours = bcd2bin(get_data[RTC_HOURS] & 0x3F);
90 }
91 return RTC_OK;
92}
93
95 u8 buffer[1];
96 u8 current_mode_12h;
97
98 // DS3231 stores the mode flag in Bit 6 of this register
99 i2c_readData_b(rtc->inst, RTC_HOURS, buffer, 1);
100
101 // Extract Bit 6 (1 = 12h mode, 0 = 24h mode)
102 current_mode_12h = (buffer[0] & 0x40) >> 6;
103
104 // If already in the correct mode, do nothing
105 if (current_mode_12h == use_12hour_mode) {
106 return RTC_SKIP;
107 }
108
109 // 2. Perform the Conversion
110 u8 h_val;
111 u8 pm_flag = 0;
112 u8 new_reg_val;
113
114 if (use_12hour_mode) {
115 // In 24h mode, bits 0-5 are the value (0-23). Bit 6 is 0.
116 h_val = bcd2bin(buffer[0] & 0x3F);
117
118 if (h_val >= 12) {
119 pm_flag = 1;
120 if (h_val > 12) h_val -= 12; // 13:00 -> 1:00
121 } else {
122 pm_flag = 0;
123 if (h_val == 0) h_val = 12; // 00:00 -> 12:00 AM
124 }
125
126 new_reg_val = 0x40 | (pm_flag << 5) | bin2bcd(h_val);
127
128 }
129 else {
130 // In 12h mode: Bit 5 is PM, Bits 0-4 are Hour (1-12)
131 pm_flag = (buffer[0] & 0x20) >> 5;
132 h_val = bcd2bin(buffer[0] & 0x1F);
133
134 if (pm_flag) {
135 // PM Case: 12 PM -> 12, 1 PM -> 13
136 if (h_val < 12) h_val += 12;
137 } else {
138 // AM Case: 12 AM -> 00, 1 AM -> 1
139 if (h_val == 12) h_val = 0;
140 }
141 new_reg_val = bin2bcd(h_val);
142 }
143
144 // 3. Write Back
145 i2c_writeData_b(rtc->inst, RTC_HOURS, &new_reg_val, 1);
146 return RTC_OK;
147}
148
150 rtc_data_t *t = &rtc->current_time;
151 u8 buffer[1];
152
153 i2c_readData_b(rtc->inst, RTC_HOURS, buffer, 1);
154
155 // Make sure it is in 24hr timesystem!
156 // Check Bit 6 (0 = 24h, 1 = 12h). If it is 1, we must clear it.
157 if (buffer[0] & 0x40) {
158 buffer[0] &= ~0x40; // Clear Bit 6 to force 24h mode
159
160 i2c_setMux(rtc->inst, 0xF);
161 i2c_writeData_b(rtc->inst, RTC_HOURS, buffer, 1);
162 }
163
164 u8 set_data[7] = {
165 bin2bcd(t->seconds),
166 bin2bcd(t->minutes),
167 bin2bcd(t->hours), // 0-23 is now perfectly valid
168 bin2bcd(t->weekdays),
169 bin2bcd(t->days),
170 bin2bcd(t->months),
171 bin2bcd(t->years)
172 };
173 i2c_writeData_b(rtc->inst, RTC_SECONDS, set_data, 7);
174
175 return RTC_OK;
176}
177
178/************************************************************************************************************************/
#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...
#define LOG_INFO(debug, fmt,...)
Definition debug.h:237
#define DBG_MOD_RTC
Real Time Clock.
Definition debug.h:109
rtc_status_t DS3231_getTime(rtc_instance_t *rtc)
Get time from DS3231 RTC.
Definition DS3231.c:62
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:94
rtc_status_t DS3231_setTime(rtc_instance_t *rtc)
Set time on DS3231 RTC.
Definition DS3231.c:149
void i2c_setMux(i2c_instance_t *inst, const uint8_t cr)
Set I2C MUX control register.
Definition i2c.c:307
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:219
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:253
rtc_status_t
RTC Status List.
Definition rtc.h:60
@ RTC_SKIP
Skip the function *‍/.
Definition rtc.h:64
@ RTC_OK
Successful Operation *‍/.
Definition rtc.h:61
struct rtc_instance rtc_instance_t
Forward declaration of RTC instance.
Definition rtc.h:110
RTC API structure.
Definition rtc.h:132
RTC time data structure.
Definition rtc.h:116
u8 hours
Hours (0-23 or 1-12) *‍/.
Definition rtc.h:119
u8 timesystem
Time System (0 = 24-hour, 1 = 12-hour) *‍/.
Definition rtc.h:121
u8 days
Day of the month (1-31) *‍/.
Definition rtc.h:123
u8 minutes
Minutes (0-59) *‍/.
Definition rtc.h:118
u8 years
Year (0-99) *‍/.
Definition rtc.h:125
u8 seconds
Seconds (0-59) *‍/.
Definition rtc.h:117
u8 PM
PM Indicator for 12-hour format (0 = AM, 1 = PM) *‍/.
Definition rtc.h:120
u8 months
Month (1-12) *‍/.
Definition rtc.h:124
u8 weekdays
Day of the week (1-7) *‍/.
Definition rtc.h:122
rtc_data_t current_time
Current time data *‍/.
Definition rtc.h:149
i2c_instance_t * inst
Pointer to I2C instance *‍/.
Definition rtc.h:147
uint8_t u8
Definition type.h:26