Cortex-M0は低消費電力が売り文句のひとつですが、これまで消費電流を調べるような実験はしたことなかったので、この機会にFRDM-KL25Zで実験してみることにしました。
FRDM-KL25Zではボード上に電流計測用のジャンパとしてJ4が用意されています。このジャンパでの電流計測を有効とするためには、ジャンパのすぐ脇にあるR73とR81を取り外してやる必要があります。ここで測れる電流はボード全体の消費電流ではなく、KL25Z部分の消費電流だけを測ることに注意しておきましょう。測定値にはボード上にあるLEDや加速度センサー、あるいは追加した気圧センサーで消費される電流は含まれません。
まずは先週作成したソフトでの消費電流を測定。
3.66mAです。クロック設定はFEIの20.97152MHz。ほとんどの時間はWFIによりWAIT (ARM的にはSleep)状態ですが、この位消費しています。クロック速度落とせばもう少し減るのでしょうが、今回はLLS(Low Leakage Stop)モードを使ってさらに落とすのを確認するのが目的なので、クロック速度低減の実験は省略。
LLSモードを使うとM0+コアはDeep Sleep状態に遷移するので、これから抜け出すにはWakeupさせる必要があります。前回の実験ではLPS25Hからの1Hz更新の割り込みをPTD4端子で受けていましたが、このPTD4はWakeup信号入力端子としても使えます。そこでPTD4を外部割り込みとしての機能割り当てから、Wakeup信号としての割り当てに変更するとともにソフトを変更しました。LLSモードを使うためのPEXの設定については、こちらの記事とほぼ同じです。ソフトウェアのメインループは次のようになります。
Cpu_SetOperationModeでDOM_STOPを指定することで、LLSモードに遷移させます。LPS25Hが割り込みを発生させると、それをトリガにWakeupします。直後に再度Cpu_SetOperationModeでDOM_RUNに設定しておきます。これを呼んでおかないと、SCB_SCRの設定がDEEP_SLEEPを許可したままなので、この後でI2Cでレジスタの読み出しやUSARTへの文字出力を行った際の割り込み待ちでWFIが発生して再度LLSに落ちてしまうためです。これで、電流値を測ってみると。。。
2.1μAとなりました。ガクンと落ちますね。
LPS25Hからの割り込みをトリガとして、KL25に割り込みをかけたりWakeupをかけたりしてみましたが、ここで気になったことがあります。
こんな事情もあって今回はPTD4を使っています。80pinあっても両方に使えるポートが2つしかないとはちょっと驚きです。
FRDM-KL25Zではボード上に電流計測用のジャンパとしてJ4が用意されています。このジャンパでの電流計測を有効とするためには、ジャンパのすぐ脇にあるR73とR81を取り外してやる必要があります。ここで測れる電流はボード全体の消費電流ではなく、KL25Z部分の消費電流だけを測ることに注意しておきましょう。測定値にはボード上にあるLEDや加速度センサー、あるいは追加した気圧センサーで消費される電流は含まれません。
まずは先週作成したソフトでの消費電流を測定。
3.66mAです。クロック設定はFEIの20.97152MHz。ほとんどの時間はWFIによりWAIT (ARM的にはSleep)状態ですが、この位消費しています。クロック速度落とせばもう少し減るのでしょうが、今回はLLS(Low Leakage Stop)モードを使ってさらに落とすのを確認するのが目的なので、クロック速度低減の実験は省略。
LLSモードを使うとM0+コアはDeep Sleep状態に遷移するので、これから抜け出すにはWakeupさせる必要があります。前回の実験ではLPS25Hからの1Hz更新の割り込みをPTD4端子で受けていましたが、このPTD4はWakeup信号入力端子としても使えます。そこでPTD4を外部割り込みとしての機能割り当てから、Wakeup信号としての割り当てに変更するとともにソフトを変更しました。LLSモードを使うためのPEXの設定については、こちらの記事とほぼ同じです。ソフトウェアのメインループは次のようになります。
while (1) { Cpu_SetOperationMode(DOM_STOP, NULL, NULL); Cpu_SetOperationMode(DOM_RUN, NULL, NULL); (void) LPS25H_ReadReg(i2cmInfo, INT_SOURCE); regval = LPS25H_ReadReg(i2cmInfo, STATUS_REG); if (regval & P_DA) { LPS25H_ReadCont(i2cmInfo, PRESS_OUT_XL, (uint8_t *)&press, 3); cons_printf("Press: %x --> %d.%02d\r\n", press, press/4096, press_point(press & 4095)); } if (regval & T_DA) { LPS25H_ReadCont(i2cmInfo, TEMP_OUT_L, (uint8_t *)&temp, 2); tempval = (int32_t) temp + TEMP_OFFSET; cons_printf("Temp: %d --> %d.%02d\r\n", temp, tempval/480, temp_point(tempval % 480)); } }
Cpu_SetOperationModeでDOM_STOPを指定することで、LLSモードに遷移させます。LPS25Hが割り込みを発生させると、それをトリガにWakeupします。直後に再度Cpu_SetOperationModeでDOM_RUNに設定しておきます。これを呼んでおかないと、SCB_SCRの設定がDEEP_SLEEPを許可したままなので、この後でI2Cでレジスタの読み出しやUSARTへの文字出力を行った際の割り込み待ちでWFIが発生して再度LLSに落ちてしまうためです。これで、電流値を測ってみると。。。
2.1μAとなりました。ガクンと落ちますね。
LPS25Hからの割り込みをトリガとして、KL25に割り込みをかけたりWakeupをかけたりしてみましたが、ここで気になったことがあります。
- 割り込みをかけられる端子が限定される。Kinetisでは全てのGPIOポートから割り込みをかけられるわけではありません。KL25ではPTAとPTDのポートに限定されています。
- Wakeupをかけられるポートも限定される。こちらの制約は珍しいことでもありませんが、主にPTCのポートがWakeup用に割り当てられています。
- 割り込みにもWakeupにも使えるポートはPTD4とPTD6しかない。
こんな事情もあって今回はPTD4を使っています。80pinあっても両方に使えるポートが2つしかないとはちょっと驚きです。