LPC1343 USB virtual COMでローカルエコー


1.LPC1343のVirtual comでエコー(Example project modify)

開発Listへ戻る

このエントリではNXPから提供されているExample Projectを使います。
準備はコチラ
・Example projectのインポート方法
・USBコネクタの接続
Win7 x64用のDriver入手方法
があります。


で、今回やってみることは
Teratermでキーボード or File転送
    ↓
LPC1343はUSB経由でデータを受け取り、まったく同じデータをUSB経由でTeratermへ返す
    ↓
Teratermの表示で結果を確認

やっていることは単なるエコーです。


モディファイしたコードです。
vcomdemo.cを修正します。青文字のところが修正した部分です。

#include
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include "LPC13xx.h"
#include "type.h"

#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "vcomdemo.h"

#define EN_TIMER32_1 (1<<10)
#define EN_IOCON (1<<16)
#define EN_USBREG (1<<14)

typedef struct {
char d[32];
int num;
}GETDAT_T;

/*----------------------------------------------------------------------------
Initializes the VCOM port.
Call this function before using VCOM_putchar or VCOM_getchar
*---------------------------------------------------------------------------*/
void VCOM_Init(void) {

CDC_Init ();
}


/*----------------------------------------------------------------------------
Reads character from serial port buffer and writes to USB buffer
*---------------------------------------------------------------------------*/
void VCOM_Serial2Usb(GETDAT_T dat) {

if (dat.num!=0 && CDC_DepInEmpty) { // 1 is empty so if empty
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&dat.d[0], dat.num);
}

}

/*----------------------------------------------------------------------------
Reads character from USB buffer and writes to serial port buffer
*---------------------------------------------------------------------------*/
#include
GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;

}
return(Getdata);
}


/*----------------------------------------------------------------------------
checks the serial state and initiates notification
*---------------------------------------------------------------------------*/
void VCOM_CheckSerialState (void) {
unsigned short temp;
static unsigned short serialState;

temp = CDC_GetSerialState();
if (serialState != temp) {
serialState = temp;
CDC_NotificationIn(); // send SERIAL_STATE notification
}
}

/*----------------------------------------------------------------------------
Main Program
*---------------------------------------------------------------------------*/
int main (void) {
/* Basic chip initialization is taken care of in SystemInit() called
* from the startup code. SystemInit() and chip settings are defined
* in the CMSIS system_.c file.
*/

/* Enable Timer32_1, IOCON, and USB blocks */
GETDAT_T Getdata;
Getdata.num=0;

LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);

USBIOClkConfig();

VCOM_Init(); // VCOM Initialization

USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect

while (!USB_Configuration) ; // wait until USB is configured

while (1) { // Loop forever
VCOM_Serial2Usb(Getdata); // read serial port and initiate USB event
Getdata.num=0;
VCOM_CheckSerialState();
Getdata=VCOM_Usb2Serial();

} // end while
} // end main ()

解説です。
といっても、USBの詳細部分はほとんど理解できてません。。
動いたからイイや程度です。


コンセプト
試してみることは、下の図のように
Example projectではUSBで受信したデータをUART TXに変換
UART RXで受信したデータをUSBに変換という機能だったのを

USBで受信データをGetdataという変数で受け渡して、USBでそのまま返すというものにします。



将来的に、センサーなどのデータをUSB経由でPCに転送することを想定して
データの受け渡し方法を確認することが目的です。

↓将来やりたいことのイメージ↓

コード
・まず、変数を定義します。
typedef struct {
char d[32];
int num;
}GETDAT_T;

d :受け渡しデータ 32byteのchar
VCOM_Usb2SerialでserBuf が32byte charだったからそうしてます。
num : 有効データ数です。

・次はmainです。

while (1) { // Loop forever
VCOM_Serial2Usb(Getdata); // read serial port and initiate USB event
Getdata.num=0;
VCOM_CheckSerialState();
Getdata=VCOM_Usb2Serial();
}

VCOM_Usb2Serial関数でUSB経由のデータと有効データ数をGetdataに入れます。
そしてVCOM_Serial2USB関数でGetdataをUSB経由でPCに送信です。
送信した後は有効データを0にしてます。


・VCOM_Usb2SerialではserBufに入ったデータと
numBytesReadに入った有効データ数をGetdataに入れ込んで戻してます。

#include
GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;
}
return(Getdata);
}


・最後にVCOM_Serial2UsbでEmpty flagが立ったうえで有効データがあった場合に
USBでデータを転送してます。

void VCOM_Serial2Usb(GETDAT_T dat) {

if (dat.num!=0 && CDC_DepInEmpty) { // 1 is empty so if empty
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&dat.d[0], dat.num);
}

}


これでエコーの完成です。

Teratermで試した結果です。


キーボードから入力した場合は転送速度が遅い(間欠的)のでまったく問題ありませんが
ファイル転送を選んだときは転送速度が速い(連続)ので
VCOM_Usb2Serial()内の serBuf [32];で指定している
32byteを超えるデータを転送すると32byte以上は無視されます。

青地で示した以下の32の数字を増やせばより多くのデータを送信できるようです
(48にして試したところOKでした)


typedef struct {
char d[32];
int num;
}GETDAT_T;


GETDAT_T VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;

GETDAT_T Getdata;
Getdata.num = 0;

CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);

strncpy(Getdata.d,serBuf,numBytesToRead);
Getdata.num = numBytesToRead;
}
return(Getdata);