Помогите пожалуйста разобраться. Никак не получается запустить простой пример с USB. МК зависает при запуске кварца подключенного к XT1:
Код
void XT1_Start(uint16_t xtdrive)
{
// Check if drive value is the expected one
if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
UCSCTL6 &= ~XT1DRIVE_3; // Clear XT1drive field
UCSCTL6 |= xtdrive; // Set requested value
}
UCSCTL6 &= ~XT1OFF; // Enable XT1
UCSCTL6 |= XTS; // Enable HF mode
while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag <--- Зависает тут
UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
}
{
// Check if drive value is the expected one
if ((UCSCTL6 & XT1DRIVE_3) != xtdrive) {
UCSCTL6 &= ~XT1DRIVE_3; // Clear XT1drive field
UCSCTL6 |= xtdrive; // Set requested value
}
UCSCTL6 &= ~XT1OFF; // Enable XT1
UCSCTL6 |= XTS; // Enable HF mode
while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag <--- Зависает тут
UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
}
Смотрел осциллографом на выводах XT1 ничего нет.
Кварц 24 Mhz (емкости по 15 pF (пробовал ещё 22 pF))
Питание МК 3.3 В (от USB)
Код main
Код
VOID main (VOID)
{
WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer
Init_Ports(); //Init ports (do first ports because clocks do change ports)
SetVCore(3);
P1OUT |= BIT1; // XOR P1.0
Init_Clock(); //Init clocks <--- Зависает тут
USB_init(); //init USB
...
{
WDTCTL = WDTPW + WDTHOLD; //Stop watchdog timer
Init_Ports(); //Init ports (do first ports because clocks do change ports)
SetVCore(3);
P1OUT |= BIT1; // XOR P1.0
Init_Clock(); //Init clocks <--- Зависает тут
USB_init(); //init USB
...
Код Init_Clock();
Код
VOID Init_Clock (VOID)
{
//Initialization of clock module
if (USB_PLL_XT == 2){
#if defined (__MSP430F552x) || defined (__MSP430F550x)
P5SEL |= 0x0C; //enable XT2 pins for F5529
#elif defined (__MSP430F563x_F663x)
P7SEL |= 0x0C;
#endif
//use REFO for FLL and ACLK
UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__REFOCLK);
UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//MCLK will be driven by the FLL (not by XT2), referenced to the REFO
Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768); //Start the FLL, at the freq indicated by the config
//constant USB_MCLK_FREQ
XT2_Start(XT2DRIVE_0); //Start the "USB crystal"
}
if (USB_PLL_XT == 1) {
#if defined (__MSP430F552x) || defined (__MSP430F550x)
P5SEL |= 0x10; //enable XT1 pins
#endif
//Use the REFO oscillator to source the FLL and ACLK
UCSCTL3 = SELREF__REFOCLK;
UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//MCLK will be driven by the FLL (not by XT2), referenced to the REFO
Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768); //set FLL (DCOCLK)
// XT1_Start(XT1DRIVE_0); //Start the "USB crystal"
XT1_Start(XT1DRIVE_3); //Start the "USB crystal"
}
}
{
//Initialization of clock module
if (USB_PLL_XT == 2){
#if defined (__MSP430F552x) || defined (__MSP430F550x)
P5SEL |= 0x0C; //enable XT2 pins for F5529
#elif defined (__MSP430F563x_F663x)
P7SEL |= 0x0C;
#endif
//use REFO for FLL and ACLK
UCSCTL3 = (UCSCTL3 & ~(SELREF_7)) | (SELREF__REFOCLK);
UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//MCLK will be driven by the FLL (not by XT2), referenced to the REFO
Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768); //Start the FLL, at the freq indicated by the config
//constant USB_MCLK_FREQ
XT2_Start(XT2DRIVE_0); //Start the "USB crystal"
}
if (USB_PLL_XT == 1) {
#if defined (__MSP430F552x) || defined (__MSP430F550x)
P5SEL |= 0x10; //enable XT1 pins
#endif
//Use the REFO oscillator to source the FLL and ACLK
UCSCTL3 = SELREF__REFOCLK;
UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);
//MCLK will be driven by the FLL (not by XT2), referenced to the REFO
Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768); //set FLL (DCOCLK)
// XT1_Start(XT1DRIVE_0); //Start the "USB crystal"
XT1_Start(XT1DRIVE_3); //Start the "USB crystal"
}
}
Код Init_FLL_Settle
Код
void Init_FLL_Settle(uint16_t fsystem, uint16_t ratio)
{
volatile uint16_t x = ratio * 32;
Init_FLL(fsystem, ratio);
while (x--) {
__delay_cycles(30);
}
}
void Init_FLL(uint16_t fsystem, uint16_t ratio)
{
uint16_t d, dco_div_bits;
uint16_t mode = 0;
// Save actual state of FLL loop control, then disable it. This is needed to
// prevent the FLL from acting as we are making fundamental modifications to
// the clock setup.
uint16_t srRegisterState = __get_SR_register() & SCG0;
__bic_SR_register(SCG0);
d = ratio;
dco_div_bits = FLLD__2; // Have at least a divider of 2
if (fsystem > 16000) {
d >>= 1;
mode = 1;
}
else {
fsystem <<= 1; // fsystem = fsystem * 2
}
while (d > 512) {
dco_div_bits = dco_div_bits + FLLD0; // Set next higher div level
d >>= 1;
}
UCSCTL0 = 0x0000; // Set DCO to lowest Tap
UCSCTL2 &= ~(0x03FF); // Reset FN bits
UCSCTL2 = dco_div_bits | (d - 1);
if (fsystem <= 630) // fsystem < 0.63MHz
UCSCTL1 = DCORSEL_0;
else if (fsystem < 1250) // 0.63MHz < fsystem < 1.25MHz
UCSCTL1 = DCORSEL_1;
else if (fsystem < 2500) // 1.25MHz < fsystem < 2.5MHz
UCSCTL1 = DCORSEL_2;
else if (fsystem < 5000) // 2.5MHz < fsystem < 5MHz
UCSCTL1 = DCORSEL_3;
else if (fsystem < 10000) // 5MHz < fsystem < 10MHz
UCSCTL1 = DCORSEL_4;
else if (fsystem < 20000) // 10MHz < fsystem < 20MHz
UCSCTL1 = DCORSEL_5;
else if (fsystem < 40000) // 20MHz < fsystem < 40MHz
UCSCTL1 = DCORSEL_6;
else
UCSCTL1 = DCORSEL_7;
while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
if (mode == 1) { // fsystem > 16000
SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK); // Select DCOCLK
}
else {
SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // Select DCODIVCLK
}
__bis_SR_register(srRegisterState); // Restore previous SCG0
}
{
volatile uint16_t x = ratio * 32;
Init_FLL(fsystem, ratio);
while (x--) {
__delay_cycles(30);
}
}
void Init_FLL(uint16_t fsystem, uint16_t ratio)
{
uint16_t d, dco_div_bits;
uint16_t mode = 0;
// Save actual state of FLL loop control, then disable it. This is needed to
// prevent the FLL from acting as we are making fundamental modifications to
// the clock setup.
uint16_t srRegisterState = __get_SR_register() & SCG0;
__bic_SR_register(SCG0);
d = ratio;
dco_div_bits = FLLD__2; // Have at least a divider of 2
if (fsystem > 16000) {
d >>= 1;
mode = 1;
}
else {
fsystem <<= 1; // fsystem = fsystem * 2
}
while (d > 512) {
dco_div_bits = dco_div_bits + FLLD0; // Set next higher div level
d >>= 1;
}
UCSCTL0 = 0x0000; // Set DCO to lowest Tap
UCSCTL2 &= ~(0x03FF); // Reset FN bits
UCSCTL2 = dco_div_bits | (d - 1);
if (fsystem <= 630) // fsystem < 0.63MHz
UCSCTL1 = DCORSEL_0;
else if (fsystem < 1250) // 0.63MHz < fsystem < 1.25MHz
UCSCTL1 = DCORSEL_1;
else if (fsystem < 2500) // 1.25MHz < fsystem < 2.5MHz
UCSCTL1 = DCORSEL_2;
else if (fsystem < 5000) // 2.5MHz < fsystem < 5MHz
UCSCTL1 = DCORSEL_3;
else if (fsystem < 10000) // 5MHz < fsystem < 10MHz
UCSCTL1 = DCORSEL_4;
else if (fsystem < 20000) // 10MHz < fsystem < 20MHz
UCSCTL1 = DCORSEL_5;
else if (fsystem < 40000) // 20MHz < fsystem < 40MHz
UCSCTL1 = DCORSEL_6;
else
UCSCTL1 = DCORSEL_7;
while (SFRIFG1 & OFIFG) { // Check OFIFG fault flag
UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags
SFRIFG1 &= ~OFIFG; // Clear OFIFG fault flag
}
if (mode == 1) { // fsystem > 16000
SELECT_MCLK_SMCLK(SELM__DCOCLK + SELS__DCOCLK); // Select DCOCLK
}
else {
SELECT_MCLK_SMCLK(SELM__DCOCLKDIV + SELS__DCOCLKDIV); // Select DCODIVCLK
}
__bis_SR_register(srRegisterState); // Restore previous SCG0
}