がれすたさんのDIY日記

電子回路、Python、組み込みシステム開発、自作エフェクターを語るblog

Seeed Arch Mixで始めるi.MX RT1052(1)

今回はSeeedStudioが出しているArchMixを使ってi.MX RT1052入門をやっていく

f:id:gsmcustomeffects:20191115210420p:plain
Seeed Arch Mix

上記の写真にあるようにかなりコンパクトに収まっている。
また値段も$29.90であり半端ない。
USB、SD、SDRAMも使えるのでお安くi.MX RTに触れたい人にとってもおすすめである。

というわけで今回はこれを使って基礎的な部分を学ぶ
環境としてはMCUXpressoIDEを使うのでそれをインストールしておいてください。
またMCUXpressoSDKでIMXRT1050用のものをビルドしてダウンロードしてください。

f:id:gsmcustomeffects:20191115225713p:plain

ダウンロードしたらIDESDKを読み込んでください
やり方はこの記事見ればわかると思います。
MCUXpresso IDEのペリフェラルコンフィグツールを使ってみる - がれすたさんのDIY日記

はじめに起動周りを整理しよう

このマイコンは内部メモリがないので外部flashから起動するXIPという方式をとることになる。*1
外部メモリとしてはHyperFlash、QSPIFlash、SDなどがあるがこのボードについているのはQSPI Flashなので評価ボードと同じプログラムでは動かない*2
修正部分を解説するためにまずは新規プロジェクトを作成する。

ドライバの部分は何も変更しなくていいので次に進む。
メモリの設定は以下の画像を参考に変更する。
f:id:gsmcustomeffects:20191115220117p:plain

そうするとプロジェクトが出来上がるのでxipというフォルダの中身を見ていく
f:id:gsmcustomeffects:20191116003851p:plain

Hyperflash向けの設定が書かれているのでこういう風に編集します。

/*
 * Copyright 2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "evkbimxrt1050_flexspi_nor_config.h"

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xip_board"
#endif

/*******************************************************************************
 * Code
 ******************************************************************************/
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.conf")))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.conf"
#endif

//const flexspi_nor_config_t hyperflash_config = {
//    .memConfig =
//        {
//            .tag                = FLEXSPI_CFG_BLK_TAG,
//            .version            = FLEXSPI_CFG_BLK_VERSION,
//            .readSampleClkSrc   = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
//            .csHoldTime         = 3u,
//            .csSetupTime        = 3u,
//            .columnAddressWidth = 3u,
//            // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
//            .controllerMiscOption =
//                (1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) |
//                (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable),
//            .sflashPadType = kSerialFlash_8Pads,
//            .serialClkFreq = kFlexSpiSerialClk_133MHz,
//            .sflashA1Size  = 64u * 1024u * 1024u,
//            .dataValidTime = {16u, 16u},
//            .lookupTable =
//                {
//                    // Read LUTs
//                    FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
//                    FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06),
//                    FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),
//                },
//        },
//    .pageSize           = 512u,
//    .sectorSize         = 256u * 1024u,
//    .blockSize          = 256u * 1024u,
//    .isUniformBlockSize = true,
//};
const flexspi_nor_config_t qspiflash_config = {
    .memConfig =
        {
            .tag = FLEXSPI_CFG_BLK_TAG,
            .version = FLEXSPI_CFG_BLK_VERSION,
            .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
            .csHoldTime = 3u,
            .csSetupTime = 3u,
            // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
            .sflashPadType = kSerialFlash_4Pads,
            .serialClkFreq = kFlexSpiSerialClk_100MHz,
            .sflashA1Size = 8u * 1024u * 1024u,
            .lookupTable =
                {
                    // Read LUTs
                    FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
                    FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
                },
        },
    .pageSize = 256u,
    .sectorSize = 4u * 1024u,
    .blockSize = 256u * 1024u,
    .isUniformBlockSize = false,
};
#endif /* XIP_BOOT_HEADER_ENABLE */

この状態でとりあえずビルドしてデバッグしてブレークポイントがちゃんと機能することを確認する。
デバッガ接続は以下のピンを使う
f:id:gsmcustomeffects:20191116220732p:plain

うまくできていたらこのようにブレークで止まる
f:id:gsmcustomeffects:20191116220521p:plain

この記事も合わせて読んでくれると自作ボードを作るときに参考になるかもです。
MIMXRT1052CVL5Bを使う際のTips - がれすたさんのDIY日記

というわけで初めからウエイト重めでしたが初期構成は終わりです。

まずはLチカからやってみる。

というわけで先ほどのプロジェクトでLチカが動くようにしましょう。
ArchMixには3色LEDが載ってるのでそれを光らせていきます。

f:id:gsmcustomeffects:20191116222604p:plain

実際にはピン設定ツールを起動して方向などの設定
f:id:gsmcustomeffects:20191116222626p:plain

全部の設定が終わったらコードを出力する。

最後にメインを以下のプログラムに書き換えればRGBのLEDが点滅するはず。

/*
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of NXP Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
/**
 * @file    MIMXRT1052xxxxB_Project.c
 * @brief   Application entry point.
 */
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1052.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */

/* TODO: insert other definitions and declarations here. */

/*
 * @brief   Application entry point.
 */

uint32_t delayCount;

void SysTick_Handler(void)
{
    if(delayCount != 0x00)
    {
    	delayCount--;
    }
}

void Systick_delay(uint32_t ms){
	SysTick->LOAD  = (SystemCoreClock/1000 & SysTick_LOAD_RELOAD_Msk) - 1;
	delayCount = ms;
	    while(delayCount!=0x00);
}

int main(void) {

  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
  	/* Init FSL debug console. */
    BOARD_InitDebugConsole();
    PRINTF("Hello World\n");
    SysTick_Config(SystemCoreClock/1000-1);
    /* Force the counter to be placed into memory. */
    volatile static int i = 0 ;
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
        GPIO_PinWrite(GPIO1, 9, 0);
        Systick_delay(200);
        GPIO_PinWrite(GPIO1, 9, 1);
        Systick_delay(200);
        GPIO_PinWrite(GPIO1, 10, 0);
  Systick_delay(200);
	GPIO_PinWrite(GPIO1, 10, 1);
	Systick_delay(200);
        GPIO_PinWrite(GPIO1, 11, 0);
	Systick_delay(200);
	GPIO_PinWrite(GPIO1, 11, 1);
	Systick_delay(200);
        /* 'Dummy' NOP to allow source level single stepping of
            tight while() loop */
        __asm volatile ("nop");
    }
    return 0 ;
}

LチカのためのタイマーはSystickタイマーを使っています。*3

まとめ

Seeed Arch Mixを用いてデバッグ環境を構築してLチカをやった。

IMXRT関連の記事はここにまとめてあるので興味があれば読んでください
i.MXRT1050 カテゴリーの記事一覧 - がれすたさんのDIY日記

*1:速度面で不利だと感じたら二段ブートローダでRAM展開して実行なんてこともできる。

*2:公式評価ボードはHyperFlashがついてる

*3:ARM共通のシステムタイマー搭載されてない機種もあるのでデータシート参照