You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CubeSatSim/libs/libmf/source/setupcal.c

125 lines
2.2 KiB

#include "ax8052.h"
#include "libmfosc.h"
/**
* \brief set up oscillator calibration
*
*/
static __reentrantb uint8_t compute_frcosccfg(uint32_t reffreq) __reentrant
{
uint8_t x = 0;
while (reffreq >= 500) {
if (x & 0x80)
return x;
x += 0x08;
reffreq >>= 1;
}
if (reffreq < 250)
return 0x80;
return x;
}
static __reentrantb void compute_frcoscref(uint32_t reffreq, uint8_t calcfg) __reentrant
{
static const uint32_t __code refs[9] = {
10000000, 10000000 << 1, 10000000 << 2, 10000000 << 3, 10000000 << 4, 10000000 << 5, 10000000 << 6, 10000000 << 7, 10000000 << 8
};
calcfg >>= 3;
if (calcfg > 8) {
calcfg -= 8;
reffreq >>= calcfg;
calcfg = 8;
}
#ifdef SDCC
FRCOSCREF = refs[calcfg] / reffreq;
#else
{
uint16_t x = refs[calcfg] / reffreq;
FRCOSCREF0 = x;
FRCOSCREF1 = x >> 8;
}
#endif
}
static __reentrantb uint8_t compute_lposccfg(uint32_t reffreq) __reentrant
{
uint8_t x = 0;
reffreq /= 320;
while (reffreq >= 0xC000) {
if (x & 0x40)
return x;
x += 0x08;
reffreq >>= 1;
}
if (reffreq < 0x6000)
return 0x40;
#ifdef SDCC
LPOSCREF = reffreq;
#else
LPOSCREF0 = reffreq;
LPOSCREF1 = reffreq >> 8;
#endif
return x;
}
__reentrantb uint8_t setup_osc_calibration(uint32_t reffreq, uint8_t refosc) __reentrant
{
uint8_t refosc1 = refosc;
uint8_t lposccfg;
uint8_t frcosccfg;
frcosccfg = compute_frcosccfg(reffreq);
if (frcosccfg & 0x80)
return 1;
compute_frcoscref(reffreq, frcosccfg);
lposccfg = compute_lposccfg(reffreq);
if (lposccfg & 0x40) {
#ifdef SDCC
LPOSCREF = 0x7A12;
#else
LPOSCREF0 = 0x12;
LPOSCREF1 = 0x7A;
#endif
lposccfg = 0x80;
} else {
lposccfg |= 0x07;
}
lposccfg |= LPOSCCONFIG & 0x40;
switch (refosc1) {
case CLKSRC_XOSC:
setup_xosc();
OSCFORCERUN |= 0x04;
frcosccfg |= 0x02;
lposccfg &= 0xF8 | 0x02;
break;
case CLKSRC_LPXOSC:
setup_lpxosc();
OSCFORCERUN |= 0x08;
frcosccfg |= 0x03;
lposccfg &= 0xF8 | 0x03;
break;
case CLKSRC_RSYSCLK:
frcosccfg |= 0x04;
lposccfg &= 0xF8 | 0x04;
break;
default:
return 2;
}
#ifdef SDCC
FRCOSCKFILT = 0x4000;
LPOSCKFILT = 0x4000;
#else
FRCOSCKFILT0 = 0x00;
FRCOSCKFILT1 = 0x40;
LPOSCKFILT0 = 0x00;
LPOSCKFILT1 = 0x40;
#endif
FRCOSCCONFIG = frcosccfg;
LPOSCCONFIG = lposccfg;
return 0;
}

Powered by TurnKey Linux.