• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <common/bk_include.h>
16 #include <os/mem.h>
17 #include <driver/calendar.h>
18 #include "calendar_driver.h"
19 #include "calendar_hal.h"
20 
21 typedef struct {
22 	calendar_hal_t hal;
23 } calendar_driver_t;
24 
25 #define CALENDAR_SRC_CLOCK_FREQ         32000
26 #define CALENDAR_CLOCKS_PER_SECOND      CALENDAR_SRC_CLOCK_FREQ
27 #define CALENDAR_PERIOD_US_PER_CLOCK    31.25f /* (1 / CALENDAR_SRC_CLOCK_FREQ) * 1000000 us */
28 
29 #define CALENDAR_RETURN_ON_NOT_INIT() do {\
30 	if (!s_calendar_driver_is_init) {\
31 		return BK_ERR_CALENDAR_NOT_INIT;\
32 	}\
33 } while(0)
34 
35 static calendar_driver_t s_calendar = {0};
36 static bool s_calendar_driver_is_init = false;
37 
calendar_deinit_common(void)38 static void calendar_deinit_common(void)
39 {
40 	calendar_hal_disable(&s_calendar.hal);
41 	calendar_hal_reset_config_to_default(&s_calendar.hal);
42 }
43 
bk_calendar_driver_init(void)44 bk_err_t bk_calendar_driver_init(void)
45 {
46 	if (s_calendar_driver_is_init) {
47 		return BK_OK;
48 	}
49 
50 	os_memset(&s_calendar, 0, sizeof(s_calendar));
51 	calendar_hal_init(&s_calendar.hal);
52 	s_calendar_driver_is_init = true;
53 
54 	return BK_OK;
55 }
56 
bk_calendar_driver_deinit(void)57 bk_err_t bk_calendar_driver_deinit(void)
58 {
59 	if (!s_calendar_driver_is_init) {
60 		return BK_OK;
61 	}
62 
63 	calendar_deinit_common();
64 	s_calendar_driver_is_init = false;
65 
66 	return BK_OK;
67 }
68 
bk_calendar_set_init_value(uint32_t init_val)69 bk_err_t bk_calendar_set_init_value(uint32_t init_val)
70 {
71 	CALENDAR_RETURN_ON_NOT_INIT();
72 	calendar_hal_set_init_value(&s_calendar.hal, init_val);
73 
74 	return BK_OK;
75 }
76 
bk_calendar_get_time_us(void)77 uint64_t bk_calendar_get_time_us(void)
78 {
79 	uint64_t total_us_since_calendar_init = 0;
80 	uint32_t seconds, pre_seconds = 0;
81 	uint32_t clocks_of_us_part, pre_clocks_of_us_part = 0;
82 	uint32_t diff_s, diff_us = 0;
83 
84 	while (1) {
85 		seconds = calendar_hal_get_second_cnt(&s_calendar.hal);
86 		clocks_of_us_part = calendar_hal_get_us_cnt(&s_calendar.hal);
87 		diff_s = seconds - pre_seconds;
88 		diff_us = clocks_of_us_part - pre_clocks_of_us_part;
89 		if ((0 == diff_s) && (0 == diff_us)) {
90 			break;
91 		}
92 
93 		pre_seconds = seconds;
94 		pre_clocks_of_us_part = clocks_of_us_part;
95 	}
96 
97 	/* The calendar source clock is lpo_clk(default 32k).
98 	 * notice:
99 	 * Please check lpo_clk_mux(sys_ctrl REG_0x40[0:1]) is whether rosc clock,
100 	 * If lpo_clk_mux select rosc clock, please check whether the rosc_clk is calibrated to 32k(sys_ctrl REG_0x4D[2])
101 	 * Please ensure the rosc_clk is calibrated to 32k if lpo_clk_mux select rosc_clk,
102 	 * otherwise the following formula is wrong if rosc_clk is calibrated to 31.25k.
103 	 */
104 	total_us_since_calendar_init = (seconds * CALENDAR_CLOCKS_PER_SECOND + clocks_of_us_part) * CALENDAR_PERIOD_US_PER_CLOCK;
105 
106 	return total_us_since_calendar_init;
107 }
108 
109