mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-02 08:42:52 +00:00
base-hw: fix EPIT duration calculation on roll-over
If Ocif was not reset between two calls to _duration(), the returned value exceeded _max_value().
This commit is contained in:
parent
abb2045e17
commit
2f1520b4c1
@ -54,6 +54,7 @@ void Board::Timer::init()
|
|||||||
Cr::access_t cr = read<Cr>();
|
Cr::access_t cr = read<Cr>();
|
||||||
Cr::En_mod::set(cr, Cr::En_mod::RELOAD);
|
Cr::En_mod::set(cr, Cr::En_mod::RELOAD);
|
||||||
Cr::Oci_en::set(cr, 1);
|
Cr::Oci_en::set(cr, 1);
|
||||||
|
Cr::Rld::set(cr, 0);
|
||||||
Cr::Prescaler::set(cr, Cr::Prescaler::DIVIDE_BY_1);
|
Cr::Prescaler::set(cr, Cr::Prescaler::DIVIDE_BY_1);
|
||||||
Cr::Clk_src::set(cr, Cr::Clk_src::HIGH_FREQ_REF_CLK);
|
Cr::Clk_src::set(cr, Cr::Clk_src::HIGH_FREQ_REF_CLK);
|
||||||
Cr::Iovw::set(cr, 1);
|
Cr::Iovw::set(cr, 1);
|
||||||
@ -97,19 +98,8 @@ time_t Timer::_duration() const
|
|||||||
Device::Cnt::access_t const initial_cnt {
|
Device::Cnt::access_t const initial_cnt {
|
||||||
(Device::Cnt::access_t)_last_timeout_duration };
|
(Device::Cnt::access_t)_last_timeout_duration };
|
||||||
|
|
||||||
/*
|
|
||||||
* There are two situations here:
|
|
||||||
*
|
|
||||||
* 1. SR.OCIF reads as 1, meaning, the timer IRQ has triggered. In
|
|
||||||
* this case we read CNT after having read SR.OCIF in order to
|
|
||||||
* ensure that we use a post-IRQ (wrapped) counter value.
|
|
||||||
*
|
|
||||||
* 2. SR.OCIF reads as 0, meaning, the timer IRQ hasn't triggered yet. In
|
|
||||||
* this case we read CNT before having read SR.OCIF in order to
|
|
||||||
* ensure that we use a pre-IRQ (non-wrapped) counter value.
|
|
||||||
*/
|
|
||||||
Device::Cnt::access_t const curr_cnt { _device.read<Device::Cnt>() };
|
Device::Cnt::access_t const curr_cnt { _device.read<Device::Cnt>() };
|
||||||
if (_device.read<Device::Sr::Ocif>())
|
if (curr_cnt > initial_cnt)
|
||||||
return _max_value() - _device.read<Device::Cnt>() + initial_cnt;
|
return _max_value() - _device.read<Device::Cnt>() + initial_cnt;
|
||||||
else
|
else
|
||||||
return initial_cnt - curr_cnt;
|
return initial_cnt - curr_cnt;
|
||||||
|
@ -40,6 +40,7 @@ struct Board::Timer : Genode::Mmio<0x14>
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Oci_en : Bitfield<2, 1> { }; /* interrupt on compare */
|
struct Oci_en : Bitfield<2, 1> { }; /* interrupt on compare */
|
||||||
|
struct Rld : Bitfield<3, 1> { }; /* counter reload mode */
|
||||||
|
|
||||||
struct Prescaler : Bitfield<4, 12> /* clock input divisor */
|
struct Prescaler : Bitfield<4, 12> /* clock input divisor */
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user