Here is the source of calculator of RC, divider:
#include <stdint.h>
#include <limits.h>
// max value of RC register with type uint16_t (unsigned short of AVR32 GCC)
#define MAX_RC (1<<(sizeof(uint16_t)*CHAR_BIT))
int
calc_tc_params(long *freq, long *err, uint16_t *presc, uint16_t *rc)
{
static const long divs[] = {2, 8, 32, 128};
static const int ndivs = sizeof divs/sizeof divs[0];
long _err = 0, _merr = *err;
uint16_t _rc = 0, _mrc = 0, _idiv = 0, _midiv = 0;
for (_idiv = 0; _idiv < ndivs; _idiv++) {
_rc = (FPBA / divs[_idiv]) / (*freq);
_rc = (_rc==0? 1 : _rc>MAX_RC? MAX_RC : _rc);
_err = abs((*freq) - (FPBA / divs[_idiv]) / (long)_rc);
if (_err <= _merr) {
_merr = _err;
_midiv = _idiv;
_mrc = _rc;
}
if (!_err) break;
}
if (_mrc) {
*rc = _mrc;
*err = _merr;
*presc = divs[_midiv];
*freq = (FPBA / divs[_midiv]) / _mrc;
return (1);
} else
return (0);
}
NOTE: FPBA is the frequency of PBA line. Inputs are:
- freq - frequency in Hz
- err - absolute error in Hz
- freq - real frequency for calculated params
- err - real absolute error
- presc - divider value (2..128)
- rc - value for RC register to load
#define PRESC2TCSRC(PRESC) ((PRESC)==2? TC_CLOCK_SOURCE_TC2 \
:(PRESC)==8? TC_CLOCK_SOURCE_TC3 \
:(PRESC)==32? TC_CLOCK_SOURCE_TC4 \
:(PRESC)==128? TC_CLOCK_SOURCE_TC5 \
:-1)
and it's result should be used as tcclks member of tc_waveform_opt_t struct.On success, returns 1, 0 otherwise.
For more information how to start 'ticks' generation, see ASF example TC_EXAMPLE3 of TC module.
Комментариев нет:
Отправить комментарий
Thanks for your posting!