diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.cc b/repos/base-hw/src/core/spec/arm/imx_epit.cc index 9dae247282..2c174eda8d 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.cc +++ b/repos/base-hw/src/core/spec/arm/imx_epit.cc @@ -36,6 +36,19 @@ Board::Timer::Timer(unsigned) void Board::Timer::init() { + /* + * Used timer mode: + * + * - Set CNT to 0xffffffff whenever CR.EN goes from 0 to 1 (CR.EN_MOD = 1). + * This happens only once: at construction time. + * - CNT is counting downwards with timer frequency. + * - When CNT reaches 0 it rolls over to 0xffffffff (CR.RLD = 0). + * - When writing LR, also set CNT to new LR value (CR.IOVW = 1). This + * happens whenever a timeout is programmed. + * - Trigger IRQ when CNT == CMPR (CR.OCI_EN = 1). CMPR is always set to + * 0xffffffff. + */ + reset(); Cr::access_t cr = read(); @@ -81,8 +94,8 @@ time_t Timer::_max_value() const { time_t Timer::_duration() const { using Device = Board::Timer; - Device::Cnt::access_t last = (Device::Cnt::access_t) _last_timeout_duration; - Device::Cnt::access_t cnt = _device.read(); - return (_device.read()) ? _max_value() - cnt + last + Device::Cnt::access_t const last = (Device::Cnt::access_t) _last_timeout_duration; + Device::Cnt::access_t const cnt = _device.read(); + return (_device.read()) ? _max_value() - _device.read() + last : last - cnt; } diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.h b/repos/base-hw/src/core/spec/arm/imx_epit.h index 6b47cb4187..328fc692ed 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.h +++ b/repos/base-hw/src/core/spec/arm/imx_epit.h @@ -41,11 +41,6 @@ struct Board::Timer : Genode::Mmio struct Oci_en : Bitfield<2, 1> { }; /* interrupt on compare */ - struct Rld : Bitfield<3, 1> /* reload or roll-over */ - { - enum { RELOAD_FROM_LR = 1 }; - }; - struct Prescaler : Bitfield<4, 12> /* clock input divisor */ { enum { DIVIDE_BY_1 = 0 };