2019年12月21日

STM32マイコン UART受信時必須処理

STM32マイコンでUARTの受信をする際に必須となるエラー処理について紹介します。

UARTの送信は一方的にマイコンから送るだけのため、そこまで大変ではありません。一方、受信は調歩同期方式ならではのエラー(フレーミング、バッファ オーバーラン エラー等)が発生するため、エラー処理を入れないとUARTの受信処理の安定性が悪化します。

更に厄介なのがSTM32マイコンのHALライブラリではUARTの受信割込みやDMA転送を使用した際に受信エラーが発生すると以降の受信処理が行われません。コマンドをUARTで処理する場合、受信エラー以降の受信が行われず、応答なし状態となっていまいます。

受信処理を継続して行うためにはエラー処理を加える必要があります。



実装としてはエラーが発生するとHAL_UART_ErrorCallbackが呼び出されます。
※設定によりますが、HAL_UART_ErrorCallbackが呼び出されないエラーがあったため、HAL_UART_ErrorCallback内でクリアせずにwhile内等でのクリア処理に変更しました。

UARTのエラーフラグを確認してクリアするHAL_UART_Abort関数を実行して受信処理を再開させます。
なお、HAL_UART_Abort関数は割込みを解除する関数ですが、各種エラーをクリアさせる機能も入っています。個々のエラーフラグだけをクリアするだけでは再開できないことが多々あるため、HAL_UART_Abort関数でレジスタをクリアさせる方法が確実です。



 if(huart->Instance==USART1){
  if (  __HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_NE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_FE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_PE) ){
     HAL_UART_Abort(&huart1);
     HAL_UART_Receive_DMA(&huart1, (uint8_t*)&UART_Data, 1);//DMAの場合
     //HAL_UART_Receive_IT(&huart1, (uint8_t*)&UART_Data, 1);//割込みの場合
  }
 }


上記処理をmain.cのwhile内等に配置することでエラー処理することができます。


以前に通常の処理ではうまく受信できるがタイミングによって受信できなくなるといった不具合に悩まされました。原因がフレーミングエラーと分かりました。電源投入直後のノイズ等でエラーが発生してしまったようです。上記の処理を加えることでエラー時に処理を再開させ、安定して通信を継続できるようになりました。

※一部HALライブラリ依存があったため、修正しました
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2019年12月14日

STM32F3マイコンでの3線SPI通信


STM32F3マイコンの3線SPI通信で少し癖があったので少し紹介します。


CubeMX上ではHalf Duplex Masterとして設定します。

SPI.png



3線式ではHalf Duplexとなるため、HAL_SPI_Transmit関数とHAL_SPI_Receive関数を使用します。今回、読み込みコマンドをHAL_SPI_Transmit関数でデバイスに送信してから値をHAL_SPI_Receive関数で読み込みます。その際にHAL_SPI_Receive関数でタイムアウトエラーが頻発し、安定して読み込みできない現象が発生しました。



使用するバージョンにもよりますが、HALライブラリに少し癖があるようです。HAL_SPI_Transmit関数の後に続けてHAL_SPI_Receive関数を呼び出すとRXNEレジスタが変わらず、タイムアウト状態になってしまうようです。
※現時点ではSTM32Cube FW_F3 V1.11.0


3線式ではHalf DuplexではGPIOの入力、出力を随時切り替えて通信する必要があります。上記のタイムアウトを防止するため、強制的に入出力を切り替える関数を呼び出しすとタイムアウトエラーが発生せずに読み込めました。

具体的には下記の通りです。

SPI_1LINE_TX(&hspi1);//強制的に送信モード
HAL_SPI_Transmit(&hspi1,sdata,2,0x1000);
SPI_1LINE_RX(&hspi1);//強制的に受信モード
HAL_SPI_Receive(&hspi1,rdata,4,0x1000);



強制的な入出力を切り替えで読み込めることが確認できました。
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2019年12月07日

FTDI2232を用いたJTAG通信 Machxo2書き込み

Lattice社のFPGAの開発環境はインストールパッケージが1GB前後と軽いのが特徴です。それもあってLattice社を好んで使っています。また書き込みツールがFTDIの2232Dなどでそのまま純正書き込みソフトで書き込むことが可能なため、高価な書き込みツールが不要なのも特徴です。
※Machxoシリーズに対応した開発環境Diamond、iCE40に対応したiCECubeともにそれぞれ1GB前後です

