最近、RT1050プロジェクトのXIPメモリとしてQSPIフラッシュ(Puya simi P25Q16H)を使用しているお客様がいましたが、初回のダウンロードに失敗し、再度電源を入れた後に再度ダウンロードが成功し、アプリが実行できるという現象が常に発生していました。プログラムアルゴリズムには、RT-UFLを使用します。解析後、この状況は通常、新しい QSPI フラッシュの QE が有効になっていないことに関連しています。したがって、お客様が使用したQSPIフラッシュのQE位置に基づいて、作成者はSDK flexspi_nor_polling_transferコードで対応するQEを特別に有効にし、新しいQSPIフラッシュでQEを有効にした後もRAMで実行してプログラムの問題があるかどうかを確認しました。ただし、お客様はプロジェクトを実行することさえできませんflexspi_nor_polling_transfer。お客様の以前の説明によると、ハードウェアはRAMコードを実行でき、最初のフラッシュダウンロードは機能しませんが、再ダウンロード後に実行できるため、ハードウェアは機能します。この現象から、当初はFlexSPI DQSが占有されていることに新たな問題が関係しているのではないかと推測されています。通常の状況では、FlexSPI DQS をフローティング状態のままにしておくことをお勧めします。プロジェクトでは flexSPI の周波数が 120MHz であるため、DQS を使用する場合、FlexSPI リード データの内部サンプリング クロック ソースは、メモリ デバイスによるリード ストロボと DQS パッドからの入力となります。この方法には問題があります。そのため、お客様にハードウェアを再度確認するように依頼しました。その結果、DQSはお客様のボード上の他の回路の制御ピンとして使用されます。通常、この状況では注意すべき点が 2 つあります。
まず、FlexSPIクロックは60MHz以内に制御されます。
次に、FlexSPI リード データの内部サンプリング クロック ソース コンフィギュレーションは、FlexSPI コントローラによって生成され、内部でループバックされるダミー リード ストロボ (FlexSPIn_MCR0[RXCLKSRC] = 0x0) です。
したがって、この記事では、お客様が使用するQSPIフラッシュに基づいて対応するQE位置のテストコードを準備する方法、DQSが有効になっている場合の動作を考慮し、RT-UFLダウンロードアルゴリズムを変更してテストする方法に焦点を当てます。
お客様の問題を再現するには、関連するソフトウェア、ハードウェア、フラッシュプログラミング用フラッシュドライバー、量的緩和状況をテストするためのコードを準備する必要があります。
MIMXRT1050-EVKBで、オンボード抵抗をデフォルトのハイパーフラッシュからQSPIフラッシュに変更します。変更点は次のとおりです。
USE QSPI FLASH(Mount R153~R158, DNP R356,R361~R366)。
搭載されているU33 ISSI QSPIフラッシュを取り外し、お客様が使用したPuya simi P25Q16Hで新しいQSPIフラッシュを書き込みます。
JLINKをご利用いただいておりますので、JLINK plusのダウンロードをご用意ください。
SDK2.14.0コード:flexspi_nor_polling_transfer、QE状況のテストに使用されます。
アプリ プロジェクト: led_blinky
RT-UFL プログラムのアルゴリズムコード:https://github.com/JayHeng/RT-UFL
JLINKドライバ:JLINKV768B使用し、それ以上のバージョンでもOKです。
図1
これはまだ一般的なステータスレジスタビット9であることがわかります。
関連する LUT の書き込みおよび読み取りコマンダーは次のとおりです。
図2
書き込みにはコマンド0X01で、2バイト連続で書き込む必要があることがわかります。しかし、readコマンドの場合、2つのステータスレジスタバイトのコマンドは別々です。QEビットを操作するときは、この点に注意する必要があります。
このコードは主に、外部フラッシュの量的緩和の有効化と無効化、消去、書き込み、読み取り機能をテストするために使用されます。
コードの変更ポイントには、P25Q16Hに準拠するようにLUTコマンドを変更することが含まれます。QE読み取り、書き込み、消去機能の追加。flexSPI の周波数と DQS ループバック内部の状況を変更します。
関連するコードは次のとおりです。
LUT関連車長:flexspi_nor_polling_transfer.c
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Normal read mode -SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Fast read mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Fast read quad mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
/* Read extend parameters */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Write Enable */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Erase Sector */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),//0xD7
/* Page Program - single mode */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Page Program - quad mode */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read ID */
[4 * NOR_CMD_LUT_SEQ_IDX_READID] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Enable Quad mode */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Enter QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Exit QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read status register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Read status register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Erase whole chip */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),//0xC7
};
flexspi_nor_flash_ops.c:私たちは読み書きします
status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = FLASH_QUAD_ENABLE;
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_cache_status_t cacheStatus;
flexspi_nor_disable_cache(&cacheStatus);
#endif
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Enable quad mode. */
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
flashXfer.data = &writeValue;
flashXfer.dataSize = writeValue <= 0xFFU ? 1 : 2;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_nor_enable_cache(cacheStatus);
#endif
return status;
}
status_t flexspi_nor_disable_quad_mode(FLEXSPI_Type *base)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = 0x0;//FLASH_QUAD_ENABLE;
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_cache_status_t cacheStatus;
flexspi_nor_disable_cache(&cacheStatus);
#endif
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Enable quad mode. */
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
flashXfer.data = &writeValue;
flashXfer.dataSize = 2;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_nor_enable_cache(cacheStatus);
#endif
return status;
}
status_t flexspi_nor_QE_register(FLEXSPI_Type *base, uint32_t *QEvalue)
{
/* Wait status ready. */
bool isBusy;
uint32_t readValue;
status_t status;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = FLASH_PORT;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1;
flashXfer.data = &readValue;
flashXfer.dataSize = 1;
do
{
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
if (FLASH_BUSY_STATUS_POL)
{
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
{
isBusy = true;
}
else
{
isBusy = false;
}
}
else
{
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
{
isBusy = false;
}
else
{
isBusy = true;
}
}
*QEvalue = readValue;
} while (isBusy);
return status;
}
QE position:App.h
#define FLASH_QUAD_ENABLE 0X0200
品質管理業務:フレックススパイ_またはポーリング_トランスファー.c
PRINTF("Get the QE bit value before QE enable!\r\n");
uint32_t QEvalue=0;
status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue);
if (status != kStatus_Success)
{
return status;
}
PRINTF("QE=%X!\r\n",(uint8_t)QEvalue);
#if 1
status = flexspi_nor_disable_quad_mode(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
PRINTF("Get the QE bit value after QE disable!\r\n");
status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue);
if (status != kStatus_Success)
{
return status;
}
PRINTF("QE=%X!\r\n",(uint8_t)QEvalue);
#endif
PRINTF("Enable the QE bit value !\r\n");
/* Enter quad mode. */
status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue);
if (status != kStatus_Success)
{
return status;
}
PRINTF("QE=%X!\r\n",(uint8_t)QEvalue);
FlexSPI周波数変更:flexspi_nor_polling_transfer.c,app.h
flexspi_device_config_t deviceconfig = {
.flexspiRootClk = 60000000,
.flashSize = FLASH_SIZE,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 0,
.columnspace = 0,
.enableWordAddress = 0,
.AWRSeqIndex = 0,
.AWRSeqNumber = 0,
.ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
};
static inline void flexspi_clock_init(void)
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 5); /* flexspi clock 60M. */
}
内部でループバック:app.h
#define EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK kFLEXSPI_ReadSampleClkLoopbackInternally
変更したコードをRT1050 RAMにダウンロードし、次のように結果を実行します。
図3
図から、QEは通常、読み取り、書き込み、消去、読み取りの機能を実装できることがわかります。この記事のQSPIは以前に運用されたことがあるので、ここでは2と読みますが、これは初めてQEが有効になります。新しいチップの場合、デフォルトで0と表示されます。これは、QEが有効になっていないことを意味します。また、変更後、外部フラッシュを正確に消去、プログラム、および読み取ることができることがわかります。これは、現在のコード変更が成功したことを示しています。LUT、QEポジション、DQS考慮事項(60MHz+ループバック内部)はすべて機能しています。
SDKのled_blinkyコードを使用して、主にFCBとReadSampleCLKSRCの周波数を変更してください。
evkbimxrt1050_flexspi_nor_config.c は次のように変更されます。
const flexspi_nor_config_t qspiflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 3u,
.csSetupTime = 3u,
.controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_60MHz,
.sflashA1Size = 8u * 1024u * 1024u,
…
}
このコードは、新しく修正されたプログラムのフラッシュドライバーをデバッグモードでテストし、プロジェクトをコンパイルし、.srecを生成するために使用されます。JFLASH方式のフラッシュプログラムに使用されます。
スーパーダウンロードアルゴリズムRT-UFLをダウンロードした後、上記の2つの要素に基づいてスーパーダウンロードアルゴリズムを変更する必要があります。
まず、QEが有効になっています。次に、DQSが使用されます。
この記事のソリューションでは、RT-UFLは引き続きオプションROMを使用してFlexSpiを初期化します。
オプションの説明に従って、以下を選択します。
オプション 0: 0xc0000201
オプション 1:0 x0
このような状況のように:
図4
ここでは、keil プロジェクトを使用します。
\ RT-UFL-1.0\ ビルド\ mdk
コードの変更は次のとおりです。
Ufl_main.c:ufl_set_target_property1
case kChipId_RT105x:
uflTargetDesc->flexspiInstance = MIMXRT105X_1st_FLEXSPI_INSTANCE;
uflTargetDesc->flexspiBaseAddr = MIMXRT105X_1st_FLEXSPI_BASE;
uflTargetDesc->flashBaseAddr = MIMXRT105X_1st_FLEXSPI_AMBA_BASE;
//p25q16h QESet bit 1 in Status Register 2 {.option0.U = 0xc0000201, .option1.U = 0x00000000},
uflTargetDesc->configOption.option0.U = 0xc0000201;
uflTargetDesc->configOption.option1.U = 0x0;
ufl_romapi.c: CLKSRC の設定のサンプルを読み込んでください
status_t flexspi_nor_auto_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option)
{
// Wait until the FLEXSPI is idle
register uint32_t delaycnt = 10000u;
while(delaycnt--)
{
}
status_t status = flexspi_nor_get_config(instance, config, option);
if (status != kStatus_Success)
{
return status;
}
config->memConfig.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally; //For DQS is used by other circuit
return flexspi_nor_flash_init(instance, config);
}
FlashDev.c
struct FlashDevice const FlashDevice = {
FLASH_DRV_VERS, // Driver Version, do not modify!
"MIMXRT_FLEXSPI", // Device Name
EXTSPI, // Device Type
0x60000000, // Device Start Address
0x00800000, // Device Size in Bytes (8mB)
256, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
100, // Program Page Timeout 100 mSec
5000, // Erase Sector Timeout 5000 mSec
// Specify Size and Address of Sectors
0x1000, 0x00000000, // Sector Size 4kB (256 Sectors)
SECTOR_END
};
FlashOS.h:フラッシュページ、セクターサイズを定義するために、UFL_L0タイプを生成します
#define FLASH_DRV_SIZE_OPT (0)
#if (FLASH_DRV_SIZE_OPT == 0)
#define FLASH_DRV_PAGE_SIZE (0x100)
#define FLASH_DRV_SECTOR_SIZE (0x1000)
#elif (FLASH_DRV_SIZE_OPT == 1)
#define FLASH_DRV_PAGE_SIZE (0x200)
#define FLASH_DRV_SECTOR_SIZE (0x1000)
#elif (FLASH_DRV_SIZE_OPT == 2)
#define FLASH_DRV_PAGE_SIZE (0x200)
#define FLASH_DRV_SECTOR_SIZE (0x10000)
#endif
コードをコンパイルすると、フラッシュドライバーのファームウェアが得られます:mimxrt_flexspi_uv5_ufl.flm
名前を次のように変更します:MIMXRT_FLEXSPI_UV5_UFL_P25Q16H。FLMの
JLINKドライバをインストールしたら、RT-UFLアルゴリズムを使用するように変更してください。
この記事によると、JLINKの駆動アルゴリズムはRT-UFLアルゴリズムに変更されています。
https://www.cnblogs.com/henjay724/p/14942574.html
In fact, just copy: RT-UFL-1.0\RT-UFL-1.0\algo\SEGGER\JLink_Vxxx
インストールされたJLINKパスへ:C:\Program Files\SEGGER\JLINKV768B
しかし、この記事では、P25Q16Hの変更されたフラッシュアルゴリズムを追加するためにこれに基づいて 、変更ポイントは次のとおりです。
(1)添付ファイル RT1050_P25Q16H_JLINK\ プログラム\ JLinkDevices.xml を次の場所にコピーしてください:
C:\Program Files\SEGGER\JLINKV768B
図5
.xmlの変更は次のとおりです。P25Q16H項目とそのアルゴリズムを追加してください:
図6
注:デバイス名はMIMXRT1050_UFL_P25Q16Hです
(2) CopyRT1050_P25Q16H_JLINK\program\ IMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM
to:C:\Program Files\SEGGER\JLINKV768B\Devices\NXP\iMXRT_UFL
図7
このMIMXRT_FLEXSPI_UV5_UFL_P25Q16H。FLM は、上記の修正フラッシュドライバーアルゴリズムです。
(3)run C:\Program Files\SEGGER\JLINKV768B\JLinkDLLUpdater.exe, update the
IDE IARのドライバを変更
MIMXRT1050-EVKBの場合、外部JLINKを使用するには、EVKBボード上のJ33を切断し、JTAGをJ21に差し込む必要があります。
まず、以前に変更したEVKB-IMXRT1050-flexspi_nor_polling_transferを使用し、QEビットを無効にして、新しいQSPIフラッシュチップをシミュレートします。テストは次のとおりです。
図8
jFlashテストの結果は:
図9
新しいフラッシュドライバーでJflashを使用すると、フラッシュが正常にプログラムできることがわかります。
QEビットを無効にして、新しいQSPIフラッシュチップをシミュレートし、図8のようにテストします。
アプリのデモ:IARプロジェクトを使用(お客様が使用します)。オプション選択:JLINK:
図10
図11
ここで、デバイスは変更されたスーパーダウンロードアルゴリズムデバイス名として選択されることに注意してください。方法は以下の通りです。IAR デバッグによって生成された settings->xxx.jlink は、次のように変更されます。
図12
2 つのポイント: override =1 と device は新しく変更されたアルゴリズム デバイス名です。
デバッグ テスト結果:
図 13
アルゴリズムは正常にデバッグでき、アルゴリズムもUFLによって変更されていることがわかります。
全速力で走らせると、オンボードのLEDが点滅しているのがわかります。
これは、すべてのフラッシュ ドライバー アルゴリズム、ハードウェア、およびコードが新しい P25Q16H QSPI フラッシュを既にサポートしていることを意味します。
新しいQSPIフラッシュを使用する場合は、まずQEの位置とDQSが使用されているかどうかに注意を払い、次に対応するRT-UFLプログラミングアルゴリズムを準備する必要があります。UFL アルゴリズムは通常、ほとんどのフラッシュ チップをデフォルトでサポートできます。QE と DQS を使用する場合は、新しい QSPI フラッシュをサポートするためにアルゴリズムを微調整するだけで済みます。したがって、この記事では、アルゴリズムを変更した後に顧客プロジェクトを書き込む問題を正常に解決しました。他のQSPIフラッシュについては、この記事の方法を使用して、書き込みアルゴリズムをそれに応じて変更し、独自のプロジェクトのニーズを確実に満たすようにすることもできます。