aitendo 96×64サイズ 16bitカラーOLED part2

折角静止画まで出しましたから、やっぱり動画を出したくなります。そんなわけでさくっと作成。対応AVIデータは無圧縮の96*64サイズのみです。簡単なフレームの選別はしてますが、変なモノをいれるとこけます。まぁ、ヘッダ解析をきちんとしなければいけないのですが、これが主目的でもないので、これ以上まともにはしませんw
再生するAVIファイルはSDカードに入れます。EVK1101の場合、SDカードはSPI接続ですので、そのまんまOLEDを一緒のバスにつなげるとSPIのバスを共用してしまうためにダブルバッファリングなどを用いた並列読み出しができないため、あまり高速化はできません。ただ、AVR32 UC3Bの場合はUSARTをSPIとしても使えますので、USART Tx,Rx,CLKをSPIのMOSI,MISO,SCKとして使えば、OLEDとSDカードで使用するSPIバスを物理的に分けられますから、両者をDMAを使うことにより、効率的に画面表示をすることも可能です。
さて、SDカードのファイルシステムはChaNさんのFatFsを使ってもいいですが、折角なのでフレームワークに入っている機能だけでやってみましょう。
AVR32の場合、フレームワークに入っているSDカードのコンポーネントは上位層のメモリ管理コンポーネントの配下にあります。同様のSPI接続のデータフラッシュ対応のコンポーネントも配下にあり、それらを個別のドライブとしてサポートすることが可能です。機能としてはFAT32,16,12とLFNは対応していますが、Unicodeはコード変換がきちんとはサポートされていません。
Exampleには、なぜかデータフラッシュの制御サンプルしかありませんが、SDカードを制御するようにするには、CONFIG\conf_access.hで以下のように設定すればいいようです。ちなみにLUN1はデータフラッシュに割り当てられています。
<conf_access.h>
#define LUN_2                ENABLE  //!< SD/MMC Card.
/** 省略 **/
/*! \name LUN 2 Definitions
 */
//! @{
#define SD_MMC_SPI_MEM                          LUN_2
#define LUN_ID_SD_MMC_MEM                       LUN_ID_2
#define LUN_2_INCLUDE                           "sd_mmc_spi_mem.h"
#define Lun_2_test_unit_ready                   sd_mmc_spi_test_unit_ready
#define Lun_2_read_capacity                     sd_mmc_spi_read_capacity
#define Lun_2_wr_protect                        sd_mmc_spi_wr_protect
#define Lun_2_removal                           sd_mmc_spi_removal
#define Lun_2_usb_read_10                       sd_mmc_spi_usb_read_10
#define Lun_2_usb_write_10                      sd_mmc_spi_usb_write_10
#define Lun_2_mem_2_ram                         sd_mmc_spi_mem_2_ram
#define Lun_2_ram_2_mem                         sd_mmc_spi_ram_2_mem
#define LUN_2_NAME                              "\"SD/MMC Card\""
//! @}

これでctrl_accessモジュールと繋がります。あとはSDカードライブラリを使う前に、自分でSDカードで使用するSPIのチャンネルの初期化を行っておきます。
と、これで動くかと思ったら、どうもSDカードのmountがNGになるときがあります。オシロで波形を確認しつつトレースしてみると、SDカードのコンポーネントの初期化部分に問題がありそうです。
SDカードを電源投入後に初期化するには、PowerOnしたあとで最初にCSをDeassertしたまま74CLK以上のクロックを入れる必要があるのですが、これをやっていないようですね。ただ、AVR32のSPI関連IPはCSをdeassertしたままクロックを出せないようなので、一度CSとCLKを通常の出力ポートのピンに設定して、自前でパタパタとクロックを作ってリセットする必要があります。取りあえず、以下のコードを作って、sd_mmc_spi_internal_init()とsd_mmc_spi_check_presence()に追加しておきます。
// for poweron reset.  @@myan
void sd_mmc_spi_poweron_reset(void)
{
  int i;
  spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS);  // unselect SD_MMC_SPI
  // GPIO pins used for SD/MMC interface
  static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
  {
    {SD_MMC_SPI_SCK_PIN,  SD_MMC_SPI_SCK_FUNCTION },  // SPI Clock.
    {SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
  };
  // generate cs=H & CLK 74clk
  gpio_set_gpio_pin(AVR32_PIN_PA17);
  for (i=0;i<100;i++) {
    gpio_set_gpio_pin(AVR32_PIN_PA15);        // CLK ON
    gpio_clr_gpio_pin(AVR32_PIN_PA15);        // CLK OFF
  }
  // re-Assign I/Os to SPI.
  gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
                     sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));
}

上記までやって、やっとSDカードとファイルシステムが安定して動作するようになりました。あとは、AVIファイルのmoviチャンク内にある00dbフレームのみを読み出ししつつ展開すれば、取りあえずは動きます。
たた、このままだとメインクロックが12MHzのままで動作させていますから遅いので、PLLをいじってもうちょっと高速化してみます。
以前取り上げたNGWに乗ってるAP7000と同様にUC3Bも内部でPLLを持っていますので、外部OSCのクロックを逓倍したクロックで60MHzで動作させることが可能です。ということで、PLLを逓倍してCPU,HSB,PBBが48MHz動作でPBA24MHzにしておきます。なお、AP7000と違ってUC3系ではHSBはCPUと同じクロックでしか設定できません。また、CPUクロックを30MHz以上にする場合には、内蔵フラッシュのアクセスウェイトを1ウェイトにする必要があります。
大体、この状態で18~9フレーム/秒ぐらいです。SDカードの読み出しがsingle block readのみだったり、DMA使ってなかったりする手抜きコードでも、これだけ出れば上出来かな?
ここまで標準でライブラリが揃っていると、結構あっという間に作れてしまうのでモノグサにはいいですね。ちなみにこの動画対応も1日ぐらいしかかけてないです。まぁ、同期を取っていない手抜き再生なんでアレですが・・・
一応、実際に再生している動画→avr32_oledtest.avi
再生テスト用のプロジェクト→ココ
ちなみに、動画を撮ってアップするのは初めてですw 先日入手したCASIOのEX-Z400で撮ってますけど、近接撮影で動画撮るのが難しいなぁ~。他のカメラもこんなもんなのかな?
固定焦点なので、近接だとMFでフォーカス合わせてから撮る必要があるので面倒・・・

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です