LaunchPadin DCO:n kellotaajuusasetukset

[size=150]
MSP430 Launchpad DCO(Digitally-controlled oscillator) > 1MHz
[/size]
Tämä ohje ei ole oma ideani vaan suomennettu yhteenveto 43oh-foorumin nimimerkeillä maxpenna, simpleavr ja NatureTM esiintyvien henkilöiden pähkäilyistä. Valokuvat ja skooppikaappaukset ovat omiani. Alkuperäiset NatureTM:n aloittamat threadit löytyvät osoitteista Value Line series easy DCO setting library ja Flashing the missing DCO calibration constants.

VAROITUS: En ota vastuuta ohjeen oikeellisuudesta tai hajonneista laitteista, mutta olen itse onnistuneesti kalibroinut näillä ohjeilla oman Launchpadini tukemaan 1MHz, 4MHz, 8MHz ja 16MHz kellotaajuuksia. Esimerkissä käytetään Launchpadin mukana tullutta MSP430G2231-kontrolleria ja 32.768kHz-kidettä. Ilmeisesti tätä pitäisi voida soveltaa muihinkin G-sarjalaisiin.

[size=150]Sisältö[/size]

  1. Johdanto
  2. Kalibrointi
  3. Kiteen juottaminen
  4. Code Composerin muokkaus
  5. Entä nyt?
  6. Mittailuja
  7. Ylikellotusta
  8. Pikakertaus

[size=150]1. Johdanto[/size]

MSP430G2231:n sisäinen DCO on kalibroitu toimimaan 1MHz taajuudella, jolla kyllä pääsee hyvin alkuun. Datalehdessä mainitaan kyseisen kontrollerin toimivan myös sisäisen oskilaattorin ajamana 16MHz taajuudella. 1MHz lisäksi kontrolleriin ei ole kuitenkaan tallennettu kalibrointiarvoja nopeammille taajuuksille, mutta onneksi yllämainittujen nimimerkkien ansiosta itse kalibrointi eri taajuuksille on tehty helpoksi.

Kalibroinnissa käytetään hyväksi ulkoista vertailutaajuutta, joka tuotetaan Launchpadin mukana toimitetulla 32kHz kiteellä. Kiteen jakson aikana lasketaan DCO-oskillaattorissa tapahtuneita jaksoja, jolloin voidaan arvioida DCO:n taajuus. Kun ulkoisen 32kHz kiteen taajuus jaetaan kahdeksalla, voidaan laskea useampia DCO-oskillaattorin jaksoja, jolloin tarkkuus paranee. Kiteen vertailutaajuudeksi saadaan siis 4096Hz ja tämän perusteella voidaan laskea seuraavat kalibroinnissa tavoiteltavat DCO-jaksot/kidejakso:

  • 1MHz Ëś 4096Hz * 244 = 999 424Hz -596ppm
  • 2MHz Ëś 4096Hz * 488 = 1 998 848Hz -596ppm
  • 3MHz Ëś 4096Hz * 732 = 2 998 272Hz -596ppm
  • 4MHz Ëś 4096Hz * 977 = 4 001 792Hz 468ppm
  • 5MHz Ëś 4096Hz * 1221 = 5 001 216Hz 263ppm
  • 6MHz Ëś 4096Hz * 1465 = 6 000 640Hz 127ppm
  • 7MHz Ëś 4096Hz * 1709 = 7 000 064Hz 29ppm
  • 8MHz Ëś 4096Hz * 1953 = 7 999 488Hz -84ppm
  • 9MHz Ëś 4096Hz * 2197 = 8 998 912Hz -141ppm
  • 10MHz Ëś 4096Hz * 2441 = 9 998 336Hz -186ppm
  • 11MHz Ëś 4096Hz * 2686 = 11 001 856Hz 189ppm
  • 12MHz Ëś 4096Hz * 2930 = 12 001 280Hz 127ppm
  • 13MHz Ëś 4096Hz * 3174 = 13 000 704Hz 74ppm
  • 14MHz Ëś 4096Hz * 3418 = 14 000 128Hz 29ppm
  • 15MHz Ëś 4096Hz * 3662 = 14 999 552Hz -50ppm
  • 16MHz Ëś 4096Hz * 3906 = 15 998 976Hz -84ppm

