Mercurial > nand-ecoscentric
changeset 2164:6087f9ab81ec
* src/timer_pit.c: fix hal_delay_us(). hal_clock_read for
initializing the PIT if needed. Change hal_clock_reset() to allow
setting of a new period. This is required when the timer is
started by hal_delay_us() or hal_clock_read() before
hal_clock_initialize().
| author | asl |
|---|---|
| date | Sun, 26 Mar 2006 11:02:59 +0000 |
| parents | 77e15aa63326 |
| children | fa277d078e96 |
| files | packages/hal/arm/at91/var/current/ChangeLog packages/hal/arm/at91/var/current/src/timer_pit.c |
| diffstat | 2 files changed, 38 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/hal/arm/at91/var/current/ChangeLog +++ b/packages/hal/arm/at91/var/current/ChangeLog @@ -1,3 +1,11 @@ +2006-03-10 Oliver Munz <munz@speag.ch> + + * src/timer_pit.c: fix hal_delay_us(). hal_clock_read for + initializing the PIT if needed. Change hal_clock_reset() to allow + setting of a new period. This is required when the timer is + started by hal_delay_us() or hal_clock_read() before + hal_clock_initialize(). + 2006-03-23 Andrew Lunn <andrew.lunn@ascom.ch> * src/timer_pit.c (hal_delay_us): Start the PIT if it is not
--- a/packages/hal/arm/at91/var/current/src/timer_pit.c +++ b/packages/hal/arm/at91/var/current/src/timer_pit.c @@ -79,7 +79,19 @@ void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period) { cyg_uint32 reg; + cyg_uint32 pimr; + CYG_ASSERT(period < 0xffffff, "Invalid HAL clock configuration"); + + // Check that the PIT has the right period. + HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR), pimr); + if ((pimr & 0xffffff) != (period - 1)){ + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + (period - 1) | + AT91_PITC_PIMR_PITEN | + AT91_PITC_PIMR_PITIEN); + } + /* Read the value register so that we clear the interrupt */ HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIVR, reg); } @@ -91,6 +103,14 @@ void hal_clock_read(cyg_uint32 *pvalue) { cyg_uint32 ir; + cyg_uint32 pimr; + + // Check that the PIT is running. If not start it. + HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr); + if (!(pimr & AT91_PITC_PIMR_PITEN)) { + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + 0xffffff | AT91_PITC_PIMR_PITEN); + } HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); *pvalue = ir & 0xfffff; @@ -105,14 +125,7 @@ void hal_delay_us(cyg_int32 usecs) { cyg_int64 ticks; cyg_uint32 val1, val2; - cyg_uint32 pimr; - - // Check that the PIT is running. If not start it. - HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr); - if (!(pimr & AT91_PITC_PIMR_PITEN)) { - HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), - 0xffff | AT91_PITC_PIMR_PITEN); - } + cyg_uint32 piv; // Calculate how many PIT ticks the required number of microseconds // equate to. We do this calculation in 64 bit arithmetic to avoid @@ -120,23 +133,18 @@ void hal_delay_us(cyg_int32 usecs) ticks = (((cyg_uint64)usecs) * ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL; - // I've no idea why, but waiting for the number of ticks calculated - // above does not work by about a factor or 3. If anybody works out - // why, please let me know! - ticks = ticks / 3; + // Calculate the wrap around period. + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv); + piv = (piv & 0xffffff) - 1; + hal_clock_read(&val1); while (ticks > 0) { - hal_clock_read(&val1); - do { - hal_clock_read(&val2); - } while (val1 == val2); - // Sometimes we miss a tick, maybe because of interrupt handling? - // So calculate the number of ticks, without making a big error - // with wrap around. - if (val2 > val1) + hal_clock_read(&val2); + if (val2 < val1) + ticks -= ((piv + val2) - val1); //overflow occurred + else ticks -= (val2 - val1); - else - ticks--; + val1 = val2; } }
