2023年10月07日

RP2040のBrown-out Reset

今回はRaspberry Pi Picoに搭載されるRP2040のBrown-out Reset(BOR)の設定方法について紹介します。BORは電源投入時や急激な負荷変動等で電源が不安定になった場合にマイコンを強制的にリセットさせることが可能です。電源が不安定になった際にマイコンをリセットさせないと意図しない処理が行われたり、初期化処理が正しく行われないということが生じます。RP2040のBORはデフォルトで0.860Vの設定がされているため、特別な理由がない限りは設定変更は不要です。電源変動が大きい環境で使用する場合などで動作を安定化させる際に必要に応じて変更します。

RP2040のCPUのコア電圧はデフォルトで1.1Vとなっています。これに対して、BORの設定はデフォルトで0.860Vとなっています。BORの設定はコア電圧よりも少し低い電圧に設定する必要がありますが、近づけすぎると少しの電圧変動でも頻繁にリセットがかかってしまいます。逆にBORの設定電圧を下げすぎると、リセットはかからないものの、電圧変動によってマイコンの処理が正しく行われず、動作が不安定になる可能性が高くなります。そのため、デフォルトの0.860Vから下げて設定することは避けるべきです。なお、RP2040のCPUのコア電圧はデフォルトで1.1VはVREG_AND_CHIP_RESET_BASEのVREG_AND_CHIP_RESET_VREG_OFFSET に値が格納されています。


今回はデフォルトの0.860Vから1.032Vに上げる場合を紹介します。BOR関連の定義は下記のヘッダで定義されているため、ヘッダに追加します。
#include "hardware/structs/vreg_and_chip_reset.h"
#include "hardware/regs/addressmap.h"

BOR定義の構造体がヘッダ内で定義されているため、構造体を利用します。BORの電圧の抜粋は下記の通りです。

// 1001 - 0.860V (default)
// 1010 - 0.903V
// 1011 - 0.946V
// 1100 - 0.989V
// 1101 - 1.032V
// 1110 - 1.075V
// 1111 - 1.118V


下記のコードを入れ込むことで1.032Vに変更することが可能です。必要に応じて3行目の0b1101の部分を設定したい電圧に変更してください。

vreg_and_chip_reset_hw_t *vcr;
vcr = vreg_and_chip_reset_hw;
vcr->bod = (0b1101 << VREG_AND_CHIP_RESET_BOD_VSEL_LSB) | VREG_AND_CHIP_RESET_BOD_EN_RESET;


当然ですが、コア電圧が1.1Vのため、コア電圧よりも高い0b1111の1.118Vに設定するとその瞬間にリセットがかかります。RP2040のBORについて、あまり情報がなかったため、紹介しました。ロボット制御やモータ制御等の場合、モータの急激な動きで電源電圧が低下し、マイコンが不安定になる場合があります。そのような場合に電源やモータのコンデンサを強化することはもちろんですが、BORの閾値電圧を少し高めに設定することで安定化できる場合があります。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2023年09月09日

RP2040で厳密なタイマ割込みを実現するための注意点

Raspberry Pi Picoに搭載されるRP2040は安価でPIOや264kBの大きなRAMと非常に魅力的なマイコンです。一方でSTM32マイコンやPICマイコンを使ったことがある経験者からすると、マイコン思想の違いからSTM32やPICと比べて思うように実装できないと感じることがあると思います。

今回はRP2040でRaspberry Pi Pico C/C++ SDKを使用した際の厳密なタイマ割込み(=ジッターが少なく、時間クリティカルな処理)を実現するために気を付けるべきポイントについて紹介します。

@タイマ実行コア
usec単位でのタイマ割込みを利用する際にadd_repeating_timer_usを使用することが多いと思います。ただ、add_repeating_timer_usはデフォルトでcore0で実行されるため、core1のタイマ割込みとしてadd_repeating_timer_usを使用するとcore0の処理の影響を受けてしまう可能性があります。例えば指定したusec単位での処理が間に合わないといった問題やジッターが生じて微小に割込みタイミングが前後するといった問題が生じます。

この問題を防ぐため、add_repeating_timer_usの代わりにalarm_pool_createとalarm_pool_add_repeating_timer_usを使用します。タイマを使用するコアからalarm_pool_create関数を実行することで、もう一方のコアの影響を受けずにタイマ割込みを行うことができます。

例えば、core1でタイマ割込みを利用する場合、multicore_launch_core1で呼び出す関数の処理の最初にalarm_pool_createを呼び出すことでタイマ割込みがcore1から実行されるようになります。

