Other Parts Discussed in Thread: MSP430F6638
I've designed and built a custom SBC using 1 msp430f5638 which is driving a 480x272 graphical LCD. All is working pretty well, but the LCD redraws the entire screen slowly. By default the MCU is using DCO at about 1 MHz. The SBC has external crystals for XT1 (32.768 kHz), and XT2 (20 MHz).
Switching the MCU from DCO to XT2 and the LCD just gets scrambled. There are two delays in the LCD init routine which I haven't experimented with yet. Wanted to get the MCU running with XT2 divided down to about 1 MHz and see if that works, and then try speeding it up with a smaller divisor. I got somewhat strange results from this.
Code to set UCSCTL5 dividers
// slow down XT2, divide both MCLK and SMCLK by divisor
if(XT2_xtal_on)
{
//UCSCTL5 = 0x0044; // divide both by 16 NOT WORKING, stalls out, locks up LCD
//UCSCTL5 = 0x0033; // divide both by 8 this works, semi-fast lcd init, medium SMCLK on scope
//UCSCTL5 = 0x0022; // divide both by 4 THIS WORKS!!! fast lcd init, fast SMCLK on scope
//UCSCTL5 = 0x0011; // divide both by 2 THIS runs but slower than /4 ???, LCD extremely slow, slow SMCLK on scope
//UCSCTL5 = 0x0000; // divide both by 1, identical to default, should lock up lcd, lcd goes whacko
// just do MCLK, but not available on MCU pin, so must do both to see it
UCSCTL5 = 0x0022; // divide MCLK by 4 THIS WORKS!!! fast lcd init, fast SMCLK on scope
}
This specific test program is putting the MCU into LPM3 and waking up from the RTC every 2 seconds, so can't accurately measure the SMCLK period and frequency on the scope. But qualitatively, why are the 2, 4, 8 divisors not behaving linearly?
/2 is very slow @ 10 Mhz
/4 is real fast @ 5 MHz
/8 is medium speed @ 2.5 Mhz
/16 seems to be dividing DCO, not XT2, extremely slow clock on scope, @ 16 MHz
Why is it doing this? Maybe I need to look at making the two LCD delays smaller for the 10 MHz speed?
Ted
/********************************************************************* * * * Ted Fryberger, PE * * DeepSoft, LLC * * 6259 Deep River Canyon * * Columbia, MD 21045 * * 443-917-2902 * * www.DeepSoftInc.com * * tkf@deepsoftinc.com * * * ********************************************************************** * * * setup-430-clocks-xx.c * * * * * * Copyright 1987 - 2021 by Ted Fryberger & * * DeepSoft, LLC; DeepSoft, Inc; & TKF Systems * * All Rights Reserved * * * * This code is proprietary and confidential to Ted Fryberger & * * DeepSoft, LLC. Possession or duplication of this code is * * prohibited without the written consent of Ted Fryberger & * * DeepSoft, LLC. All included functions and modules are also * * proprietary and confidential to DeepSoft, LLC. * * * * Engineer: Ted Fryberger Current last revision: 1/06/2021 * * Prior last revision: * * * *********************************************************************/ /************************** MSP430 Clocks ******************************/ // XT1 = 32.768 KHz xtal // XT2 = 20 MHz xtal, max is 32 MHz // DCO = MCLK = SMCLK ~ 1.045 MHz // MCLK master clock, high frequency xtal, or DCO // SMCLK subsystem master clock // DCO digitally controlled oscillator = MCLK // ACLK auxiliary clock 32.768 KHz, external xtal required, used for precise timing RTC /************************** MSP430 Clock Settings ***********************/ // ACLK = XT1 = 32.768 KHz xtal for RTC_B // MCLK = XT2 = 20 MHz xtal, max is 32 MHz // SMCLK = XT2 = 20 MHz xtal // DCO = MCLK = SMCLK ~ 1.045 MHz // want to be able to switch MCU-1 from XT2 to DCO as needed to save power // RTC_B sets system timing, requires XT1 /************************** DC2 Test Results ****************************/ // no dividers used for these tests, UCS default settings unless set in code below // ACLK = XT1 @ XT1 TP // 0.6 div x 50 us/div = 30 us = 33,333 kHz // 0.4 div x 1v/div = 0.40 volts // SMCLK = MCLK = XT2 @ P3.4 S2 Pin 3 // 0.25 div x 0.2 us/div = 0.05 us = 20 MHz // 0.4 div x 5v/div = 2.0 volts // SMCLK = MCLK = XT2 @ XT2 TP // 0.22 div x 0.2 us/div = 0.044 us = 22.73 MHz // 0.22 div x 0.5v/div = 0.11 volts // STP3005DH power supply // 3.34 v @ 162mA with LCD // 3.34v @ 0mA without LCD // with SMCLK = MCLK = DCO // nothing out of S2 P3.4 // must disable XT2 pins at a minimum to use DCO // SMCLK = MCLK = DCO @ P3.4 S2 Pin 3 // 1.9 div x .5 us/div = 0.95 us = 2.105 MHz // 0.6 div x 5v/div = 3.0 v // STP3005DH power supply // 3.34 v @ 163mA with LCD /************************** Test Conclusions ******************************/ // XT1 has to be enabled and used all the time for RTC // must be able to switch between XT2 and DCO dynamically in the program // use global var to set either one, include any required XT2 settings // or // may be better off using separate functions to turn either XT2 or DCO on #include <msp430f5638.h> // constants to put ACLK and SMCLK out to port pins #define ACLK_OUT 1 #define SMCLK_OUT 1 // relevant global var // 0 = DCO // 1 = XT2 extern unsigned int XT2_xtal_on; // initial setup of 430 clocks // ACLK = XT1 // MCLK = XT2 or DCO // SMCLK = XT2 or DCO // need another function to dynamically change this after startup void setup_430_clocks(void) { // put clock signals onto out ports #if(ACLK_OUT) P1DIR |= BIT0; // ACLK out to P1.0 P1SEL |= BIT0; #endif #if(SMCLK_OUT) P3DIR |= BIT4; // SMCLK out to P3.4, S2 pin 3 P3SEL |= BIT4; #endif // unlock XT1 pins // battery backup registers, UG Table 3-2, p. 130 // BAKCTL Register bits // 15-4 reserved read as 0 // 3 BAKDIS disable backup supply switching, reset to 0 after complete power cycle // 0 backup supply switching enabled // 1 backup supply switching disabled, backup subsystem always powered from Vcc // 2 BAKADC battery backup supply to ADC // 0 Vbat measurement disabled // 1 Vbat measurement enabled // 1 BAKSW manual switch to battery backup supply // 0 switching is automatic // 1 switch to backup battery // 0 LOCKBAK lock battery backup subsystem, only write as 0 after RTC configured // SVSH must be active when LOCKBAK is cleared // LOCKBAK is always set to 1 by hardware after core has powered down from DVCC or LPMx.5 // 0 backup subsystem not locked // 1 backup subsystem locked // all go to 0 on Reset // BAKCTL Register // 1111 11 // msb 5432 1098 7654 3210 lsb // 0000 0000 0000 1100 = 0x000C // if locked, unlock battery backup system // where are these set by default? // Unlock XT1 pins for operation while(BAKCTL & LOCKBAK) // both must eval to 1 for AND to be true BAKCTL &= ~(LOCKBAK); // clear bit low to unlock // Port select XT2 pins, disable for DCO if(XT2_xtal_on) { P7SEL |= BIT2 + BIT3; } // UCSCTL5 // sets any divisors on ACLK, ACLK/n, MCLK, SMCLK // 15 Reserved // 14-12 DIVPA ACLK source divider, available at external pin, 1,2,4,8,16,32 // 000b = fACLK/1 // 001b = fACLK/2 // 010b = fACLK/4 // 011b = fACLK/8 // 100b = fACLK/16 // 101b = fACLK/32 // 110b = Reserved for future use. Defaults to fACLK/32. // 111b = Reserved for future use. Defaults to fACLK/32. // 11 Reserved // 10-8 DIVA ACLK source divider // 000b = fACLK/1 // 001b = fACLK/2 // 010b = fACLK/4 // 011b = fACLK/8 // 100b = fACLK/16 // 101b = fACLK/32 // 110b = Reserved for future use. Defaults to fACLK/32. // 111b = Reserved for future use. Defaults to fACLK/32. // 7 Reserved // 6-4 DIVS SMCLK source divider // 000b = fSMCLK/1 // 001b = fSMCLK/2 // 010b = fSMCLK/4 // 011b = fSMCLK/8 // 100b = fSMCLK/16 // 101b = fSMCLK/32 // 110b = Reserved for future use. Defaults to fSMCLK/32. // 111b = Reserved for future use. Defaults to fSMCLK/32. // 3 Reserved // 2-0 DIVM MCLK source divider // 000b = fMCLK/1 // 001b = fMCLK/2 // 010b = fMCLK/4 // 011b = fMCLK/8 // 100b = fMCLK/16 // 101b = fMCLK/32 // 110b = Reserved for future use. Defaults to fMCLK/32. // 111b = Reserved for future use. Defaults to fMCLK/32. // currently LCD is running at DCO frequencies of 1-2 MHz, but not XT2 of 20 MHz // probably need to adjust delays in LCD_init_3() // use a divider to set XT2 down to DCO and try that // 1111 11 // msb 5432 1098 7654 3210 lsb // 0000 0000 0100 0100 = 0x0044 divide both by 16 // 0000 0000 0011 0011 = 0x0033 divide both by 8 // 0000 0000 0010 0010 = 0x0022 divide both by 4 // 0000 0000 0001 0001 = 0x0011 divide both by 2 // 0000 0000 0000 0000 = 0x0000 divide both by 1, same as default of course // slow down XT2, divide both MCLK and SMCLK by divisor if(XT2_xtal_on) { //UCSCTL5 = 0x0044; // divide both by 16 NOT WORKING, stalls out, locks up LCD //UCSCTL5 = 0x0033; // divide both by 8 this works, semi-fast lcd init, medium SMCLK on scope //UCSCTL5 = 0x0022; // divide both by 4 THIS WORKS!!! fast lcd init, fast SMCLK on scope //UCSCTL5 = 0x0011; // divide both by 2 THIS runs but slower than /4 ???, LCD extremely slow, slow SMCLK on scope //UCSCTL5 = 0x0000; // divide both by 1, identical to default, should lock up lcd, lcd goes whacko // just do MCLK, but not available on MCU pin, so must do both to see it UCSCTL5 = 0x0022; // divide MCLK by 4 THIS WORKS!!! fast lcd init, fast SMCLK on scope } // above is slowing down 1 MHz / 16 = 62.5 khz // NOT slowing down 20 MHz to 1.25 MHz?????? // UCSCTL6 // 15-14 XT2DRIVE XT2 oscillator drive current, high initially, can be lowered, based on speed // 0 00b lowest current, 4-8 MHz // 1 01b increased current, 8-16 MHz // 2 10b increased current, 16-24 MHz, use this for 20 MHz xtal // 3 11b max current, 24-32 Mhz // 13 reserved // 12 XT2BYPASS // 0 external crystal // 1 external clock signal // 11-9 reserved // 8 XT2OFF // 0 on // 1 off // 7-6 XT1DRIVE XT1 oscillator drive current, high initially, can be lowered, based on speed // 00b lowest current, 4-8 MHz // 01b increased current, 8-16 MHz // 10b increased current, 16-24 MHz // 11b max current, 24-32 Mhz // 5 XTS XT1 mode select // 0 LF mode, XCAP bits define capacitance at XIN and XOUT pins // 1 HF mode, XCAP bits not used // 4 XTBYPASS // 0 XT1 sourced from external crystal // 1 XT1 sourced from external clock signal // 3-2 XCAPx oscillator capacitor selection, 3 bits select internal cap for LF crystal in LF mode, see DS // 00b 0 2 pf internal caps, DS p. 53 for XT1 // 01b 1 5.5 pf // 10b 2 8.5 pf // 11b 3 12 pf // 1 SMCLKOFF // 0 SMCLK on // 1 SMCLK off // 0 XT1OFF // 0 XT1 on // 1 XT1 off, if not used as a source, or FLL reference // 1111 11 // msb 5432 1098 7654 3210 lsb // 0000 0000 0000 0000 = 0x0000 // Set XT2 On or not if(XT2_xtal_on) { UCSCTL6 &= ~XT2OFF; } // Always set XT1 On UCSCTL6 &= ~XT1OFF; // Set XT1 internal load cap // external 12 pf on PCB, assume internal parallel, will add internal cap // internal 2 pf, parasitic bond and package capacitance, requires external caps, DS p. 53, footnote 6 UCSCTL6 |= XCAP_0; // UCSCTL7 // 15-4 Reserved // 3 XT2OFFG XT2 oscillator fault flag // 0 no fault condition after last reset // 1 XT2 fault after last reset // 2 XT1HFOFFG XT1 oscillator fault flag in HF mode // 0 no fault condition after last reset // 1 XT1 HF fault after last reset // 1 XT1LFOFFG XT1 oscillator fault flag in LF mode // 0 no fault condition after last reset // 1 XT1 LF fault after last reset // 0 DCOFFG DCO fault flag // 0 no fault condition after last reset // 1 DCO fault after last reset // SFR Special Function Register // SFRIE1 interrupt enable // SFRIE1_L // SFRIE1_H // SFRIFG1 interrupt flag // SFRIFG1_L (IFG1) // SFRIFG1_H (IFG2) // SFRRPCR reset pin control // SFRRPCR_L // SFRRPCR_H // SFRIE1 Register // UG, p. 84, Table 1-12 // 15-8 Reserved // 7 JMBOUTIE JTAG mailbox output interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 6 JMBINIE JTAG mailbox input interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 5 ACCVIE Flash controller access violation interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 4 NMIIE NMI pin interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 3 VMAIE Vacant memory access interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 2 Reserved // 1 OFIE Oscillator fault interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // 0 WDTIE Watchdog timer interrupt enable flag // 0 interrupts disabled // 1 interrupts enabled // SFRIFG1 Register // UG, p. 85, Table 1-13 // 7 JMBOUTIFG JTAG mailbox output interrupt flag // 0 no interrupt pending // 1 interrupt pending // 6 JMBINIFG JTAG mailbox input interrupt flag // 0 no interrupt pending // 1 interrupt pending // 5 Reserved // 4 NMIIFG NMI pin interrupt // 0 no interrupt pending // 1 interrupt pending // 3 VMAIFG vacant memory access interrupt flag // 0 no interrupt pending // 1 interrupt pending // 2 Reserved // 1 OFIFG oscillator fault interrupt flag // 0 no interrupt pending // 1 interrupt pending // 0 WDTIFG watchdog timer interrupt flag // 0 no interrupt pending // 1 interrupt pending // SFRRPCR Register // UG, p. 87, table 1-14 //15-4 Reserved // 3 SYSRSTRE reset pin resistor enable // 0 pullup / pulldown resistor at RST/NMI is disabled // 1 pullup / pulldown resistor at RST/NMI is enabled // 2 SYSRSTUP reset resistor pin pullup / pulldown // 0 pulldown resistor selected // 1 pullup resistor selected // 1 SYSNMIIES NMI edge select // when SYSNMI = 1, modifying this bit can cause an NMI // clear SYSNMI = 0 to avoid this NMI // 0 NMI on rising edge // 1 NMI on falling edge // 0 SYSNMI NMI select, picks function for RST/NMI pin // 0 reset function // 1 NMI function // Loop until XT1, XT2, DCO oscillator fault flags are cleared do { UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG); // Clear XT2, XT1 LF, DCO oscillator fault flags SFRIFG1 &= ~OFIFG; // Clear overall oscillator fault flag }while (SFRIFG1 & OFIFG); // Test: are oscillator fault flags clear // set XT2 drive current for 20 MHz clock, disable for DCO if(XT2_xtal_on) { UCSCTL6 &= ~XT2DRIVE_2; // Set XT2 Drive according to xtal frequency = 20 MHz } // UCSCTL4 // 15-11 Reserved // 10-8 SELA selects ACLK source // 000b = XT1CLK // 001b = VLOCLK // 010b = REFOCLK // 011b = DCOCLK // 100b = DCOCLKDIV // 101b = XT2CLK when available, otherwise DCOCLKDIV // 110b = Reserved for future use. Defaults to XT2CLK when available, otherwise DCOCLKDIV. // 111b = Reserved for future use. Defaults to XT2CLK when available, otherwise DCOCLKDIV. // 7 Reserved // 6-4 SELS selects SMCLK source // 000b = XT1CLK // 001b = VLOCLK // 010b = REFOCLK // 011b = DCOCLK // 100b = DCOCLKDIV // 101b = XT2CLK when available, otherwise DCOCLKDIV // 110b = Reserved, Defaults to XT2CLK when available, otherwise DCOCLKDIV. // 111b = Reserved, Defaults to XT2CLK when available, otherwise DCOCLKDIV. // 3 Reserved // 2-0 SELM selects MCLK source // 000b = XT1CLK // 001b = VLOCLK // 010b = REFOCLK // 011b = DCOCLK // 100b = DCOCLKDIV // 101b = XT2CLK when available, otherwise DCOCLKDIV // 110b = Reserved, Defaults to XT2CLK when available, otherwise DCOCLKDIV. // 111b = Reserved, Defaults to XT2CLK when available, otherwise DCOCLKDIV. // below from 5638.h // ACLK source - uses double underscore // SELA__XT1CLK = SELA_0 = 0x0000 // SELA__DCOCLK = SELA_3 = 0x0300 // SELA__XT2CLK = SELA_5 = 0x0500 // // SMCLK source // SELS__XT1CLK = SELS_0 = 0x0000 // SELS__DCOCLK = SELS_3 = 0x0030 // SELS__XT2CLK = SELS_5 = 0x0050 // // MCLK source // SELM__XT1CLK = SELM_0 = 0x0000 // SELM__DCOCLK = SELM_3 = 0x0003 // SELM__XT2CLK = SELM_5 = 0x0005 // 1111 11 // msb 5432 1098 7654 3210 lsb // 0000 0000 0101 0101 = 0x0055 // set all 3 clock sources for XT1, XT2, DCO // XT1 always needed if(XT2_xtal_on) { // use XT2 source for MCLK and SMCLK UCSCTL4 |= SELA__XT1CLK | SELS__XT2CLK | SELM__XT2CLK; // Select ACLK = XT1, SMCLK = MCLK = XT2 sources } else { // use DCO source for MCLK and SMCLK UCSCTL4 |= SELA__XT1CLK | SELS__DCOCLK | SELM__DCOCLK; // Select ACLK = XT1, SMCLK = MCLK = DCO sources } }