[size=150]2. Kiteen juottaminen Launchpadiin[/size]

Kide juotetaan MSP430G2231-piirin oikealle puolelle C21:n ja C22:n väliin. C21 ja C22 ovat paikkoja kiteen kuormakondensaattoreille. Niitä ei kuitenkaan tarvitse lisätä, koska kalibroinnissa käytetään mikrokontrollerin sisäisiä kuormakondensaattoreita (säädettävä 1-11pF).

launch_lahto_325.jpgMSP430 Launchpad

Juotetaan kide sille tarkoitettuun paikkaan. Juottamisessa kannattaa käyttää ohutta lankaa, että fluksia tulee tasaisesti ja juotoksista tulee nättejä. Itsehän oppikirjamaisesti luultavasti sotkin tuon lyijyttömän esitinauksen ja lyijyllisen. (pienemmät pädit himmeitä? paksumman pään koostumus taisi jo korjaantua sen verran tinan paljouden takia) :smiley:

kide_325.jpgPoistin piikkirimalle menevät hyppyvastukset. Lyhemmät johtimet kiteelle(merkitystä?) ja empähän kytke sinne mitään vahingossa :smiley:.

[size=150]3. Kalibrointi[/size]

C-kielinen kalibrointiohjelma on saatavissa 43oh-foorumilta (…köh…BugMeNot) käyttäjän maxpenna viestistä. Kalibroinnin suoritettuaan ohjelma alkaa vilkuttaa vihreää lediä(huomaa ketjun viimeisellä sivulla oleva korjaus). Kalibroinnin tuloksena MSP430G2231-kontrolleriin tallentui minulla ainakin seuraavanlaiset korjaukset. Vertailuarvona jbremnant-nimimerkin lähettämät tiedot 43oh-foorumilta:

kalibrointi_tulos_v1.0.pngArvot lähentelevät toisiaan aika paljon paitsi tuo DCOTL(hienosäätö?). Muistia voi tutkia ainakin Code Composerin Memory-työkalulla debug-tilassa.

Lisäsin pienen tarran muokattuun kontrolleriin tietääkseni, millä kontrollerilla voi käyttää suurempia taajuuksia.
launch_merkki_325.jpgMerkattu mikrokontrolleri.

Kalibroinnin jälkeen 32kHz kidettä ei tarvita, koska arvot on jo kirjoitettu flashiin talteen.

[size=150]4. Code Composerin muokkaus[/size]

Jotta uusia kalibroituja kellotaajuuksia voitaisiin käyttää, täytyy meidän jotenkin kertoa kääntäjälle, missä ne sijaitsevat. Seikkaillaan aluksi Code Composerin include-kansioon “…\Texas Instruments\ccsv4\msp430\include”.

Luodaan kopiot näistä esimerkkimikrokontrolleriin liittyvistä tiedostoista:

  • msp430g2231.cmd
  • lnk_msp430g2231.cmd
  • msp430g2231.h

Nimetään kopioidut tiedostot osuvasti:

  • msp430g2231_16MHz.cmd
  • lnk_msp430g2231_16MHz.cmd
  • msp430g2231_16MHz.h

Muokataan “msp430g2231_16MHz.cmd”-tiedoston kalibraatio kohta näyttämään tältä, eli määritellään nimellä esitettäviä osoitteita mikrokontrollerin muistista.

[code]/************************************************************

  • Calibration Data in Info Mem
    ************************************************************/
    CALDCO_16MHZ = 0x10F8;
    CALBC1_16MHZ = 0x10F9;
    CALDCO_12MHZ = 0x10FA;
    CALBC1_12MHZ = 0x10FB;
    CALDCO_8MHZ = 0x10FC;
    CALBC1_8MHZ = 0x10FD;
    CALDCO_1MHZ = 0x10FE;
    CALBC1_1MHZ = 0x10FF;
    /************************************************************[/code]

Muokataan “lnk_msp430g2231_16MHz.cmd”-tiedoston loppua, jotta muistin kohdistus toimii.

[code]//
/
INCLUDE PERIPHERALS MEMORY MAP /
/
/

-l msp430g2231_16MHz.cmd[/code]

Korjataan vielä esikääntäjän määritelmät (“msp430g2231_16MHz.h”) kohdilleen, jotta eri muistialueisiin voidaan osoitella.

[code]/************************************************************

  • Calibration Data in Info Mem
    ************************************************************/

