がれすたさんのDIY日記

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

MIMXRT10xxのUARTを使ってみる(ポーリングAPI)

今回はUARTについてやっていきたいと思います。
prinfに関しては評価ボードを使う限りは初期プロジェクト作成でリンクしてくれるので説明はしません。あくまでbyte転送APIで何か送るという感じですね。

環境としては以下を例に説明しますがRT1020でもRT1015でも同じシリーズならできると思います。

  • MCUXpressoIDE v11.0
  • Forlix MIMXRT1052CVL5B or MIMXRT1050-EVK: i.MX RT1050

プロジェクトの作成

新規プロジェクト(new project)作成をクリック

f:id:gsmcustomeffects:20190526045710p:plain
プロジェクトの作成

次にメモリ関連の設定です。
ここに関しては自分の環境にあったメモリ構成を作成して下さい

f:id:gsmcustomeffects:20190526045811p:plain
メモリ構成について

ForlinxのRT1052boardを使う場合のメモリ構成や起動に関してはここを読むといいと思います。

プロジェクト構成の確認とピン設定

前項まででプロジェクトの作成が終わっていると思うのでプロジェクト構成の確認をしていきます。
普通通りにプロジェクトを作成すると評価ボード用の設定がいろいろインサートされてると思います。(公式評価ボードのSDKおよびBSPをフォークして使っているため)

f:id:gsmcustomeffects:20190526054128p:plain
ピン設定ツール

CANとかCSIとかその辺いらないと思うので整理します。

f:id:gsmcustomeffects:20190526060145p:plain
ルーチンの整理
もとから入ってるBOARD_InitDEBUG_UARTPinsってのがあるのでそれはそのまま使うとして
LPUART1を使うのでそのピンが設定されていることを一応確認する。
(もし別のLPUART(2~8)を使いたい場合はそれのピン設定もしておくとよい)
f:id:gsmcustomeffects:20190526065817p:plain
BOARD_InitDEBUG_UARTPins

整理したら上のほうにあるupdate projectをクリックしてコードを吐き出します。

クロックの設定

次にクロックの確認をしていく
自分は工業グレードのMIMXRT1052CVL5Bを使っているのでメインクロックを528MHzにします。(コンシューマグレードの方は600MHzでいいと思う

f:id:gsmcustomeffects:20190527064643p:plain
メインクロックの設定

そしてLPUARTのクロックの設定を確認する。

f:id:gsmcustomeffects:20190528232809p:plain
LPUARTのクロック

ボーレート計算が以下の図のように計算されるのでボーレート誤差が大きいようなら元クロックを調整する必要があると思うがこの辺はブログ末尾のメモ読んでくれればいいと思う。

f:id:gsmcustomeffects:20190529073610p:plain
ボーレートの計算

※OSRはオーバーサンプリングレシオのことでBAUDレジスタで設定することが可能(SDKだと自動?
こちらも同様に終わったらupdate projectをクリックしてコードを出力しておく

ペリフェラルツールで設定する

最後にペリフェラルツールでLPUARTの設定をする。
右上のUSBマークアイコンをクリックして設定画面を開く。

f:id:gsmcustomeffects:20190530004528p:plain
ペリフェラルツール

LPUART画面のコンフィグタブでプリセットを選ぶとほぼ自動設定してくれる。
基本的な使い方をするならこれで十分なのでこういったアシストがあるのはうれしい

f:id:gsmcustomeffects:20190530005832p:plain
LPUART設定

こちらも同様に終わったらupdate projectをクリックしてコードを出力

コードを書いていく

最後にコードについてだが、初期化に関しては別ファイルで行われているので実質記述するのは数行でいい

/**
 * @file    uarttest2.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.
 */
uint8_t txbuff[] = "uart sample\r\n";
int main(void) {

  	/* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
    BOARD_InitDEBUG_UARTPins();
  	/* Init FSL debug console. */
    //BOARD_InitDebugConsole();

    //PRINTF("Hello World\n");
    LPUART_WriteBlocking(LPUART_1_PERIPHERAL, txbuff, sizeof(txbuff) - 1);
    /* Force the counter to be placed into memory. */
    volatile static int i = 0 ;
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
        i++ ;
    }
    return 0 ;
}

説明的なのをすると

uint8_t txbuff[] = "uart sample\r\n";

で送信するバッファを定義している。

BOARD_InitDEBUG_UARTPins();
/* Init FSL debug console. */
//BOARD_InitDebugConsole();

BOARD_InitDEBUG_UARTPins()で先ほど作ったピン設定をする。
BOARD_InitDebugConsole()はprintfとUARTをつないでくれるやつで今回は使わないのでコメントアウトしている。

最後にポーリングAPIです。

LPUART_WriteBlocking(LPUART_1_PERIPHERAL, txbuff, sizeof(txbuff) - 1);

受信はLPUART_ReadBlockingというAPIでできます。

uint8_t rxbuff[10] = {0};
LPUART_ReadBlocking(LPUART_1_PERIPHERAL, rxbuff, sizeof(rxbuff));

こんな感じでいいと思います。

Memo

ボーレート設定について

ボーレート値の計算はペリフェラルツール上で行ってるわけではなくLPUART_Initの冒頭でOSRとSBRの最適化を行う設計になっているため実行するまで実ボーレートがわからない仕様になっている。

f:id:gsmcustomeffects:20190529081358p:plain
LPUART_Init冒頭のボーレートにかかわるレジスタ値の最適値探索

そして探索後誤差を評価して返す

f:id:gsmcustomeffects:20190529081642p:plain
誤差評価

これかならず動く設定が決まってればいいけど可変ボーレートにした場合落ちる可能性もあるよね・・・・・
というよりmainでこのAPI呼んだ際にエラーコード見てない感じなのでサンプルとしてはそんなに優秀ではないかなという印象

エラーコードはこのように定義されているのでもとからあるアサートを利用するなりifで区切って無限ループで止めたりバグになりにくい設計にするといいかもしれない

f:id:gsmcustomeffects:20190530014303p:plain
LPUARTのエラーコード