clock: Mutex, better names, stopping the counter.
*Found a periodic bug with wrong time addition. (probably the overflow handling.)
This commit is contained in:
parent
b5b54769b3
commit
27487de4f9
@ -43,28 +43,37 @@ Clock::~Clock() {}
|
|||||||
*/
|
*/
|
||||||
void Clock::updateClock()
|
void Clock::updateClock()
|
||||||
{
|
{
|
||||||
int64_t diff = 0;
|
int64_t diff_overflows = 0;
|
||||||
//Remember old number of overflows.
|
//Remember old number of overflows.
|
||||||
int64_t old_overflows = this->_overflows;
|
int64_t old_overflows = this->_overflows;
|
||||||
/* It would be nice to halt the counter for the next 2 lines.
|
|
||||||
Unless we are fine with rare 1-second errors.
|
this->_guard.lock();
|
||||||
*/
|
//Stop the counter.
|
||||||
|
Chip_SCT_SetControl(LPC_SCT1, 0x1 << 1);
|
||||||
//Capture number of counter overflows.
|
//Capture number of counter overflows.
|
||||||
this->_overflows = counter_overflows;
|
this->_overflows = counter_overflows;
|
||||||
//Capture the counter value.
|
//Capture the counter value.
|
||||||
uint32_t cur_count_u = LPC_SCT1->COUNT_U;
|
uint32_t cur_count_u = LPC_SCT1->COUNT_U;
|
||||||
|
//Resume the counter.
|
||||||
|
Chip_SCT_ClearControl(LPC_SCT1, 0x1 << 1);
|
||||||
|
this->_guard.unlock();
|
||||||
|
|
||||||
//Handle overflows.
|
//Handle overflows.
|
||||||
diff = (old_overflows <= this->_overflows)
|
diff_overflows = (old_overflows <= this->_overflows)
|
||||||
|
//Usually it is new amount of overflows - old.
|
||||||
? (this->_overflows - old_overflows)
|
? (this->_overflows - old_overflows)
|
||||||
|
//It is possible that overflows counter will overflow.
|
||||||
: (0xffffffffffffffff - old_overflows + this->_overflows + 1);
|
: (0xffffffffffffffff - old_overflows + this->_overflows + 1);
|
||||||
|
|
||||||
|
// Bug
|
||||||
|
// Counts += 1 minute 30 seconds (90 seconds, 90000 ms) sometimes, while has to count 10 seconds (10000 ms)
|
||||||
|
|
||||||
//Formula for getting elapsed milliseconds since the last function call.
|
//Formula for getting elapsed milliseconds since the last function call.
|
||||||
//Multiply max counter value by the number of overflows.
|
//Multiply max counter value by the number of overflows.
|
||||||
_raw_time += (double)((double)diff * (uint32_t)0xffffffff
|
_raw_time += (double)((double)diff_overflows * (uint32_t)0xffffffff
|
||||||
//Add full counter value if there are overflows.
|
//Add full counter value if there are overflows.
|
||||||
//Add difference between 2 captured counter values otherwise.
|
//Add difference between 2 captured counter values otherwise.
|
||||||
+ ((diff) ? cur_count_u : cur_count_u - this->_last_counter_value))
|
+ ((diff_overflows) ? cur_count_u : cur_count_u - this->_last_counter_value))
|
||||||
//We need the value in milliseconds
|
//We need the value in milliseconds
|
||||||
* 1000
|
* 1000
|
||||||
//Divide it by the clock frequency. t = 1 / f
|
//Divide it by the clock frequency. t = 1 / f
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#define PERIPHERALS_CLOCK_H_
|
#define PERIPHERALS_CLOCK_H_
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
#include "Fmutex.h"
|
||||||
|
|
||||||
struct TimeFromStart
|
struct TimeFromStart
|
||||||
{
|
{
|
||||||
@ -32,6 +33,7 @@ private:
|
|||||||
double _raw_time; //ms
|
double _raw_time; //ms
|
||||||
int64_t _overflows;
|
int64_t _overflows;
|
||||||
uint32_t _last_counter_value;
|
uint32_t _last_counter_value;
|
||||||
|
Fmutex _guard;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PERIPHERALS_CLOCK_H_ */
|
#endif /* PERIPHERALS_CLOCK_H_ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user