マイコン工作実験日記

Microcontroller を用いての工作、実験記録

emWin(STemWin)を動かす -- 補足

2017-12-06 22:43:09 | Weblog
前記事で書き忘れたことがあったので、追加でメモしておきます。

STM32Cubeに含まれているemWin(STemWin)を動かす上で、忘れてはならない設定がひとつありました。それは、 ペリフェラルのCRCをイネーブルしておくことです。CRCをイネーブルしておかないと、STemWinの初期化段階で動作が止まってしまいます。調べてみると、 CRCのクロックがイネーブルされていないと、永久ループするコードになっているようです。このチェックを入れることで、STemWinのライブラリが STM32でしか動作しないように制限をかけているようです。

LCDConf.c ではGUIDRV_FlexColor_SetFunc()を使って使用するLCDコントローラの種類を指定しています。GUIDRV_FLEXCOLOR_F66709の指定では、ILI9341だけでなく ILI9488や HX8353, ST7637などのコントローラもカバーしています。最初は、複数種類のLCDコントローラを識別して動作しているのかと想像したのですが、実際の動きを確認してみると全然そんなことはしていませんでした。これらのコントローラはメーカが違ってもコマンド体系がほぼ同じなので、同じグループとしてまとめて扱っているようです。



emWin(STemWin)を動かす -- その3

2017-12-03 16:25:59 | Weblog
前回の記事から間が空いてしまいましたが、続きを書くことにします。

前回記事も書いたように、emWinをターゲットのハードウェアで表示できるようにする為には、Configディレクトリのファイルさえ変更してやれば対応することが可能です。ほとんどの場合には
  • GUIConf.c
  • LCDConf.c
のふたつのファイルを編集するだけで用が足りるでしょう。GUIConf.cにおいては、emWinに割り当てるメモリ量を指定しているだけですので、実際に作業が必要になるのはターゲットのLCDに合わせてLCDConf.cを書き換えるだけになるのですが、その作業もほとんどのLCDの場合とっても簡単です。

emWinでは多くのマイコンで使われているフレームバッファを用いたLCDインターフェースや、8/16ビットのバスインタフェースを介して接続するLCDコントローラ用のドライバがあらかじめライブラリとして提供されています。後者の場合には、広く普及している ILIxxxx, SDxxxx, STxxxx といったコントローラに対応したドライバが用意されています。今回、購入したLCDではコントローラとして ILI9341が使われていますので、これに対応する為の手順を以下に示します。

まず最初に、LCD_X_Config()において、使用するドライバの種類を選択します。

pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_565, 0, 0);

GUIDRV_FLEXCOLORがドライバの種類の指定になり、ILI9341もこのドライバでサポートされていることがマニュアルに明記されています。GUICC_565は1画素の深さがRGB565であることを指定します。このドライバの場合にはRGB565の16ビットとRGB666の18ビットがサポートされているようです。

次にドライバが実際にLCDのレジスタや画素データにアクセスする際に呼び出す関数を与えてやります。

PortAPI.pfWrite8_A0 = LcdWriteReg;
PortAPI.pfWrite8_A1 = LcdWriteData;
PortAPI.pfWriteM8_A1 = LcdWriteDataMultiple;
PortAPI.pfRead8_A1 = LCDReadData;
PortAPI.pfReadM8_A1 = LcdReadDataMultiple;
GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66709,
GUIDRV_FLEXCOLOR_M16C0B8);


ドライバは8ビットまたは16ビットのバスインタフェースを使用することを想定していますが、SPIでつなぐ場合も8ビットのインタフェースを用いて実装することができます。上記の例では LcdWritexxx, LcdReadxxx の5種類の関数が
実際にLCDへアクセスする関数であり、それらの関数へのポインタをGUIDRV_FlexColor_SetFunc()を使って渡していることになります。これら5種類の関数は使用するハードウェアに合わせて実装する必要があります。
pfWrite8_A0 がコマンドレジスタへの書き込みであり、pfWrite8_A1がパラメータやデータの書き込みに使う関数になります。具体的にはLCDコントローラのC/S信号の状態の違いに対応します。Mがついている関数は複数のデータのアクセスに用いられる関数であり、具体的にはLCDに表示される画素データの書き込みや、表示されている画素データの読み取りに使われます。

