From 4aec0012440ceeeee45913cfe5ce8869597db1f6 Mon Sep 17 00:00:00 2001 From: Tomasz Moń Date: Tue, 20 Dec 2011 12:49:59 +0000 Subject: TMS320DM320: Use TIMER1 (tick generator) to make udelay() precise. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31376 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/tms320dm320/system-dm320.c | 38 +++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'firmware') diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c index 267fbd46af..a2a9ec3661 100644 --- a/firmware/target/arm/tms320dm320/system-dm320.c +++ b/firmware/target/arm/tms320dm320/system-dm320.c @@ -412,14 +412,38 @@ void set_cpu_frequency(long frequency) } #endif -/* This function is pretty crude. It is not acurate to a usec, but errors on - * longer. - */ void udelay(int usec) { - volatile int temp=usec*(175000/200); - - while(temp) { - temp--; + unsigned short count = IO_TIMER1_TMCNT; + unsigned short stop; + unsigned short tmp = IO_TIMER1_TMDIV; + int prev_tick = current_tick; + + /* + * On Sansa Connect tick timer counts from 0 to 26999 + * in this case stop will overflow only if usec > 10000 + * such long delays shouldn't be blocking (use sleep() instead) + */ + stop = count + usec*((tmp+1)/10000); + stop += (unsigned short)(((unsigned long)(usec)*((tmp%10000)+1))/10000); + + /* stop values over tmdiv won't ever be reached */ + if (stop > tmp) + { + stop -= tmp; + } + + if (stop < count) + { + /* udelay will end after counter reset (tick) */ + while ((((tmp = IO_TIMER1_TMCNT) < stop) && + (current_tick != prev_tick)) || + (current_tick == prev_tick)); /* ensure new tick */ + } + else + { + /* udelay will end before counter reset (tick) */ + while (((tmp = IO_TIMER1_TMCNT) < stop) && + (current_tick == prev_tick)); } } -- cgit v1.2.3