MSP430の最新シリーズMSP430F5418使用時に、マニュアルやサンプルプログラムどおり行っても外付け32768Hz水晶を利用できない問題に遭遇し、これを解消するのに2日もかかってしまいました。
MSP430F5xxxのクロックシステムは図のようにいくつかのクロックソースから、ACLK、MCLK、SMCLKという名前のそれぞれのクロックのソースとして選択し、周辺モジュールはACLK、MCLK、SMCLKの中からソースクロックを選択するというような仕組みになっています。
RTCは
RTCCTL01 = RTCMODE
とするだけで他はほぼ自動で設定されますが、RTCにソースクロックとして32768Hzのクロックを与える必要があります。外付け時計用水晶はXT1(XIN/XOUT)に接続するようになっています。このXT1のクロックをACLKという名前のクロックソースとして指定し、このACLKがRTCのソースクロックとして使用されます。
XT1の水晶クロック → ACLK → RTCのクロックソース
XT1に外付けの時計用水晶(32768Hz)を取り付けて、XT1をLFモードに設定し起動します。対応するポートを機能セレクトにて切り替えれば通常はXT1のクロックが利用できます。
少なくともマニュアルにはこう書いてありますが、これでは一見動いているように見えて、RFOCLKという内部32768Hz RC発振回路が使用され大幅に時計がずれます(数分/1日)。
MSP430F5xxのクロックシステムにはフェイルセーフ機能があり、クロックの障害が発生すると自動的に(クロックソース選択レジスタの内容は変わらずに)安全なクロックソースに切り替える機能があります。XT1の時計用水晶に切り替えようとしても発振開始時に障害が検出されるため((当たり前))、代替発振機であるRC発振器のRFOCLKが常に使用されてしまいます。
しかも厄介なことに、代替ソースから本来のクロックソースに切り替える方法がマニュアルに書かれていません。
その方法ですが、発振安定後にXT1LFOFFGというXT1の発振障害フラグとOFIFGというクロック障害割り込み要求フラグの両方をクリアすることです。
UCSCTL7 &= ~XT1LFOFFG;
SFRIFG1 &= ~OFIFG;
動作確認済のソースを置いておきます。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を本格的に使用している人はほとんど見つかりませんし、TIも売る気満々な割に浸透してないし、大口以外は相手にしてないのかも知れませんがちょっとツメが甘いように感じますね。