このようにドライバが対応しているLCDコントローラであれば、基本的には物理的なアクセスに使用する関数さえ用意してやるだけで、emWinが動くようになります。しかしながら、それぞれのパネルの初期化までemWinが面倒見てくれる訳ではありません。初期化手順はパネルのメーカが提供する情報に基づいて行う必要があります。LCDConf.cにおいては、LCD_X_DisplayDrover()の中で、LCD_X_INITCONTROLERコマンドにより、初期化を行うようになっていますので、この部分から初期化コードを呼び出してやればOKです。

このように、実際にやってみるとあっけないくらい簡単にemWinを動かして表示することができるがわかりました。まだタッチパネルの対応とかはやっていないませんが、そのうちに調べて対応するつもりです。


RとH

2017-11-18 08:33:15 | Weblog


10代工学が新たなビデオを公開していたので、早速確認。ロボットアームとの組み合わせとは面白い。こんなスマートスピーカーだったらすぐに買っちゃうけど、モータ音が気にならないか?


DFUが安定して動くようになった

2017-11-08 22:54:40 | Weblog
前記事ではDFUでの書き込みができるようになったものの、読み出しの調子が極めて悪い状態でした。

USB送信がうまくできていないようだったので、USBのクロック設定を確認してみたものの問題なさそうでした。STM32L452ではHSI48という内蔵RC発振器を持っており、こいつを使うことで水晶を実装しなくてもUSBを使うことができます。念のために、48MHzのクロック弦をMSIに変更してみたりもしましたが、症状は変わりません。

クロック精度に問題がなさそうなので、クロック速度の方を見直すことにしました。これまでは消費電力を抑えることも考えSystem Clockを16MHz で動かしていましたが、これを80MHz に変更。すると、あっさりと読み出しが何の問題もなく、正常に終了するようになりました。

DFUでの読み書きが正常にできるようになったので、これで安心してSPIフラッシュをフォントの格納に使えそうです。表示装置として注文しておいたLCDも、もうしばらくすると届きそうです。次は、その接続作業に取り掛かることにします。

USB DFUを動かす

2017-11-06 09:22:48 | Weblog
STM32でUSB DFUを動かすには、CubeMXでコード生成をするだけではダメでUSBのI/Oとファームウェア格納領域に対するI/Oとをインタフェースするコードを補ってやる必要があります。CubeMXでは、その部分のコードをusbd_dfu_if.c というファイルとしてスケルトンとして用意してくれます。 今回は、Quad SPIフラッシュをファーム格納領域として使用しますので、フラッシュの消去、書き込み、読み出しのコードをこのファイルに追加してやります。

さて、実際にインタフェースを調べてみると、BSPで用意されているドライバととても簡単につなげられることがわかりました。usbd_dfu_if.c の関数と、Quad SPIのBSPのドライバとを1対1で対応させることができます。

  • MEM_If_Init_FS() --> BSP_QSPI_Init()を呼ぶ
  • MEM_If_Erase_FS() --> BSP_QSPI_Erase_Block()を呼ぶ
  • MEM_If_Write_FS() --> BSP_QSPI_Write()を呼ぶ
  • MEM_If_Read_FS() --> BSP_QSPI_Read()を呼ぶ
  • MEM_If_GetStatus_FS() --> Erase, Programに必要なウェイト時間を返す

と、いうようにコードを追加してやるだけ。簡単すぎるのと、BSPの関数がポーリング待ちするのが気になり、こんなんで動くのか? と心配ではありますが、ひとまず試してみることに。

SPIフラッシュは8MB分の容量がありますので、動作試験のために /dev/randomを使って8MB分のランダムデータを用意してやります。そして、そのデータをdfu-utilを使ってSPIフラッシュの領域に書き込んでやります。



64KBのブロック毎に消去をしてから、64KB分のデータを書き込むという動作を繰り返していきます。消去とプログラムの終了待ちをするために随分と時間がかかりましたが、書き込みは無事終了。

続いて読み出しをしてみると、途中でエラーが発生してしまいました。

気を取り直して、再度実行。



今度は無事に読み出しが終了しました。cmpで比較しても書いた通りのデータが読み出せています。

何度か動かしてみましたが、5割以上の確率で読み出し途中でエラーが発生してしまうようです。エラーから察するにQSPIの読み出しではなく、USBの転送でエラーが発生しているようです。QSPIの読み出しでポーリングしているのが原因になっているのかもしれませんが。。。


USB DFUを動かす - 下調べ

2017-10-30 00:02:36 | Weblog
Quad SPIフラッシュの動作が確認できたので、次にUSB経由で書き込む手段を用意します。その手段とは、USBのDFUインターフェースを組み込みことです。STM32L452では元々のブートローダでUSB DFUがサポートされていますので、まずはその見え方を確認してみましょう。



拡張コネクタのBOOT0ピンの上がVDDになっているので、この2つの端子をジャンパした状態で追加実装したUSBコネクタからE5V端子に5Vを供給してやれば、USB DFUで ブートローダが動きます。dfu-utilで確認してみると...




フラッシュのプログラム領域だけでなく、オプションバイト等もDFUで統一的にアクセス可能になっており、Alternate Interfaceを切り替えることで、どの領域にアクセスするかを決められるようになっているのですね。Serial番号はUniq Device IDレジスタを読みだして使っているのだろうと思い、該当領域(0x1FFF7590からの3ワード)を確認してみると...



うーん、なんか違うようです。ちょっと気になったので、STM32のフォーラムで検索してみたら、答えが見つかりました
0x00230017+0x20323634 --> 0x2055364B
0x5736500F --> 0x5736

と、合成しているそうです。

STM32風のDFUの流儀がわかったので、次に実際にSPI FlashにアクセスできるDFUを組み立て始めましょう。幸いなことに CubeMXを使うことで簡単にDFUクラスのインタフェースの枠組みを生成することができますので、まずはCubeMXでの設定から作業を開始します。



QSPIのメモリ空間は0x90000000からのアドレスにマップされますので、それに応じてUSB_DFU_MEDIA Interaceを設定します。ここではMX25R6435Fを64Kのブロックが128ある構成であることも示しています。USB_DFU_XFER_SIZEは少し大きめの4KBに設定してみました。



Device Descriptorの内容はCubeMXのディフォルトのままとしました。この設定だとシリアルは固定になってしまうので、後ほどUniq Device IDから導出することを考えてみたいと思います。

上記のように設定しただけでコード生成を行なって、ビルドしてみると、とりあえずEnumeratitonまでは動作するようになりました。



まだDFUクラスのインタフェース部分のコードは何も書いていないので、実際にSPI Flashにアクセスすることはできません。この部分を追加で作ってやれば、実際にフラッシュへの書き込みができるようになるはずです。

QSPI Flashの動作確認

2017-10-28 16:18:27 | Weblog
Nucleo-L452につなげたQSPI Flash (MX25R6435F)の動作確認をしました。

QSPI Flashの操作のためのコードは、CubeL4に含まれているSTM32L496G-Discovery用のBSPのコード(stm32l496g_discovery_qspi.c)を流用しました。PIN割り当てを変更すればいいだけのようなものです。BSPのAPIには初期化、Read, Write, Eraseといった基本操作が用意されているので、それらをシェルから使えるようにして、動作確認です。


先頭の256バイトの部分しか試していませんが、消去、書き込み、読み出しができることを確認。BSPのコードは割り込みを使っておらず、書き込み終了もポーリングで検出しているのですが、今回の用途にはこれでも十分に用が足りるので、このまま使うつもりです。

一旦、データの書き込みができれば、QSPIの動作モードをMemory mappedに変更してやると、0x90000000以降のメモリ空間で内容が読み出せるようになります。以下、Map前メモリダンプ、Map操作、そしてMap後のメモリダンプです。





