9#include <clock_msp432.h>
14clock_msp432::clock_msp432() {
16 kalib04 = (768 - TLV->DCOIR_FCAL_RSEL04);
17 kalib04 += 1.0f / *((
float *)(&TLV->DCOIR_CONSTK_RSEL04));
19 kalib5 = (768 - TLV->DCOIR_FCAL_RSEL04);
20 kalib5 += 1.0f / *((
float *)(&TLV->DCOIR_CONSTK_RSEL5));
30clock_msp432::~clock_msp432() {
33void clock_msp432::setOscFrequency(CLKSYS::OSC clk, uint32_t hz) {
41 assert(hz>=1000000 && hz<=64000000);
43 int16_t maxtune04 = (int16_t)(TLV->DCOIR_MAXPOSTUNE_RSEL04);
44 int16_t mintune04 = (int16_t)(TLV->DCOIR_MAXNEGTUNE_RSEL04 | 0xffffe000);
45 int16_t maxtune5 = (int16_t)(TLV->DCOIR_MAXPOSTUNE_RSEL5);
46 int16_t mintune5 = (int16_t)(TLV->DCOIR_MAXNEGTUNE_RSEL5 | 0xffffe000);
47 float f_center = 1500000;
50 for (rsel=0; rsel <= 5; ++rsel) {
51 tune = 1.0f - (f_center / (float)hz);
54 if ((tune <= maxtune04) && (tune >= mintune04))
59 if ((tune <= maxtune5) && (tune >= mintune5))
66 int16_t tune_int = (int16_t)(tune + 0.5f);
74 assert(hz==32768 || hz==128000);
76 CS->CLKEN &= ~CS_CLKEN_REFOFSEL;
82 default: assert(
false);
88uint32_t clock_msp432::getOscFrequency(CLKSYS::OSC osc) {
90 case CLKSYS::LFXT:
return 32768;
91 case CLKSYS::HFXT:
return 48000000;
92 case CLKSYS::DCO:
return getDcoFrequency();
93 case CLKSYS::VLO:
return 10000;
95 case CLKSYS::MODOSC:
return 24000000;
100uint32_t clock_msp432::getClockFrequency(CLKSYS::CLK clk) {
115 case CLKSYS::HSMCLK: {
120 case CLKSYS::SMCLK: {
132 case 0: f=getOscFrequency(CLKSYS::LFXT);
break;
133 case 1: f=getOscFrequency(CLKSYS::VLO);
break;
134 case 2: f=getOscFrequency(CLKSYS::REFO);
break;
135 case 3: f=getOscFrequency(CLKSYS::DCO);
break;
136 case 4: f=getOscFrequency(CLKSYS::MODOSC);
break;
137 case 5: f=getOscFrequency(CLKSYS::HFXT);
break;
138 default: assert(
false);
144void clock_msp432::setCLockSource(CLKSYS::CLK clk, CLKSYS::OSC osc, uint8_t div) {
145 assert ((div > 0) && (div < 129) && !(div & (div-1)));
151 uint8_t osc_shift = 0;
152 uint8_t div_shift = 0;
153 while (!(div & 0x01)) {
159 assert(osc == CLKSYS::LFXT ||
160 osc == CLKSYS::VLO ||
161 osc == CLKSYS::REFO);
171 case CLKSYS::HSMCLK: {
176 case CLKSYS::SMCLK: {
184 case CLKSYS::LFXT: CS->CTL1 &= ~CS_CTL1_SELB;
break;
186 default: assert(
false);
192 if (clk != CLKSYS::BCLK) {
193 CS->CTL1 &= ~ (0x07 << osc_shift);
195 case CLKSYS::LFXT: CS->CTL1 |= 0x00 << osc_shift;
break;
196 case CLKSYS::VLO: CS->CTL1 |= 0x01 << osc_shift;
break;
197 case CLKSYS::REFO: CS->CTL1 |= 0x02 << osc_shift;
break;
198 case CLKSYS::DCO: CS->CTL1 |= 0x03 << osc_shift;
break;
199 case CLKSYS::MODOSC: CS->CTL1 |= 0x04 << osc_shift;
break;
200 case CLKSYS::HFXT: CS->CTL1 |= 0x05 << osc_shift;
break;
202 CS->CTL1 &= ~ (0x07 << div_shift);
203 CS->CTL1 |= div_val << div_shift;
210uint32_t clock_msp432::getDcoFrequency() {
212 float kalib = (rsel <= 4) ? kalib04 : kalib5;
213 uint32_t f_center = 1500000 << rsel;
214 int16_t tune = (CS->CTL0 & 0x1fff);
215 if (tune & 0x1000) tune |= 0xe000;
216 float f = (float)f_center / (kalib - (
float)tune) * kalib;
217 return (uint32_t)(f + 0.5f);
#define CS_CTL1_DIVS_MASK
#define CS_CTL1_SELS_MASK
#define CS_CTL0_DCORSEL_MASK
#define CS_CTL0_DCORSEL_OFS
#define CS_CTL1_DIVA_MASK
#define CS_CTL1_SELM_MASK
#define CS_CTL1_SELA_MASK
#define CS_CLKEN_REFOFSEL
#define CS_CTL1_DIVHS_OFS
#define CS_CTL1_DIVHS_MASK
#define CS_CTL1_DIVM_MASK