現在、DCF77 ライブラリ(ソース コードは GitHub にあります) を Arduino (AVR ベース) から Arduino Due (ARM Cortex M3) に移植しています。
ライブラリには、正確な 1 ミリ秒のタイミングが必要です。明らかな候補は、syssticks の使用です。便利なことに、Arduino Due は 1 kHz のシステムスティック用にすでにセットアップされています。
ただし、私の (AVR) DCF77 ライブラリは、DCF77 にロックするとタイミングを調整できます。これは、タイマーのリロード値を次のように操作することによって行われます。
void isr_handler() {
cumulated_phase_deviation += adjust_pp16m;
// 1 / 250 / 64000 = 1 / 16 000 000
if (cumulated_phase_deviation >= 64000) {
cumulated_phase_deviation -= 64000;
// cumulated drift exceeds 1 timer step (4 microseconds)
// drop one timer step to realign
OCR2A = 248;
} else if (cumulated_phase_deviation <= -64000) {
// cumulated drift exceeds 1 timer step (4 microseconds)
// insert one timer step to realign
cumulated_phase_deviation += 64000;
OCR2A = 250;
} else {
// 249 + 1 == 250 == 250 000 / 1000 = (16 000 000 / 64) / 1000
OCR2A = 249;
}
DCF77_Clock_Controller::process_1_kHz_tick_data(the_input_provider());
}
これをARMプロセッサに移植したい。ARM インフォメーション センターで、次のドキュメントを見つけました。
SysTick の構成
...
SysTick を設定するには、SysTick イベント間に必要な間隔で SysTick Reload Value レジスタをロードする必要があります。タイマー割り込みまたは COUNTFLAG ビット (SysTick Control and Status レジスタ内) は、1 から 0 への遷移でアクティブになるため、n+1 クロック ティックごとにアクティブになります。100 の期間が必要な場合は、SysTick Reload Value レジスタに 99 を書き込む必要があります。SysTick Reload Value レジスタは、1 ~ 0x00FFFFFF の値をサポートします。
SysTick を使用して 1ms などの時間間隔でイベントを生成する場合は、SysTick キャリブレーション値レジスタを使用して、リロード レジスタの値をスケーリングできます。SysTick キャリブレーション値レジスタは、TENMS フィールド (ビット 0 ~ 23) に 10ms の期間のパルス数を含む読み取り専用レジスタです。このレジスタには SKEW ビット (30) もあり、クロック周波数の変動が小さいため、TENMS セクションの 10ms のキャリブレーションが正確に 10ms ではないことを示すために使用されます。ビット 31 は、基準クロックが提供されているかどうかを示すために使用されます。
...
残念ながら、SysTick->LOAD と SysTick->CALIB がどのように接続されているかについては何も見つかりませんでした。つまり、システムスティックを抑制または加速したい場合、LOAD または CALIB 値を操作する必要がありますか? また、これらのレジスタにどの値を入力する必要がありますか?
インターネットで検索しても、これ以上のヒントは見つかりませんでした。多分私は間違った場所を探しています。これらの質問に対するより詳細なリファレンスはどこにありますか? それとも、いくつかの良い例でさえありますか?