uint8_t ucs_clockinit(unsigned long freq, uint8_t use_xt1, uint8_t vlo_as_aclk) { unsigned long attempts = 0; //, divided; uint16_t flld; static uint8_t did_vcoreup = 0; UCSCTL4 = SELM__DCOCLK | SELS__DCOCLK; if (vlo_as_aclk) UCSCTL4 = (UCSCTL4 & ~SELA_7) | SELA__VLOCLK; if (use_xt1) { PJSEL |= BIT4|BIT5; UCSCTL6 &= ~XT1OFF; UCSCTL6 = (UCSCTL6 & ~(XCAP_3|XT1DRIVE_3)) | XCAP_0 | XT1DRIVE_3; if (!vlo_as_aclk) UCSCTL4 = (UCSCTL4 & ~SELA_7) | SELA__XT1CLK; // Wait for XT1 to stabilize do { UCSCTL7 &= ~XT1LFOFFG; attempts++; } while (UCSCTL7 & XT1LFOFFG && attempts < 1000000); if (attempts == 1000000) return 0; // XT1 FAILED } else { UCSCTL6 |= XT1OFF; UCSCTL7 &= ~(XT1LFOFFG | XT1HFOFFG); UCSCTL3 = SELREF__REFOCLK; } // Using frequency, determine which VCore level we should achieve. // Set Vcore to maximum if (!did_vcoreup) { SetVCoreUp(1); SetVCoreUp(2); SetVCoreUp(3); did_vcoreup = 1; } // Initialize DCO __bis_SR_register(SCG0); // Disable FLL control loop UCSCTL0 = 0x0000; // Determine which DCORSEL we should use UCSCTL1 = _dcorsel_compute_f5172(freq); // FLL reference is 32768Hz, determine multiplier flld = _flld_compute(freq); UCSCTL2 = ((flld/2) << 12) | (uint16_t)(freq / 32768UL / flld); __bic_SR_register(SCG0); // Re-enable FLL control loop // Loop until XT1 & DCO fault flags have cleared do { UCSCTL7 &= ~(XT1LFOFFG | XT1HFOFFG | DCOFFG); SFRIFG1 &= ~OFIFG; } while ( (UCSCTL7 & DCOFFG) || (use_xt1 && (SFRIFG1 & OFIFG)) ); // DCOCLK stable return 1; }
int main(void) { uint16_t time = 0; led_color_t col; // dog WDTCTL = WDTPW + WDTHOLD; // set vcore to highest value, mclk 24 MHz SetVCoreUp(0x01); SetVCoreUp(0x02); SetVCoreUp(0x03); // hw init hardware_clock_init(); init_spi_master(); timer_init(); // internal LED and debug pins P1DIR |= BIT0; P2DIR |= BIT2; // channel 17 = UCATXIFG as trigger for DMA DMACTL0 = 0; DMACTL1 = 17; DMACTL2 = 0; DMACTL3 = 0; // DMA2 configuration // bytewise access for source and destination, increment source, single transfer DMA2CTL = DMADT_0 | DMASRCINCR_3 | DMASRCBYTE | DMADSTBYTE | DMAIE; DMA2SA = (uint16_t)(&led_raw[1]); // source DMA2DA = (uint16_t)&UCA0TXBUF; // destination DMA2SZ = SIZE_OF_LED_ARRAY-1; // size in bytes __eint(); // all set, now let the DMA run DMA2CTL |= DMAEN ; UCA0TXBUF = led_raw[0]; while (1) { time++; P1OUT ^= BIT0; LPM0; // DMA transfer has finished, you may calculate LED updates now // timer A is triggered app. every 10msec, so you have around 6msec time // to update the strip // this is a color fading thing for (uint8_t i=0; i<NR_OF_LEDS; i++){ col.g = (time % 512) + i*4; col.r = (time % 256) + i; col.b = (time / 1024) + (NR_OF_LEDS - i); set_LED(i,&col); } } }
//***************************************************************************** // // 时钟初始化 // //***************************************************************************** void Osccon_Initial(void) { SetVCoreUp(PMMCOREV_3); // Set Vcore to accomodate for max. allowed system speed UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Select DCO range 24MHz operation UCSCTL2 = FLLD_1 + 374; // Set DCO Multiplier for 12MHz __bic_SR_register(SCG0); // Enable the FLL control loop P5SEL |= BIT2 + BIT3; // Port select XT2 UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL6 &= ~(XT1OFF); // XT1 On UCSCTL6 |= XCAP_3; // Internal load cap UCSCTL4 &= ~SELS_5; UCSCTL4 |= SELS_4; //SMCLKѡ��DCOCLKDIV (��Ƶ���Ƶ��) UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags delayms(800); UCSCTL6 &= ~XT2DRIVE0;// Decrease XT2 Drive according to expected frequency }
//****************************************************************************// // Set VCore level // SetVCore level is called from the user API //****************************************************************************// void SetVCore (unsigned char level) // Note: change level by one step only { unsigned char actLevel; do { actLevel = PMMCTL0_L & PMMCOREV_3; if (actLevel < level) SetVCoreUp(++actLevel); // Set VCore (step by step) if (actLevel > level) SetVCoreDown(--actLevel); // Set VCore (step by step) }while (actLevel != level); }
/************************************************************************************************** * @fn SetVCore * * @brief SetVCore level is called from the user API. Change level by one step only. * * @param level - VcCore level * * @return none ************************************************************************************************** */ static void SetVCore (uint8_t level) { uint8_t actLevel; do { actLevel = PMMCTL0_L & PMMCOREV_3; if (actLevel < level) SetVCoreUp(++actLevel); /* Set VCore (step by step) */ if (actLevel > level) SetVCoreDown(--actLevel); /* Set VCore (step by step) */ }while (actLevel != level); }
uint16_t SetVCore (uint8_t level) { uint16_t actlevel; uint16_t status = 0; level &= PMMCOREV_3; // Set Mask for Max. level actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore while (((level != actlevel) && (status == 0)) || (level < actlevel)) // step by step increase or decrease { if (level > actlevel) status = SetVCoreUp(++actlevel); } return status; }
//****************************************************************************// // Set VCore //****************************************************************************// unsigned int SetVCore (unsigned char level) { unsigned int actlevel; unsigned int status = 0; level &= PMMCOREV_3; // Set Mask for Max. level actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore while (((level != actlevel) && (status == 0)) || (level < actlevel)) { // step by step increase or decrease if (level > actlevel) status = SetVCoreUp(++actlevel); else status = SetVCoreDown(--actlevel); } return status; }