CDC-HOST のおぼえがき

基板をCDC-Device にするのは良く実装するし、Cube-MXのサポートもなかなか良いのだが、 CDC-HOSTは格段にサポートの質が落ちる・・・、というよりあと一歩使えないライブラリ。
送信は簡単( USBH_CDC_Transmit を呼ぶ )だが受信が難しい。
原因は以下のコード、受信したときの処理(USBH_CDC_Receive を呼び出したあと、定期的に以下のコードが呼ばれます)

HAL側Library のコード


  length = USBH_LL_GetLastXferSize(phost, CDC_Handle->DataItf.InPipe);

  if (((CDC_Handle->RxDataLength - length) > 0U) && (length > CDC_Handle->DataItf.InEpSize))
  {
    CDC_Handle->RxDataLength -= length ;
    CDC_Handle->pRxData += length;
    CDC_Handle->data_rx_state = CDC_RECEIVE_DATA;
  }
  else
  {
    USBH_CDC_ReceiveCallback(phost);
  }

 

このコードの意味するところは、分割されたデータの一部を受けとったときは、 CDC_Handleという構造に順にデータを入れていく。

データが分割されていないか、分割されたデータの最後の一つを受けとったときは、
(このケースが一般のようだ)
USBH_CDC_ReceiveCallback (アプリ側がデータを受け取るコールバック) 難点は、コールバックにはサイズすら教えてくれないこと(どういう設計だ?)

コールバック側で再度データサイズを取り直してポインタを進めれば良い。

  //  proceed the pump last data.
  CDC_HandleTypeDef *hcdc = (CDC_HandleTypeDef *) hUsbHostFS.pActiveClass->pData;
  uint32_t length = USBH_LL_GetLastXferSize(phost, hcdc->DataItf.InPipe);
  hcdc->pRxData += length;

 

USBH_CDC_Receive の引数に設定したバッファの先頭ポインタと、このhcdc->pRxDataとの間に 受信したデータが入ります。

普通に考えるとシリアル通信のエミュレートなので、受信するデータのサイズは知らなくて、 受け取ったそばから、FIFOに格納していって、STXとETXに挟まれたデータを読み出すか、 改行コード区切りでgets のようなコードでとりだすかをしたいところ

この実現方法は、USBH_CDC_ReceiveCallbackの中でデータをFIFOに格納して、 再度、USBH_CDC_Receiveを呼び出すという形で対応できる。