AtmelStudioにLUFAライブラリをインストールしてUSB-MIDIデバイスを作成

####LUFAライブラリでUSBデバイスの作成
AVRマイコンでUSBデバイスを作成する場合V-USBやATmega32U4を使いArduinoIDEを利用する方法、LUFAライブラリを使用するなどがあります
LUFAに関してはAtmelStuido6.2以前の記事しか見当たらないのでAtmelStudio7へのLUFAのインストールからsampleのMIDIデバイスを変更してMIDIのNOTEO_ONに対してC4(標準のド)のNOTE_ONを返すデバイスを作成するまでを記事にしてみました。

#####AtmelStudio7とLUFAライブラリのインストール
[AtmelStudio7](https://www.microchip.com/mplab/avr-support/atmel-studio-7)をMicrochip社のサイトからダウンロードしインストールします。
![AtmelStudio.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/c4c2ee81-9d8a-80f2-aed2-63137bb0b12c.jpeg)

Start PageからDownload Atmel Studio Extensionsを選び
![AtmelStudio3.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/777722a8-abbe-6357-8dde-390868695502.jpeg)


OnlineからLUFA LibrasyをDownload
![AtmelStudioLUFA.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/3f9ca315-ea0d-db35-3ec3-af2ab47626ab.jpeg)

これで準備完了、一度AtmelStudioを終了させます。

#####Exampleプログラムをロード
File->New->Example ProjectからMIDI Device Demo(Class Driver APIs)-AVR8 Achitectueを選びます。
![AtmelStudioLUFASampleMIDI.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/7dd946ec-8af1-5edc-43b7-ab73e0bc3c02.jpeg)


#####不要なモジュールの削除
このままではサンプルボード用のモジュールがリンクされるのでASF Wizardタブを開き不要なモジュールをRemoveしておきます（Board Suppotはuser、LED,Joystic,Buttonsは不要、ヘッダファイルのインクルードとか関係するコードはRemoveしてくれないので**後で手で削除しないといけません**)
![AtmelStudioLUFASampleAFS.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/d0b17582-f8ac-ae57-cfa2-401a9b7f1780.jpeg)



次にAlt+F7でプロパティタブを開きDeviceから(Change Device)をクリックしターゲットのデバイスを変更します。
![AtmelStudioLUFASampleDeviceChange.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/e48b0af8-86f5-7900-67ec-cffae795688f.jpeg)



Solution Exploereから編集するファイルを選び、必要な所を変更削除します。
![AtmelStudioLUFASampleSolExp.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/aa2d632d-7747-c0db-e2c8-9f90f6b4f3c7.jpeg)


後はBuild(F7)して不要なモジュールに関するエラー表示を見ながら不要なコードを削って行けば、Document/Atmel Studio/7.0/(プロジェクト名)/(プロジェクト名)/Debugにhexファイルが作成されるのでターゲットに書き込めばUSBデバイスが作成出来ます。
今回はDFUで書き込み。
![AtmelStudioLUFASampleMIDIDFU.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/496952c2-f36d-0050-a525-f4582356faa3.jpeg)

MIDIデバイスの確認、ちゃんと認識してます
![AtmelStudioLUFASampleMIDIDevice.jpg](https://qiita-image-store.s3.amazonaws.com/0/205783/0d43b45b-d710-4ec2-c34f-1db1b17d8274.jpeg)

検証に使用したATmega32U2デバイス
![SANY0126.JPG](https://qiita-image-store.s3.amazonaws.com/0/205783/f30a5cd8-715d-3dc3-308e-baad40abf3bb.jpeg)

####sampleを変えてみる
MIDIのNOTE_ONを受けるとLEDを光らせる元sampleをNOTE_ONを受けるとC4(note_no 60)のNOTE_ONを返すようにmain.cを変更します、CDCデバイスのコールバックテストみたいな感じ(LEDモジュールt等をRemoveしたので関連するコードも**手作業で削除**)[ReceivedMIDIEvent.Event](http://www.fourwalledcubicle.com/files/LUFA/Doc/130901/html/struct_m_i_d_i___event_packet__t.html)を見て[MIDI_EVENT](http://www.fourwalledcubicle.com/files/LUFA/Doc/130901/html/group___group___u_s_b_class_m_i_d_i_common.html#gac47273cb876009f79b023b8dae8f1019)のNOTE_NOと判断しているので他のイベントを拾うときはこの辺りを変更して下さい。

```C:main.cの一部
int main(void)
{
	SetupHardware();
	GlobalInterruptEnable();
	for (;;)
	{
		MIDI_EventPacket_t ReceivedMIDIEvent;
		while (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
		{
			if ((ReceivedMIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && (ReceivedMIDIEvent.Data3 > 0))
				if(ReceivedMIDIEvent.Data2 != 60)
					send_NOTE(60,127);  //C4 ON
		}
		MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
		USB_USBTask();
	}
}
```
反対にMIDIコマンドをホストへ送るにはMIDI_EventPacket_tにMIDI_COMMANDをセットして[MIDI_Device_SendEventPacket](http://www.fourwalledcubicle.com/files/LUFA/Doc/130901/html/group___group___u_s_b_class_m_i_d_i_device.html#gad55056397b71abf267e7ec24352be6cb)と[MIDI_Device_Flush](http://www.fourwalledcubicle.com/files/LUFA/Doc/130901/html/group___group___u_s_b_class_m_i_d_i_device.html#gaeb0a51c4524af9a331599a2a520326db)を呼び出せば良いようです。

```C:MIDIのNOTE_ONを返す関数
void send_NOTE(uint8_t note_no,uint8_t velo){
	MIDI_EventPacket_t MIDIEvent;
	
	MIDIEvent = (MIDI_EventPacket_t)
	  {
		  .Event       = MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON),

		  .Data1       = 0x90,
		  .Data2       = note_no,
		  .Data3       = velo,
	  };
	  MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
	  MIDI_Device_Flush(&Keyboard_MIDI_Interface);
}
```
####最後に
LUFAライブラリを使ったUSB-MIDIデバイスの作成をAtmelStudioのインストールからざっくり説明してみました、[LUFAのライブラリのドキュメントのこの辺り](http://www.fourwalledcubicle.com/files/LUFA/Doc/130901/html/group___group___u_s_b_class_drivers.html)を読めばsampleコードを変更して色々なUSBデバイスを作ることが出来ます。
お手軽さではArduino(Leonaldo,Micro)ですがATmeag32U2を使う場合や、ディスクリプタがV-USBなどと比べ非常に読み易いのでUSBの知識はある程度必要ですが複合デバイスが作り易いなども長所です、USBの速度とUSB-MIDデバイスであるリアルタイム処理（PC側のバッファリング処理等が無い）を生かして音源制御などが向いているのではないでしょうか。