Skip to content

Commit 31e4196

Browse files
author
Wayne Ren
authored
Merge pull request #103 from IRISZZW/arc_timer
arc: timer: add microsecond delay function
2 parents 0ad4396 + fdaa5d1 commit 31e4196

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

arc/arc_timer.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
* \todo RTC support should be improved if RTC is enabled
3636
*/
3737
#include "arc_timer.h"
38+
#include "arc_exception.h"
39+
40+
#define LPS_PREC 8
41+
42+
volatile uint64_t gl_loops_per_jiffy = 1;
43+
volatile uint32_t gl_count = 1;
44+
45+
46+
3847

3948

4049
/**
@@ -363,3 +372,86 @@ void secure_timer_init(void)
363372
}
364373
#endif /* ARC_FEATURE_SEC_TIMER1_PRESENT && ARC_FEATURE_SEC_TIMER0_PRESENT */
365374

375+
/**
376+
* \brief provide US delay function
377+
*
378+
* \param[in] usecs US to delay
379+
*/
380+
void arc_delay_us(uint32_t usecs)
381+
{
382+
__asm__ __volatile__(
383+
384+
" .extern gl_loops_per_jiffy \n"
385+
" .extern gl_count \n"
386+
" cmp %0, 0 \n"
387+
" jeq 1f \n"
388+
" ld %%r1, [gl_loops_per_jiffy] \n"
389+
" mpy %%r1, %%r1, %0 \n"
390+
" ld %%r2, [gl_count] \n"
391+
" divu %%r1, %%r1, %%r2 \n"
392+
" .align 4 \n"
393+
" mov %%lp_count, %%r1 \n"
394+
" lp 1f \n"
395+
" nop \n"
396+
"1: \n"
397+
:
398+
: "r"(usecs)
399+
: "lp_count", "r1", "r2");
400+
}
401+
402+
/**
403+
* \brief calibrate delay
404+
*
405+
* \param[in] board cpu clock
406+
* \return loops_per_jiffy
407+
*/
408+
uint64_t timer_calibrate_delay(uint32_t cpu_clock)
409+
{
410+
unsigned long loopbit;
411+
int lps_precision = LPS_PREC;
412+
volatile uint64_t loops_per_jiffy;
413+
uint32_t timer0_limit;
414+
uint32_t status;
415+
416+
gl_loops_per_jiffy = 1;
417+
gl_count = 1;
418+
419+
cpu_clock /= 1000;
420+
421+
status = cpu_lock_save();
422+
423+
timer0_limit = _arc_aux_read(AUX_TIMER0_LIMIT);
424+
_arc_aux_write(AUX_TIMER0_LIMIT, 0xFFFFFFFF);
425+
426+
loops_per_jiffy = (1 << 4);
427+
while ((loops_per_jiffy <<= 1) != 0) {
428+
429+
_arc_aux_write(AUX_TIMER0_CNT, 0);
430+
arc_delay_us(loops_per_jiffy);
431+
if (_arc_aux_read(AUX_TIMER0_CNT) > cpu_clock) {
432+
break;
433+
}
434+
}
435+
436+
loops_per_jiffy >>= 1;
437+
loopbit = loops_per_jiffy;
438+
while (lps_precision-- && (loopbit >>= 1)) {
439+
440+
loops_per_jiffy |= loopbit;
441+
_arc_aux_write(AUX_TIMER0_CNT, 0);
442+
arc_delay_us(loops_per_jiffy);
443+
if (_arc_aux_read(AUX_TIMER0_CNT) > cpu_clock) {
444+
loops_per_jiffy &= ~loopbit;
445+
}
446+
}
447+
448+
gl_loops_per_jiffy = loops_per_jiffy;
449+
gl_count = 1000;
450+
451+
_arc_aux_write(AUX_TIMER0_CNT, 0);
452+
_arc_aux_write(AUX_TIMER0_LIMIT, timer0_limit);
453+
cpu_unlock_restore(status);
454+
455+
return loops_per_jiffy;
456+
}
457+

board/board.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ void board_main(void)
180180
board_init();
181181
/* board level middlware init */
182182

183+
timer_calibrate_delay(BOARD_CPU_CLOCK);
183184

184185
#ifdef MID_COMMON
185186
xprintf_setup();

inc/arc/arc_timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ extern int32_t timer_stop(const uint32_t no);
109109
extern int32_t timer_current(const uint32_t no, void* val);
110110
extern int32_t timer_int_clear(const uint32_t no);
111111
extern void timer_init(void);
112+
extern void arc_delay_us(uint32_t usecs);
113+
extern uint64_t timer_calibrate_delay(uint32_t cpu_clock);
112114
extern int32_t secure_timer_present(const uint32_t no);
113115
extern int32_t secure_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val);
114116
extern int32_t secure_timer_stop(const uint32_t no);

0 commit comments

Comments
 (0)