###V-USBを使ってタイミングクリティカルな処理を行う方法。
V-USBを使用するにあたってインタラプト転送で使用する場合約10msごとにUSBの割り込みが発生し他のデバイスなどと通信中に割り込みが発生すると問題が起きるので、処理を割り込みに同期させて問題を回避しました。
例えばAppleの旧規格のキーボード(ADB)のUSBコンバーターなどを作ろうとすると、キーボードにコマンドを送信してデータの受信までにUSBの割り込みが発生した場合データを取りこぼしてしまいます。
これを避けるためUSBの割り込み発生時にフラグを立て、次の割り込みが発生する前に処理を終了させることで問題を回避させてみました。
V-USBはかなりタイミング的にシビアなコードなのでフラグを立てるコードで問題が起きないようにvusb/usbdrv内のusbdrvasmXXX.inc(クロック依存のインクルードファイル)内でUSB_INT_VECTOR:のすぐ後で最初のタイミング合わせている辺りが良いでしょう。
waitForJ:
inc YL
sbis USBIN, USBMINUS
brne waitForJ ; just make sure we have ANY timeout
waitForK:
;The following code results in a sampling window of 1/4 bit which meets the spec.
ldi x4,1 <ここでフラグを立てる
sts adbSend,x4
sbis USBIN, USBMINUS
rjmp foundK
sbis USBIN, USBMINUS
rjmp foundK
sbis USBIN, USBMINUS
rjmp foundK
sbis USBIN, USBMINUS
rjmp foundK
sbis USBIN, USBMINUS ;[0]
rjmp foundK ;[1]
usbdrvasmXXX.incはusbdrvasm.Sでインクルードされるのでフラグの変数をexternしておきます。
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
extern usbTxBuf, usbTxStatus1, usbTxStatus3
extern adbSend <これ
main.cでフラグの宣言しておきます、volatile宣言を忘れずに。
volatile uchar adbSend = 0;
main内でフラグが立ったら割り込みから復帰直後と判断しフラグをクリアして処理を行います、次の割り込みまでの8msぐらいの処理ならこの様にして同期すれば問題は起きません。
usbPoll();
if (usbConfiguration && usbInterruptIsReady()) {
if(adbSend == 1){
adbSend = 0; /*フラグをクリア*/
メインの処理