マイコン工作実験日記

Microcontroller を用いての工作、実験記録

USBD ROM Stackを使う

2013-11-10 11:32:09 | Weblog
LPC11U37でUSB CDCを動かすために、ROM内蔵のUSB APIを使ってみました。ユーザ・マニュアルではLPC11Uxx USB on-chip driversとして ひとつの章が割かれているのですが、こいつがDoxygenで生成した内容をマニュアルの体裁に合わせて文書整形しなおしたようなもので、読みにくくてわかりずらいものになっています。調べてみると、オンラインで読めるページがありました。こちらの方がはるかに読み易いです。

そしてさらにLPC11UXXのサンプルコードをダウンロード。この中にある USBシリアルブリッジとして機能するUSB_ROM_CDCのコードをベースとして使って、文字列を出力するプログラムを作成してみました。単純にCDC接続されるのを待って、接続ができたら文字列を出力するだけ。



これでデバック用メッセージの出力ができる準備が整ったので、便利に使えそうです。

サンプルコードを見るとAPIの使い方の概要もわかるのですが、よく見ると安易にそのままコピペして使ってはいけない危険なコードだということも判明。USBドライバAPIを使うにあたっては、まず最初にUSBスタックがハードウェアを初期化する際に、スタックが使用するメモリ領域に関するパラメータを渡す必要があるのですが、そこにはこんなコードが。。
 /* initilize call back structures */
 memset((void*)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
 usb_param.usb_reg_base = LPC_USB_BASE;
 usb_param.mem_base = 0x10001000;
 usb_param.mem_size = 0x1000;
 usb_param.max_num_ep = 3;

使用するメモリ領域の開始アドレスとサイズが直書きされてます。LPC11U37だとこの領域は8KBあるSRAM領域の後半4KBにあたります。これじゃぁ、アプリは前半4KBしか使えないじゃないですか。続いてCDC層のドライバを初期化する際にもメモリ領域を割り当てていますが。。

cdc_param.mem_base = 0x10001500;
cdc_param.mem_size = 0x300;

こちらも決め打ちです。しかも、さきほどハードウェア初期化時に指定したメモリ領域と重なっちゃっているじゃぁないですか。おそらくはどちらもテキトーに決めた値で、サンプルを動かす分には実害も無いのでしょうが、いくらなんでも乱暴すぎですね。

初期化APIには必要とするメモリ領域の大きさを求めるGetMemSize()という関数が用意されているので、これを呼び出して調べてみると、ハード初期化時に必要とするメモリ領域サイズは2KB, CDC層ドライバが必要とするのは100バイトにも満たないことがわかりました。

このようにサンプルではUSBD ROM StackのためにメインのSRAM内の領域を割り当てています。しかしながら、LPC11U37/501では、別途USB RAMが2KBとSRAM1領域が2KB用意されています。そこでハード初期化時にには、USB RAMの2KBを割り当て、CDC層初期化時にはSRAM1領域からメモリを割り当てることにしました。