chakokuのブログ(rev4)

日々のごった煮ブログです

nRF51822(micro:bitのマイコン)のクロック設定を確認

まずはクロックの設定を確認、ということで、clock周りのレジスタを表示させてみた。自分のテストプログラムはクロック設定は何もせず、StartUP(asm)からmainが呼ばれるだけの実装。clock controllerは初期設定(RC oscillator)で動ているはずなんだが、、

#define CLOCK_BASE (unsigned int *)0x40000000
void show_clock_stat(void)
{
  printf("----------------------------------\n");
  printf("HFCLKSTARTED %x\n",*(CLOCK_BASE+0x100));
  printf("LFCLKSTARTED %x\n",*(CLOCK_BASE+0x104));
  printf("DONE %x\n",*(CLOCK_BASE+0x10C));
  printf("CTTO %x\n",*(CLOCK_BASE+0x110));
  printf("INTENSET %x\n",*(CLOCK_BASE+0x304));
  printf("INTENCLR %x\n",*(CLOCK_BASE+0x308));
  printf("HFCLKRUN %x\n",*(CLOCK_BASE+0x408));
  printf("HFCLKSTAT %x\n",*(CLOCK_BASE+0x40C));
  printf("LFCLKRUN %x\n",*(CLOCK_BASE+0x414));
  printf("LFCLKSTAT %x\n",*(CLOCK_BASE+0x418));
  printf("LFCLKSRCCOPY %x\n",*(CLOCK_BASE+0x41C));
  printf("LFCLKSRC %x\n",*(CLOCK_BASE+0x518));
  printf("CTIV %x\n",*(CLOCK_BASE+0x538));
  printf("XTALFREQ %x\n",*(CLOCK_BASE+0x550));
  printf("----------------------------------\n");
}

実行させると以下。なぜRUNとかのステータスフラグ(HFCLKSTAT)が0のままなのか??

----------------------------------
HFCLKSTARTED 4
LFCLKSTARTED 0
DONE 0
CTTO 0
INTENSET 0
INTENCLR 0
HFCLKRUN 0
HFCLKSTAT 0
LFCLKRUN 0
LFCLKSTAT 0
LFCLKSRCCOPY 0
LFCLKSRC 0
CTIV 0
XTALFREQ 0
----------------------------------

初期設定である、RC oscillatorで動作している間はHFCLKSTASTは変化しないのか??
ググって見つけたクロックの切り替え方(内部オッシレータから外付けXtalへの切り替え)

NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;

while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
{
}

https://devzone.nordicsemi.com/f/nordic-q-a/20628/using-external-16mhz-help-with-code/80401#80401

■追記

このサンプル(自分が作ったコード)は決定的な間違いを犯していて、ポインタに加算するのはいいけど、0x40000000の定数は宣言により、int型ポインタの定数なので、 0x00 + 1 すると、一見0x01になるように思うが、int型=4Bなので、0x1にならず0x4 になる。。意図通りには動いていない。。Cの基本が分かっていないということか。。使い始めたのは大学の時だが。。なんたる。。
修正版は以下

#define CLOCK_BASE 0x40000000UL
void clock_test(void){

  unsigned int *ptr ;
  printf("----------------------------------\n");
  ptr = (unsigned int *)(CLOCK_BASE + 0x100);
  printf("HFCLKSTARTED %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x104);
  printf("LFCLKSTARTED %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x10C);
  printf("DONE %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x110);
  printf("CTTO %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x304);
  printf("INTENSET %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x308);
  printf("INTENCLR %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x408);
  printf("HFCLKRUN %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x40C);
  printf("HFCLKSTAT %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x414);
  printf("LFCLKRUN %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x418);
  printf("LFCLKSTAT %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x41C);
  printf("LFCLKSRCCOPY %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x518);
  printf("LFCLKSRC %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x538);
  printf("CTIV %x(%x)\n",*ptr,ptr);
  ptr = (unsigned int *)(CLOCK_BASE + 0x550);
  printf("XTALFREQ %x(%x)\n",*ptr,ptr);
  printf("----------------------------------\n");
}

出力結果

----------------------------------
HFCLKSTARTED 0(40000100)
LFCLKSTARTED 0(40000104)
DONE 0(4000010c)
CTTO 0(40000110)
INTENSET 0(40000304)
INTENCLR 0(40000308)
HFCLKRUN 0(40000408)
HFCLKSTAT 10000(4000040c)
LFCLKRUN 0(40000414)
LFCLKSTAT 0(40000418)
LFCLKSRCCOPY 0(4000041c)
LFCLKSRC 0(40000518)
CTIV 0(40000538)
XTALFREQ ffffffff(40000550)
----------------------------------

ステータスを見ると、HFCLKがRCオッシレータで動いていることになっている。まぁCPUもクロックがないと動かないので、そういうことなんだろう。一方、LFCLKSTATが0であり、LFCLKは動いていないようだ。