平成26年 8月24日
プログラムの修正
プログラムに関して最低限の変更を行います。
・シリアルポートのポート数を比較的簡単に変更できるようにする。
ポート数は当面デバッグ用の標準入出力と標準エラー出力の2ポートあれば事足りますが、それ以外のポート、
例えばログ出力用のポートやユーザー用のポートを簡単に追加できるようにプログラムをパラメータ化しておく。
・事実上ポーリングとなっているシリアルの送信処理を割り込み処理に変更する。
シリアルの送信処理(PICからPCへの送信)は、ファイルusb_device_cdc.c内の関数CDCTxService()を周期的に呼び出すことで、
送信している。これを最初の送信開始はputUSBUSART()関数で行い、それ以後の継続処理を割り込み処理関数内で
行うように変更する。
まず、ポート数の変更には、今後CDC以外のUSB機能を追加することを前提に幾つかの関数を定義しておきます。
・各EPがどの機能に割り当てられているかを返す関数(enum FuncType EP2Func(uint8_t ep))
・各EPが特定機能の何番目(CH)に割り当てられているかを返す関数(uint8_t EP2Ch(uint8_t ep))
・特定機能のn番目には、どのEPが割り当てられているかを返す関数(uint8_t xxx2EP(uint8_t ch))
今回はCDC機能のみなのでEP2Func()関数は実装しません。今回は下記のようになります。
// CDCのCH番号から対応するデータEP番号を返す
uint8_t CDCCh2EP(uint8_t ch)
{
const uint8_t Ch2EP[CDC_CNT] =
{ 2, 4 };
if(ch >= CDC_CNT)
return (uint8_t)(-1);
else
return Ch2EP[ch];
}
uint8_t CDCEP2Ch(uint8_t ep)
{
#define NOTDEF (uint8_t)(-1)
const uint8_t EP2Ch[16] =
{ NOTDEF, 0, 0, 1, 1, NOTDEF, NOTDEF, NOTDEF,
NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF, NOTDEF };
if(ep>= 16)
return NOTDEF;
else
return EP2Ch[ep];
}
これらの関数は、プログラム中で特定の機能やCHを選択するときに必要になります。ディスクリプタを変更するときに一緒に変更出来るようにしておきます。ディスクリプタの記述もマクロを使って追加削除しやすい形に書き換えます。
次にデータの送受信についてですが、シリアル受信(PCからPICへ)は、EPに設定された受信バッファにデータが送られると割り込みが
発生します。割り込み処理でデータを扱うなら割り込み処理ルーチン内部でこれを処理します。現在はgetsUSBUSART()関数が呼ばれた
時に処理するポーリングになっています。ここはそのままにしておきます。割り込み処理で行うならFIFOなどの追加が必要でしょう。
シリアル送信(PICからPCへ)は、もう少し変則的で送信開始の指示はputUSBUSART()関数が行いますが、実際の処理はCDCTxService()関数で行うようになっています。このためプログラムのメインループ内でCDCTxService()関数を呼び出す必要があります。例えば送信文字数が多くて一度の送信では送りきれないとき、最初の送信完了後に再びCDCTxService()関数が呼ばれて初めて残りの文字が送信されるように設定されます。
これではメインの処理によって通信速度が影響を受けるので、putUSBUSART()関数内で送信を開始し、送信の継続処理は割り込み処理内部で行うように変更します。これでCDCTxService()関数は不要になります。
これで最低限の動作確認は出来そうです。ある程度検証して必要な処理内容が理解できたら、その後に全面的に書き直すかどうかを考えるようにします。