123_USBCDC - embedded-kiddie/beauto-rover-arm GitHub Wiki

1.2.3 USBシリアル通信プロジェクトのインポート

ビュートローバーARM の搭載のCPUボード VS-WRC103LV には LPCXpresso でソースコードデバッグが可能とする「LPC-Link 接続ポート」が備わっていますが、NXP 純正の LPC-Link2 は絶版となっているらしく入手が困難です(以前は秋月で2000円台で購入できたらしい…)。

SWD(Serial Wire Debug)をサポートしたJTAGエミュレータなら可能なのかもしれませんが、せめて追加コスト無しに USB(Universal Serial Bus)を介して Tera Term などに printf() の出力が出せるように設定します。

  1. usbcdc(USB Communications Device Class)のサンプルプロジェクトをインポートし、
  2. usbcdc から必要なファイルだけを自身のプロジェクトにコピーし、
  3. ビュートローバーがちゃんと走るようにいくつかのファイルを修正、
  4. 最後に printf() が使えるように設定し、動作を確認します。

以下はその手順です。

1. usbcdc サンプルプロジェクトのインポート

CD-ROM に入っているサンプルではなく、必ず Vstone 社のダウンロードページ から最新版の「PCとのシリアル通信」サンプル をダウンロードします。そうしないとコンパイル時にエラーで悩むことになります。

「Quickstart Panel」の「Import project(s)」から、ダウンロードした VS-WRC103LV_Sample_Serial_20170808.zip をインポートします。

2. 必要なファイルのコピー

srcinc にある以下のソースコードを自身のプロジェクトの srcinc にそれぞれコピーします。

  • src/cdcuser.c, src/usbcore.c, src/usbdesc.c, src/usbhw.c, src/usbuser.c
  • inc/cdc.h, inc/cdcuser.h, inc/config.h, inc/type.h, inc/usb.h, inc/usbcfg.h, inc/usbcore.h, inc/usbdesc.h, usbhw.h, inc/usbreg.h, inc/usbuser.h

新しくファイルが加わったことを LPCXpresso に知らせるため、プロジェクト名を右クリックし「Refresh」を実行します。

念の為、ファイルが追加されたか確認しましょう。

3. ファイルの修正

次にコンパイル時に出るワーニングへの対処です。コピーした inc/usbcore.h の52行目をコメントアウトします(Vstone 社の最新版で src/usbcore.c が修正済みのため、この定義は不要になりました)。

- __inline void UsbAddPtr(void **vpptr, uint32_t n);
+ //__inline void UsbAddPtr(void **vpptr, uint32_t n);

続いて CPU ボード上の押しボタンを機能させるために src/usbhw.c の45行目と46行目をコメントアウトします。

-   LPC_IOCON->PIO0_1 &= ~0x07;
-   LPC_IOCON->PIO0_1 |= 0x01;		/* CLK OUT */
+ //LPC_IOCON->PIO0_1 &= ~0x07;
+ //LPC_IOCON->PIO0_1 |= 0x01;		/* CLK OUT */

ちなみに50行目、51行目にある GPIO ピン PIO0_3 への設定は USB_VBUS のために必要で、競合する LED1(橙)が点灯しなくなります。

LPC_IOCON->PIO0_3   &= ~0x1F;
LPC_IOCON->PIO0_3   |= 0x01;		/* Secondary function VBUS */

また最適化のレベルを上げた Release でコンパイルすると動作しなくなる不具合を修正するため、57行目からの関数 delay() を最適化の適用外に指定します。

- void delay (uint32_t length ) {
+ void __attribute__((optimize("O0"))) delay (uint32_t length ) {

同様に src/cdcuser.c の74行目を次のように修正します。

- void SciInit() {
+ void __attribute__((optimize("O0"))) SciInit() {

以上で1バイトずつ送受信する関数 SciByteRx()SciByteTx() が使えるようになりました。

4. printf() の設定と動作確認

最後にリポジトリの src/sci.cinc/sci.h をダウンロードし、プロジェクトの srcinc にそれぞれコピーします。コピー後は「Refresh」を忘れずに…

動作を確認するため main() のあるファイルに以下をコピペして下さい。

// TODO: insert other include files here
#include <stdio.h>
#include "sci.h"

// TODO: insert other definitions and declarations here
void sciExample(void);

int main(void) {
	unsigned char data = 0;

	// TODO: insert code here
	sciInit();

	// リターンが送られてくるまで待機
	do {
		SciByteRx(&data);
	} while (data != '\r');

	// printf(), scanf()のテスト
	sciExample();

	return 0 ;
}

/*----------------------------------------------------------------------
 * printf(), scanf() 動作例
 *----------------------------------------------------------------------*/
void sciExample(void) {
	int i = 0;
	double f = 0.0;
	const char *txt = "0123456789012345678901234567890123456789012345678901234567890123456789\r\n";

	CDC_SetLineCoding();
	sciPrintf("%s%s", "\e[2J", "\e[0;0H"); // 画面クリア+原点に移動
	sciPrintf("Baud rate   = %d\r\n", CDC_LineCoding.dwDTERate);
	sciPrintf("Stop bit(s) = %d\r\n", CDC_LineCoding.bCharFormat);
	sciPrintf("Parity type = %d\r\n", CDC_LineCoding.bParityType);
	sciPrintf("Data bits   = %d\r\n", CDC_LineCoding.bDataBits);

	printf("Circle ratio = %7.4lf\r\n", (double)3.1415926);
	printf("Cyborg %03d is a Japanese famous animation.\r\n", 9);
	printf(txt); // sciPrintf()はヌル文字含め64文字で制限される

	printf("%sPlease input a number: ", "\r\n");
	sciScanf("%8lf", &f); // scanf()は使えない
	printf("%sYour input is '%f'.", "\r\n", f);

	while (1) {
		printf("\e[%d;%dH Count = %10ld", 10, 30, i++);
 	}
}

コンパイルし、ビュートローバーに書き込んだら電源を入れ直します。Tera Term を立ち上げ、VS-WRC003LV COM Port につなぎます。

次いでメニューの「設定 → シリアルポート(E)…」からボーレートを最大に設定します(小さいとPC側が取りこぼす可能性があります)。他はそのままで大丈夫です。

最上部の表示が「Tera Term - [未接続] VT」から「COM3 - Tera Term VT」に変わったことを確認し、リターンキーを押します。コピペしたプログラムが無事動くことを確認して完了です。

お疲れ様でした。


※ サンプルのバージョンについて

「PCとのシリアル通信」サンプル は LPCXpresso 3.5 がベースの LPCOpen バージョン 1.03(最終版は 2.05)をリンクしているようなので、必要なファイルだけをコピーすることにしました。

※ リンクされるライブラリについて

printf() は Redlib のライブラリを使っています。scanf() の方はオーバーライトすべきシステムコールが見つからず、sciScanf() でないと正しく動きません。NXP のフォーラム によると (none) が付いているライブラリが最小の メモリフットプリント ということで、ガマンして下さい。他にも Newlib とか NewlibNano とかあるので、そちらなら動くカモですが未確認です。悪しからず…


目次 のページに戻ります。

⚠️ **GitHub.com Fallback** ⚠️