#ifndef __DisableCalData

SFR_8BIT(CALDCO_16MHZ); /* DCOCTL Calibration Data for 16MHz /
SFR_8BIT(CALBC1_16MHZ); /
BCSCTL1 Calibration Data for 16MHz /
SFR_8BIT(CALDCO_12MHZ); /
DCOCTL Calibration Data for 12MHz /
SFR_8BIT(CALBC1_12MHZ); /
BCSCTL1 Calibration Data for 12MHz /
SFR_8BIT(CALDCO_8MHZ); /
DCOCTL Calibration Data for 8MHz /
SFR_8BIT(CALBC1_8MHZ); /
BCSCTL1 Calibration Data for 8MHz /
SFR_8BIT(CALDCO_1MHZ); /
DCOCTL Calibration Data for 1MHz /
SFR_8BIT(CALBC1_1MHZ); /
BCSCTL1 Calibration Data for 1MHz */

#endif /* #ifndef __DisableCalData */

/************************************************************[/code]

[size=150]5. Entä nyt?[/size]

Uutta projektia luodessa Code Composerissa täytyy muistaa, että valitsee Linker Command File -kohtaan oikean muokatun “lnk_msp430g2231_16MHz.cmd”-tiedoston.

tarkkana_325.pngValitse “lnk_msp430g2231_16MHz.cmd”.

Itse kun rakastan lukea näitä kädestäpitäen tutoriaaleja, niin laitampa tähän loppuun vielä yksinkertaisen koodin, jolla itse testasin eri kellotaajuuksia.

[code]#include <msp430g2231_16MHz.h> // <—HUOMAA :smiley:

void main( void ){
WDTCTL = WDTPW + WDTHOLD; // watchdog pois

//tarkista että [x]MHz on kalibroitu
if (CALBC1_16MHZ != 0xff && CALDCO_16MHZ != 0xff) {  
    //aseta kello
    BCSCTL1 = CALBC1_16MHZ;
    DCOCTL = CALDCO_16MHZ;
}

//kello ulos @ P1.4
P1SEL |= (1<<4);                             // P1.4 SMCLK output
P1DIR |= (1<<4);                             // P1.4 output
while(1);

}[/code]Anteeksi välilyönnin käyttö koodissa, mutta tabulaattori ei toiminut BBCode:lla kirjoitetussa tekstissä?
Java-tyylisestä aaltosulkujen käytöstä en kyllä luovu :smiley:.

[size=150]6. Mittailuja[/size]

Mittasin edellä olevan kappaleen testiohjelman syöttämiä signaaleja eri taajuuksilla oskilloskoopilla. Kuvista huomaa, että toivotut taajuudet toteutuivat aika hyvin, mutta kellosignaalin jaksossa on aika paljon huojuntaa. Samanlaista huojuntaa ei esiinny uudella Launchpadillä eikä kalibroidulla jos BCSCTL1 ja DCOCTL -rekisterit jättää määrittelemättä. Ilmeisesti tämä jitter on ominaisuus :smiley:, koska kellotaajuuden tarkka säätäminen tapahtuu säätelemällä kahden eri kellotaajuuden suhdetta (tarkemmin alapuolen viestissäni).

1MHz + jitterScope 1Mhz.png

8MHz + jitterScope 8Mhz.png

12MHz + jitterScope 12Mhz.png

16MHz + jitterScope 16Mhz.png

[size=150]7. Ylikellotusta[/size]

Näköjään tuohon C-kalibrointi-ohjelmaan voi syöttää käsin vertailuarvoja, jolloin voi saada korkeampiakin taajuuksia. :smiley:

Scope 20Mhz_325.pngYlikellotettu MSP430G2231 vertailuarvona 4882.

Yritin saada vielä korkeampiakin taajuuksia, mutta kalibrointi ei suostunut asettumaan ja kalibrointiohjelma jäi ikuiseen silmukkaan. Kontrolleri ei hajonnut, vaan ajoin kalibrointi-ohjelman uudestaan järkevämmillä arvoilla ja taas mentiin. Luultavasti olisi mahdollista päästä korkeampiin taajuuksin kirjoittamalla käsin kalibrointiarvon flashiin.

[size=150]8. Pikakertaus[/size]

  1. Juota 32kHz kide
  2. Suorita kalibrointiohjelma
  3. Luo muokatut tiedostot Code Composeria varten (“msp430g2231_16MHz.cmd”,“lnk_msp430g2231_16MHz.cmd” ja “msp430g2231_16MHz.h”).
  4. Uutta projektia luodessasi muista valita “lnk_msp430g2231_16MHz.cmd”
  5. #Include <msp430g2231_16MHz.h>
  6. BCSCTL1 = CALBC1_16MHZ;
    DCOCTL = CALDCO_16MHZ;

[size=150]Siinäpä se[/size]

Kumarrus ja kiitos loppuun asti lukeneille :smiley:

Kysymyksiä voi esittää ja vastaan jos osaan.
Palaute ja parannusehdotukset ovat aina tervetulleita. :stuck_out_tongue:

EDIT:
Lisäsin noihin tavoite taajuuksiin Vuokon laskemat virheet ja lisäsin siihen tuon ±20ppm ja ilmoitin worst case -tuloksen.

Lisäsin tuon kiteen tarpeettomuuden kalibroinnin jälkeen.

EDIT:
Jitterin selittellyä.

Lisäänpä virheen täuohon taulukon perään. Jos nyt laskin tämän oikein niin (kalibroitu taajuus-kellotaajuus)/kellotaajuus. 1MHz:lla tulee -576ppm. Jos tuolla tekee kellon niin silloin noin 29 minuutin päästä kello on sekunnin jälessä.

  • 1MHz Ëś 4096Hz * 244 = 999 424Hz → -576 ppm
  • 2MHz Ëś 4096Hz * 488 = 1 998 848Hz → -576 ppm
  • 3MHz Ëś 4096Hz * 732 = 2 998 272Hz → -576 ppm
  • 4MHz Ëś 4096Hz * 977 = 4 001 792Hz → 448 ppm
  • 5MHz Ëś 4096Hz * 1221 = 5 001 216Hz → 243 ppm
  • 6MHz Ëś 4096Hz * 1465 = 6 000 640Hz → 106 ppm
  • 7MHz Ëś 4096Hz * 1709 = 7 000 064Hz → 9 ppm
  • 8MHz Ëś 4096Hz * 1953 = 7 999 488Hz → -64 ppm
  • 9MHz Ëś 4096Hz * 2197 = 8 998 912Hz → -121 ppm
  • 10MHz Ëś 4096Hz * 2441 = 9 998 336Hz → -166 ppm
  • 11MHz Ëś 4096Hz * 2686 = 11 001 856Hz → 168 ppm
  • 12MHz Ëś 4096Hz * 2930 = 12 001 280Hz → 106 ppm
  • 13MHz Ëś 4096Hz * 3174 = 13 000 704Hz → 54 ppm
  • 14MHz Ëś 4096Hz * 3418 = 14 000 128Hz → 9 ppm
  • 15MHz Ëś 4096Hz * 3662 = 14 999 552Hz → 30 ppm
  • 16MHz Ëś 4096Hz * 3906 = 15 998 976Hz → 64 ppm

Tähän sitten se huomio, että tuon referenssikellon tarkkuus on +/- 20 ppm. Näin väsyneenä ei saisi tälläisiä väitteitä heitellä lonkalta ilmaan, mutta jos 600ppm on sekunti puolessa tunnissa,niin 300 ppm on sekunti tunnissa, 150 ppm sekunti kahdessa tunnissa, 75 ppm sekunti neljässä tunnissa.

Olisiko niin, että kellon ulosotto tulee keskeytyksestä ja jos 32kHz kelloa jaetaan neljällä ja siellä on keskeytyksiä ja kellosignaali ei tule raudasta pihalle vaan ohjelmasta niin tuo voisi olla syy tuohon jitteriin. Jokin

main(){ while(1){ PORT ^= PORT; } } voisi olla myös hyvä skoopitettava.

Tai sitten syy on aivan jotain muuta. Parallaxin propellerista törmäsin mielenkiintoiseen artikkeliin tästä synkkauksen puitteissa: http://www.linusakesson.net/programming/propeller/pllsync.php Uskomattoman hieno kehitystarina.

Flash ja muistit sieltä yleensä tippuvat ensimmäisenä. Sitten lähtee väylä. Luku yleensä onnistuu nopeammalla nopeudella kuin kirjoitus, mutta siinä vaiheessa, kun näihin törmää, on jo kaukana datalehden arvoista. Itse en saanut enään revittyä Atmelista yli 240% kellotaajuuksia pihalle suosiolla. Silloin jo mentiin epäsymmetrisellä kellolla ja tiedettäessä käskyn vievän kaksi kellojaksoa, tuli toinen pulssi “hieman” ajoissa:) Normaali käyttö tippui 40% ylityksessä, kun taisi muisti alkaa katoamaan.

Hyvä idea nuo virheet! Jos et kauheasti pahastuisi laitan ne tuonne credittien kera :smiley:

Kokeilin myös tuota togglea.

[code]#include <msp430g2231_16MHz.h>

void main(void){
WDTCTL = WDTPW + WDTHOLD; // watchdog

//tarkista että [x]MHz on kalibroitu
if (CALBC1_16MHZ != 0xff && CALDCO_16MHZ != 0xff) {  
    //aseta kello
    BCSCTL1 = CALBC1_16MHZ;
    DCOCTL = CALDCO_16MHZ;
}

P1DIR |= (1<<0);
while(1){
    P1OUT ^= (1<<0);
}

}[/code]
toggle_16MHz_540.png

EDIT 1:
Ei esiinny jitteriä läheskään niin paljon uudella levyllä EIKÄ vanhallakaan jos jättää tuon kellon määrittelemättä.

if (CALBC1_16MHZ != 0xff && CALDCO_16MHZ != 0xff) { //aseta kello BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; }
korkkaamaton_1MHz_jitter_540.png

EDIT 2:
Northeastern University College of Computer and Information Sciencen sivulta löyty kiinnostava pdf

Sain kaavittua seuraavaa:
DCOCTL-rekisteri koostuu DCOx ja MODx osasta.

DCOx sijaitsee biteissä 7…5 ja sillä valitaan yksi DCO:n kahdeksasta(2^3=8) valmiiksi asetettusta taajuudesta.
MODx sijaitsee biteissä 4…0 ja sillä valitaan kuinka usein käytetään korkeampaa fDCO+1-taajuutta 32:n DCO-kellon jaksonaikana. Lopulla ajalla käyetään valittua fDCO:ta

Nopeasti pääteltynä tuo MODx voisi olla syypää tuohon kellosignaalin jitteriin. Se, että miksi 1MHz signaalissa esiintyy jitteriä johtuu luultavasti siitä, että tehtaalla on suosittu vakaampaa taajuutta vs oikea?

Käynnistyksen yhteydessä kontrolleri ei ilmeisesti lue noita flash:ssä sijaitsevia kalibrointiarvoja, koska jitteriä ei esiinny ennenkuin on määritellyt “DCOCTL = CALDCO_1MHZ;”.

okei ohjelma meni launchpadiin. tarkoittaako tuo punainen ledi että se meni läpi? se syttyy hetken virran laittamisen jälkee.

Taisi olla näin, jos ajoi 43oh-foorumin c-kielisellä kalibrointiohjelmalla.

ja tuon korjauksen kanssa syttyy vihreä ledi onnistumisen jälkeen.