diff options
| author | Tomasz Moń <desowin@gmail.com> | 2011-12-20 12:49:59 +0000 |
|---|---|---|
| committer | Tomasz Moń <desowin@gmail.com> | 2011-12-20 12:49:59 +0000 |
| commit | 4aec0012440ceeeee45913cfe5ce8869597db1f6 (patch) | |
| tree | bc8a76bbb8343f65834ec7db91290f4f83ae9c01 /firmware | |
| parent | 1a4aea3ad8920edd6c5fa4cb419a98f0d3c91fbf (diff) | |
| download | rockbox-4aec0012440ceeeee45913cfe5ce8869597db1f6.zip rockbox-4aec0012440ceeeee45913cfe5ce8869597db1f6.tar.gz rockbox-4aec0012440ceeeee45913cfe5ce8869597db1f6.tar.bz2 rockbox-4aec0012440ceeeee45913cfe5ce8869597db1f6.tar.xz | |
TMS320DM320: Use TIMER1 (tick generator) to make udelay() precise.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31376 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
| -rw-r--r-- | firmware/target/arm/tms320dm320/system-dm320.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c index 267fbd4..a2a9ec3 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)); } } |