예제 #1
0
파일: MIDI.c 프로젝트: eta4ever/led-kb
int main(void)
{
	SetupHardware();

	// LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	GlobalInterruptEnable();

	// uint8_t BUT_current = PIND & (1 << PD1);; // текущее значение кнопки
	// uint8_t BUT_previous = BUT_current; // предыдущее значение кнопки
	//uint8_t BUT_message=0; // 0 - ничего не отправлять, 1 - отправить vel 0, 2 - отправить vel 127
	//uint8_t LED_current = 0; // текущее значение светодиода

	int ADC_current[16]; // текущие значения АЦП
	int ADC_previous[16]; // предыдущие значения АЦП
	uint8_t ADC_deviation = 20; // порог фиксации изменения АЦП, давить шум

	for (uint8_t i=0; i<16; i++) { ADC_current[i] = raw_ADC(); ADC_previous[i] = ADC_current[i];} // инициализация

	for (;;)
	{
		
		// дроп входящих
		MIDI_EventPacket_t ReceivedMIDIEvent; 
		while (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent));
		
		// опрос 16 входов мультиплексора
		for (int MUX_pos = 0; MUX_pos < 3; MUX_pos++ ){

				MUX_address(MUX_pos); // установить адрес

				// _delay_ms(1);
				
				// MUX_enable();

				// _delay_ms(1);

				ADC_current[MUX_pos] = raw_ADC(); // АЦП

				// MUX_disable();
				
				if ( abs(ADC_current[MUX_pos] - ADC_previous[MUX_pos]) >= ADC_deviation ) // если изменения больше порога, отправить сообщение CC
				{
					cc_send(MUX_pos, ADC_current[MUX_pos] / 8);
					ADC_previous[MUX_pos] = ADC_current[MUX_pos];
				}

				_delay_ms(10);

				MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
				USB_USBTask();
		}

		// MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
		// USB_USBTask();
	}
}
예제 #2
0
void MIDI_IN(void) {

	MIDI_EventPacket_t ReceivedMIDIEvent;

	if (MIDI_Device_ReceiveEventPacket(&MIDI_Interface, &ReceivedMIDIEvent)) {
		LEDs_TurnOnLEDs(LEDMASK_RX);
		Serial_TxByte(ReceivedMIDIEvent.Data1);
		Serial_TxByte(ReceivedMIDIEvent.Data2);
		Serial_TxByte(ReceivedMIDIEvent.Data3); 	
	}
		
	else {
		LEDs_TurnOffLEDs(LEDMASK_RX);
	}

}
예제 #3
0
void usb_get_midi(MidiDevice * device) {
   /* Select the MIDI OUT stream */
   Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPNUM);

   MIDI_EventPacket_t event;
   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {

      midi_packet_length_t length = midi_packet_length(event.Data1);

      //pass the data to the device input function
      //not dealing with sysex yet
      if (length != UNDEFINED)
         midi_device_input(device, length, event.Data1, event.Data2, event.Data3);

   }
   MIDI_Device_USBTask(&USB_MIDI_Interface);
   USB_USBTask();
}
예제 #4
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
  SetupHardware();

  sei();
  
  unsigned char c = 0;
  for (;;) {
    //Check if we've received any MIDI messages from the USB line
    if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIpacket_out))
    {
      handle_MIDI_out();
    }
    if (Serial_getChar(&c)) {
      handle_MIDI_in(c);
    }
    MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
    USB_USBTask();
  }
}
예제 #5
0
파일: midi_usb.c 프로젝트: JoeMatt/p600fw
void usb_get_midi(MidiDevice * device) {
   MIDI_EventPacket_t event;
   while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {

      midi_packet_length_t length = midi_packet_length(event.Data1);

      //pass the data to the device input function
      //not dealing with sysex yet
      if (length != UNDEFINED) {
         uint8_t input[3];
         input[0] = event.Data1;
         input[1] = event.Data2;
         input[2] = event.Data3;
         midi_device_input(device, length, input);
      }

   }
   MIDI_Device_USBTask(&USB_MIDI_Interface);
   USB_USBTask();
}
예제 #6
0
파일: DualMIDI.c 프로젝트: 40000ft/lufa
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	GlobalInterruptEnable();

	for (;;)
	{
		CheckJoystickMovement();

		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))
			  LEDs_SetAllLEDs(ReceivedMIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2);
			else
			  LEDs_SetAllLEDs(LEDS_NO_LEDS);
		}

		MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
		USB_USBTask();
	}
}
예제 #7
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
	SetupHardware();

	LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
	GlobalInterruptEnable();

	for (;;)
	{
		MIDI_EventPacket_t ReceivedMIDIEvent;
		if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))
		{
			if ((ReceivedMIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
			{
				DDSNoteData* LRUNoteStruct = &NoteData[0];

				/* Find a free entry in the note table to use for the note being turned on */
				for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
				{
					/* Check if the note is unused */
					if (!(NoteData[i].Pitch))
					{
						/* If a note is unused, it's age is essentially infinite - always prefer unused not entries */
						LRUNoteStruct = &NoteData[i];
						break;
					}
					else if (NoteData[i].LRUAge >= LRUNoteStruct->LRUAge)
					{
						/* If an older entry that the current entry has been found, prefer overwriting that one */
						LRUNoteStruct = &NoteData[i];
					}

					NoteData[i].LRUAge++;
				}

				/* Update the oldest note entry with the new note data and reset its age */
				LRUNoteStruct->Pitch          = ReceivedMIDIEvent.Data2;
				LRUNoteStruct->TableIncrement = (uint32_t)(BASE_INCREMENT * SCALE_FACTOR) +
						                         ((uint32_t)(BASE_INCREMENT * NOTE_OCTIVE_RATIO * SCALE_FACTOR) *
						                          (ReceivedMIDIEvent.Data2 - BASE_PITCH_INDEX));
				LRUNoteStruct->TablePosition  = 0;
				LRUNoteStruct->LRUAge         = 0;

				/* Turn on indicator LED to indicate note generation activity */
				LEDs_SetAllLEDs(LEDS_LED1);
			}
			else if ((ReceivedMIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_OFF)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))
			{
				bool FoundActiveNote = false;

				/* Find the note in the note table to turn off */
				for (uint8_t i = 0; i < MAX_SIMULTANEOUS_NOTES; i++)
				{
					if (NoteData[i].Pitch == ReceivedMIDIEvent.Data2)
					  NoteData[i].Pitch = 0;
					else if (NoteData[i].Pitch)
					  FoundActiveNote   = true;
				}

				/* If all notes off, turn off the indicator LED */
				if (!(FoundActiveNote))
				  LEDs_SetAllLEDs(LEDS_NO_LEDS);
			}
		}

		MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
		USB_USBTask();
	}
}
// The MIDI processing task.
//
// Read the buttons and expansion ports to generate MIDI notes. This routine
// is the heart of the MidiFighter.
//
void Midifighter_Task(void)
{
    // If the Midifighter is not completely enumerated by the USB Host,
    // don't go any further - no updating of LEDs, no reading from
    // endpoints, we wait for the USB to connect.
    if (USB_DeviceState != DEVICE_STATE_Configured) {
		main_watchdog_flag = true;		
        return;
    }

    // Overview
    // --------
    // The state of all the active notes is kept in an array of bytes
    // recording the most recent velocity of the note. A nonzero velocity is
    // a NoteOn and a zero velocity is a NoteOff. We update the keystate
    // from the outside world first, from the keyboard second, from the
    // expansion port third and generate LEDs from the resulting table at
    // the end.
    //
    // Midi Map
    // --------
    // In normal mode only 16 notes are being tracked, as well as the
    // digital expansion ports, plus two notes for each analog port for the
    // smart filters:
    //
    //     2  2  3  3  <- analog 2,3 = 104 .. 107
    //     0  0  1  1  <- analog 0,1 = 100 .. 103
    //
    //     .  .  .  .  <- bank 0 = 48 .. 52
    //     .  .  .  .  <- bank 0 = 44 .. 47
    //     .  .  .  .  <- bank 0 = 40 .. 43
    //     .  .  .  .  <- bank 0 = 36 .. 39
    //
    //     D  D  D  D  <- digital = 4 .. 7
    //
    //
    // In 4banks Internal mode, the top 4 buttons are used as bank
    // selection keys so we are tracking four banks of 12 notes plus the
    // digital and analog notes.
    //
    //     .  .  .  .  <- 124 .. 127
    //     .  .  .  .  <- 120 .. 123
    //     .  .  .  .  <- 116 .. 119
    //     .  .  .  .  <- 108 .. 115
    //     2  2  3  3  <- analog 2,3 = 104 .. 107
    //     0  0  1  1  <- analog 0,1 = 100 .. 103
    //     .  .  .  .  <- bank 3 = 96 .. 99
    //     .  .  .  .  <- bank 3 = 92 .. 95
    //     .  .  .  .  <- bank 3 = 88 .. 91
    //     .  .  .  .  <- bank 3 = 84 .. 87
    //     @  @  @  @  <- bank 3 = 80 .. 83
    //     @  @  @  @  <- bank 3 = 76 .. 79
    //     @  @  @  @  <- bank 3 = 72 .. 75
    //     #  #  #  #  <- bank 2 = 68 .. 71
    //     #  #  #  #  <- bank 2 = 64 .. 67
    //     #  #  #  #  <- bank 2 = 60 .. 63
    //     @  @  @  @  <- bank 1 = 56 .. 59
    //     @  @  @  @  <- bank 1 = 52 .. 55
    //     @  @  @  @  <- bank 1 = 48 .. 51
    //     #  #  #  #  <- bank 0 = 44 .. 47
    //     #  #  #  #  <- bank 0 = 40 .. 43
    //     #  #  #  #  <- bank 0 = 36 .. 39
    //     .  .  .  .  <- 32 .. 35
    //     .  .  .  .  <- 28 .. 31
    //     .  .  .  .  <- 24 .. 27
    //     .  .  .  .  <- 20 .. 23
    //     .  .  .  .  <- 16 .. 19
    //     .  .  .  .  <- 12 .. 15
    //     .  .  .  .  <- 08 .. 11
    //     D  D  D  D  <- digital = 4 .. 7
    //     B  B  B  B  <- bank select keys 0..3
    //
    //
    // In 4banks External mode, the four digital pins are used as bank
    // select keys giving us four banks of 16 keys:
    //
    //     .  .  .  .  <- 124 .. 127
    //     .  .  .  .  <- 120 .. 123
    //     .  .  .  .  <- 116 .. 119
    //     .  .  .  .  <- 108 .. 115
    //     2  2  3  3  <- analog 2,3 = 104 .. 107
    //     0  0  1  1  <- analog 0,1 = 100 .. 103
    //     @  @  @  @  <- bank 3 = 96 .. 99
    //     @  @  @  @  <- bank 3 = 92 .. 95
    //     @  @  @  @  <- bank 3 = 88 .. 91
    //     @  @  @  @  <- bank 3 = 84 .. 87
    //     #  #  #  #  <- bank 2 = 80 .. 83
    //     #  #  #  #  <- bank 2 = 76 .. 79
    //     #  #  #  #  <- bank 2 = 72 .. 75
    //     #  #  #  #  <- bank 2 = 68 .. 71
    //     @  @  @  @  <- bank 1 = 64 .. 67
    //     @  @  @  @  <- bank 1 = 60 .. 63
    //     @  @  @  @  <- bank 1 = 56 .. 59
    //     @  @  @  @  <- bank 1 = 52 .. 55
    //     #  #  #  #  <- bank 0 = 48 .. 51
    //     #  #  #  #  <- bank 0 = 44 .. 47
    //     #  #  #  #  <- bank 0 = 40 .. 43
    //     #  #  #  #  <- bank 0 = 36 .. 39
    //     .  .  .  .  <- 32 .. 35
    //     .  .  .  .  <- 28 .. 31
    //     .  .  .  .  <- 24 .. 27
    //     .  .  .  .  <- 20 .. 23
    //     .  .  .  .  <- 16 .. 19
    //     .  .  .  .  <- 12 .. 15
    //     .  .  .  .  <- 08 .. 11
    //     D  D  D  D  <- digital = 04 .. 07
    //     B  B  B  B  <- bank select keys 00 .. 03
    //
    //
    // The Bank Select key events are sent whenever a bank select key is
    // pressed, regardless whether the key is on the digital port or on the
    // keypad.


    SysEx_t sysEx;
    uint8_t index = 0;


    // INPUT MIDI from USB -----------------------------------------------------

    // If there is data in the Endpoint for us to read, get a USB-MIDI
    // packet to process. Endpoint_IsReadWriteAllowed() returns true if
    // there is data remaining inside an OUT endpoint or if an IN endpoint
    // has space left to fill. The same function doing two jobs, confusing
    // but there you are.
    MIDI_EventPacket_t input_event;
    while (MIDI_Device_ReceiveEventPacket(g_midi_interface_info,
                                          &input_event)) {
        // Assuming all virtual MIDI cables are intended for us, ensure that
        // this event is being sent on our current MIDI channel.
        //
        // The lower 4-bits (".Command") of the USB_MIDI event packet tells
        // us what kind of data it contains, and whether to expect more data
        // in the same message. Commands are:
        //     0x0 = Reserved for Misc
        //     0x1 = Reserved for Cable events
        //     0x2 = 2-byte System Common
        //     0x3 = 3-byte System Common
        //     0x4 = 3-byte Sysex starts or continues
        //     0x5 = 1-byte System Common or Sysex ends
        //     0x6 = 2-byte Sysex ends
        //     0x7 = 3-byte Sysex ends
        //     0x8 = Note On
        //     0x9 = Note Off
        //     0xA = Poly KeyPress
        //     0xB = Control Change (CC)
        //     0xC = Program Change
        //     0xD = Channel Pressure
        //     0xE = PitchBend Change
        //     0xF = 1-byte message

        // System Real Time events don't have a channel, so we check for
        // them first.
        if (input_event.Command == 0xF) {
            if (input_event.Data1 == 0xF8) {
                // Clock event, increment the counter.
                g_led_groundfx_counter++;
            } else if (input_event.Data1 == 0xFA) {
                // Song Start, reset the counter.
                g_led_groundfx_counter = 0;
            } else if (input_event.Data1 == 0xFC) {
                // Song Stop event, reset the counter.
                g_led_groundfx_counter = 0;
            }
        }
            else if (input_event.Command == 0x4) { // Start or continue 3 bytes
                    SYSEX_READ(1);
                    SYSEX_READ(2);
                    SYSEX_READ(3);
            }
            else if (input_event.Command == 0x5) { // End  1 byte
                    SYSEX_READ(1);
                    SYSEX_END();
            }
            else if (input_event.Command == 0x6) { // End 2 bytes
                    SYSEX_READ(1);
                    SYSEX_READ(2);
                    SYSEX_END();
            }
            else if (input_event.Command == 0x7) { // End 3 bytes
                    SYSEX_READ(1);
                    SYSEX_READ(2);
                    SYSEX_READ(3);
                    SYSEX_END();
            }
            else {

                    // Now we can check that the MIDI channel is the one we're payin
                    // attention to before parsing the event.
                    uint8_t channel = input_event.Data1 & 0x0f;
                    if (channel == g_midi_channel) {
                            // Work out the valid range of MIDI notes we will accept.
                            uint8_t highest_note = MIDI_BASE_NOTE + 16;
                            if (g_key_fourbanks_mode == FOURBANKS_INTERNAL) {
                                    highest_note = MIDI_BASE_NOTE + 48;
                            } else if (g_key_fourbanks_mode == FOURBANKS_EXTERNAL) {
                                    highest_note = MIDI_BASE_NOTE + 64;
                            }
                            // Check to see if we have a NoteOn or NoteOff event.
                            switch (input_event.Command) {
                            case 0x9 : {
                                            // A NoteOn event was found, so update the MIDI
                                            // keystate with the note velocity (which may be
                                            // zero).
                                            uint8_t note = input_event.Data2;
                                            uint8_t velocity = input_event.Data3;
                                            // Check to see if this note is one we need to care
                                            // about.
                                            if (note >= MIDI_BASE_NOTE &&
                                                    note < MIDI_BASE_NOTE + highest_note) {
                                                    // record the note velocity in the MIDI note state
                                                    g_midi_note_state[note] = velocity;
                                            }
                                    }
                                    break;
                            case 0x8 : {
                                            // A NoteOff event, so record a zero in the MIDI
                                            // keystate. Yes, a noteoff can have a "velocity",
                                            // but we're relying on the keystate to be zero when
                                            // we have a noteoff, otherwise the LEDs won't match
                                            // the state when we come to calculate them.
                                            uint8_t note = input_event.Data2;
                                            // Check to see if the note is one we need to care
                                            // about.
                                            if (note >= MIDI_BASE_NOTE &&
                                                    note < MIDI_BASE_NOTE + highest_note) {
                                                    // record a zero note velocity in the MIDI note state
                                                    g_midi_note_state[note] = 0;
                                            }
                                    }
                                    break;
                            }  // end switch on command
                    } // end channel test
            } // end command test
    } // end while


    // OUTPUT events from the EXPANSION ports ----------------------------------

    // Generate MIDI events for key changes on the digital input ports that
    // are currently activated (with the lower four bits of
    // g_exp_digital_read being the mask).
    //

    // NOTE(rgreen): Because Fourbanks External mode may be enabled, do the
    // external key scan once and for all right here. No need to hide it
    // behind g_exp_digital_read any more.
    exp_key_read();  // scan the debounce buffer.
    exp_key_calc();  // update the keyup/keydown variables.

    // Expansion port pins generate the MIDI notes 4 to 7.
    const uint8_t MIDI_DIGITAL_NOTE = 4;  // lowest digital note.
	
    // NOTE: enabling fourbanks external mode turns off digital note generation.
    if (g_key_fourbanks_mode != FOURBANKS_EXTERNAL &&
        g_exp_digital_read != 0) {

        uint8_t allow_read = g_exp_digital_read;
        uint8_t keydown = g_exp_key_down;
        uint8_t keyup = g_exp_key_up;
        for(uint8_t i=0; i<4; ++i) {
            if(allow_read & 1) {
                if (keydown & 1) {
                    // There's a key down, generate a NoteOn
                    midi_stream_note(MIDI_DIGITAL_NOTE + i, true);
                    // Record the note in the MIDI state so we can generate LEDs
                    // from it later.
                    g_midi_note_state[MIDI_DIGITAL_NOTE + i] = g_midi_velocity;
                }
                if (keyup & 1) {
                    // There's a key up, insert a NoteOff
                    midi_stream_note(MIDI_DIGITAL_NOTE + i, false);
                    // Record the note in the MIDI state.
                    g_midi_note_state[MIDI_DIGITAL_NOTE + i] = 0;
                }
            }
            allow_read >>= 1;
            keydown >>= 1;
            keyup >>= 1;
        }
    }
예제 #9
0
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
    MIDI_EventPacket_t midiEvent;
    struct {
	uint8_t command;
	uint8_t channel;
	uint8_t data2;
	uint8_t data3;
    } midiMsg;
    int ind;

    int led1_ticks = 0;
    int led2_ticks = 0;

    SetupHardware();

    RingBuffer_InitBuffer(&USBtoUSART_Buffer);
    RingBuffer_InitBuffer(&USARTtoUSB_Buffer);

    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
    sei();

    for (;;) {
	RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);

	/* See if we have a message yet */
	if (BufferCount >= 4) {
	    /* Read in the message from the serial buffer */
	    for (ind=0; ind<4; ind++) {
		((uint8_t *)&midiMsg)[ind] = RingBuffer_Remove(&USARTtoUSB_Buffer);
	    }

	    /* Build a midi event to send via USB */
	    midiEvent.CableNumber = 0;
	    midiEvent.Command = midiMsg.command >> 4;
	    midiEvent.Data1 = (midiMsg.command & 0xF0) | ((midiMsg.channel-1) & 0x0F);
	    midiEvent.Data2 = midiMsg.data2;
	    midiEvent.Data3 = midiMsg.data3;

	    MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &midiEvent);
	    MIDI_Device_Flush(&Keyboard_MIDI_Interface);

	    /* Turn on the TX led and starts its timer */
	    LEDs_TurnOnLEDs(LEDS_LED1);
	    led1_ticks = LED_ON_TICKS;
	}
	
	/* Turn off the Tx LED when the tick count reaches zero */
	if (led1_ticks) {
	    led1_ticks--;
	    if (led1_ticks == 0) {
		LEDs_TurnOffLEDs(LEDS_LED1);
	    }
	}

	if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &midiEvent)) {
	    RingBuff_Count_t count = RingBuffer_GetCount(&USBtoUSART_Buffer);
	    /* Room to send a message? */
	    if ((BUFFER_SIZE - count) >= sizeof(midiMsg)) {
		midiMsg.command = midiEvent.Command << 4;
		midiMsg.channel = (midiEvent.Data1 & 0x0F) + 1;
		midiMsg.data2 = midiEvent.Data2;
		midiMsg.data3 = midiEvent.Data3;

		for (ind=0; ind<sizeof(midiMsg); ind++) {
		    RingBuffer_Insert(&USBtoUSART_Buffer, ((uint8_t *)&midiMsg)[ind]);
		}

		/* Turn on the RX led and start its timer */
		LEDs_TurnOnLEDs(LEDS_LED2);
		led2_ticks = LED_ON_TICKS;
	    } else {
		/* Turn on the RX led and leave it on to indicate the
		 * buffer is full and the sketch is not reading it 
		 * fast enough.
		 */
		LEDs_TurnOnLEDs(LEDS_LED2);
	    }

	    /* if there's no room in the serial buffer the message gets dropped */
	}

	/* Turn off the RX LED when the tick count reaches zero */
	if (led2_ticks) {
	    led2_ticks--;
	    if (led2_ticks == 0) {
		LEDs_TurnOffLEDs(LEDS_LED2);
	    }
	}

	/* any data to send to main processor? */
	if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
	    Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
	}

	MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
	USB_USBTask();
    }
}