alarm_pool_t* core1Alarm = alarm_pool_create(0, 4);
alarm_pool_add_repeating_timer_us(core1Alarm, 100, timer_callback, NULL, &timer);

A関数RAM配置
RP2040はFlashを内蔵していないため、QSPI接続の外部Flashにアクセスしながら処理を実行します(XiP機能)。外部Flashは内蔵Flashに比べて速度が遅いため、usec単位でのタイマ割込みの処理中に外部Flashへのアクセスが発生すると大幅に処理が遅れます(1回で数10usec~)。Raspberry Pi Pico C/C++ SDKでは外部Flashへのアクセスを抑制するための手段が提供されています。外部Flashへのアクセスを抑制するため、usec単位でのタイマ割込みで処理する関数に__not_in_flash_funcマクロや__time_critical_funcマクロを使用します。

例えば void timer_callback(){・・・}という関数の場合、void __not_in_flash_func(timer_callback)(){・・・}という風に関数を書き換えることで関数をRAMに展開し、外部Flashへのアクセスを抑制することが可能です。詳細についてはここでは説明しませんが、platform.h内に当該マクロの定義と説明があります。

また、__not_in_flash_funcマクロや__time_critical_funcマクロの他にすべての関数をRAMに展開する方法もあります。ただ、RAMに入りきらない場合もあるため、すべてのケースで推奨される方法ではありません。すべての関数をRAMに展開するにはCMakeLists.txtの先頭から数行目に下記の設定を追加します。

set(PICO_COPY_TO_RAM,1)


BベクタテーブルRAM配置
割込みのベクタテーブルはデフォルトでRAM配置(PICO_NO_RAM_VECTOR_TABLE 0)となっているため、そのままの設定であれば注意する必要はありません。意図的にPICO_NO_RAM_VECTOR_TABLE 1に変更した際は割込み等で外部Flashへのアクセスが発生するため、意図せず遅れの原因になる可能性があるため、注意が必要です。


今回はRP2040で厳密なタイマ割込みを実現するために気を付けるべきポイントについて紹介しました。モータ制御や電流制御、音声処理等を行う場合、usec単位で細かくタイマ割込みを実現する必要があります。デュアルコアかつ外部FLASHから読み込みというRP2040固有の仕様からSTM32やPICとは違った注意が必要です。実際にSTM32から移植した際、デュアルコアにも関わらず、思ったようなパフォーマンスが出ないといった場面がありました。具体的にはあるモータ制御の処理を72MHzのSTM32F3マイコンでは100usec毎に処理を実行できていたにも関わらず、125MHzのRP2040では150usecに設定しないと処理が間に合わない状況でした。処理の実行時間をIO出力させてオシロで調べると最速で30usecで処理が終わっているものの、外部Flashへのアクセス等で時々100usecを超えてしまうことが分かりました。上記の設定を見直すことでRP2040のデュアルコアを生かして、STM32F3マイコンよりも高速に50usecで処理ができるようになりました。

他にもRP2040固有の気を付けるべきポイントがあるため、また別の機会に紹介したいと思います。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2023年08月12日

ToF測距センサMTOF171000C0

今回はToF測距センサーモジュールMTOF171000C0を紹介したいと思います。モジュール内部にマイコンを搭載しており、I2CもしくはUARTで距離を簡単に取得することが可能です。


I2Cで使用する場合は少し特殊で、RXをGNDに落とす必要があります。UARTを無効化するためにモジュールセレクトとしてRXピンを使用しているようです。実際に使用してみたところ、I2Cしか使用しない場合はRXピンを常にGNDに落としたままでも測距できました。そのため、専用のIOでRXピンを上げ下げしなくてもI2Cデバイスとして利用できるようです。


対応距離のラインアップの充実ではVL53LXXシリーズが勝りますが、VL53LXXシリーズはドライバが重く、マイコンの種類によってはROMに収まりきらないことが多々あります。ToF測距センサーモジュールMTOF171000C0は初期化コマンドも不要でレジスタにアクセスするだけで距離を取得することができます。ドライバプログラムが非常にシンプルで便利だと思いました。


USBシリアルI2C変換基板とWebシリアルAPIを活用して、モニタツールを実装してみました。


ToF.jpg

ToF測距センサーモジュールMTOF171000C0は比較的低価格で薄く小型なため、色々な機器に組み込んで活用できそうです。色々試してみたいと思います。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子工作 | このブログの読者になる | 更新情報をチェックする

2023年07月08日

Elecrow Partner Seller

今回は電子部品販売、PCBやPCBAサービス等を行っている深圳のElecrowの新しいサービス、Elecrow Partner Sellerについて少し紹介したいと思います。

