• 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 "string.h"
18 
19 #include <driver/int.h>
20 #include "sys_driver.h"
21 
22 #include <driver/aon_rtc.h>
23 #include "aon_rtc_hal.h"
24 #include "aon_rtc_driver.h"
25 
26 #define AON_RTC_UNIT_NUM (AON_RTC_HAL_UNIT_NUM)
27 #define AON_RTC_NAME ((uint8_t *)"aon_rtc")
28 
29 typedef struct {
30 	//aon_rtc_id_t id;	//no needs it until now:the id is matched from APP,DRIVER,HAL,HW/SOC layer.
31 	bool inited;
32 	//uint8_t using_cnt;	//remove it as only one HW can't for many APPs
33 
34 	aon_rtc_hal_t hal;
35 
36 	//Record APP param's
37 	//bool period;
38 	//uint32_t tick;
39 
40 	//Alarm list
41 	alarm_node_t *alarm_head_p;
42 	uint32_t alarm_node_cnt;
43 } aon_rtc_driver_t;
44 
45 typedef struct {
46 	aon_rtc_isr_t callback;
47 	void *isr_param;
48 } aon_rtc_callback_t;
49 
50 typedef struct {
51 	alarm_node_t nodes[AON_RTC_MAX_ALARM_CNT];
52 	uint64_t busy_bits;
53 } aon_rtc_nodes_memory_t;
54 
55 static aon_rtc_driver_t s_aon_rtc[AON_RTC_UNIT_NUM] = {0};
56 static aon_rtc_callback_t s_aon_rtc_tick_isr[AON_RTC_UNIT_NUM] = {NULL};
57 static aon_rtc_callback_t s_aon_rtc_upper_isr[AON_RTC_UNIT_NUM] = {NULL};
58 static aon_rtc_nodes_memory_t *s_aon_rtc_nodes_p[AON_RTC_UNIT_NUM];
59 static uint64_t s_high_tick[AON_RTC_UNIT_NUM];
60 
alarm_dump_node(alarm_node_t * node_p)61 static void alarm_dump_node(alarm_node_t *node_p)
62 {
63 #if AON_RTC_DEBUG
64 	AON_RTC_LOGD("%s[+]\r\n", __func__);
65 
66 	AON_RTC_LOGD("node_p=0x%x\r\n", node_p);
67 	if(node_p)
68 	{
69 		AON_RTC_LOGD("next=0x%x\r\n", node_p->next);
70 		AON_RTC_LOGD("name=%s\r\n", node_p->name);
71 		AON_RTC_LOGD("period_tick=0x%x\r\n", node_p->period_tick);
72 		AON_RTC_LOGD("period_cnt=%d\r\n", node_p->period_cnt);
73 		AON_RTC_LOGD("start_tick=0x%x\r\n", node_p->start_tick);
74 		AON_RTC_LOGD("expired_tick=0x%x\r\n", node_p->expired_tick);
75 	}
76 
77 	AON_RTC_LOGD("%s[-]\r\n", __func__);
78 #endif
79 }
80 
alarm_dump_list(alarm_node_t * head_p)81 static void alarm_dump_list(alarm_node_t *head_p)
82 {
83 #if AON_RTC_DEBUG
84 	alarm_node_t *cur_p = head_p;
85 	uint32_t count = 0;
86 	uint32_t int_level = 0;
87 
88 	AON_RTC_LOGD("%s[+]\r\n", __func__);
89 
90 	int_level = rtos_disable_int();
91 	while(cur_p)
92 	{
93 		alarm_dump_node(cur_p);
94 		count++;
95 
96 		cur_p = cur_p->next;
97 	}
98 	rtos_enable_int(int_level);
99 
100 	AON_RTC_LOGD("node cnt=%d\r\n", count);
101 
102 	AON_RTC_LOGD("%s[-]\r\n", __func__);
103 #endif
104 }
105 
aon_rtc_request_node(aon_rtc_id_t id)106 static alarm_node_t* aon_rtc_request_node(aon_rtc_id_t id)
107 {
108 	uint32_t i = 0;
109 
110 	AON_RTC_LOGD("%s[+]\r\n", __func__);
111 
112 	for(i = 0; i < AON_RTC_MAX_ALARM_CNT; i++)
113 	{
114 		if((s_aon_rtc_nodes_p[id]->busy_bits & (0x1<<i)) == 0)
115 		{
116 			AON_RTC_LOGD("%s[-]:node[%d]=0x%x\r\n", __func__, i, &s_aon_rtc_nodes_p[id]->nodes[i]);
117 			s_aon_rtc_nodes_p[id]->busy_bits |= (0x1<<i);
118 			return &s_aon_rtc_nodes_p[id]->nodes[i];
119 		}
120 	}
121 
122 	return NULL;
123 }
124 
aon_rtc_release_node(aon_rtc_id_t id,alarm_node_t * node_p)125 static void aon_rtc_release_node(aon_rtc_id_t id, alarm_node_t *node_p)
126 {
127 	uint32_t i = 0;
128 
129 	AON_RTC_LOGD("%s[+]\r\n", __func__);
130 
131 	for(i = 0; i < AON_RTC_MAX_ALARM_CNT; i++)
132 	{
133 		if(&s_aon_rtc_nodes_p[id]->nodes[i] == node_p)
134 		{
135 			s_aon_rtc_nodes_p[id]->busy_bits &= ~(0x1<<i);
136 			os_memset(&s_aon_rtc_nodes_p[id]->nodes[i], 0, sizeof(alarm_info_t));
137 			AON_RTC_LOGD("%s[-]:node[%d]=0x%x\r\n", __func__, i, &s_aon_rtc_nodes_p[id]->nodes[i]);
138 			break;
139 		}
140 	}
141 
142 	BK_ASSERT(i < AON_RTC_MAX_ALARM_CNT);
143 }
144 
alarm_insert_node(aon_rtc_id_t id,alarm_node_t * node_p)145 static int32_t alarm_insert_node(aon_rtc_id_t id, alarm_node_t *node_p)
146 {
147 	alarm_node_t *cur_p = NULL;
148 	alarm_node_t *next_p = NULL;
149 	uint32_t int_level = 0;
150 
151 	AON_RTC_LOGD("%s[+]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
152 
153 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
154 
155 	int_level = rtos_disable_int();
156 
157 	//check whether the same name
158 	cur_p = s_aon_rtc[id].alarm_head_p;
159 	while(cur_p)
160 	{
161 		if(strncmp((const char *)cur_p->name, (const char *)node_p->name, ALARM_NAME_MAX_LEN) == 0)
162 		{
163 			AON_RTC_LOGE("name=%s has registered\r\n", node_p->name);
164 			rtos_enable_int(int_level);
165 			return -1;
166 		}
167 
168 		cur_p = cur_p->next;
169 	}
170 
171 	//search the node position
172 	cur_p = s_aon_rtc[id].alarm_head_p;
173 
174 	//no node
175 	if(cur_p == NULL)
176 	{
177 		s_aon_rtc[id].alarm_head_p = node_p;
178 		s_aon_rtc[id].alarm_node_cnt++;
179 		AON_RTC_LOGD("insert first node 0x%x,name=%s\r\n", node_p, node_p->name);
180 
181 		rtos_enable_int(int_level);
182 		return 0;
183 	}
184 
185 	//only one node
186 	next_p = cur_p->next;
187 	if(next_p == NULL)
188 	{
189 		if(cur_p->expired_tick <= node_p->expired_tick)
190 			cur_p->next = node_p;
191 		else
192 		{
193 			node_p->next = cur_p;
194 			s_aon_rtc[id].alarm_head_p = node_p;
195 		}
196 		s_aon_rtc[id].alarm_node_cnt++;
197 		rtos_enable_int(int_level);
198 
199 		//TODO:log debug
200 		AON_RTC_LOGD("list total has two nodes\r\n");
201 
202 		return 0;
203 	}
204 
205 	//more then 2 nodes
206 	while(next_p)
207 	{
208 		if(cur_p->expired_tick <= node_p->expired_tick)	//move after cur_p
209 		{
210 			if(next_p->expired_tick <= node_p->expired_tick)	//search next
211 			{
212 				cur_p = next_p;
213 				next_p = next_p->next;
214 				continue;
215 			}
216 			else	//insert
217 			{
218 				node_p->next = next_p;
219 				cur_p->next = node_p;
220 				s_aon_rtc[id].alarm_node_cnt++;
221 				rtos_enable_int(int_level);
222 				return 0;
223 			}
224 		}
225 		else	//insert before cur_p, means the first node, head
226 		{
227 			node_p->next = cur_p;
228 			s_aon_rtc[id].alarm_head_p = node_p;
229 			s_aon_rtc[id].alarm_node_cnt++;
230 			rtos_enable_int(int_level);
231 			return 0;
232 		}
233 	}
234 
235 	//the last one
236 	cur_p->next = node_p;
237 	s_aon_rtc[id].alarm_node_cnt++;
238 	rtos_enable_int(int_level);
239 
240 	//dump list info
241 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
242 
243 	AON_RTC_LOGD("%s[-]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
244 
245 	return 0;
246 }
247 
alarm_remove_node(aon_rtc_id_t id,uint8_t * name_p)248 static alarm_node_t *alarm_remove_node(aon_rtc_id_t id, uint8_t *name_p)
249 {
250 	alarm_node_t *cur_p = NULL;
251 	alarm_node_t *previous_p = NULL;
252 	alarm_node_t *remove_node_p = NULL;
253 	uint32_t int_level = 0;
254 	uint32_t node_cnt = 0;
255 
256 	AON_RTC_LOGD("%s[+]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
257 
258 	int_level = rtos_disable_int();
259 	//
260 	previous_p = cur_p = s_aon_rtc[id].alarm_head_p;
261 	while(cur_p)
262 	{
263 		//double check pointer is valid
264 		node_cnt++;
265 		BK_ASSERT(node_cnt <= AON_RTC_MAX_ALARM_CNT);
266 
267 		if(strncmp((const char *)cur_p->name, (const char *)name_p, ALARM_NAME_MAX_LEN) == 0)
268 		{
269 			//first one
270 			if(previous_p == cur_p)
271 			{
272 				remove_node_p = s_aon_rtc[id].alarm_head_p;
273 				s_aon_rtc[id].alarm_head_p = cur_p->next;
274 				s_aon_rtc[id].alarm_node_cnt--;
275 
276 				AON_RTC_LOGD("free=0x%x,name=%s\r\n", cur_p, cur_p->name);
277 				aon_rtc_release_node(id, cur_p);
278 				break;
279 			}
280 			else
281 			{
282 				remove_node_p = cur_p;
283 				previous_p->next = cur_p->next;
284 				s_aon_rtc[id].alarm_node_cnt--;
285 				AON_RTC_LOGD("free=0x%x,name=%s\r\n", cur_p, cur_p->name);
286 				aon_rtc_release_node(id, cur_p);
287 				break;
288 			}
289 		}
290 
291 		previous_p = cur_p;
292 		cur_p = cur_p->next;
293 	}
294 
295 	rtos_enable_int(int_level);
296 
297 	if(remove_node_p == NULL)
298 	{
299 		AON_RTC_LOGE("%s:can't find %s alarm\r\n", __func__, name_p);
300 	}
301 
302 	//dump list info
303 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
304 
305 	AON_RTC_LOGD("%s[-]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
306 
307 	return remove_node_p;
308 }
309 
alarm_update_expeired_nodes(aon_rtc_id_t id)310 static void alarm_update_expeired_nodes(aon_rtc_id_t id)
311 {
312 	alarm_node_t *cur_p = NULL;
313 	alarm_node_t *next_p = NULL;
314 	uint32_t node_cnt = 0;
315 	uint64_t cur_tick = 0;
316 	uint32_t int_level = 0;
317 
318 	AON_RTC_LOGD("%s[+]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
319 
320 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
321 
322 	int_level = rtos_disable_int();
323 
324 	//search the node position
325 	cur_p = s_aon_rtc[id].alarm_head_p;
326 	while(cur_p)
327 	{
328 		alarm_dump_node(cur_p);
329 		alarm_dump_node(cur_p->next);
330 
331 		//double check pointer is valid
332 		node_cnt++;
333 		BK_ASSERT(node_cnt <= AON_RTC_MAX_ALARM_CNT);
334 
335 		next_p = cur_p->next;
336 
337 		cur_tick = bk_aon_rtc_get_current_tick(id);
338 		//maybe callback runs too much time,so assume the time in AON_RTC_MS_TICK_CNT means has expired
339 		if(cur_p->expired_tick <= cur_tick + AON_RTC_PRECISION_TICK)
340 		{
341 			if(cur_p->callback)
342 			{
343 				cur_p->callback(id, cur_p->name, cur_p->cb_param_p);
344 			}
345 
346 			//last time alarm
347 			if(cur_p->period_cnt == 1)
348 			{
349 				cur_p->period_cnt = 0;
350 				s_aon_rtc[id].alarm_head_p = cur_p->next;	//head move to next
351 				s_aon_rtc[id].alarm_node_cnt--;
352 /*
353  * WARNING:As freertos doesn't support free memory in ISR context.
354  * The chip no needs to use a task for AON RTC which wastes some memory.
355  * so the APPLIACTION who calls bk_alarm_register should release the memory
356  * returns by bk_alarm_register.
357  */
358 #if 0
359 				AON_RTC_LOGD("last alarm:free=0x%x,name=%s\r\n", cur_p, cur_p->name);
360 				os_free(cur_p);
361 #endif
362 				aon_rtc_release_node(id, cur_p);
363 			}
364 			//loop timer
365 			else
366 			{
367 				if(cur_p->period_cnt != ALARM_LOOP_FOREVER)
368 				{
369 					cur_p->period_cnt--;
370 					AON_RTC_LOGD("%s left %d times \r\n", cur_p->name, cur_p->period_cnt);
371 				}
372 
373 				//has next
374 				if(next_p)	//move to switable position
375 				{
376 					s_aon_rtc[id].alarm_head_p = cur_p->next;	//head move to next
377 					cur_p->expired_tick += cur_p->period_tick;
378 					cur_p->next = NULL;		//cur_p is removed
379 					s_aon_rtc[id].alarm_node_cnt--; //it will ++ in alarm_insert_node
380 					if(alarm_insert_node(id, cur_p) != 0)
381 					{
382 						AON_RTC_LOGE("alarm name=%s insert fail\r\n", cur_p->name);
383 						rtos_enable_int(int_level);
384 						return;
385 					}
386 				}
387 				else	//only self
388 				{
389 					//just update self expired time
390 					cur_p->expired_tick += cur_p->period_tick;
391 					AON_RTC_LOGD("%s update next expired time %d \r\n", cur_p->name, cur_p->expired_tick);
392 				}
393 			}
394 		}
395 		else	//no expired
396 		{
397 			break;
398 		}
399 
400 		cur_p = next_p;	//TODO:maybe cur_p offset is too small and calback excutes too much time, here can't switch to next NODE.
401 
402 		alarm_dump_list(s_aon_rtc[id].alarm_head_p);
403 	}
404 
405 	rtos_enable_int(int_level);
406 
407 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
408 
409 	AON_RTC_LOGD("%s[-]cnt=%d\r\n", __func__, s_aon_rtc[id].alarm_node_cnt);
410 }
411 
bk_aon_rtc_register_tick_isr(aon_rtc_id_t id,aon_rtc_isr_t isr,void * param)412 bk_err_t bk_aon_rtc_register_tick_isr(aon_rtc_id_t id, aon_rtc_isr_t isr, void *param)
413 {
414 	//AON_RTC_RETURN_ON_INVALID_ID(id);
415 	uint32_t int_level = rtos_disable_int();
416 	s_aon_rtc_tick_isr[id].callback = isr;
417 	s_aon_rtc_tick_isr[id].isr_param = param;
418 	rtos_enable_int(int_level);
419 	return BK_OK;
420 }
421 
422 /*
423  * aon rtc set tick uses 3 cycles of 32k in ASIC,
424  * cpu should check whether set tick success.
425  * If twice set tick in 3/32 ms, the second time set tick value will be failed.
426  */
aon_rtc_set_tick(aon_rtc_hal_t * hal,uint32_t val)427 static void aon_rtc_set_tick(aon_rtc_hal_t *hal, uint32_t val)
428 {
429 	volatile int i = 0;
430 
431 	aon_rtc_hal_set_tick_val(hal, val);
432 	while(aon_rtc_hal_get_tick_val_lpo(hal) != val)
433 	{
434 		i++;
435 		if(i > 768)	//32k, 3ticks == 3/32 ms:++is 30 cycles
436 		{
437 			AON_RTC_LOGE("%s:set tick timeout\r\n", __func__);
438 			break;
439 		}
440 	}
441 }
442 
bk_aon_rtc_register_upper_isr(aon_rtc_id_t id,aon_rtc_isr_t isr,void * param)443 bk_err_t bk_aon_rtc_register_upper_isr(aon_rtc_id_t id, aon_rtc_isr_t isr, void *param)
444 {
445 	//AON_RTC_RETURN_ON_INVALID_ID(id);
446 	uint32_t int_level = rtos_disable_int();
447 	s_aon_rtc_upper_isr[id].callback = isr;
448 	s_aon_rtc_upper_isr[id].isr_param = param;
449 	rtos_enable_int(int_level);
450 	return BK_OK;
451 }
452 
453 #if 0
454 static bk_err_t aon_rtc_isr_handler(aon_rtc_id_t id)
455 {
456 	//uses tick as one time timer
457 	if(aon_rtc_hal_get_tick_int_status(&s_aon_rtc[id].hal))
458 	{
459 		if (s_aon_rtc_tick_isr[id].callback) {
460 			s_aon_rtc_tick_isr[id].callback(id, AON_RTC_NAME, s_aon_rtc_tick_isr[id].isr_param);
461 		}
462 		aon_rtc_hal_clear_tick_int_status(&s_aon_rtc[id].hal);
463 
464 		bk_aon_rtc_destroy(id);
465 	}
466 
467 	//uses upper timer as period timer
468 	if(aon_rtc_hal_get_upper_int_status(&s_aon_rtc[id].hal))
469 	{
470 		if (s_aon_rtc_upper_isr[id].callback) {
471 			s_aon_rtc_upper_isr[id].callback(id, AON_RTC_NAME, s_aon_rtc_upper_isr[id].isr_param);
472 		}
473 
474 		aon_rtc_hal_clear_upper_int_status(&s_aon_rtc[id].hal);
475 	}
476 
477 	//TODO: clear NVIC/INTC/PLIC int pending status
478 
479 	return BK_OK;
480 }
481 #else
482 
483 #if AON_RTC_DEBUG
484 #define AON_RTC_ISR_DEBUG_MAX_CNT (256)
485 static uint32_t s_isr_cnt = 0;
486 static uint32_t s_isr_debug_in_tick[AON_RTC_ISR_DEBUG_MAX_CNT];
487 static uint32_t s_isr_debug_out_tick[AON_RTC_ISR_DEBUG_MAX_CNT];
488 static uint32_t s_isr_debug_set_tick[AON_RTC_ISR_DEBUG_MAX_CNT];
489 #endif
aon_rtc_isr_handler(aon_rtc_id_t id)490 static bk_err_t aon_rtc_isr_handler(aon_rtc_id_t id)
491 {
492 	uint32_t int_level = rtos_disable_int();
493 
494 #if AON_RTC_DEBUG
495 	s_isr_debug_in_tick[(s_isr_cnt)%AON_RTC_ISR_DEBUG_MAX_CNT] = bk_aon_rtc_get_current_tick(id);
496 #endif
497 
498 	AON_RTC_LOGD("%s[+]\r\n", __func__);
499 
500 	//uses tick as one time timer
501 	if(aon_rtc_hal_get_tick_int_status(&s_aon_rtc[id].hal))
502 	{
503 		//maybe the isr callback runs too much time and set next tick value too small, caused next isr can't response.
504 		aon_rtc_hal_clear_tick_int_status(&s_aon_rtc[id].hal);
505 
506 		alarm_update_expeired_nodes(id);
507 
508 		//reset the timer tick
509 		if(s_aon_rtc[id].alarm_head_p)
510 		{
511 			//+1:to assume set it valid,maybe aon rtc add 1 tick when set the value now.
512 			BK_ASSERT(bk_aon_rtc_get_current_tick(id) + 1/*AON_RTC_PRECISION_TICK*/ < s_aon_rtc[id].alarm_head_p->expired_tick);	//4:reserve enough time to set the tick
513 			aon_rtc_set_tick(&s_aon_rtc[id].hal, (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick);
514 #if AON_RTC_DEBUG
515 			s_isr_debug_set_tick[(s_isr_cnt)%AON_RTC_ISR_DEBUG_MAX_CNT] = (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick;
516 #endif
517 			AON_RTC_LOGD("next tick=0x%x, cur_tick=0x%x\r\n", (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick, (uint32_t)bk_aon_rtc_get_current_tick(id));
518 		}
519 		else
520 		{
521 			aon_rtc_set_tick(&s_aon_rtc[id].hal, AON_RTC_ROUND_TICK);
522 			AON_RTC_LOGI("no alarm:cur_tick=0x%x\r\n", (uint32_t)bk_aon_rtc_get_current_tick(id));
523 		}
524 	}
525 
526 	//uses upper timer as period timer
527 	if(aon_rtc_hal_get_upper_int_status(&s_aon_rtc[id].hal))
528 	{
529 		s_high_tick[id]++;
530 		AON_RTC_LOGI("32bits data overflow:high_tick=%d\r\n", s_high_tick[id]);
531 		if (s_aon_rtc_upper_isr[id].callback) {
532 			s_aon_rtc_upper_isr[id].callback(id, AON_RTC_NAME, s_aon_rtc_upper_isr[id].isr_param);
533 		}
534 
535 		aon_rtc_hal_clear_upper_int_status(&s_aon_rtc[id].hal);
536 	}
537 
538 	//TODO: clear NVIC/INTC/PLIC int pending status
539 
540 	AON_RTC_LOGD("%s[-]\r\n", __func__);
541 #if AON_RTC_DEBUG
542 	s_isr_debug_out_tick[(s_isr_cnt)%AON_RTC_ISR_DEBUG_MAX_CNT] = bk_aon_rtc_get_current_tick(id);
543 	s_isr_cnt++;
544 #endif
545 	rtos_enable_int(int_level);
546 
547 	return BK_OK;
548 }
549 
550 #endif
551 
aon_rtc1_isr_handler(void)552 static void aon_rtc1_isr_handler(void)
553 {
554 	aon_rtc_isr_handler(AON_RTC_ID_1);
555 }
556 
557 #if (SOC_AON_RTC_UNIT_NUM > 1)
aon_rtc2_isr_handler(void)558 static void aon_rtc2_isr_handler(void)
559 {
560 	aon_rtc_isr_handler(AON_RTC_ID_2);
561 }
562 #endif
563 
564 #if (CONFIG_SYSTEM_CTRL)
aon_rtc_interrupt_enable(aon_rtc_id_t id)565 static void aon_rtc_interrupt_enable(aon_rtc_id_t id)
566 {
567 	switch(id)
568 	{
569 		case AON_RTC_ID_1:
570 			sys_drv_int_group2_enable(RTC_INTERRUPT_CTRL_BIT);
571 			break;
572 #if (SOC_AON_RTC_UNIT_NUM > 1)
573 		case AON_RTC_ID_2:
574 			sys_drv_int_group2_enable(RTC1_INTERRUPT_CTRL_BIT);
575 			break;
576 #endif
577 		default:
578 			break;
579 	}
580 }
581 
aon_rtc_interrupt_disable(aon_rtc_id_t id)582 static void aon_rtc_interrupt_disable(aon_rtc_id_t id)
583 {
584 	switch(id)
585 	{
586 		case AON_RTC_ID_1:
587 			sys_drv_int_group2_disable(RTC_INTERRUPT_CTRL_BIT);
588 			break;
589 #if (SOC_AON_RTC_UNIT_NUM > 1)
590 		case AON_RTC_ID_2:
591 			sys_drv_int_group2_disable(RTC1_INTERRUPT_CTRL_BIT);
592 			break;
593 #endif
594 		default:
595 			break;
596 	}
597 }
598 #endif
599 
600 //run from 0
601 #if 0
602 static void aon_rtc_start_run(aon_rtc_id_t id)
603 {
604 	extern void delay_10us(UINT32 count);
605 
606 	AON_RTC_LOGD("%s[+]\r\n", __func__);
607 
608 	//start to run
609 	aon_rtc_hal_start_counter(&s_aon_rtc[id].hal);
610 	aon_rtc_hal_reset_counter(&s_aon_rtc[id].hal);	//maybe the start value isn't 0
611 	delay_10us(4);	//one cycle of 32k
612 	aon_rtc_hal_clear_reset_counter(&s_aon_rtc[id].hal);
613 
614 	AON_RTC_LOGD("%s[-]\r\n", __func__);
615 }
616 #endif
617 
aon_rtc_sw_init(aon_rtc_id_t id)618 static bk_err_t aon_rtc_sw_init(aon_rtc_id_t id)
619 {
620 	os_memset(&s_aon_rtc[id], 0, sizeof(s_aon_rtc[id]));
621 	os_memset(&s_aon_rtc_tick_isr[id], 0, sizeof(s_aon_rtc_tick_isr[id]));
622 	os_memset(&s_aon_rtc_upper_isr[id], 0, sizeof(s_aon_rtc_upper_isr[id]));
623 
624 	s_high_tick[id] = 0;
625 
626 	s_aon_rtc_nodes_p[id] = os_zalloc(sizeof(aon_rtc_nodes_memory_t));
627 	if(s_aon_rtc_nodes_p[id] == NULL)
628 	{
629 		return BK_ERR_NO_MEM;
630 	}
631 
632 	return BK_OK;
633 }
634 
aon_rtc_hw_init(aon_rtc_id_t id)635 static void aon_rtc_hw_init(aon_rtc_id_t id)
636 {
637 	aon_rtc_int_config_t int_config_table[] = AON_RTC_INT_CONFIG_TABLE;
638 	aon_rtc_int_config_t *cur_int_cfg = &int_config_table[id];
639 
640 	aon_rtc_hal_init(&s_aon_rtc[id].hal);
641 
642 	//set upper to max value
643 	aon_rtc_hal_set_upper_val(&s_aon_rtc[id].hal, AON_RTC_ROUND_TICK);
644 	aon_rtc_hal_enable_upper_int(&s_aon_rtc[id].hal);
645 
646 	bk_int_isr_register(cur_int_cfg->int_src, cur_int_cfg->isr, NULL);
647 #if (CONFIG_SYSTEM_CTRL)
648 	aon_rtc_interrupt_enable(id);
649 #endif
650 	aon_rtc_hal_start_counter(&s_aon_rtc[id].hal);
651 }
652 
bk_aon_rtc_driver_init(void)653 bk_err_t bk_aon_rtc_driver_init(void)
654 {
655 
656 	AON_RTC_LOGD("%s[+]\r\n", __func__);
657 
658 	//TOTO: Enter critical protect
659 	for (int id = AON_RTC_ID_1; id < AON_RTC_ID_MAX; id++) {
660 		if(!s_aon_rtc[id].inited)
661 		{
662 			aon_rtc_sw_init(id);
663 			aon_rtc_hw_init(id);
664 			s_aon_rtc[id].inited = true;
665 		}
666 	}
667 
668 	//TOTO: exit critical protect
669 	AON_RTC_LOGD("%s[-]\r\n", __func__);
670 
671 	return BK_OK;
672 }
673 
bk_aon_rtc_driver_deinit(void)674 bk_err_t bk_aon_rtc_driver_deinit(void)
675 {
676 	aon_rtc_int_config_t int_cfg_table[] = AON_RTC_INT_CONFIG_TABLE;
677 
678 	AON_RTC_LOGD("%s[+]\r\n", __func__);
679 
680 	for (int id = AON_RTC_ID_1; id < AON_RTC_ID_MAX; id++) {
681 		if(s_aon_rtc[id].inited)
682 		{
683 			bk_int_isr_unregister(int_cfg_table[id].int_src);
684 #if (CONFIG_SYSTEM_CTRL)
685 			aon_rtc_interrupt_disable(id);
686 #endif
687 			if(s_aon_rtc_nodes_p[id] != NULL)
688 			{
689 				os_free(s_aon_rtc_nodes_p[id]);
690 				s_aon_rtc_nodes_p[id] = NULL;
691 			}
692 
693 			s_aon_rtc[id].inited = false;
694 		}
695 	}
696 
697 	AON_RTC_LOGD("%s[-]\r\n", __func__);
698 	return BK_OK;
699 }
700 
701 #if 0	//remove it, only one HW can't be used for many APPs.
702 bk_err_t bk_aon_rtc_create(aon_rtc_id_t id, uint32_t tick, bool period)
703 {
704 	//Avoid APP call this function before driver has done bk_aon_rtc_driver_init
705 	if(s_aon_rtc[id].inited == false)
706 	{
707 		//TODO: logs: call aon_rtc_init first.
708 		return BK_ERR_NOT_INIT;
709 	}
710 
711 	if(s_aon_rtc[id].using_cnt)
712 	{
713 		//TODO: logs: call bk_aon_rtc_destroy first.
714 		return BK_ERR_BUSY;
715 	}
716 
717 	//TOTO: Enter critical protect
718 
719 	s_aon_rtc[id].using_cnt++;
720 	s_aon_rtc[id].tick = tick;
721 	s_aon_rtc[id].period = period;
722 
723 	//init HW
724 	s_aon_rtc[id].hal.id = id;
725 	aon_rtc_hal_init(&s_aon_rtc[id].hal);
726 
727 	if(period)	//use upper value int
728 	{
729 		aon_rtc_hal_set_upper_val(&s_aon_rtc[id].hal, tick);
730 		aon_rtc_hal_enable_upper_int(&s_aon_rtc[id].hal);
731 	}
732 	else
733 	{
734 		//confirm tick val <= upper value, or tick int never be entry.
735 		aon_rtc_hal_set_upper_val(&s_aon_rtc[id].hal, AON_RTC_UPPER_VAL_MAX);
736 
737 		aon_rtc_set_tick(&s_aon_rtc[id].hal, tick);
738 		aon_rtc_hal_enable_tick_int(&s_aon_rtc[id].hal);
739 	}
740 
741 	//start to run
742 	aon_rtc_start_run(id);
743 
744 	//TOTO: Exit critical protect
745 
746 	return BK_OK;
747 }
748 
749 bk_err_t bk_aon_rtc_destroy(aon_rtc_id_t id)
750 {
751 	//TOTO: Enter critical protect
752 
753 	if(s_aon_rtc[id].inited == false)
754 	{
755 		//TODO: logs: call aon_rtc_init first.
756 		//TOTO: Exit critical protect
757 		return BK_ERR_NOT_INIT;
758 	}
759 
760 	if(s_aon_rtc[id].using_cnt == 0)
761 	{
762 		//TODO: logs: call bk_aon_rtc_create first.
763 		//TOTO: Exit critical protect
764 		return BK_ERR_NOT_INIT;
765 	}
766 
767 	//stop HW before SW change value, avoid ISR status was update to INTC/NVIC/PLIC...
768 	//but doesn't response ISR, after HW deinit, the ISR comes caused error.
769 	aon_rtc_hal_deinit(&s_aon_rtc[id].hal);
770 
771 	s_aon_rtc[id].using_cnt = 0;
772 	s_aon_rtc[id].tick = 0;
773 	s_aon_rtc[id].period = false;
774 
775 	//TOTO: Exit critical protect
776 
777 	return BK_OK;
778 }
779 #endif
780 
bk_alarm_register(aon_rtc_id_t id,alarm_info_t * alarm_info_p)781 bk_err_t bk_alarm_register(aon_rtc_id_t id, alarm_info_t *alarm_info_p)
782 {
783 	alarm_node_t *node_p = NULL;
784 	uint32_t int_level = 0;
785 
786 	AON_RTC_LOGD("%s[+]\r\n", __func__);
787 
788 	if(id >= AON_RTC_ID_MAX)
789 	{
790 		AON_RTC_LOGE("%s:id=%d\r\n", __func__, id);
791 		return BK_ERR_PARAM;
792 	}
793 
794 	if(alarm_info_p == NULL)
795 	{
796 		return BK_ERR_PARAM;
797 	}
798 
799 	if(alarm_info_p->period_tick < AON_RTC_PRECISION_TICK)	//in protect area to reduce consume time before set tick.
800 	{
801 		AON_RTC_LOGE("period_tick should not smaller then %d\r\n", AON_RTC_PRECISION_TICK);
802 		return BK_FAIL;
803 	}
804 
805 	int_level = rtos_disable_int();
806 
807 	if(s_aon_rtc[id].alarm_node_cnt >= AON_RTC_MAX_ALARM_CNT)
808 	{
809 		rtos_enable_int(int_level);
810 		AON_RTC_LOGE("alarm registered too much:%d\r\n", AON_RTC_MAX_ALARM_CNT);
811 		return BK_FAIL;
812 	}
813 
814 	//request a node
815 	node_p = aon_rtc_request_node(id);
816 	if(node_p == NULL)
817 	{
818 		rtos_enable_int(int_level);
819 		AON_RTC_LOGE("alarm registered:no memory\r\n");
820 		return BK_ERR_NO_MEM;
821 	}
822 
823 	memset(node_p, 0, sizeof(alarm_node_t));
824 	node_p->callback = alarm_info_p->callback;
825 	node_p->cb_param_p = alarm_info_p->param_p;
826 	memcpy(&node_p->name[0], alarm_info_p->name, ALARM_NAME_MAX_LEN);
827 	node_p->name[ALARM_NAME_MAX_LEN] = 0;
828 	node_p->start_tick = bk_aon_rtc_get_current_tick(id);	//tick
829 	node_p->period_tick = alarm_info_p->period_tick;
830 	BK_ASSERT(alarm_info_p->period_cnt);
831 	node_p->period_cnt = alarm_info_p->period_cnt;
832 	node_p->expired_tick = node_p->start_tick + (alarm_info_p->period_tick);
833 
834 	//push to alarm list
835 	if(alarm_insert_node(id, node_p) != 0)
836 	{
837 		AON_RTC_LOGE("alarm name=%s has registered\r\n", alarm_info_p->name);
838 		aon_rtc_release_node(id, node_p);
839 		rtos_enable_int(int_level);
840 		return BK_FAIL;
841 	}
842 
843 	//reset the timer tick
844 	if(node_p == s_aon_rtc[id].alarm_head_p)	//insert node is the first one, should reset tick val
845 	{
846 		//+1:to assume set it valid,maybe aon rtc add 1 tick when set the value now.
847 		BK_ASSERT(bk_aon_rtc_get_current_tick(id) + 1/*AON_RTC_PRECISION_TICK*/ < s_aon_rtc[id].alarm_head_p->expired_tick);	//4:reserve enough time to set the tick
848 		aon_rtc_set_tick(&s_aon_rtc[id].hal, (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick);
849 	}
850 
851 	aon_rtc_hal_enable_tick_int(&s_aon_rtc[id].hal);
852 	AON_RTC_LOGD("next tick=0x%x, cur_tick=0x%x\r\n", (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick, (uint32_t)bk_aon_rtc_get_current_tick(id));
853 
854 	rtos_enable_int(int_level);
855 
856 	AON_RTC_LOGD("%s[-]\r\n", __func__);
857 
858 	return BK_OK;
859 }
860 
861 
862 //the timer isn't expired, but app un-register it.
bk_alarm_unregister(aon_rtc_id_t id,uint8_t * name_p)863 bk_err_t bk_alarm_unregister(aon_rtc_id_t id, uint8_t *name_p)
864 {
865 	alarm_node_t *remove_node_p = NULL;
866 	alarm_node_t *previous_head_node_p = NULL;
867 	uint32_t int_level = 0;
868 
869 	AON_RTC_LOGD("%s[+]\r\n", __func__);
870 
871 	if(id >= AON_RTC_ID_MAX)
872 	{
873 		AON_RTC_LOGE("%s:id=%d\r\n", __func__, id);
874 		return BK_ERR_PARAM;
875 	}
876 
877 	int_level = rtos_disable_int();
878 	previous_head_node_p = s_aon_rtc[id].alarm_head_p;
879 	remove_node_p = alarm_remove_node(id, name_p);
880 
881 	//reset the timer tick
882 	if(previous_head_node_p == remove_node_p)	//the previous head is removed
883 	{
884 		if(s_aon_rtc[id].alarm_head_p)	//new head exist
885 		{
886 			//+1:to assume set it valid,maybe aon rtc add 1 tick when set the value now.
887 			BK_ASSERT(bk_aon_rtc_get_current_tick(id) + 1/*AON_RTC_PRECISION_TICK*/ < s_aon_rtc[id].alarm_head_p->expired_tick);	//reserve enough time to set the tick
888 			aon_rtc_set_tick(&s_aon_rtc[id].hal, (uint32_t)s_aon_rtc[id].alarm_head_p->expired_tick);
889 			AON_RTC_LOGD("next tick=0x%x, cur_tick=0x%x\r\n", s_aon_rtc[id].alarm_head_p->expired_tick, bk_aon_rtc_get_current_tick(id));
890 		}
891 		else	//has no nodes now
892 		{
893 			aon_rtc_set_tick(&s_aon_rtc[id].hal, AON_RTC_ROUND_TICK);
894 			AON_RTC_LOGI("no alarm:cur_tick=0x%x\r\n", bk_aon_rtc_get_current_tick(id));
895 		}
896 	}
897 
898 	rtos_enable_int(int_level);
899 
900 	AON_RTC_LOGD("%s[-]\r\n", __func__);
901 	return BK_OK;
902 }
903 
904 #if (CONFIG_AON_RTC && (!CONFIG_AON_RTC_MANY_USERS))
bk_aon_rtc_tick_init()905 bk_err_t bk_aon_rtc_tick_init()
906 {
907     aon_rtc_hal_tick_init();
908 	return BK_OK;
909 }
bk_aon_rtc_open_rtc_wakeup(uint32_t period)910 bk_err_t bk_aon_rtc_open_rtc_wakeup(uint32_t period)
911 {
912     aon_rtc_hal_open_rtc_wakeup(period);
913 	return BK_OK;
914 }
915 #endif
916 
bk_aon_rtc_get_current_tick(aon_rtc_id_t id)917 uint64_t bk_aon_rtc_get_current_tick(aon_rtc_id_t id)
918 {
919 	if(id >= AON_RTC_ID_MAX)
920 	{
921 		AON_RTC_LOGE("%s:id=%d\r\n", __func__, id);
922 		return 0;
923 	}
924 
925 	return ((s_high_tick[id] << 32) + aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal));
926 }
927 
928 #if AON_RTC_DEBUG
bk_aon_rtc_timing_test(aon_rtc_id_t id,uint32_t round,uint32_t cycles,uint32_t set_tick)929 void bk_aon_rtc_timing_test(aon_rtc_id_t id, uint32_t round, uint32_t cycles, uint32_t set_tick)
930 {
931 	uint32_t int_level = 0;
932 	uint32_t i = 0, j = 0;
933 	uint32_t start_tick = 0, end_tick = 0;
934 	uint64_t u64_start_tick = 0, u64_end_tick = 0;
935 	uint32_t max_offset_tick = 0, min_offset_tick = 0xffffffff;
936 	uint32_t fail_cnt = 0;
937 
938 	AON_RTC_LOGD("%s[+]\r\n", __func__);
939 
940 	int_level = rtos_disable_int();
941 
942 	//get uint32_t tick counter check
943 	for(i = 0; i < round; i++)
944 	{
945 		start_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
946 		for(j = 0; j < cycles; j++)
947 		{
948 			aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
949 		}
950 		end_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
951 
952 		if(min_offset_tick > end_tick - start_tick)
953 			min_offset_tick = end_tick - start_tick;
954 		if(max_offset_tick < end_tick - start_tick)
955 			max_offset_tick = end_tick - start_tick;
956 	}
957 	AON_RTC_LOGI("Gettick uint32:%d rounds*%d times:max=%d,min=%d\r\n", i, j, max_offset_tick, min_offset_tick);
958 
959 	//get uint64_t tick counter check
960 	max_offset_tick = 0;
961 	min_offset_tick = 0xffffffff;
962 	for(i = 0; i < round; i++)
963 	{
964 		u64_start_tick = bk_aon_rtc_get_current_tick(id);
965 		for(j = 0; j < cycles; j++)
966 		{
967 			bk_aon_rtc_get_current_tick(id);
968 		}
969 		u64_end_tick = bk_aon_rtc_get_current_tick(id);
970 
971 		if(min_offset_tick > (uint32_t)(u64_end_tick - u64_start_tick))
972 			min_offset_tick = (uint32_t)(u64_end_tick - u64_start_tick);
973 		if(max_offset_tick < u64_end_tick - u64_start_tick)
974 			max_offset_tick = u64_end_tick - u64_start_tick;
975 	}
976 	AON_RTC_LOGI("Gettick uint64:%d rounds*%d times:max=%d,min=%d\r\n", i, j, max_offset_tick, min_offset_tick);
977 
978 	//set tick val check
979 	max_offset_tick = 0;
980 	min_offset_tick = 0xffffffff;
981 	for(i = 0; i < round; i++)
982 	{
983 		start_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
984 		for(j = 0; j < cycles; j++)
985 		{
986 			aon_rtc_set_tick(&s_aon_rtc[id].hal, set_tick);
987 		}
988 		end_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
989 
990 		if(min_offset_tick > end_tick - start_tick)
991 			min_offset_tick = end_tick - start_tick;
992 		if(max_offset_tick < end_tick - start_tick)
993 			max_offset_tick = end_tick - start_tick;
994 	}
995 	AON_RTC_LOGI("Settick:%d rounds*%d times:max=%d,min=%d\r\n", i, j, max_offset_tick, min_offset_tick);
996 
997 	fail_cnt = 0;
998 	max_offset_tick = 0;
999 	min_offset_tick = 0xffffffff;
1000 	for(i = 0; i < round; i++)
1001 	{
1002 		start_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
1003 		for(j = 0; j < cycles; j++)
1004 		{
1005 			aon_rtc_set_tick(&s_aon_rtc[id].hal, set_tick);
1006 			if(set_tick != aon_rtc_hal_get_tick_val(&s_aon_rtc[id].hal))
1007 			{
1008 				fail_cnt++;
1009 			}
1010 		}
1011 		end_tick = aon_rtc_hal_get_counter_val(&s_aon_rtc[id].hal);
1012 
1013 		if(min_offset_tick > end_tick - start_tick)
1014 			min_offset_tick = end_tick - start_tick;
1015 		if(max_offset_tick < end_tick - start_tick)
1016 			max_offset_tick = end_tick - start_tick;
1017 	}
1018 	AON_RTC_LOGI("Settick:%d rounds*%d times:max=%d,min=%d\r\n", i, j, max_offset_tick, min_offset_tick);
1019 	AON_RTC_LOGI("Settick:%d rounds*%d times:check fail_cnt=%d\r\n", i, j, fail_cnt);
1020 
1021 	rtos_enable_int(int_level);
1022 	AON_RTC_LOGD("%s[-]\r\n", __func__);
1023 }
1024 #endif
1025 
bk_aon_rtc_dump(aon_rtc_id_t id)1026 void bk_aon_rtc_dump(aon_rtc_id_t id)
1027 {
1028 #if AON_RTC_DEBUG
1029 	uint32_t i = 0, index = 0;
1030 
1031 	for(i = s_isr_cnt - AON_RTC_ISR_DEBUG_MAX_CNT; i < s_isr_cnt; i++)
1032 	{
1033 		index = i % AON_RTC_ISR_DEBUG_MAX_CNT;
1034 
1035 		for(volatile uint32_t j = 0; j < 1800; j++);	//confirm log output normarlly
1036 
1037 		AON_RTC_LOGI("isr_in[%d]=0x%x,out=0x%x,set=0x%x\r\n", index, s_isr_debug_in_tick[index], s_isr_debug_out_tick[index], s_isr_debug_set_tick[index]);
1038 	}
1039 #endif
1040 	aon_rtc_struct_dump();
1041 
1042 	alarm_dump_list(s_aon_rtc[id].alarm_head_p);
1043 }
1044 
1045 #if AON_RTC_DEBUG
bk_64bits_test(void)1046 void bk_64bits_test(void)
1047 {
1048 	uint64_t val_64bits = 0xffffffffffff;
1049 	uint64_t x1 = 0x111111111, x2 = 0x222222222, x3 = 0x333333333, t = 0;
1050 	uint32_t xh1 = 0x1, xl1 = 0x11111111;
1051 	//uint32_t xh2 = 0x2, xl2 = 0x22222222;
1052 	//uint32_t xh3 = 0x3, xl3 = 0x33333333;
1053 	//uint32_t th1 = 0, tl1 = 0;
1054 
1055 	t = xh1;
1056 	t = t<<32;
1057 	t += xl1;
1058 	if (t == 0x111111111)
1059 	{
1060 		AON_RTC_LOGD("left move 0x1<<32 is right\r\n");
1061 	}
1062 
1063 	if (t == x1)
1064 	{
1065 		AON_RTC_LOGD("uint64 compare is right\r\n");
1066 	}
1067 
1068 	if ((t & 0xffffffff) == xl1)
1069 	{
1070 		AON_RTC_LOGD("uint64 low 32bits is right\r\n");
1071 	}
1072 
1073 	if ((t >> 32) == xh1)
1074 	{
1075 		AON_RTC_LOGD("right move uint64 high 32bits is right\r\n");
1076 	}
1077 
1078 	if(x1 + x2 == x3)
1079 	{
1080 		AON_RTC_LOGD("uint64 add is right\r\n");
1081 	}
1082 
1083 	if(x3 - x2 == x1)
1084 	{
1085 		AON_RTC_LOGD("uint64 minus is right\r\n");
1086 	}
1087 
1088 	if((x1 * 2) == x2)
1089 	{
1090 		AON_RTC_LOGD("uint64 multi is right\r\n");
1091 	}
1092 
1093 	if((x2 / 2) == x1)
1094 	{
1095 		AON_RTC_LOGD("uint64 divide2 is right\r\n");
1096 	}
1097 
1098 	if((x2 / 32) == 0x11111111)
1099 	{
1100 		AON_RTC_LOGD("uint64 divide32 is right\r\n");
1101 	}
1102 
1103 	//pass:only output low 32 bits valid data
1104 	for(uint32_t i = 0; i < 64; i++)
1105 		AON_RTC_LOGD("0xffffffffffff>>%d == 0x%llx\r\n", i, val_64bits>>i);		//64 bits printf is error
1106 
1107 	//print:BIT64(i) low 32 bits
1108 	for(uint32_t i = 0; i < 64; i++)
1109 		AON_RTC_LOGD("Bit[%d] = 0x%llx, &=0x%llx\r\n", i, BIT64(i), (val_64bits & BIT64(i)));
1110 
1111 	AON_RTC_LOGD("64bits move\r\n");
1112 	for(uint64_t i = 0; i < 64; i++)
1113 		AON_RTC_LOGD("Bit[%d] = 0x%llx, &=0x%llx\r\n", i, BIT64(i), (val_64bits & BIT64(i)));
1114 
1115 	AON_RTC_LOGD("32bits move\r\n");
1116 	val_64bits = 0xa0a0a0a0a0a0a0a0;
1117 	for(uint32_t i = 0; i < 64; i++)
1118 	{
1119 		uint64_t ret = val_64bits & BIT64(i);
1120 		AON_RTC_LOGD("ret[%d] = 0x%llx = 0x%llx \r\n", i, ret, ret);	//print ret twice as 64 bits
1121 	}
1122 
1123 	AON_RTC_LOGD("64bits move\r\n");
1124 	val_64bits = 0xa0a0a0a0a0a0a0a0;
1125 	for(uint64_t i = 0; i < 64; i++)
1126 	{
1127 		uint64_t ret = val_64bits & BIT64(i);
1128 		AON_RTC_LOGD("ret[%d] = 0x%llx = 0x%llx \r\n", i, i, ret);		//print i twice as 64 bits
1129 	}
1130 }
1131 #endif
1132 
1133