今回はLattice社のFPGA、Machxo2(LCMXO2-256HC-4TG100C)の書き込みについて少し紹介します。

秋月のサイトにもMachxo2の書き込み方法(PDF)について紹介されていますが、安定した書き込みができず少し苦労しました。



Machxo2のJTAGポートは弱いプルアップやプルダウンがありますが、安定化のための十分でないため、外部に別途プルアップやプルダウンが必要です。

TDO、TDI、TMSはプルアップ、TCKはプルダウンですが、抵抗値もポイントです。すべて4.7kohmでは安定した書き込みができませんでした。

評価用ボードの回路を確認すると理由が分かりました。TDO、TDI、TMSはプルアップが4.7kohmというのは同じでしたが、TCKのプルダウン抵抗が違いました。純正の評価ボードのTCKは2.2kohmでプルダウンしていました。



jtag_pull.jpg


純正の評価ボードに合わせてTCKを2.2kohmでプルダウンすると安定して書き込みできることが分かりました。
ただ、正直、Machxo2(LCMXO2-256HC-4TG100C)を書き込む際には2232DよりもTinyFPGAプログラマが簡単です。
TinyFPGAプログラマ専用のソフトウェアでの書き込みになりますが、書き込み速度も高速で便利です。
TinyFPGA AX2 Boardでなくても書き込みできました。
なお、Machxo3は識別コードが異なるため、TinyFPGAプログラマ専用のソフトウェアそのままでは書き込みできませんでした。
posted by Crescent at 00:00| Comment(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする

2019年11月16日

STM32 RTC起因のUART不具合

STM32マイコンの多くはVBAT端子があり、RTC機能をマイコンに内蔵しています。VBAT端子にリチウム電池等を接続することで時刻を保持することができます。

STM32マイコンのRTCの特徴として、マイコンのファームを書き換えた際にも時刻が保持されます。また、時刻の他にバックアップレジスタがあり、ちょっとしたデータを保持することが可能です。

マイコンのファームを書き換えた際にも時刻が保持されるため、開発側としては非常に便利ですが、ごく稀に不具合が発生することがあったので現象と対処方法を紹介します。


前提:
VBAT端子にリチウム電池を接続し、時刻を保持した状態でファームを書き換える

不具合:
ごく稀にUARTのボーレートが異常な値となり、マイコン自体は動いているものの、UART通信ができなくなる

対処方法:
マイコンのメイン電源を切り、VBAT端子にリチウム電池を外して数秒放置させる


上記の事象が発生した場合、ファームをフルイレースしても現象は直りません。VBAT端子の供給を遮断し、RTC関連をリセットする必要があります。RTC関連をリセットすれば時刻情報は消えますが、再度、ファーム書き換え直す必要もなく、UARTは正常に戻ります。


もし、STM32 RTCを使用していてUARTに不具合が発生した場合はVBAT端子の電池を外してみてください。
posted by Crescent at 00:00| Comment(0) | 電子工作 | このブログの読者になる | 更新情報をチェックする

2019年11月09日

スリープ不具合調査 その2

対策しても、時々再発してしまうことがあったため、再度試行錯誤してみました。


普段はメインPCは電源を切らず、使わないときはスリープや休止で運用しています。使用しているPCのマザーボードはIntel i5-8400+ ASROCK製 H310M-ITX/acを使用しています。

High Definition Audio Controllerが原因と分かっていますが、以前、紹介した方法の「powercfg」コマンドでは完治しませんでした。


今回はドライバ側から原因を追ってみまいした。RealtechのオーディオドライバーをインストールするとRealtech Audio Cosoleを利用することができます。

「デバイス詳細設定」の項目から「フロントパネル」を「ヘッドフォン」に設定した上で、コネクタ設定「フロントパネルのジャックポップアップダイアログを無効にする」が「オフ」になっていたため、「オン」にして無効化しました。合わせて、「デバイスを差し込むとき、ジャック検出を有効にする」が「オン」になっていたため、「オフ」に設定しました。


realtech-audio.jpg

ジャック検出の無効化で様子を見てみるとスリープ状態に入らず、勝手に復帰する不具合はなくなりました。原因はジャック検出だったようです。一旦、様子をみてみたいと思います。

posted by Crescent at 00:00| Comment(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする