STM32F4シリーズを使ってみる11 - STM32F429I-Discovery発動編 -
ぇー…前回のSTM32の記事の最後で新しいコードスニペットと称するどことなく
卑猥な名称のふれこみで発表されたSTM32CubeMXとそのF4シリーズのサポートを
行うCubeF4という新たなファームウエアライブラリに触れましたが…
私も移植を目指して頑張ってたのですが…
私の従来のいつものに当てはめようと思うと改造個所が多岐に及び、さらにコード
サイズとオーバーヘッドも増加してしまったので移植は見送りにして新規に作る
プロジェクトからCubeF4を使用する方針に逃げ変えました。
STM32CubeF4には抽象化がさら進められ、インスタンスという概念が追加され
ています。これがかなりの曲者で従来のF4シリーズで言うDSP_StdPeriph_Driver
ライブラリに相当する"STM32F4xx_HAL_Driver"はすべてこれの
使用を前提としていてさらにサイズが大きい構造体と併用しなければならない
のが分かりました。
これSRAMやFLASHのリソースが膨大にあるF4シリーズだからよいものをF1やF0
にも当てはめるのはかなりヤバいと思います。
私も過度の抽象化は良いとは思っていません。移植性を重視しすぎてせっかくの
マイコンの性能を引き出せないのであれば本末転倒です。
あんまし考えたくないのですが無理くそ全CPUの格差を埋めるべく抽象化を
目指し、そして失敗して結局ライブラリのバージョンが多岐に分かれて
しまったLPCOpenと同じ道を歩んでいる感じがします。
おそらくCube系のライブラリに遷移していくあたって大混乱が起こると
思いますね。無理にCubeへの遷移を煽る中途半端に発言力が持ってる人が
湧くのは容易に予測されます。学生さんなんかは自分のボスの"せんせい"
にまたCubeライブラリの使い方をwikiにまとめさせられると思います。
そういうこと言ってくる人らには"こんなことしてること自体が時間の無駄。
したけりゃ自分でやれ!"とはっきりNOを突き付けるべきです。
とはいえ私のぶろぐを見られている方は私よりも技術力がはるかに上の方
ばっかなのでそもそもこんなとこ見てない私が注意しなくても各自しっかり
対処出来することができるでしょうからぐだぐだ言いましたがやっぱし
私の杞憂かな〜と思います。
さて、前置きが長くなってしまいましたが以前から触れてきた
STM32F429I-DiscoveryのTFT-LCDをSPIではなくRGBインターフェースで
動かすことに成功しました。
前回は低速なSPIインターフェースでお茶を濁していました。
しかしSTM32F429シリーズにTFT-LCDに特化したグラフィックコント
ローラ(LTDC)とグラフィックに特化したDMAである(Chrom-ART Accelerator)
が搭載されているのでこれらの機能を使っていつものの再現を目指し
ようやく完成したわけです。
●STM32F429Iにあるグラフィック機能
私が説明するよりもこちらのPDFを見たら一目瞭然です。
LTDCに関してはフレームバッファとして確保したメモリアドレスにRGBの
データを書き込むだけで色の表示が可能です。また、STM32F429系では
SDRAMがサポートされているので容量を喰う画像データでも余裕で
取り扱うことができます。
Chrom-ART Acceleratorに関しては別名DMA2Dと称されていて文字通り
2Dグラフィック特化型DMAです。しかもデータ形式を変換してメモリ間
転送したり単一データを指定して転送する(レクタングルフィルに効果を
発揮)ことができます。
STM32F429I-Discoveryでは上記二つの機能を体験可能です。同ボードに
搭載されたTFTLCDの解像度は工作物ではメジャーな240x320となっています。
STM32のLTDC単体ではレクタングルを指定して書き込み時にアドレスを
自動インクリメントしながら連続で書き込める機能はない(DMA2Dで
解説します)ためアドレス計算は必須です。
具体的にいうとたとえば座標x,yにドットを打ちたい場合は基本的には先ず
以下のように座標を指定します
(RGB=565,1ドットあたり2Byteのデータを想定)。
lcd_c_buf_ptr = lcd_f_buf_ptr + 2*(x + (MAX_X*y));
lcd_c_buf_ptr :ドットデータを実際に書き込むメモリのアドレス
lcd_f_buf_ptr :フレームバッファとして確保したメモリ領域のベースアドレス
MAX_X :TFT-LCDのX軸の最大ドット数(F429I-Discoveryでは240と定義)
次にRGBデータcolourを書き込みます。
*(volatile uint16_t*)(lcd_c_buf_ptr) = colour;
lcd_c_buf_ptr +=2;
より具体的な実装はいつものの./lib/display/mcu_depend/src/lcdc_if_basis.cを
ご覧下さい。FONTX2等の描画ルーチンは完全にドット単位で行っていますが
MCUバスと外部LCDコントローラとの通信オーバーヘッドがなくなるので
ドット単位でも十分に早くなります。また、LTDCは2枚のレイヤーを使用可能で
さらにアルファブレンディングの透過効果も使用可能です。現状では単一の
レイヤとしてしか使用していませんがこちらも学習を重ねてモノにしていきます!
次にもう一つの目玉機能Chrom-ART Accelerator(以下DMA2D)です。
私のいつものではFillRect系のレクタングル指定塗りつぶしやレクタングル
指定の動画データ転送に使用しています。
基本的には通常のDMAと同じですがグラフィック特化なのでRGBデータを
格納するレジスタもあります。単一色描画では以下のように設定します。
※RGB565,黒色,全画面(240x320)塗りつぶしの場合
/* configure DMA2D */
DMA2D_DeInit();
DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;
DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
DMA2D_InitStruct.DMA2D_OutputGreen = (0x07E0 & COL_BLACK) >> 5;
DMA2D_InitStruct.DMA2D_OutputBlue = 0x001F & COL_BLACK;
DMA2D_InitStruct.DMA2D_OutputRed = (0xF800 & COL_BLACK) >> 11;
DMA2D_InitStruct.DMA2D_OutputAlpha = 0x0F;
DMA2D_InitStruct.DMA2D_OutputMemoryAdd = (uint32_t)lcd_f_buf_ptr;
DMA2D_InitStruct.DMA2D_OutputOffset = (MAX_X - 1));
DMA2D_InitStruct.DMA2D_NumberOfLine = MAX_X+1;
DMA2D_InitStruct.DMA2D_PixelPerLine = MAX_Y+1;
DMA2D_Init(&DMA2D_InitStruct);
/* Start Transfer */
DMA2D_StartTransfer();
/* Wait for CTC Flag activation */
while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET){}
lcd_f_buf_ptr :フレームバッファとして確保したメモリ領域のベースアドレス
MAX_X :TFT-LCDのX軸の最大ドット数(F429I-Discoveryでは240と定義
MAX_Y :TFT-LCDのY軸の最大ドット数(F429I-Discoveryでは320と定義
フォアグラウンドのレイヤーへ画像データを転送したい場合は以下のように。
/* configure DMA2D */
DMA2D_DeInit();
DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M;
DMA2D_InitStruct.DMA2D_CMode = DMA2D_RGB565;
DMA2D_InitStruct.DMA2D_OutputGreen = 0; /* M2M系転送の場合は使わない */
DMA2D_InitStruct.DMA2D_OutputBlue = 0; /* M2M系転送の場合は使わない */
DMA2D_InitStruct.DMA2D_OutputRed = 0; /* M2M系転送の場合は使わない */
DMA2D_InitStruct.DMA2D_OutputMemoryAdd = (uint32_t)lcd_f_buf_ptr;
DMA2D_InitStruct.DMA2D_OutputOffset = 1;
DMA2D_InitStruct.DMA2D_NumberOfLine = MAX_X+1;
DMA2D_InitStruct.DMA2D_PixelPerLine = MAX_Y+1;
DMA2D_Init(&DMA2D_InitStruct);
/* Configure default values for foreground */
DMA2D_FG_StructInit(&DMA2D_FG_InitStruct);
DMA2D_FG_InitStruct.DMA2D_FGMA = (uint32_t)p;
DMA2D_FGConfig(&DMA2D_FG_InitStruct);
/* Start Transfer */
DMA2D_StartTransfer();
/* Wait for CTC Flag activation */
while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET){}
lcd_f_buf_ptr :フレームバッファとして確保したメモリ領域のベースアドレス
MAX_X :TFT-LCDのX軸の最大ドット数(F429I-Discoveryでは240と定義
MAX_Y :TFT-LCDのY軸の最大ドット数(F429I-Discoveryでは320と定義
p :転送したい画像データのポインタ
と、従来のDMAと同じ感覚で使用が可能です。もっと汎用なDMA2Dの使用法は
同じくlcdc_if_basis.cをご参照ください。DMA2DはLTDCと組み合わせると
強力なレイヤー機能が使えるようになるでしょうね。
私のサンプルでは全く使いこなせてませんがー!
という訳でそれを踏まえたいつものをビルドして書き込み、
動作させたものが上の画像です。
静止画では違いが分からないと思いますが以前の8-bitSPIのみで動かしてた
ものとは描画速度がダンチですよ♥
惜しむらくはSTM32F429I-Discoveryに使用されているTFT-LCDが発色にちょっと
劣る点です。2014年現在では超高視野角液晶はすでにホビイストでも容易に
入手可能なのでそれに慣れた私にとってはあと一歩がほしいところと感じました
(多分最新の奴搭載したら値段跳ね上がるでしょうけど)。
●いつものFatFs+TFTLCD表示サンプルの細かい整備など
LTDC+DMA2Dに対応したついでに長らく放置していた全部載せSTM32F427IIT6基板の
プログラムも見直して安定化を図りました。いまさら気付いたのですが、新しい
STM32F4に存在するFMC(フレキシブル・メモリコントローラ)ではFSMCの
設定とは微妙に違っておりました…。
なんとFSMCでは存在しなかった変数が構造体に追加されていてこれを設定して
なかったせいで動作が不安定になっておりましたorzいまさら気付きましたが
まだFMC世代の新しいSTM32F4を使用されている方が少ないのか指摘されず
助かりましたうふふふふふふふf
また、この全部載せ基板はI2Cのコーデックも乗っていて音質は非常に悪い
ですがmp3やwaveファイルの再生も可能です。私のいつものプログラムでは
SDIO経由でSDカードのmp3ファイルなどを読みだして再生します
…がしかしビットレートが高いmp3の再生ではSDIOのデータ読みだしにDMAの
転送を行うとI2Sの方のサーキュラモードDMA転送と干渉しまくりあっと
いう間にオーバーフローになってエラーをはいて止まります。
という訳でこれを避けるためにSTM32F4でもFIFOのポーリングでの読み書きに
本格的に対応させることにしました。STマイクロ配布のSTM32F4のデモでは
ポーリングの読み書きはRead/WriteBlockしか対応しておらず非常に低速度
なのですがマルチブロック転送でもポーリングで読み書きできるように
改良しております。ポーリングでもDMAとほぼ同等の転送速度が得られたので
速度に関しては問題なしです。
…という訳でDMAあえてを使用せずポーリングによる読み出しだけで無事ビット
レートの高いmp3ファイルの再生も可能となりましためでたしめでたし!
(helixのフォルダにあるassembly.hのマクロが前回の機能追加で間違ってて
そもそもmp3ファイルが全く再生できなくなっていたのは見逃していただきたい)
●もいっこおまけ
私のいつものでは一部のmp3ファイルを再生したときにアーティスト/曲名情報
表示の際にゴミデータが表示されてしまっておりましたが、こちらも文字列ストア用の
バッファ(私のプログラムではCCM領域にあたる)を一旦ゼロクリアしてから
表示を行うようにしてバグを潰しております。
以前は変なゴミデータが表示されていましたが…、
修正後はこんな感じにすっきりです★
-
免責・連絡先は↑のリンクを
↓SNSもやってます↓
powered by まめわざ- ARM/STM32 (116)
- OpenOCD (27)
- ARM/NxP (34)
- ARM/Cypress (5)
- ARM/Others (3)
- ARM/Raspi (1)
- AVR (13)
- FPGA (4)
- GPS/GNSS (19)
- MISC (81)
- STM8 (2)
- Wirelessなアレ (16)
- おきぱ (1)
- ブラウザベンチマーク (28)
- 日本の自然歩道 (25)
- STM32U0はぢめました
⇒ ねむい (08/07) - STM32U0はぢめました
⇒ ひかわ (07/28) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ねむい (05/17) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) - いろいろ試す61(と今年の反省会)
⇒ ねむい (01/02) - いろいろ試す61(と今年の反省会)
⇒ ひかわ (01/02) - いろいろ試す61(と今年の反省会)
⇒ ひかわ (01/01) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ねむい (12/31) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ひかわ (12/31)
- October 2024 (1)
- September 2024 (1)
- August 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (1)
- April 2024 (1)
- March 2024 (1)
- February 2024 (2)
- January 2024 (1)
- December 2023 (4)
- November 2023 (2)
- October 2023 (2)
- September 2023 (1)
- August 2023 (2)
- July 2023 (1)
- June 2023 (2)
- May 2023 (3)
- April 2023 (1)
- March 2023 (1)
- February 2023 (1)
- January 2023 (1)
- December 2022 (2)
- November 2022 (1)
- October 2022 (1)
- September 2022 (1)
- August 2022 (1)
- July 2022 (1)
- June 2022 (1)
- May 2022 (1)
- April 2022 (1)
- March 2022 (1)
- February 2022 (1)
- January 2022 (1)
- December 2021 (2)
- November 2021 (2)
- October 2021 (1)
- September 2021 (1)
- August 2021 (1)
- July 2021 (1)
- June 2021 (1)
- May 2021 (1)
- April 2021 (1)
- March 2021 (1)
- February 2021 (1)
- January 2021 (1)
- December 2020 (3)
- November 2020 (1)
- October 2020 (1)
- September 2020 (1)
- August 2020 (1)
- July 2020 (1)
- June 2020 (2)
- May 2020 (1)
- April 2020 (1)
- March 2020 (1)
- February 2020 (1)
- January 2020 (1)
- December 2019 (3)
- November 2019 (1)
- October 2019 (1)
- September 2019 (2)
- August 2019 (1)
- July 2019 (1)
- June 2019 (1)
- May 2019 (1)
- April 2019 (1)
- March 2019 (1)
- February 2019 (1)
- January 2019 (1)
- December 2018 (3)
- November 2018 (2)
- October 2018 (1)
- September 2018 (1)
- August 2018 (1)
- July 2018 (1)
- June 2018 (1)
- May 2018 (1)
- April 2018 (2)
- March 2018 (1)
- February 2018 (1)
- January 2018 (1)
- December 2017 (2)
- November 2017 (2)
- October 2017 (1)
- September 2017 (1)
- August 2017 (1)
- July 2017 (1)
- June 2017 (1)
- May 2017 (1)
- April 2017 (1)
- March 2017 (2)
- February 2017 (2)
- January 2017 (2)
- December 2016 (7)
- November 2016 (2)
- October 2016 (2)
- September 2016 (1)
- August 2016 (1)
- July 2016 (1)
- June 2016 (1)
- May 2016 (2)
- April 2016 (1)
- March 2016 (2)
- February 2016 (1)
- January 2016 (1)
- December 2015 (3)
- November 2015 (1)
- October 2015 (3)
- September 2015 (2)
- August 2015 (2)
- July 2015 (3)
- June 2015 (3)
- May 2015 (4)
- April 2015 (2)
- March 2015 (4)
- February 2015 (1)
- January 2015 (3)
- December 2014 (3)
- November 2014 (2)
- October 2014 (1)
- September 2014 (2)
- August 2014 (2)
- July 2014 (3)
- June 2014 (2)
- May 2014 (1)
- April 2014 (1)
- March 2014 (4)
- February 2014 (4)
- January 2014 (3)
- December 2013 (5)
- November 2013 (4)
- October 2013 (3)
- September 2013 (2)
- August 2013 (2)
- July 2013 (2)
- June 2013 (3)
- May 2013 (2)
- April 2013 (2)
- March 2013 (2)
- February 2013 (2)
- January 2013 (3)
- December 2012 (4)
- November 2012 (2)
- October 2012 (2)
- September 2012 (4)
- August 2012 (1)
- July 2012 (3)
- June 2012 (2)
- May 2012 (3)
- April 2012 (3)
- March 2012 (2)
- February 2012 (3)
- January 2012 (3)
- December 2011 (5)
- November 2011 (3)
- October 2011 (2)
- September 2011 (2)
- August 2011 (2)
- July 2011 (2)
- June 2011 (2)
- May 2011 (2)
- April 2011 (2)
- March 2011 (2)
- February 2011 (2)
- January 2011 (3)
- December 2010 (7)
- November 2010 (1)
- October 2010 (1)
- September 2010 (1)
- August 2010 (3)
- July 2010 (4)
- May 2010 (1)
- April 2010 (2)
- March 2010 (2)
- February 2010 (2)
- January 2010 (3)
- December 2009 (3)
- November 2009 (8)
- October 2009 (7)
- September 2009 (5)
- August 2009 (4)
- July 2009 (6)
- June 2009 (6)
- May 2009 (14)
- January 1970 (1)
Copyright(C) B-Blog project All rights reserved.