Elecrow Partner Sellerでは自作基板等をElecrowのサイトで販売できるサービスで特にこれまでElecrowのPCBA等を利用している場合はPCBA後にそのままElecrowのサイトで自作の製品を販売することが可能です。日本ではお馴染みのスイッチサイエンスのマーケットプレイスやビットトレードワンのBTOマイプロダクトサービス等がありますが、すぐに海外前提で販売できるElecrow Partner Sellerは非常に魅力的です。

Elecrow Partner Sellerの特徴
・PCBAからそのまま販売できるため、製品を預けるための送料不要
・手数料は売上の5%
・月々の管理費や梱包費は無料
・グローバル前提で販売できる
・Paypal等で手数料を引いた売上を受け取り

他の委託販売同様に製品製造の初期投資は必要です。ただ、手数料が5%と非常に低く、輸送費用や梱包費用、管理費用が不要なのは非常に魅力的です。Elecrow Partner Sellerを始める前にElecrow側と契約書を交わす必要がありますが、そこまで煩雑なものではなく、契約後にElecrow Partner Sellerで売る製品のPCBA依頼、製品の説明や写真の登録等をElecrowのサイトから行います。


国内向けについては委託販売を複数製品で行っていますが、海外向けについては22年6月にスイッチサイエンスの海外販売が終了し、販売できない状況が続いていました。特にDigital MEMS Microphoneについては海外から購入したいという要望が多く、どのように提供するか検討していました。特にコロナ以降、海外郵送が混乱し、SAL便が利用できない等、以前よりも安く海外に電子部品を送ることが難しくなっています。

このような状況下でElecrow Partner Sellerサービスは委託販売の手段の1つとして非常に魅力的だと思い、早速、先日からDigital MEMS Microphoneの販売を開始してみました。海外向けには当ブログ含めて積極的な宣伝をしていないため、まだ販売数は微々たるものですが、今後に期待したいと思います。既に国内で委託販売等をしている方で海外問い合わせが多い製品がある方はぜひ、Elecrow Partner Sellerを選択肢の1つとして検討してみてください。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2023年06月10日

RTC SD30XXシリーズ

以前に外付けRTC比較について紹介しましたが、昨今の円安の影響でより低価格かつ高精度なRTCについて調査していました。その中で要求を満たす中華製RTCがあったため、今回、紹介したいと思います。

深圳にあるwave社のRTC SD3031、SD3077、SD3078は温度補正機能付きのRTCで水晶発振子内蔵、精度±3.8ppm、電源/電池切り替え内蔵(電池と電源のピンがそれぞれある)、1個250円前後の低価格です。更に70byteのSRAMも利用できます。中華製なのでDigi-keyやMouser等での入手性は悪いものの、LCSCやAliexpress等で入手可能です。SD3031モジュールDigi-keyでも入手可能です。


SD3031、SD3077、SD3078のアドレスや内部レジスタ等は全て同じで、ピンアサインのみが異なります。他のRTCからの置き換えを想定してピンアサインの互換性のために3種類販売されています。ただし、既存のRTCとはソフトウェアでは互換性がなく、更にちょっと癖があるため、注意点についても紹介します。


■時刻書き込み時の注意点
・日時を書き込む際は先にCTRレジスタのWRTC1に1をセットし、続いてWRTC2,3に1をセットする必要
・hourは0~23時表現の場合は7bit目に1を立てて書き込む必要
・時刻、日付の7バイトを一括で書き込む必要
・書き込み後は先にWRTC2,3を0に戻してからWRTC1を0に戻す必要
・SRAMの書き込み時も日時同様にWRTCレジスタの書き換えが必要

■時刻読み込み時の注意点
・hourは0~23時表現の場合は7bit目の1を除く必要

■その他注意点
・汎用的なSOP8パッケージだが、NOR Flashで使用される幅が広い208milタイプ

一般的なRTCではレジスタに日時を書き込めばそのまま更新できますが、SD30XXの場合、事前にレジスタで書き込み有効化の処理が必要であり、手間がかかります。また、時間は24時間表記固定でなく、12時間モード/24時間モードの両方に対応している分、書き込みと読み込みに処理が必要です。これらを考慮して、USBシリアルI2C変換基板を使用したSD30XXシリーズ用のWebシリアルの設定/確認ツールを作成してみました。日本における入手性が悪い点と扱いにちょっと癖のあるRTCですが、低価格で高精度なのは非常に魅力的だと思いました。
posted by Crescent at 00:00| Comment(2) | TrackBack(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする