MSP430な超低消費電力、振動ロガー(単3で1年動作)

はてブ数 2009/08/26 デバイス::MSP430

MSP430を使用した超低消費電力な加速度(振動)ロガーを製作しました。

概要

ulp_logger_photo01.jpg
ulp_logger_photo02.jpg
ulp-logge_data01.png

  • 単3電池×3で半年~、単3×4で1年動作
  • MicroSDカード(SDHC対応)へのデータ保存(FAT/FAT32)
    • MicroSDなので入出力インターフェイスが不要。
  • カウント機能(万歩計みたいな感じ)

写真は「TAKACHI 防水・防塵アルミダイキャスト(AD10-7-4/W100×D65×H40)」に入れたものです。基板は厚さ約6mm以下になります。

続きを読む

MSP430F5xx のXT1にRTC用水晶を付けるときの罠

はてブ数 2009/07/12 デバイス::MSP430

MSP430の最新シリーズMSP430F5418使用時に、マニュアルやサンプルプログラムどおり行っても外付け32768Hz水晶を利用できない問題に遭遇し、これを解消するのに2日もかかってしまいました。

RTCのソースクロック

msp430_UCS-diagram.png

MSP430F5xxxのクロックシステムは図のようにいくつかのクロックソースから、ACLK、MCLK、SMCLKという名前のそれぞれのクロックのソースとして選択し、周辺モジュールはACLK、MCLK、SMCLKの中からソースクロックを選択するというような仕組みになっています。

RTCは

RTCCTL01 = RTCMODE

とするだけで他はほぼ自動で設定されますが、RTCにソースクロックとして32768Hzのクロックを与える必要があります。外付け時計用水晶はXT1(XIN/XOUT)に接続するようになっています。このXT1のクロックをACLKという名前のクロックソースとして指定し、このACLKがRTCのソースクロックとして使用されます。

XT1の水晶クロック → ACLK → RTCのクロックソース

XT1の設定

XT1に外付けの時計用水晶(32768Hz)を取り付けて、XT1をLFモードに設定し起動します。対応するポートを機能セレクトにて切り替えれば通常はXT1のクロックが利用できます。

少なくともマニュアルにはこう書いてありますが、これでは一見動いているように見えて、RFOCLKという内部32768Hz RC発振回路が使用され大幅に時計がずれます(数分/1日)。

MSP430F5xxのクロックシステムにはフェイルセーフ機能があり、クロックの障害が発生すると自動的に(クロックソース選択レジスタの内容は変わらずに)安全なクロックソースに切り替える機能があります。XT1の時計用水晶に切り替えようとしても発振開始時に障害が検出されるため((当たり前))、代替発振機であるRC発振器のRFOCLKが常に使用されてしまいます

代替ソースから本来のクロックソースに切り替える方法

しかも厄介なことに、代替ソースから本来のクロックソースに切り替える方法がマニュアルに書かれていません*1

その方法ですが、発振安定後にXT1LFOFFGというXT1の発振障害フラグとOFIFGというクロック障害割り込み要求フラグの両方をクリアすることです。

UCSCTL7 &= ~XT1LFOFFG;
SFRIFG1 &= ~OFIFG;

*1 : あとで述べるように、間接的記述は後から見つかりました……

MSP430F5418(80pin用)のRTC設定ソース

動作確認済のソースを置いておきます。MSP430F5xxにはXCAPという発振安定用コンデンサを内臓してそれを利用する機能がありますが、温度補償用の外付けコンデンサを使用したいためオフにしてあります。

void init_rtc()
{
	// Set up XT1 by 32k oscillator
	P7SEL |=  0x03;			// Analog function for XT1 Pins
	UCSCTL6 = XT2DRIVE_0		// Lowest current drive mode
			| 0		// XT2 internal
			| XT2OFF	// XT2 off
			| XT1DRIVE_0	// XT1 0=lowest current
			| 0		// LF mode
			| 0		// XT1 internal
			| XCAP_0	// Internal cap 0=off, 3=12pF
			| 0;		// XT1 on, if not user source
	// ACLK source is XT1CLK
	UCSCTL4 = (UCSCTL4 & ~SELA_7) | SELA__XT1CLK;

	// Clear XT1 fault flags
	while(UCSCTL7 & XT1LFOFFG) {
		UCSCTL7 &= ~XT1LFOFFG;
		SFRIFG1 &= ~OFIFG;
	}

	// RTC initalize
	// RTxSSEL, RTxPSDIV, etc automatically configure and don't care
	RTCCTL01 = RTCMODE;			// Calender mode
}

感想とか

こんなことで2日つぶれました。デバイスのエラッタじゃないだけよかったのですが、エラッタの多さといい、ひどいRTCバグといい、最新デバイスだけに機能や性能は良いのですが枯れてないのが不便です。

今見たらマニュアルへの記載を発見しました。これほど重要なことを割り込み要因解除の文脈でついでに書かないでほしい……。

msp430_UCS-OFIFG.png

それにしても、ネット検索してもMSP430を本格的に使用している人はほとんど見つかりませんし、TIも売る気満々な割に浸透してないし、大口以外は相手にしてないのかも知れませんがちょっとツメが甘いように感じますね。

MSP430F5xx の RTCバグ

はてブ数 2009/06/07 デバイス::MSP430

MSP430F5xxx(REV L)には、RTCに設定できないというとても迷惑なバグ(RTC3 Errata)があります。

ErrataのPDFを見るとサンプルプログラムの中にRTC_Workaround.zipというファイルがあるからそれを使えとなっています。

中にはアセンブラで書かれたRTC操作ファンクションがあり「編集禁止」と書かれています。これを C から使おうとしたらハマりました。

  • 割り込み禁止中でも構わず割り込みを許可する。
  • LARGE CODE MODELでは動作せず、呼び出すとスタックを破壊しプログラムが暴走する。

LARGE MODELにはいつ切り替わるのかよく分かりませんが、とにかくRTC設定ファンクションを呼び出すと変数が破壊されておかしいし、禁止中の割り込みが呼ばれて大変な目に合うし……と散々でした。*1

ついでにC++からも利用できないので、その辺修正したライブラリを置いておきます。

  • rtc_func.lzh
    • LARGE CODE MODELに対応した。
    • C++から利用可能にした。
    • SetXXXXX() を呼び出すと「常に割り込みが禁止(GIE=0)されて戻ってくる」ので受側で適当に処理してください。

*1 : CALLAで呼び出しているのに、アセンブラ側で RET で戻っているのが原因。CALLにはRET、CALLAにはRETA。

2008/10/23(木)SDのCRC7計算ルーチン

SD Card専用のCRC7計算ルーチン(C言語汎用)。戻り値をそのまま「6byte目」として送信できる。このソースは自由にご利用ください。

//******************************************************************************
// Calc SD CRC7
//******************************************************************************
int calc_sd_crc7(char *buf) {
	int crc, crc_prev;
	int i,j;
	crc = buf[0];
	for(i=1; i<6; i++) {
		for(j=7; j>=0; j--) {
			crc <<= 1;
			crc_prev = crc;
			if (i<5) crc |= (buf[i]>>j) & 1;
			if (crc & 0x80) { crc ^= 0x89; }	// Generator
		}
	}
	return crc_prev | 1;
}

元データに x7 かけるのを見落としていたため、えらいハマった(汗)

思うに

CRCの説明って、どこもあんまりストレートじゃないなあ。

「引き算の代わりにXORを使った」(2進数)のわり算でいえばいいんですが、桁借り*1を無視した(2進数の)わり算って書いてあれば、すぐに思い出せたのにと思ったのでした。*2

*1 : 上の桁から1借りてくること。上の桁に影響なくいつでも桁狩りできると思えばいい

*2 : さもなくばもっとシンプルに「GF(2)における多項式除算」とか