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
PCF8523.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#include <stdio.h>
16#include "bsp.h"
17#include "rtc/device/PCF8523.h"
18
19/* -----------------------------------------------------------------------------*/
20/* RTC - Hardware Register Map for PCF8523
21/* -----------------------------------------------------------------------------*/
22
23/* --- Address: Control Status Register --- */
24#define RTC_CONTROL_1 0X00
25#define RTC_CONTROL_2 0X01
26#define RTC_CONTROL_3 0X02
27
28/* --- Address: Timekeeping Register --- */
29#define RTC_SECONDS 0X03
30#define RTC_MINUTES 0X04
31#define RTC_HOURS 0X05
32#define RTC_DAYS 0X06
33#define RTC_WEEKDAYS 0X07
34#define RTC_MONTH 0X08
35#define RTC_YEAR 0X09
36
37/* --- Address: Timer Register --- */
38#define TIMER_A_FREQ_CTRL 0x10
39#define TIMER_A_REG 0x11
40#define TIMER_B_FREQ_CTRL 0x12
41#define TIMER_B_REG 0x13
42
43/* --- Address: Timekeeping/ALARM in Each Register --- */
44#define SECONDS_DATA 0X7F
45#define MINUTES_DATA 0X7F
46#define HOURS_DATA 0X3F
47#define DAYS_DATA 0X3F
48#define WEEKDAYS_DATA 0X07
49#define MONTHS_DATA 0X1F
50#define YEARS_DATA 0XFF
51
52/* -----------------------------------------------------------------------------*/
53/* RTC: Plug & Play Driver
54/* -----------------------------------------------------------------------------*/
56{
57 .getTime = PCF8523_getTime,
58 .setTime = PCF8523_setTime,
59 .setTimeSystem = PCF8523_setTimeSystem,
60
61};
62
64
65 LOG_INFO(DBG_MOD_RTC,"This is PCF8523_getTime func!\n");
66 rtc_data_t *time = &rtc->current_time;
67 u8 get_data[9] = {0};
68
69 // Hardware Read
70 i2c_setMux(rtc->inst, 0x1);
71 i2c_readData_b(rtc->inst, RTC_CONTROL_1, get_data, 14);
72
73 // Parsing
74 time->timesystem = (get_data[RTC_CONTROL_1] & 0x08) >> 3;
75 time->seconds = bcd2bin(get_data[RTC_SECONDS] & SECONDS_DATA);
76 time->minutes = bcd2bin(get_data[RTC_MINUTES] & MINUTES_DATA);
77 time->years = bcd2bin(get_data[RTC_YEAR]);
78 time->months = bcd2bin(get_data[RTC_MONTH] & MONTHS_DATA);
79 time->days = bcd2bin(get_data[RTC_DAYS] & DAYS_DATA);
80 time->weekdays = get_data[RTC_WEEKDAYS] & WEEKDAYS_DATA;
81 u8 raw_hours = get_data[RTC_HOURS];
82
83 if (time->timesystem == 1) {
84 // --- 12 Hour Mode ---
85 time->PM = (raw_hours & 0x20) >> 5;
86 time->hours = bcd2bin(raw_hours & 0x1F);
87 }
88 else {
89 // --- 24 Hour Mode ---
90 time->PM = 0; // Not applicable
91 time->hours = bcd2bin(raw_hours & 0x3F);
92 }
93
94 return RTC_OK;
95}
96
98 rtc_data_t *t = &rtc->current_time;
99 u8 buffer[1];
100
101 i2c_setMux(rtc->inst, 0x1);
102 i2c_readData_b(rtc->inst, RTC_CONTROL_1, buffer, 1);
103
104 // Make sure it is in 24hr timesystem!
105 // Check Bit 3 (0 = 24h, 1 = 12h). If it is 1, we must clear it.
106 if (buffer[0] & 0x08) {
107 buffer[0] &= ~0x08; // Clear Bit 3 to force 24h mode
108
109 i2c_setMux(rtc->inst, 0xF);
110 i2c_writeData_b(rtc->inst, RTC_CONTROL_1, buffer, 1);
111 }
112
113 u8 set_data[7] = {
114 bin2bcd(t->seconds),
115 bin2bcd(t->minutes),
116 bin2bcd(t->hours), // 0-23 is now perfectly valid
117 bin2bcd(t->days),
118 bin2bcd(t->weekdays),
119 bin2bcd(t->months),
120 bin2bcd(t->years)
121 };
122 i2c_setMux(rtc->inst, 0xF);
123 i2c_writeData_b(rtc->inst, RTC_SECONDS, set_data, 7);
124
125 return RTC_OK;
126}
127
129 u8 buffer[1];
130 u8 current_mode_12h;
131
132 // Check Current Status
133 i2c_setMux(rtc->inst,0x1);
134 i2c_readData_b(rtc->inst, RTC_CONTROL_1, buffer, 1);
135
136 // Extract Bit 3 (0 = 24h, 1 = 12h)
137 current_mode_12h = (buffer[0] & 0x08) >> 3;
138
139 // If already in the correct mode, exit
140 if (current_mode_12h == use_12hour_mode) {
141 return RTC_SKIP;
142 }
143
144 // Update the Control Register (Switch the Mode bit)
145 if (use_12hour_mode) {
146 buffer[0] |= 0x08; // Set Bit 3 (12h)
147 } else {
148 buffer[0] &= ~0x08; // Clear Bit 3 (24h)
149 }
150
151 i2c_setMux(rtc->inst,0xF); // Assuming this is needed for writes on your board
152 i2c_writeData_b(rtc->inst, RTC_CONTROL_1, buffer, 1);
153
154
155 // Update Current Time Hour Register
156 i2c_setMux(rtc->inst, 0x1);
157 i2c_readData_b(rtc->inst, RTC_HOURS, buffer, 1);
158
159 buffer[0] = convert_hour_register(buffer[0], use_12hour_mode);
160
161 i2c_setMux(rtc->inst,0xF);
162 i2c_writeData_b(rtc->inst, RTC_HOURS, buffer, 1);
163
164 // User Feedback
165 return RTC_OK;
166}
167
169{
170 u8 status[1] = {0x58};
171 i2c_setMux(rtc->inst,0xF);
172 i2c_writeData_b(rtc->inst,RTC_CONTROL_1,status,1);
173 return RTC_OK;
174}
175
177{
178 u8 status[3] = { };
179 i2c_setMux(rtc->inst,0x1);
180 i2c_readData_b(rtc->inst, RTC_CONTROL_1, status, 3);
181 for (int i = 1; i < 4; i++) {
182 LOG_INFO(DBG_MOD_RTC,"RTC CSR%d readback: %x", RTC_CONTROL_1 + i, status[i - 1]);
183 }
184 return RTC_OK;
185}
#define RTC_YEAR
Definition DS3231.c:31
#define RTC_WEEKDAYS
Definition DS3231.c:28
#define DAYS_DATA
Definition DS3231.c:45
#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
#define MINUTES_DATA
Definition DS3231.c:42
#define MONTHS_DATA
Definition PCF8523.c:49
#define RTC_CONTROL_1
Definition PCF8523.c:24
rtc_status_t PCF8523_softreset(rtc_instance_t *rtc)
Definition PCF8523.c:168
#define WEEKDAYS_DATA
Definition PCF8523.c:48
PCF8523 Driver API definitions. This file provides data structures and APIs for controlling the PCF85...
#define LOG_INFO(debug, fmt,...)
Definition debug.h:237
#define DBG_MOD_RTC
Real Time Clock.
Definition debug.h:109
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
const rtc_api_t PCF8523_DRIVER
PCF8523 Driver Instance. Point your generic RTC pointer to this structure to use the PCF8523 hardware...
Definition PCF8523.c:55
rtc_status_t PCF8523_getTime(rtc_instance_t *rtc)
Get time from PCF8523 RTC.
Definition PCF8523.c:63
rtc_status_t PCF8523_getCSR(rtc_instance_t *rtc)
Get control/status register from PCF8523 RTC.
Definition PCF8523.c:176
rtc_status_t PCF8523_setTimeSystem(rtc_instance_t *rtc, u8 use_12hour_mode)
Set time system (12-hour or 24-hour) on PCF8523 RTC.
Definition PCF8523.c:128
rtc_status_t PCF8523_setTime(rtc_instance_t *rtc)
Set time on PCF8523 RTC.
Definition PCF8523.c:97
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
u8 convert_hour_register(u8 old_reg_val, u8 to_12h)
Convert hour register between 12-hour and 24-hour format.
Definition rtc.c:80
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