1. Overview
MCX N947 チップは、堅牢な処理能力、豊富な周辺機能、高度なセキュリティ機能を備えた高集積マイクロコントローラであり、複雑なアプリケーションにも適しています。その主要な周辺機能の一つが FlexSPI です。
FlexSPI は、QuadSPI NOR フラッシュ、QuadSPI NAND フラッシュ、HyperRAM などのソリッドステート・ストレージ・デバイスを接続するための拡張可能なシリアル・ペリフェラル・インタフェースであり、多様なストレージ・デバイスをサポートできるよう複数のモードに設定できます。
NXP の FRDM-MCXN947 ボードは、MCXN947 デバイスをベースとした低コストの評価用ボードです。NXP では、ハードウェア評価ボード、統合開発環境 (IDE)、サンプル・アプリケーション、ドライバなど、MCXN947 用のツールとソフトウェアを提供しています。デフォルトでは、本ボードの FlexSPI インタフェースは MT35XU512 NOR フラッシュに接続されています。
本資料では、HyperRAM を MCXN947 ボードの FlexSPI インタフェースへ接続する方法について説明します。
ハードウェア環境:
開発ボード: FRDM-MCXN947
HyperRAM: W956D8MBYA
ソフトウェア環境:
IDE: MCUXpresso IDE v11.9.0
SDK: SDK Builder | MCUXpresso SDK Builder (nxp.com)
2. HyperRAM 回路図
以下に、FRDM-MCXN947 ボードにおける 8 線式フラッシュの公式回路図を示します。HyperRAM の W956D8MBYA パッケージは TFBGA 24 ボール 5 × 5 アレイであるため、そのまま置き換えることができます。
上記回路図を基に、HyperRAM メモリの信号接続を表にまとめました。
HyperRAM信号接続表
|
HyperRAM チップのピン |
機能 |
MCXN947に接続されています |
|
CS |
CSチップセレクト信号 |
P3_0/FLEXSPI0_A_SS0_b |
|
SCK |
SCKクロック信号 |
P3_7/FLEXSPI0_A_SCLK |
|
DQS |
DQS Signal |
P3_6/FLEXSPI0_A_DQS |
|
DQ0 |
OSPIデータ信号D0 |
P3_8/FLEXSPI0_A_DATA0 |
|
DQ1 |
OSPIデータ信号D1 |
P3_9/FLEXSPI0_A_DATA1 |
|
DQ2 |
OSPIデータ信号D2 |
P3_10/FLEXSPI0_A_DATA2 |
|
DQ3 |
OSPIデータ信号D3 |
P3_11/FLEXSPI0_A_DATA3 |
|
DQ4 |
OSPIデータ信号D4 |
P3_12/FLEXSPI0_A_DATA4 |
|
DQ5 |
OSPIデータ信号D5 |
P3_13/FLEXSPI0_A_DATA5 |
|
DQ6 |
OSPIデータ信号D6 |
P3_14/FLEXSPI0_A_DATA6 |
|
DQ7 |
OSPIデータ信号D7 |
P3_15/FLEXSPI0_A_DATA7 |
3. HyperRAM設定プロセス
3.1 クロック構成
FlexSPI のクロックは正しく設定される必要があります。
プログラミング段階では安全性を考慮して低い周波数を選択する方が望ましく、ここでは 75 MHz を使用します。
3.2 FlexSPI 初期化構成
続いて、FlexSPI 関連の設定を行います。FLEXSPI_GetDefaultConfig を呼び出すことで、FlexSPI 機能構造体 flexspi_config_t のデフォルト設定を取得できます。これらの設定は汎用性が高く、ほとんどの FlexSPI デバイスでそのまま使用できます。W956D8MBYA HyperRAM では、デフォルト設定に加えて次のパラメータを設定します。
config.ahbConfig.enableAHBPrefetch = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
(1) enableAHBPrefetch — AHB プリフェッチを有効にするかどうか有効にすると、FlexSPI は現在の AHB バースト読み取りより多くのデータを先読みします。
(2) enableAHBBufferable — AHB 書き込みバッファアクセスを有効にするかどうか有効にすると、書き込みコマンドの完了を待たずに戻るため、後続の命令を継続でき、システムの並行性が向上します。
(3) enableReadAddressOpt — AHB 読み取りバーストの開始アドレス整列制限を解除するかどうか有効にすると、バースト読み取りの開始アドレスはバイトアラインメントの制限を受けません。
(4) enableAHBCachable — AHB バスのキャッシュ可能な読み取りを有効にするかどうかキャッシュヒットが発生した場合はキャッシュからデータを取得しますが、データ整合性の確保が必要です。
(5) rxSampleClock — データ読み取りに使用するクロックソースHyperRAM では、デバイス自体がリードストローブパルスを生成し、DQS ピン経由で入力されます。
3.3 FlexSPI 外部デバイス構成構造の詳細説明
FlexSPI が外部デバイスと通信する際には、クロック周波数やデータの有効期間など、デバイスとの通信タイミングを調整する必要があることが多いです。NXPのソフトウェアライブラリは、これらのパラメータを構成するためのflexspi_device_config_t構造体を提供します。
typedef struct _flexspi_device_config {
uint32_t flexspiRootClk;
bool isSck2Enabled;
uint32_t flashSize;
flexspi_cs_interval_cycle_unit_t CSIntervalUnit;
uint16_t CSInterval;
uint8_t CSHoldTime;
uint8_t CSSetupTime;
uint8_t dataValidTime;
uint8_t columnspace;
bool enableWordAddress;
uint8_t AWRSeqIndex;
uint8_t AWRSeqNumber;
uint8_t ARDSeqIndex;
uint8_t ARDSeqNumber;
flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit;
uint16_t AHBWriteWaitInterval;
bool enableWriteMask;
} flexspi_device_config_t;
(1) flexspiRootClk = 75 000 000 — 前述の FlexSPI クロック周波数に合わせます。
(2) flashSize = 0x2000 — フラッシュ容量 (KB)。W956D8MBYA の場合、64 Mb = 8 MB = 8 × 1024 KB です。
(3) CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle、このパラメータは CS 信号線間隔の時間単位を設定します。
(4) CSInterval = 2、このパラメータは CS 信号線の有効状態と無効状態を切り替える際の最小時間間隔を、上記 CSIntervalUnit で定義された単位で設定します。
(5) CSHoldTime = 3、このパラメータは FlexSPI ルート・クロック・サイクル数で測定される CS 信号線のホールド時間を設定します。
(6) CSSetupTime = 3、このパラメータは FlexSPI ルート・クロック・サイクル数で測定される CS 信号線のセットアップ時間を設定します。
MCXNx4x のデータシートによると、T_CK = 6ns、最小 T_CSS = 8.3ns、最小 T_CSH = 9.8nsです。75MHzのクロック周期は約13.3ナノ秒です。したがって、CSHoldTimeとCSSetupTimeはどちらも1以上である必要があり、3に設定することができます。
(1)dataValidTime=2、レジスタDLLACRとDLLBCRは通信における有効データ時間を設定するために使用されます。単位はナノ秒です。
3.4 LUTテーブル構成
以下に、HyperRAM の読み取りおよび書き込みタイミング用 LUT テーブル構成のコード例を示します。
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Read Data */
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07),
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA + 2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
/* Write data */
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07),
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA + 2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
};
(1) 8 ライン差動 HyperRAM を使用しており、クロックの両エッジを利用します。そのため、外部メモリとの通信に使用されるデータ ライン数は kFLEXSPI_8PAD です。
(2) HyperRAM と HyperFlash は、Cypress Semiconductor 社の HyperBus™ インターフェース仕様に基づいて設計されたメモリ製品です。このオペランドは仕様で定義されているため、読み取り操作のオペランドは 0xA0、書き込みデータのオペランドは 0x20 に固定されています。
(3) CADDR_DDR 列アドレス: 1 回の転送で送られるバイト数は 8 の倍数である必要があるため、指定した行アドレスと列アドレスが対象 HyperRAM の上限を超える場合、FlexSPI は自動的に上位ビットを 0 に設定します。
上の表によれば、下位 16 ビットが列アドレス(有効ビット 3 ビット)、上位 13 ビットは互換性のために予約され 0 に設定する必要があります。したがって、列アドレスに対するタイミング パラメータは 16、すなわち 0x10 に設定します。
(4) RADDR_DDR 行アドレス: 図に示すとおり、FLSHxxCR1[CAS] ビットが 0 でない場合、FlexSPI 周辺回路は実際にマップされたフラッシュ アドレス(メモリのオフセット アドレス)を、行アドレス FA[31:CAS+1] と列アドレス [CAS:1] に分割して転送します。ワード アドレス指定が可能なフラッシュ デバイスでは、フラッシュが 2 バイト単位で読み書きされるため、アドレスの最下位ビットは不要です。
FlexSPI では 1 ワードを 2 バイトと見なすため、2 バイト境界へ合わせる場合、必要なアドレス ビットは 1 ビット減ります。行アドレスと列アドレスの合計は 1 ビット少ない必要があります。W956D8MBYA は 64 Mbit (2^26) です。列アドレスに 3 ビットを割り当てる場合、HyperRAM 全体にアクセスするには理論上 26‑1‑3 = 22 ビットの行アドレスが必要です。その後、8 ビット境界にアラインします。アラインしない場合、FlexSPI が下位ビットを 0 でパディングし、意図しないアドレスへアクセスしてしまいます。したがって、パラメータは 0x18、すなわち 24 ビットです。
4. 実験による検証
単純な AHB 読み取り/書き込み操作により、この HyperRAM が正常に動作するかを検証できます。
コードは次のとおりです。
for (i = 0; i < sizeof(s_psram_write_buffer); i++)
{
s_psram_write_buffer[i] = i;
}
memcpy((uint32_t*)(EXAMPLE_FLEXSPI_AMBA_BASE), s_psram_write_buffer, sizeof(s_psram_write_buffer));
memcpy(s_psram_read_buffer,(uint32_t*)(EXAMPLE_FLEXSPI_AMBA_BASE) , sizeof(s_psram_read_buffer));
if (memcmp(s_psram_read_buffer, s_psram_write_buffer, sizeof(s_psram_write_buffer)) == 0)
{
PRINTF("AHB Command Read/Write data successfully !\r\n");
}
シリアルポートに「AHB コマンドのデータの読み取り/書き込みが正常に完了しました!」と表示されたら、
これは、HyperRAM への FlexSPI 接続が正常に機能していることを示しています。