From: smckown Date: Tue, 9 Sep 2008 02:30:44 +0000 (+0000) Subject: The msp430 now has two basic clock peripherals. Add tos/chips/msp430/clock and X-Git-Tag: release/2.1.0-1~69 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;ds=sidebyside;h=b83aa91d0424245008bc68cecceac8b12efda682;p=tinyos-2.x.git The msp430 now has two basic clock peripherals. Add tos/chips/msp430/clock and move basic clock and clock configuration files from timer to clock directories. Update .platform files accordingly. --- diff --git a/tos/chips/msp430/clock/Msp430ClockC.nc b/tos/chips/msp430/clock/Msp430ClockC.nc new file mode 100644 index 00000000..5249fbe0 --- /dev/null +++ b/tos/chips/msp430/clock/Msp430ClockC.nc @@ -0,0 +1,38 @@ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * @author Cory Sharp + */ + +configuration Msp430ClockC +{ + provides interface Init; + provides interface Msp430ClockInit; +} +implementation +{ + components Msp430ClockP, Msp430TimerC; + + Init = Msp430ClockP; + Msp430ClockInit = Msp430ClockP; +} + diff --git a/tos/chips/msp430/clock/Msp430ClockInit.nc b/tos/chips/msp430/clock/Msp430ClockInit.nc new file mode 100644 index 00000000..e78caf18 --- /dev/null +++ b/tos/chips/msp430/clock/Msp430ClockInit.nc @@ -0,0 +1,39 @@ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * @author Cory Sharp + * @author Vlado Handziski + */ + +interface Msp430ClockInit +{ + event void setupDcoCalibrate(); + event void initClocks(); + event void initTimerA(); + event void initTimerB(); + + command void defaultSetupDcoCalibrate(); + command void defaultInitClocks(); + command void defaultInitTimerA(); + command void defaultInitTimerB(); +} + diff --git a/tos/chips/msp430/clock/Msp430ClockP.nc b/tos/chips/msp430/clock/Msp430ClockP.nc new file mode 100644 index 00000000..55aaba33 --- /dev/null +++ b/tos/chips/msp430/clock/Msp430ClockP.nc @@ -0,0 +1,236 @@ +//$Id$ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * @author Cory Sharp + * @author Vlado Handziski + */ + +#include + +#include "Msp430Timer.h" + +module Msp430ClockP @safe() +{ + provides interface Init; + provides interface Msp430ClockInit; +} +implementation +{ + MSP430REG_NORACE(IE1); + MSP430REG_NORACE(TACTL); + MSP430REG_NORACE(TAIV); + MSP430REG_NORACE(TBCTL); + MSP430REG_NORACE(TBIV); + + enum + { + ACLK_CALIB_PERIOD = 8, + TARGET_DCO_DELTA = (TARGET_DCO_KHZ / ACLK_KHZ) * ACLK_CALIB_PERIOD, + }; + + + command void Msp430ClockInit.defaultSetupDcoCalibrate() + { + + // --- setup --- + + TACTL = TASSEL1 | MC1; // source SMCLK, continuous mode, everything else 0 + TBCTL = TBSSEL0 | MC1; + BCSCTL1 = XT2OFF | RSEL2; + BCSCTL2 = 0; + TBCCTL0 = CM0; + } + + command void Msp430ClockInit.defaultInitClocks() + { + // 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)); + + // 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 + // .DCOR = 0; select internal resistor for DCO + BCSCTL2 = DIVS1; + + // IE1.OFIE = 0; no interrupt for oscillator fault + CLR_FLAG( IE1, OFIE ); + } + + command void Msp430ClockInit.defaultInitTimerA() + { + TAR = 0; + + // TACTL + // .TACLGRP = 0; each TACL group latched independently + // .CNTL = 0; 16-bit counter + // .TASSEL = 2; source SMCLK = DCO/4 + // .ID = 0; input divisor of 1 + // .MC = 0; initially disabled + // .TACLR = 0; reset timer A + // .TAIE = 1; enable timer A interrupts + TACTL = TASSEL1 | TAIE; + } + + command void Msp430ClockInit.defaultInitTimerB() + { + TBR = 0; + + // TBCTL + // .TBCLGRP = 0; each TBCL group latched independently + // .CNTL = 0; 16-bit counter + // .TBSSEL = 1; source ACLK + // .ID = 0; input divisor of 1 + // .MC = 0; initially disabled + // .TBCLR = 0; reset timer B + // .TBIE = 1; enable timer B interrupts + TBCTL = TBSSEL0 | TBIE; + } + + default event void Msp430ClockInit.setupDcoCalibrate() + { + call Msp430ClockInit.defaultSetupDcoCalibrate(); + } + + default event void Msp430ClockInit.initClocks() + { + call Msp430ClockInit.defaultInitClocks(); + } + + default event void Msp430ClockInit.initTimerA() + { + call Msp430ClockInit.defaultInitTimerA(); + } + + default event void Msp430ClockInit.initTimerB() + { + call Msp430ClockInit.defaultInitTimerB(); + } + + + void startTimerA() + { + // TACTL.MC = 2; continuous mode + TACTL = MC1 | (TACTL & ~(MC1|MC0)); + } + + void stopTimerA() + { + //TACTL.MC = 0; stop timer B + TACTL = TACTL & ~(MC1|MC0); + } + + void startTimerB() + { + // TBCTL.MC = 2; continuous mode + TBCTL = MC1 | (TBCTL & ~(MC1|MC0)); + } + + void stopTimerB() + { + //TBCTL.MC = 0; stop timer B + TBCTL = TBCTL & ~(MC1|MC0); + } + + void set_dco_calib( int calib ) + { + BCSCTL1 = (BCSCTL1 & ~0x07) | ((calib >> 8) & 0x07); + DCOCTL = calib & 0xff; + } + + uint16_t test_calib_busywait_delta( int calib ) + { + int8_t aclk_count = 2; + uint16_t dco_prev = 0; + uint16_t dco_curr = 0; + + set_dco_calib( calib ); + + while( aclk_count-- > 0 ) + { + TBCCR0 = TBR + ACLK_CALIB_PERIOD; // set next interrupt + TBCCTL0 &= ~CCIFG; // clear pending interrupt + while( (TBCCTL0 & CCIFG) == 0 ); // busy wait + dco_prev = dco_curr; + dco_curr = TAR; + } + + return dco_curr - dco_prev; + } + + // busyCalibrateDCO + // Should take about 9ms if ACLK_CALIB_PERIOD=8. + // DCOCTL and BCSCTL1 are calibrated when done. + void busyCalibrateDco() + { + // --- variables --- + int calib; + int step; + + // --- calibrate --- + + // Binary search for RSEL,DCO,DCOMOD. + // It's okay that RSEL isn't monotonic. + + for( calib=0,step=0x800; 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; + + set_dco_calib( calib ); + } + + command error_t Init.init() + { + // Reset timers and clear interrupt vectors + TACTL = TACLR; + TAIV = 0; + TBCTL = TBCLR; + TBIV = 0; + + atomic + { + signal Msp430ClockInit.setupDcoCalibrate(); + busyCalibrateDco(); + signal Msp430ClockInit.initClocks(); + signal Msp430ClockInit.initTimerA(); + signal Msp430ClockInit.initTimerB(); + startTimerA(); + startTimerB(); + } + + return SUCCESS; + } +} + diff --git a/tos/chips/msp430/clock/Msp430DcoCalibC.nc b/tos/chips/msp430/clock/Msp430DcoCalibC.nc new file mode 100644 index 00000000..78e4e9e4 --- /dev/null +++ b/tos/chips/msp430/clock/Msp430DcoCalibC.nc @@ -0,0 +1,36 @@ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * @author Cory Sharp + */ + +configuration Msp430DcoCalibC +{ +} +implementation +{ + components Msp430DcoCalibP, Msp430TimerC; + + Msp430DcoCalibP.TimerMicro -> Msp430TimerC.TimerA; + Msp430DcoCalibP.Timer32khz -> Msp430TimerC.TimerB; +} + diff --git a/tos/chips/msp430/clock/Msp430DcoCalibP.nc b/tos/chips/msp430/clock/Msp430DcoCalibP.nc new file mode 100644 index 00000000..d75e9aad --- /dev/null +++ b/tos/chips/msp430/clock/Msp430DcoCalibP.nc @@ -0,0 +1,82 @@ + +/* "Copyright (c) 2000-2003 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY + * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + */ + +/** + * @author Cory Sharp + */ + +#error "Msp430DcoCalibP is broken and will incorrectly adjust TimerA because it does not take into account MCU sleep." + +module Msp430DcoCalibP +{ + uses interface Msp430Timer as TimerMicro; + uses interface Msp430Timer as Timer32khz; +} +implementation +{ + uint16_t m_prev; + + enum + { + TARGET_DELTA = 2048, // number of 32khz ticks during 65536 ticks at 1mhz + MAX_DEVIATION = 7, // about 0.35% error + }; + + // this gets executed 32 times a second + async event void TimerMicro.overflow() + { + uint16_t now = call Timer32khz.get(); + uint16_t delta = now - m_prev; + m_prev = now; + + if( delta > (TARGET_DELTA+MAX_DEVIATION) ) + { + // too many 32khz ticks means the DCO is running too slow, speed it up + if( DCOCTL < 0xe0 ) + { + DCOCTL++; + } + else if( (BCSCTL1 & 7) < 7 ) + { + BCSCTL1++; + DCOCTL = 96; + } + } + else if( delta < (TARGET_DELTA-MAX_DEVIATION) ) + { + // too few 32khz ticks means the DCO is running too fast, slow it down + if( DCOCTL > 0 ) + { + DCOCTL--; + } + else if( (BCSCTL1 & 7) > 0 ) + { + BCSCTL1--; + DCOCTL = 128; + } + } + } + + async event void Timer32khz.overflow() + { + } +} + diff --git a/tos/chips/msp430/clock/Msp430DcoSpec.h b/tos/chips/msp430/clock/Msp430DcoSpec.h new file mode 100644 index 00000000..84ce060a --- /dev/null +++ b/tos/chips/msp430/clock/Msp430DcoSpec.h @@ -0,0 +1,49 @@ +/* -*- 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/chips/msp430/pins/HplMsp430GeneralIOP.nc b/tos/chips/msp430/pins/HplMsp430GeneralIOP.nc index 78104ac3..191d4f21 100644 --- a/tos/chips/msp430/pins/HplMsp430GeneralIOP.nc +++ b/tos/chips/msp430/pins/HplMsp430GeneralIOP.nc @@ -46,7 +46,7 @@ implementation async command void IO.clr() { atomic PORTx &= ~(0x01 << pin); } async command void IO.toggle() { atomic PORTx ^= (0x01 << pin); } async command uint8_t IO.getOutRaw() { return PORTx & (0x01 << pin); } - async command bool IO.getOut() { return IO.getOutRaw() != 0; } + async command bool IO.getOut() { return (call IO.getOutRaw() != 0); } async command uint8_t IO.getRaw() { return PORTxIN & (0x01 << pin); } async command bool IO.get() { return (call IO.getRaw() != 0); } async command void IO.makeInput() { atomic PORTxDIR &= ~(0x01 << pin); } @@ -59,5 +59,5 @@ implementation async command bool IO.isIOFunc() { return (PORTxSEL & (0x01< - */ - -configuration Msp430ClockC -{ - provides interface Init; - provides interface Msp430ClockInit; -} -implementation -{ - components Msp430ClockP, Msp430TimerC; - - Init = Msp430ClockP; - Msp430ClockInit = Msp430ClockP; -} - diff --git a/tos/chips/msp430/timer/Msp430ClockInit.nc b/tos/chips/msp430/timer/Msp430ClockInit.nc deleted file mode 100644 index e78caf18..00000000 --- a/tos/chips/msp430/timer/Msp430ClockInit.nc +++ /dev/null @@ -1,39 +0,0 @@ - -/* "Copyright (c) 2000-2003 The Regents of the University of California. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement - * is hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY - * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - */ - -/** - * @author Cory Sharp - * @author Vlado Handziski - */ - -interface Msp430ClockInit -{ - event void setupDcoCalibrate(); - event void initClocks(); - event void initTimerA(); - event void initTimerB(); - - command void defaultSetupDcoCalibrate(); - command void defaultInitClocks(); - command void defaultInitTimerA(); - command void defaultInitTimerB(); -} - diff --git a/tos/chips/msp430/timer/Msp430ClockP.nc b/tos/chips/msp430/timer/Msp430ClockP.nc deleted file mode 100644 index 55aaba33..00000000 --- a/tos/chips/msp430/timer/Msp430ClockP.nc +++ /dev/null @@ -1,236 +0,0 @@ -//$Id$ - -/* "Copyright (c) 2000-2003 The Regents of the University of California. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement - * is hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY - * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - */ - -/** - * @author Cory Sharp - * @author Vlado Handziski - */ - -#include - -#include "Msp430Timer.h" - -module Msp430ClockP @safe() -{ - provides interface Init; - provides interface Msp430ClockInit; -} -implementation -{ - MSP430REG_NORACE(IE1); - MSP430REG_NORACE(TACTL); - MSP430REG_NORACE(TAIV); - MSP430REG_NORACE(TBCTL); - MSP430REG_NORACE(TBIV); - - enum - { - ACLK_CALIB_PERIOD = 8, - TARGET_DCO_DELTA = (TARGET_DCO_KHZ / ACLK_KHZ) * ACLK_CALIB_PERIOD, - }; - - - command void Msp430ClockInit.defaultSetupDcoCalibrate() - { - - // --- setup --- - - TACTL = TASSEL1 | MC1; // source SMCLK, continuous mode, everything else 0 - TBCTL = TBSSEL0 | MC1; - BCSCTL1 = XT2OFF | RSEL2; - BCSCTL2 = 0; - TBCCTL0 = CM0; - } - - command void Msp430ClockInit.defaultInitClocks() - { - // 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)); - - // 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 - // .DCOR = 0; select internal resistor for DCO - BCSCTL2 = DIVS1; - - // IE1.OFIE = 0; no interrupt for oscillator fault - CLR_FLAG( IE1, OFIE ); - } - - command void Msp430ClockInit.defaultInitTimerA() - { - TAR = 0; - - // TACTL - // .TACLGRP = 0; each TACL group latched independently - // .CNTL = 0; 16-bit counter - // .TASSEL = 2; source SMCLK = DCO/4 - // .ID = 0; input divisor of 1 - // .MC = 0; initially disabled - // .TACLR = 0; reset timer A - // .TAIE = 1; enable timer A interrupts - TACTL = TASSEL1 | TAIE; - } - - command void Msp430ClockInit.defaultInitTimerB() - { - TBR = 0; - - // TBCTL - // .TBCLGRP = 0; each TBCL group latched independently - // .CNTL = 0; 16-bit counter - // .TBSSEL = 1; source ACLK - // .ID = 0; input divisor of 1 - // .MC = 0; initially disabled - // .TBCLR = 0; reset timer B - // .TBIE = 1; enable timer B interrupts - TBCTL = TBSSEL0 | TBIE; - } - - default event void Msp430ClockInit.setupDcoCalibrate() - { - call Msp430ClockInit.defaultSetupDcoCalibrate(); - } - - default event void Msp430ClockInit.initClocks() - { - call Msp430ClockInit.defaultInitClocks(); - } - - default event void Msp430ClockInit.initTimerA() - { - call Msp430ClockInit.defaultInitTimerA(); - } - - default event void Msp430ClockInit.initTimerB() - { - call Msp430ClockInit.defaultInitTimerB(); - } - - - void startTimerA() - { - // TACTL.MC = 2; continuous mode - TACTL = MC1 | (TACTL & ~(MC1|MC0)); - } - - void stopTimerA() - { - //TACTL.MC = 0; stop timer B - TACTL = TACTL & ~(MC1|MC0); - } - - void startTimerB() - { - // TBCTL.MC = 2; continuous mode - TBCTL = MC1 | (TBCTL & ~(MC1|MC0)); - } - - void stopTimerB() - { - //TBCTL.MC = 0; stop timer B - TBCTL = TBCTL & ~(MC1|MC0); - } - - void set_dco_calib( int calib ) - { - BCSCTL1 = (BCSCTL1 & ~0x07) | ((calib >> 8) & 0x07); - DCOCTL = calib & 0xff; - } - - uint16_t test_calib_busywait_delta( int calib ) - { - int8_t aclk_count = 2; - uint16_t dco_prev = 0; - uint16_t dco_curr = 0; - - set_dco_calib( calib ); - - while( aclk_count-- > 0 ) - { - TBCCR0 = TBR + ACLK_CALIB_PERIOD; // set next interrupt - TBCCTL0 &= ~CCIFG; // clear pending interrupt - while( (TBCCTL0 & CCIFG) == 0 ); // busy wait - dco_prev = dco_curr; - dco_curr = TAR; - } - - return dco_curr - dco_prev; - } - - // busyCalibrateDCO - // Should take about 9ms if ACLK_CALIB_PERIOD=8. - // DCOCTL and BCSCTL1 are calibrated when done. - void busyCalibrateDco() - { - // --- variables --- - int calib; - int step; - - // --- calibrate --- - - // Binary search for RSEL,DCO,DCOMOD. - // It's okay that RSEL isn't monotonic. - - for( calib=0,step=0x800; 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; - - set_dco_calib( calib ); - } - - command error_t Init.init() - { - // Reset timers and clear interrupt vectors - TACTL = TACLR; - TAIV = 0; - TBCTL = TBCLR; - TBIV = 0; - - atomic - { - signal Msp430ClockInit.setupDcoCalibrate(); - busyCalibrateDco(); - signal Msp430ClockInit.initClocks(); - signal Msp430ClockInit.initTimerA(); - signal Msp430ClockInit.initTimerB(); - startTimerA(); - startTimerB(); - } - - return SUCCESS; - } -} - diff --git a/tos/chips/msp430/timer/Msp430DcoCalibC.nc b/tos/chips/msp430/timer/Msp430DcoCalibC.nc deleted file mode 100644 index 78e4e9e4..00000000 --- a/tos/chips/msp430/timer/Msp430DcoCalibC.nc +++ /dev/null @@ -1,36 +0,0 @@ - -/* "Copyright (c) 2000-2003 The Regents of the University of California. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement - * is hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY - * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - */ - -/** - * @author Cory Sharp - */ - -configuration Msp430DcoCalibC -{ -} -implementation -{ - components Msp430DcoCalibP, Msp430TimerC; - - Msp430DcoCalibP.TimerMicro -> Msp430TimerC.TimerA; - Msp430DcoCalibP.Timer32khz -> Msp430TimerC.TimerB; -} - diff --git a/tos/chips/msp430/timer/Msp430DcoCalibP.nc b/tos/chips/msp430/timer/Msp430DcoCalibP.nc deleted file mode 100644 index d75e9aad..00000000 --- a/tos/chips/msp430/timer/Msp430DcoCalibP.nc +++ /dev/null @@ -1,82 +0,0 @@ - -/* "Copyright (c) 2000-2003 The Regents of the University of California. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement - * is hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY - * OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." - */ - -/** - * @author Cory Sharp - */ - -#error "Msp430DcoCalibP is broken and will incorrectly adjust TimerA because it does not take into account MCU sleep." - -module Msp430DcoCalibP -{ - uses interface Msp430Timer as TimerMicro; - uses interface Msp430Timer as Timer32khz; -} -implementation -{ - uint16_t m_prev; - - enum - { - TARGET_DELTA = 2048, // number of 32khz ticks during 65536 ticks at 1mhz - MAX_DEVIATION = 7, // about 0.35% error - }; - - // this gets executed 32 times a second - async event void TimerMicro.overflow() - { - uint16_t now = call Timer32khz.get(); - uint16_t delta = now - m_prev; - m_prev = now; - - if( delta > (TARGET_DELTA+MAX_DEVIATION) ) - { - // too many 32khz ticks means the DCO is running too slow, speed it up - if( DCOCTL < 0xe0 ) - { - DCOCTL++; - } - else if( (BCSCTL1 & 7) < 7 ) - { - BCSCTL1++; - DCOCTL = 96; - } - } - else if( delta < (TARGET_DELTA-MAX_DEVIATION) ) - { - // too few 32khz ticks means the DCO is running too fast, slow it down - if( DCOCTL > 0 ) - { - DCOCTL--; - } - else if( (BCSCTL1 & 7) > 0 ) - { - BCSCTL1--; - DCOCTL = 128; - } - } - } - - async event void Timer32khz.overflow() - { - } -} - 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/chips/msp430/usci/Msp430SpiP.nc b/tos/chips/msp430/usci/Msp430SpiP.nc index 2d8db430..33202005 100644 --- a/tos/chips/msp430/usci/Msp430SpiP.nc +++ b/tos/chips/msp430/usci/Msp430SpiP.nc @@ -93,18 +93,21 @@ implementation { { atomic { const msp430_usci_spi_t* config = call Configure.get(); + uint8_t ctl0; call Registers.setCtl1(UCSWRST); + /* Force 3-pin SPI if config says I2C */ + ctl0 = config->ctl0 | UCSYNC; + if ((ctl0 & UCMODE_3) == UCMODE_3) + ctl0 &= ~(UCMODE_3); + /* Configure USCI registers */ - call Registers.assignCtl0(config->ctl0); - call Registers.assignCtl1(config->ctl1|UCSWRST); + call Registers.assignCtl0(ctl0); + call Registers.assignCtl1(config->ctl1 | UCSWRST); call Registers.assignBr0(config->brx & 0xff); call Registers.assignBr1(config->brx >> 8); - call Registers.assignMctl(config->mctl); - call Registers.assignIrtctl(config->irtctl); - call Registers.assignIrrctl(config->irrctl); - call Registers.assignAbctl(config->abctl); + call Registers.assignMctl(config->mctl); /* ??? */ call Registers.clrStat(UCLISTEN); /* Save pin IO states */ diff --git a/tos/chips/msp430/usci/Msp430UartP.nc b/tos/chips/msp430/usci/Msp430UartP.nc index 49dc1f1b..ce31d9ce 100644 --- a/tos/chips/msp430/usci/Msp430UartP.nc +++ b/tos/chips/msp430/usci/Msp430UartP.nc @@ -95,8 +95,8 @@ implementation { call Registers.setCtl1(UCSWRST); /* Configure USCI registers */ - call Registers.assignCtl0(config->ctl0); - call Registers.assignCtl1(config->ctl1|UCSWRST); + call Registers.assignCtl0(config->ctl0 & ~UCSYNC); + call Registers.assignCtl1(config->ctl1 | UCSWRST); call Registers.assignBr0(config->brx & 0xff); call Registers.assignBr1(config->brx >> 8); call Registers.assignMctl(config->mctl); diff --git a/tos/chips/msp430/usci/Msp430Usci.h b/tos/chips/msp430/usci/Msp430Usci.h index 94ca476c..50a0ca72 100644 --- a/tos/chips/msp430/usci/Msp430Usci.h +++ b/tos/chips/msp430/usci/Msp430Usci.h @@ -76,6 +76,8 @@ typedef enum { */ UBRX_32768HZ_9600=3, UMCTL_32768HZ_9600=(0 << 4) + (3 << 1) + 0, UBRX_1MHZ_9600=109, UMCTL_1MHZ_9600=(0 << 4) + (2 << 1) + 0, + UBRX_1MHZ_19200=54, UMCTL_1MHZ_19200=(0 << 4) + (5 << 1) + 0, + UBRX_1MHZ_38400=27, UMCTL_1MHZ_38400=(0 << 4) + (2 << 1) + 0, UBRX_1MHZ_115200=9, UMCTL_1MHZ_115200=(0 << 4) + (1 << 1) + 0, UBRX_1E6MHZ_9600=104, UMCTL_1E6MHZ_9600=(0 << 4) + (1 << 1) + 0, UBRX_1E6MHZ_115200=8, UMCTL_1E6MHZ_115200=(0 << 4) + (6 << 1) + 0, diff --git a/tos/platforms/shimmer/.platform b/tos/platforms/shimmer/.platform index 8ea49534..310bbb72 100644 --- a/tos/platforms/shimmer/.platform +++ b/tos/platforms/shimmer/.platform @@ -27,6 +27,7 @@ push( @includes, qw( %T/chips/cc2420/unique %T/chips/msp430 %T/chips/msp430/adc12 + %T/chips/msp430/clock %T/chips/msp430/dma %T/chips/msp430/pins %T/chips/msp430/timer @@ -72,4 +73,4 @@ $ENV{'CIL_MACHINE'} = "big_endian=false " . "underscore_name=false " . "__builtin_va_list=true " . - "__thread_is_keyword=true"; \ No newline at end of file + "__thread_is_keyword=true"; diff --git a/tos/platforms/telosa/.platform b/tos/platforms/telosa/.platform index dc6d34bd..00f9de94 100644 --- a/tos/platforms/telosa/.platform +++ b/tos/platforms/telosa/.platform @@ -27,6 +27,7 @@ push( @includes, qw( %T/chips/at45db %T/chips/msp430 %T/chips/msp430/adc12 + %T/chips/msp430/clock %T/chips/msp430/pins %T/chips/msp430/timer %T/chips/msp430/usart @@ -75,4 +76,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/telosb/.platform b/tos/platforms/telosb/.platform index 5fab8f26..816de3fd 100644 --- a/tos/platforms/telosb/.platform +++ b/tos/platforms/telosb/.platform @@ -26,6 +26,7 @@ push( @includes, qw( %T/chips/cc2420/transmit %T/chips/cc2420/unique %T/chips/msp430 + %T/chips/msp430/clock %T/chips/msp430/adc12 %T/chips/msp430/dma %T/chips/msp430/pins diff --git a/tos/platforms/tinynode/.platform b/tos/platforms/tinynode/.platform index 818c7a83..a6050ac4 100644 --- a/tos/platforms/tinynode/.platform +++ b/tos/platforms/tinynode/.platform @@ -19,6 +19,7 @@ push( @includes, qw( %T/chips/msp430 %T/chips/msp430/adc12 + %T/chips/msp430/clock %T/chips/msp430/dma %T/chips/msp430/pins %T/chips/msp430/timer diff --git a/tos/platforms/tmicore/.platform b/tos/platforms/tmicore/.platform index 97022c58..3cd16861 100755 --- a/tos/platforms/tmicore/.platform +++ b/tos/platforms/tmicore/.platform @@ -8,6 +8,8 @@ push( @includes, qw( %T/platforms/telosa %T/chips/msp430 %T/chips/msp430/adc12 + %T/chips/msp430/clock2 + %T/chips/msp430/clock %T/chips/msp430/dma %T/chips/msp430/pins %T/chips/msp430/timer