イメージとしては理解してましたが、実際に動かしてみるととっても簡単に使えて便利そう。

LCD表示の事前準備

2017-10-27 21:08:19 | Weblog
BM20で再生中の曲名の取得ができるところまで作業を進めたところで、しばらく停滞していました。次の段階として、曲名をLCDに表示しようと考えていたのですが、今までも何度か同じようなことはやっているので、今回は何か新しい要素を入れたいところです。どうしたもんかと考えているうちに時間ばかりが経ってしまいました。おおよその方向性は決めたので、作業を再開することにします。LCD本体はまだ注文を入れたばかりで到着まで少し時間がかかりそうなので、まずは事前準備から進めることにします。

再生中の曲名は、当然ながら日本語での表示を可能とします。フォントデータを用意するとともに、その格納方法を準備する必要があります。これまではSDカードやNANDフラッシュを使ったりしてきましたが、近頃はNOR SPI Flash が安くなってきていますので、今回はSPIフラッシュにフォントデータを格納することにしました。STM32L452にはQuaD SPIインターフェースが備わっていますので、Quad SPI Flashを使うことにします。一旦、フォントデータを書き込んでしまえば、Flashメモリの内容をメモリ空間にマッピングすることができますので、簡単にフォントデータにアクセスすることが可能になるのも利点です。



使うことにしたのでは容量64MbのMX25R6435Fです。Quad SPI 使うの初めてなんで、評価ボードでも使われているMX25R6435を実装して、コードはそのままパクろうという魂胆です。

ついでにUSBのコネクタも接続。SPIフラッシュにフォントデータを格納するためには、まずSPIへフォントデータの書き込みを行わねばなりません。Discoveryボードではデモのプログラムで使用するデータをSPIフラッシュへ書き込む際にはST-Link Utilityと外部のローダを使っているようですが、わたしはDiscoveryボードを使っているわけでもないし、ST-Link Utilityも使ってないので、この方法は使えません。そこで、書き込みはUSB経由で行うことにします。具体的にはUSBのDFUクラスのドライバを組み込んで、SPIフラッシュへの書き込みを行うことにします。

STM32L4R9I

2017-10-26 22:08:22 | Weblog
STM32CubeMXの新バージョンが出たので、更新。CubeL4も新バージョンが出たのでダウンロード。今度のバージョンは前回のバージョンよりも1GBもデカくなって1.8GBもあります。内容を確認してみると未発表のL4+シリーズの評価ボードであるSTM32L4R9I-DiscoveryとSTM32L4R9I_EVAL向けのコードとイメージがその大半を占めているようです。どうやらデモ用のバイナリや、デモで使用する音楽再生用のWAVファイルなどの容量が大きいようです。

STM32L4R9はフラッシュ2MBで、SRAMも640KBという大容量になるようですが、どうやらDiscoveryには円形のLCDが搭載されているようです。STM32L4+ではGFXMMUという機能が搭載されていますが、CubeMXの設定パラメータをみると、どうやら各ラスター行毎にフレームバッファーの開始アドレスを指定できる機能のようです。この機能を使うことで、四角形でないディスプレイ形状でもフレームバッファのメモリを無駄なく有効に使えるというアイデアのようです。
Wearable機器向けに特徴を出してアピールする面白い機能ですね。正式発表が楽しみです。

FRDM-K28

2017-10-02 16:04:23 | Weblog

NXPからFRDM-K28 が出ていることを今頃になって知りました。内蔵RAMが1MBもあってUSB High speed PHYも付いているようです。STM32F4を使ってのUSB High speedの実験が今ひとつ満足できなかったので、こちらを使って挑戦してみるのもいいかもしれないのですが...

自分としての問題は開発環境です。結構気に入って使っていたKDE が NXPになってからLPCXpressoと統合されてMCUXpressoになってからというものの、使っていません。KDEではRTOSとしてMQX Lite が使えたのも個人的にはポイントが高かったのですが、それも無くなってしまったために新しいIDEとSDKに手をつける気になれません。