From: R. Steve McKown Date: Wed, 2 Dec 2009 17:46:08 +0000 (-0700) Subject: MSP430 clock enhancements. X-Git-Tag: patchset/2.1.1-4.5~21 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=aa4cce05c4de388b4451c7fc70bcceea95f88b7e MSP430 clock enhancements. * DCO frequency selection using TinyOS semantics. * Support for Basic Clock + (clock2). * Correctly sets SMCLK divider for 1 MiHz if DCO is 1, 2, 4, or 8 MiHz --- diff --git a/tos/chips/msp430/timer/Msp430ClockC.nc b/tos/chips/msp430/timer/Msp430ClockC.nc index 7feab6ab..e2247fad 100644 --- a/tos/chips/msp430/timer/Msp430ClockC.nc +++ b/tos/chips/msp430/timer/Msp430ClockC.nc @@ -23,14 +23,14 @@ * @author Cory Sharp */ -configuration Msp430ClockC +generic configuration Msp430ClockC(uint16_t TARGET_DCO_KHZ, uint16_t ACLK_KHZ) { provides interface Init; provides interface Msp430ClockInit; } implementation { - components Msp430ClockP, Msp430TimerC, McuSleepC; + components new Msp430ClockP(TARGET_DCO_KHZ, ACLK_KHZ), Msp430TimerC, McuSleepC; Init = Msp430ClockP; Msp430ClockInit = Msp430ClockP; diff --git a/tos/chips/msp430/timer/Msp430ClockP.nc b/tos/chips/msp430/timer/Msp430ClockP.nc index 689175de..7d081ab6 100644 --- a/tos/chips/msp430/timer/Msp430ClockP.nc +++ b/tos/chips/msp430/timer/Msp430ClockP.nc @@ -25,11 +25,9 @@ * @author Vlado Handziski */ -#include - #include "Msp430Timer.h" -module Msp430ClockP @safe() +generic module Msp430ClockP(uint16_t TARGET_DCO_KHZ, uint16_t ACLK_KHZ) @safe() { provides interface Init; provides interface Msp430ClockInit; @@ -43,8 +41,18 @@ implementation MSP430REG_NORACE(TBCTL); MSP430REG_NORACE(TBIV); + #if defined(__MSP430_HAS_BC2__) /* basic clock module+ */ + #define FIRST_STEP 0x1000 + #else /* orig basic clock module */ + #define RSEL3 0 + #define FIRST_STEP 0x800 + #endif + enum { + DCOX = DCO2 + DCO1 + DCO0, + MODX = MOD4 + MOD3 + MOD2 + MOD1 + MOD0, + RSELX = RSEL3 + RSEL2 + RSEL1 + RSEL0, ACLK_CALIB_PERIOD = 8, TARGET_DCO_DELTA = (TARGET_DCO_KHZ / ACLK_KHZ) * ACLK_CALIB_PERIOD, }; @@ -67,20 +75,37 @@ implementation command void Msp430ClockInit.defaultInitClocks() { + const unsigned int divider = TARGET_DCO_KHZ / 1000; + // BCSCTL1 // .XT2OFF = 1; disable the external oscillator for SCLK and MCLK // .XTS = 0; set low frequency mode for LXFT1 // .DIVA = 0; set the divisor on ACLK to 1 // .RSEL, do not modify - BCSCTL1 = XT2OFF | (BCSCTL1 & (RSEL2|RSEL1|RSEL0)); + BCSCTL1 = XT2OFF | (BCSCTL1 & RSELX); // BCSCTL2 // .SELM = 0; select DCOCLK as source for MCLK // .DIVM = 0; set the divisor of MCLK to 1 // .SELS = 0; select DCOCLK as source for SCLK - // .DIVS = 2; set the divisor of SCLK to 4 + // .DIVS = see below // .DCOR = 0; select internal resistor for DCO - BCSCTL2 = DIVS1; + // + // TinyOS upper layers assume SMCLK runs at 1 binary MHz, or 1,048,576HZ. + // If DCOCLK has been set to 1, 2, 4 or 8 binary MHz, we can correctly set + // SMCLK to the expected value. Platforms using different clocks should + // set the divider by overriding Msp430ClockInit.initClocks(), calling + // Msp430ClockInit.defaultInitClocks(), then massaging the DIVS bits as + // required. + if (divider >= 8) + BCSCTL2 = DIVS_3; + else if (divider >= 4) + BCSCTL2 = DIVS_2; + else if (divider >= 2) + BCSCTL2 = DIVS_1; + else + BCSCTL2 = DIVS_0; + // IE1.OFIE = 0; no interrupt for oscillator fault CLR_FLAG( IE1, OFIE ); @@ -163,7 +188,7 @@ implementation void set_dco_calib( int calib ) { - BCSCTL1 = (BCSCTL1 & ~0x07) | ((calib >> 8) & 0x07); + BCSCTL1 = (BCSCTL1 & ~RSELX) | ((calib >> 8) & RSELX); DCOCTL = calib & 0xff; } @@ -201,16 +226,16 @@ implementation // Binary search for RSEL,DCO,DCOMOD. // It's okay that RSEL isn't monotonic. - for( calib=0,step=0x800; step!=0; step>>=1 ) + for( calib=0,step=FIRST_STEP; step!=0; step>>=1 ) { // if the step is not past the target, commit it if( test_calib_busywait_delta(calib|step) <= TARGET_DCO_DELTA ) calib |= step; } - // if DCOx is 7 (0x0e0 in calib), then the 5-bit MODx is not useable, set it to 0 - if( (calib & 0x0e0) == 0x0e0 ) - calib &= ~0x01f; + // if DCOx is all 1s in calib, then MODx is not useable, set it to 0 + if( (calib & DCOX) == DCOX ) + calib &= ~MODX; set_dco_calib( calib ); } diff --git a/tos/chips/msp430/timer/Msp430DcoSpec.h b/tos/chips/msp430/timer/Msp430DcoSpec.h deleted file mode 100644 index 84ce060a..00000000 --- a/tos/chips/msp430/timer/Msp430DcoSpec.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- mode:c++; indent-tabs-mode: nil -*- - * Copyright (c) 2007, Technische Universitaet Berlin - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - Neither the name of the Technische Universitaet Berlin nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES {} LOSS OF USE, DATA, - * OR PROFITS {} OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * Specify the target cpu clock speed of your platform by overriding this file. - * - * Be aware that tinyos relies on binary 4MHz, that is 4096 binary kHz. Some - * platforms have an external high frequency oscilator to generate the SMCLK - * (e.g. eyesIFX, and possibly future ZigBee compliant nodes). These - * oscillators provide metric frequencies, but may not run in power down - * modes. Here, we need to switch the SMCLK source, which is easier if - * the external and thd DCO source frequency are the same. - * - * @author: Andreas Koepke (koepke@tkn.tu-berlin.de) - */ - - -#ifndef MS430DCOSPEC_H -#define MS430DCOSPEC_H - -#define TARGET_DCO_KHZ 4096 // the target DCO clock rate in binary kHz -#define ACLK_KHZ 32 // the ACLK rate in binary kHz -#endif diff --git a/tos/platforms/eyesIFX/PlatformC.nc b/tos/platforms/eyesIFX/PlatformC.nc index 4beccbf4..e8192c07 100644 --- a/tos/platforms/eyesIFX/PlatformC.nc +++ b/tos/platforms/eyesIFX/PlatformC.nc @@ -32,7 +32,7 @@ configuration PlatformC implementation { components PlatformP - , Msp430ClockC + , new Msp430ClockC(4096, 32) ; Init = PlatformP; diff --git a/tos/platforms/shimmer/MoteClockC.nc b/tos/platforms/shimmer/MoteClockC.nc index 12df90bd..ef2ade67 100644 --- a/tos/platforms/shimmer/MoteClockC.nc +++ b/tos/platforms/shimmer/MoteClockC.nc @@ -41,7 +41,7 @@ configuration MoteClockC implementation { - components Msp430ClockC; + components new Msp430ClockC(4096, 32); MoteClockInit = Msp430ClockC.Init; } diff --git a/tos/platforms/telosa/.platform b/tos/platforms/telosa/.platform index dc6d34bd..2f273950 100644 --- a/tos/platforms/telosa/.platform +++ b/tos/platforms/telosa/.platform @@ -75,4 +75,4 @@ $ENV{'CIL_MACHINE'} = "underscore_name=false " . "__builtin_va_list=true " . "__thread_is_keyword=true"; - \ No newline at end of file + diff --git a/tos/platforms/telosa/MoteClockC.nc b/tos/platforms/telosa/MoteClockC.nc index 12df90bd..ef2ade67 100644 --- a/tos/platforms/telosa/MoteClockC.nc +++ b/tos/platforms/telosa/MoteClockC.nc @@ -41,7 +41,7 @@ configuration MoteClockC implementation { - components Msp430ClockC; + components new Msp430ClockC(4096, 32); MoteClockInit = Msp430ClockC.Init; } diff --git a/tos/platforms/telosb/MoteClockC.nc b/tos/platforms/telosb/MoteClockC.nc index 4fe33910..f8576218 100644 --- a/tos/platforms/telosb/MoteClockC.nc +++ b/tos/platforms/telosb/MoteClockC.nc @@ -41,7 +41,7 @@ configuration MoteClockC implementation { - components Msp430ClockC, MoteClockP; + components new Msp430ClockC(4096, 32), MoteClockP; MoteClockInit = Msp430ClockC.Init; //MoteClockP.Msp430ClockInit -> Msp430ClockC; diff --git a/tos/platforms/tinynode/PlatformC.nc b/tos/platforms/tinynode/PlatformC.nc index 73b1e248..2435334a 100644 --- a/tos/platforms/tinynode/PlatformC.nc +++ b/tos/platforms/tinynode/PlatformC.nc @@ -32,7 +32,7 @@ configuration PlatformC implementation { components PlatformP - , Msp430ClockC + , new Msp430ClockC(4096, 32) ; Init = PlatformP;