char ButtonState(void) { char ButtonFace; ButtonFace = 0x00; if (BUTTON_IsPressed(BUTTON_S3)) ButtonFace = 0x01; if (BUTTON_IsPressed(BUTTON_S6)) ButtonFace = 0x02; if (BUTTON_IsPressed(BUTTON_S5)) ButtonFace = 0x04; if (BUTTON_IsPressed(BUTTON_S4)) ButtonFace = 0x08; return ButtonFace; }
/********************************************************************* * Function: void APP_DeviceCustomHIDTasks(void); * * Overview: Keeps the Custom HID demo running. * * PreCondition: The demo should have been initialized and started via * the APP_DeviceCustomHIDInitialize() and APP_DeviceCustomHIDStart() demos * respectively. * * Input: None * * Output: None * ********************************************************************/ void APP_DeviceCustomHIDTasks() { //Check if we have received an OUT data packet from the host if(HIDRxHandleBusy(USBOutHandle) == false) { //We just received a packet of data from the USB host. //Check the first uint8_t of the packet to see what command the host //application software wants us to fulfill. switch(ReceivedDataBuffer[0]) //Look at the data the host sent, to see what kind of application specific command it sent. { case COMMAND_TOGGLE_LED: //Toggle LEDs command LED_Toggle(LED_USB_DEVICE_HID_CUSTOM); break; case COMMAND_GET_BUTTON_STATUS: //Get push button state //Check to make sure the endpoint/buffer is free before we modify the contents if(!HIDTxHandleBusy(USBInHandle)) { ToSendDataBuffer[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first uint8_t. In this case, the Get Pushbutton State command. if(BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_CUSTOM) == false) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high { ToSendDataBuffer[1] = 0x01; } else //sw3 must be == 0, pushbutton is pressed and overpowering the pull up resistor { ToSendDataBuffer[1] = 0x00; } //Prepare the USB module to send the data packet to the host USBInHandle = HIDTxPacket(CUSTOM_DEVICE_HID_EP, (uint8_t*)&ToSendDataBuffer[0],64); } break; case COMMAND_READ_POTENTIOMETER: //Read POT command. Uses ADC to measure an analog voltage on one of the ANxx I/O pins, and returns the result to the host { uint16_t pot; //Check to make sure the endpoint/buffer is free before we modify the contents if(!HIDTxHandleBusy(USBInHandle)) { //Use ADC to read the I/O pin voltage. See the relevant HardwareProfile - xxxxx.h file for the I/O pin that it will measure. //Some demo boards, like the PIC18F87J50 FS USB Plug-In Module board, do not have a potentiometer (when used stand alone). //This function call will still measure the analog voltage on the I/O pin however. To make the demo more interesting, it //is suggested that an external adjustable analog voltage should be applied to this pin. pot = ADC_Read10bit(ADC_CHANNEL_POTENTIOMETER); ToSendDataBuffer[0] = 0x37; //Echo back to the host the command we are fulfilling in the first uint8_t. In this case, the Read POT (analog voltage) command. ToSendDataBuffer[1] = (uint8_t)pot; //LSB ToSendDataBuffer[2] = pot >> 8; //MSB //Prepare the USB module to send the data packet to the host USBInHandle = HIDTxPacket(CUSTOM_DEVICE_HID_EP, (uint8_t*)&ToSendDataBuffer[0],64); } } break; } //Re-arm the OUT endpoint, so we can receive the next OUT data packet //that the host may try to send us. USBOutHandle = HIDRxPacket(CUSTOM_DEVICE_HID_EP, (uint8_t*)&ReceivedDataBuffer, 64); }
/********************************************************************* * Function: void SYSTEM_Initialize( SYSTEM_STATE state ) * * Overview: Initializes the system. * * PreCondition: None * * Input: SYSTEM_STATE - the state to initialize the system into * * Output: None * ********************************************************************/ void SYSTEM_Initialize( SYSTEM_STATE state ) { switch(state) { case SYSTEM_STATE_USB_START: //Switch to alternate interrupt vector table for bootloader INTCON2bits.ALTIVT = 1; BUTTON_Enable(BUTTON_USB_DEVICE_HID_CUSTOM); if((BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_CUSTOM)==false) && ((RCON & 0x83) != 0)) { //Switch to app standare IVT for non boot mode INTCON2bits.ALTIVT = 0; __asm__("goto 0x1800"); } LED_Enable(LED_USB_DEVICE_STATE); LED_Enable(LED_USB_DEVICE_HID_CUSTOM); break; case SYSTEM_STATE_USB_SUSPEND: break; case SYSTEM_STATE_USB_RESUME: break; } }
/******************************************************************** * Function: void main(void) *******************************************************************/ MAIN_RETURN main(void) { SYSTEM_Initialize(); USBDeviceInit(); USBDeviceAttach(); while(1) { SYSTEM_Tasks(); #if defined(USB_POLLING) USBDeviceTasks(); #endif /* If the USB device isn't configured yet, we can't really do anything * else since we don't have a host to talk to. So jump back to the * top of the while loop. */ if( USBGetDeviceState() < CONFIGURED_STATE ) { /* Jump back to the top of the while loop. */ continue; } /* If we are currently suspended, then we need to see if we need to * issue a remote wakeup. In either case, we shouldn't process any * keyboard commands since we aren't currently communicating to the host * thus just continue back to the start of the while loop. */ if( USBIsDeviceSuspended() == true ) { /* Jump back to the top of the while loop. */ continue; } // implement nMCLR button if ( BUTTON_IsPressed(BUTTON_S1)) { LUNSoftDetach(0); // mark the media as temporarily unavailable ICSP_nMCLR = SLAVE_RESET; LED_Off(GREEN_LED); // turn off RED LED to indicate ready for download LED_On (RED_LED); DIRECT_Initialize(); // reset the programming state machine } else { // simply act as a slave reset LUNSoftAttach(0); // mark the media as available if ( !DIRECT_ProgrammingInProgress()) { // do not release during prog.! ICSP_nMCLR = SLAVE_RUN; LED_On(GREEN_LED); // turn off RED LED to indicate ready for download LED_Off(RED_LED); } } //Application specific tasks APP_DeviceMSDTasks(); APP_DeviceCDCEmulatorTasks(); }//end while }//end main
/********************************************************************* * * _cbButton * * Purpose: * 1. Calls the owner draw function if the WM_PAINT message has been send * 2. Calls the original callback for further messages * 3. After processing the messages the function evaluates the pressed-state * if the WM_TOUCH message has been send */ static void _cbButton(WM_MESSAGE *pMsg) { switch (pMsg->MsgId) { case WM_PAINT: _OnPaint(pMsg->hWin); break; default: _pcbCallback(pMsg); /* The original callback */ break; } if (pMsg->MsgId == WM_TOUCH) { if (BUTTON_IsPressed(pMsg->hWin)) { if (!_Pressed) { _Pressed = 1; } } else { _Pressed = 0; } } }
/********************************************************************* * Function: void SYSTEM_Initialize( SYSTEM_STATE state ) * * Overview: Initializes the system. * * PreCondition: None * * Input: SYSTEM_STATE - the state to initialize the system into * * Output: None * ********************************************************************/ void SYSTEM_Initialize( SYSTEM_STATE state ) { switch(state) { case SYSTEM_STATE_USB_START: //Switch to alternate interrupt vector table for bootloader INTCON2bits.ALTIVT = 1; BUTTON_Enable(BUTTON_USB_DEVICE_HID_CUSTOM); if((BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_CUSTOM)==false) && ((RCON & 0x83) != 0)) { //Switch to app standare IVT for non boot mode INTCON2bits.ALTIVT = 0; __asm__("goto 0x1800"); } //On the PIC24FJ64GB004 Family of USB microcontrollers, the PLL will not power up and be enabled //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL). //This allows the device to power up at a lower initial operating frequency, which can be //advantageous when powered from a source which is not gauranteed to be adequate for 32MHz //operation. On these devices, user firmware needs to manually set the CLKDIV<PLLEN> bit to //power up the PLL. { unsigned int pll_startup_counter = 600; CLKDIVbits.PLLEN = 1; while(pll_startup_counter--); } LED_Enable(LED_USB_DEVICE_STATE); LED_Enable(LED_USB_DEVICE_HID_CUSTOM); break; case SYSTEM_STATE_USB_SUSPEND: break; case SYSTEM_STATE_USB_RESUME: break; } }
int main(void) { SYSTEM_Initialize(SYSTEM_STATE_USB_START); LED_Initialize(); APP_KeyboardConfigure(); #ifdef WITH_HOS HosCheckDFU(BOOT_FLAGS_VALUE & BOOT_WITH_APP); if (!isUSBMode() || !isBusPowered()) { HosMainLoop(); } for (uint16_t i = 0; i < HOS_STARTUP_DELAY; ++i) { if (HosSleep(HOS_TYPE_DEFAULT)) { break; } __delay_ms(4); } #endif USBDeviceInit(); USBDeviceAttach(); for (;;) { #ifdef WITH_HOS if (!isBusPowered() || !isUSBMode()) { Reset(); Nop(); Nop(); // NOT REACHED HERE } #endif SYSTEM_Tasks(); #if defined(USB_POLLING) /* Check bus status and service USB interrupts. Interrupt or polling * method. If using polling, must call this function periodically. * This function will take care of processing and responding to SETUP * transactions (such as during the enumeration process when you first * plug in). USB hosts require that USB devices should accept and * process SETUP packets in a timely fashion. Therefore, when using * polling, this function should be called regularly (such as once every * 1.8ms or faster** [see inline code comments in usb_device.c for * explanation when "or faster" applies]) In most cases, the * USBDeviceTasks() function does not take very long to execute * (ex: <100 instruction cycles) before it returns. */ USBDeviceTasks(); #endif APP_LEDUpdateUSBStatus(); /* If the USB device isn't configured yet, we can't really do anything * else since we don't have a host to talk to. So jump back to the * top of the while loop. */ if (USBGetDeviceState() < CONFIGURED_STATE) { /* Jump back to the top of the while loop. */ continue; } /* If we are currently suspended, then we need to see if we need to * issue a remote wakeup. In either case, we shouldn't process any * keyboard commands since we aren't currently communicating to the host * thus just continue back to the start of the while loop. */ if (USBIsDeviceSuspended()) { //Check if we should assert a remote wakeup request to the USB host, //when the user presses the pushbutton. if (BUTTON_IsPressed()) { USBCBSendResume(); //Does nothing unless we are in USB suspend with remote wakeup armed. } /* Jump back to the top of the while loop. */ continue; } if (USBIsBusSuspended()) { /* Jump back to the top of the while loop. */ continue; } /* Run the keyboard tasks. */ APP_KeyboardTasks(); }//end while }//end main
/********************************************************************* * Function: void APP_HostMSDDataLoggerTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized via * the APP_HostMSDDataLoggerInitialize() * * Input: None * * Output: None * ********************************************************************/ void APP_HostMSDDataLoggerTasks() { if(FILEIO_MediaDetect(&gUSBDrive, &deviceAddress) == false) { //The device has been removed. Now we should wait for a new // device to be attached. demoState = WAITING_FOR_ATTACH; } switch( demoState) { case WAITING_FOR_ATTACH: break; case MOUNTING_DRIVE: { // Attempt to mount the drive described by gUSBDrive as drive 'A' // The deviceAddress parameter describes the USB address of the device; it is initialized by the application in the // USB_ApplicationEventHandler function when a new device is detected. if( FILEIO_DriveMount ('A', &gUSBDrive, &deviceAddress) == FILEIO_ERROR_NONE) { demoState = OPENING_FILE; } break; } case OPENING_FILE: // Opening a file with the FILEIO_OPEN_WRITE option allows us to write to the file. // Opening a file with the FILEIO_OPEN_CREATE file will create the file if it does not already exist. // Opening a file with the FILEIO_OPEN_TRUNCATE file will truncate it to a 0-length file if it already exists. if(FILEIO_Open(&myFile, "LOG.CSV", FILEIO_OPEN_WRITE | FILEIO_OPEN_CREATE | FILEIO_OPEN_TRUNCATE) == FILEIO_RESULT_SUCCESS) { //Opening the file failed. Since we can't write to the // device, abort the write attempt and wait for the device // to be removed. demoState = WRITING_TO_FILE; blinkCount = 0; sampleRequested = false; TIMER_RequestTick(&APP_HostMSDDataLoggerTickHandler, 50); LED_On(LED_USB_HOST_MSD_DATA_LOGGER); ADC_ChannelEnable(ADC_USB_HOST_MSD_DATA_SOURCE); break; } break; case WRITING_TO_FILE: if(sampleRequested == true) { uint16_t adcResult; int charCount; sampleRequested = false; adcResult = ADC_Read10bit(ADC_USB_HOST_MSD_DATA_SOURCE); charCount = sprintf(printBuffer, "%d\r\n", adcResult); //Write some data to the new file. FILEIO_Write(printBuffer, 1, charCount, &myFile); } if(BUTTON_IsPressed(BUTTON_USB_HOST_MSD_DATA_LOGGER) == true) { demoState = CLOSING_FILE; } break; case CLOSING_FILE: //Always make sure to close the file so that the data gets // written to the drive. FILEIO_Close(&myFile); TIMER_CancelTick(&APP_HostMSDDataLoggerTickHandler); demoState = UNMOUNT_DRIVE; break; case UNMOUNT_DRIVE: // Unmount the drive since it is no longer in use. FILEIO_DriveUnmount ('A'); //Now that we are done writing, we can do nothing until the // drive is removed. demoState = WAITING_FOR_DETACH; break; case WAITING_FOR_DETACH: LED_Off(LED_USB_HOST_MSD_DATA_LOGGER); break; default: break; } }
/********************************************************************* * Function: void APP_DeviceCDCBasicDemoTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized and started via * the APP_DeviceCDCBasicDemoInitialize() and APP_DeviceCDCBasicDemoStart() demos * respectively. * * Input: None * * Output: None * ********************************************************************/ void APP_DeviceCDCBasicDemoTasks() { /* If the user has pressed the button associated with this demo, then we * are going to send a "Button Pressed" message to the terminal. */ if(BUTTON_IsPressed(BUTTON_DEVICE_CDC_BASIC_DEMO) == true) { /* Make sure that we only send the message once per button press and * not continuously as the button is held. */ if(buttonPressed == false) { /* Make sure that the CDC driver is ready for a transmission. */ if(mUSBUSARTIsTxTrfReady() == true) { putrsUSBUSART(buttonMessage); buttonPressed = true; } } } else { /* If the button is released, we can then allow a new message to be * sent the next time the button is pressed. */ buttonPressed = false; } /* Check to see if there is a transmission in progress, if there isn't, then * we can see about performing an echo response to data received. */ if( USBUSARTIsTxTrfReady() == true) { uint8_t numBytesRead; numBytesRead = getsUSBUSART(readBuffer, sizeof(readBuffer)); if (numBytesRead > 0) { switch(readBuffer[0]) { case 0x10: { unsigned char size = readBuffer[1]; debug_flag2 = !debug_flag2; PORTCbits.RC1 = debug_flag2; writeBuffer[0] = 0x90; writeBuffer[1] = 4; writeBuffer[2] = numBytesRead; writeBuffer[3] = readBuffer[1]; writeBuffer[4] = readBuffer[2]; writeBuffer[5] = readBuffer[3]; writeBuffer[1] = 4+size; for (unsigned char i = 0; i<size; i++) { writeBuffer[i+6] = readBuffer[4 + i]; } if (WaitToReadySerial()) putUSBUSART(writeBuffer, writeBuffer[1]+2); WaitToReadySerial(); } { unsigned char size = readBuffer[1]; i2c_start(0x50, 0); // address in big-endian format i2c_send(readBuffer[3]); // address MSB i2c_send(readBuffer[2]); // address LSB for (unsigned char i = 0; i<size; i++) { i2c_send(readBuffer[4 + i]); } i2c_stop(); __delay_ms(10); } break; case 0x11: { unsigned char size = readBuffer[1]; unsigned char data; unsigned char i; i2c_start(0x50, 0); // address in big-endian format i2c_send(readBuffer[3]); // address MSB i2c_send(readBuffer[2]); // address LSB i2c_start(0x50, 1); for (i=0; i<size-1; i++) { writeBuffer[i+2] = i2c_receive(ACK); } writeBuffer[i+2] = i2c_receive(NOACK); i2c_stop(); __delay_ms(10); writeBuffer[0] = 0x12; writeBuffer[1] = size; putUSBUSART(writeBuffer, writeBuffer[1]+2); } break; } } //if (debug_flag) { // debug_flag = 0; // writeBuffer[0] = 9; // writeBuffer[1] = 1; // writeBuffer[2] = debug_data; // putUSBUSART(writeBuffer, writeBuffer[1]+2); //} } CDCTxService(); }
/********************************************************************* * Function: void SYSTEM_Initialize( SYSTEM_STATE state ) * * Overview: Initializes the system. * * PreCondition: None * * Input: SYSTEM_STATE - the state to initialize the system into * * Output: None * ********************************************************************/ void SYSTEM_Initialize( SYSTEM_STATE state ) { switch(state) { case SYSTEM_STATE_USB_START: //Switch to alternate interrupt vector table for bootloader INTCON2bits.ALTIVT = 1; BUTTON_Enable(BUTTON_USB_DEVICE_HID_CUSTOM); if((BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_CUSTOM)==false) && ((RCON & 0x83) != 0)) { //Switch to app standare IVT for non boot mode INTCON2bits.ALTIVT = 0; __asm__("goto 0x1800"); } ANSELA = 0x0000; ANSELB = 0x0000; ANSELC = 0x0000; ANSELD = 0x0000; ANSELE = 0x0000; ANSELG = 0x0000; // Configure the device PLL to obtain 60 MIPS operation. The crystal // frequency is 8MHz. Divide 8MHz by 2, multiply by 60 and divide by // 2. This results in Fosc of 120MHz. The CPU clock frequency is // Fcy = Fosc/2 = 60MHz. Wait for the Primary PLL to lock and then // configure the auxilliary PLL to provide 48MHz needed for USB // Operation. PLLFBD = 58; /* M = 60 */ CLKDIVbits.PLLPOST = 0; /* N1 = 2 */ CLKDIVbits.PLLPRE = 0; /* N2 = 2 */ OSCTUN = 0; /* Initiate Clock Switch to Primary * Oscillator with PLL (NOSC= 0x3)*/ __builtin_write_OSCCONH(0x03); __builtin_write_OSCCONL(0x01); while (OSCCONbits.COSC != 0x3); // Configuring the auxiliary PLL, since the primary // oscillator provides the source clock to the auxiliary // PLL, the auxiliary oscillator is disabled. Note that // the AUX PLL is enabled. The input 8MHz clock is divided // by 2, multiplied by 24 and then divided by 2. Wait till // the AUX PLL locks. ACLKCON3 = 0x24C1; ACLKDIV3 = 0x7; ACLKCON3bits.ENAPLL = 1; while(ACLKCON3bits.APLLCK != 1); LED_Enable(LED_USB_DEVICE_STATE); LED_Enable(LED_USB_DEVICE_HID_CUSTOM); break; case SYSTEM_STATE_USB_SUSPEND: break; case SYSTEM_STATE_USB_RESUME: break; } }
/********************************************************************* * Function: void APP_DeviceCDCBasicDemoTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized and started via * the APP_DeviceCDCBasicDemoInitialize() and APP_DeviceCDCBasicDemoStart() demos * respectively. * * Input: None * * Output: None * ********************************************************************/ void APP_DeviceCDCBasicDemoTasks() { uint8_t numBytesWrite = 0; uint8_t packet[MAX_PACKET_SIZE]; uint8_t packetSize; packet_data_u data; /* Make sure that the CDC driver is ready for a transmission. */ if (mUSBUSARTIsTxTrfReady() == true) { uint16_t value; uint32_t percent; button_state_s cur_state[3]; memset(cur_state, 0x00, 3 * sizeof(button_state_s)); bool button1IsPressed = BUTTON_IsPressed(BUTTON_S1); bool button2IsPressed = BUTTON_IsPressed(BUTTON_S2); bool button3IsPressed = BUTTON_IsPressed(BUTTON_S3); value = ADC_Read10bit(ADC_CHANNEL_1); percent = ((uint32_t)100 * value) / 0x03FF; cur_state[0].pos = 0; cur_state[0].state = button1IsPressed ? BUTTON_PRESSED : BUTTON_RELEASED; cur_state[0].state |= ((percent >= 95) ? BUTTON_UNMOUNTED : BUTTON_MOUNTED); cur_state[0].uid = percent; value = ADC_Read10bit(ADC_CHANNEL_2); percent = ((uint32_t)100 * value) / 0x03FF; cur_state[1].pos = 1; cur_state[1].state = button2IsPressed ? BUTTON_PRESSED : BUTTON_RELEASED; cur_state[1].state |= ((percent >= 95) ? BUTTON_UNMOUNTED : BUTTON_MOUNTED); cur_state[1].uid = percent; value = ADC_Read10bit(ADC_CHANNEL_3); percent = ((uint32_t)100 * value) / 0x03FF; cur_state[2].pos = 2; cur_state[2].state = button3IsPressed ? BUTTON_PRESSED : BUTTON_RELEASED; cur_state[2].state |= ((percent >= 95) ? BUTTON_UNMOUNTED : BUTTON_MOUNTED); cur_state[2].uid = percent; if ((buttons_state[0].state != cur_state[0].state) || (buttons_state[1].state != cur_state[1].state) || (buttons_state[2].state != cur_state[2].state)) { memset(&data, 0x00, sizeof(packet_data_u)); memcpy(data.buttons_state, cur_state, 3 * sizeof(button_state_s)); assemblyPacket(GET_BUTTONS_STATE, &data, packet, &packetSize); memcpy(writeBuffer, packet, packetSize); numBytesWrite = packetSize; if (numBytesWrite > 0) { putUSBUSART(writeBuffer, numBytesWrite); } memcpy(buttons_state, cur_state, 3 * sizeof(button_state_s)); } } /* Check to see if there is a transmission in progress, if there isn't, then * we can see about performing an echo response to data received. */ if( USBUSARTIsTxTrfReady() == true) { uint16_t i; uint16_t validDataLen; uint16_t numBytesRead; char deviceID[] = "Keys 011"; char *e; packet_type_e type; uint8_t payload[MAX_DATA_SIZE]; uint8_t payloadSize; // Collect incoming data in read buffer. Bear in mind, buffer have to had ability receive whole CDC packet. if ((readPos + CDC_DATA_OUT_EP_SIZE) >= sizeof(readBuffer)) { e = memchr(readBuffer, PREAMBLE, sizeof(readBuffer)); // Wipe out trash before valid data if (e == 0) { memset(readBuffer, 0x00, sizeof(readBuffer)); readPos = 0; } else { validDataLen = (uint16_t)(&readBuffer[sizeof(readBuffer)] - e); memmove(readBuffer, e, validDataLen); memset(&readBuffer[validDataLen], 0x00, sizeof(readBuffer) - validDataLen); readPos = 0; } } numBytesRead = getsUSBUSART(&readBuffer[readPos], CDC_DATA_OUT_EP_SIZE); if (numBytesRead > 0) { // Parse all collected incoming data do { e = memchr(readBuffer, PREAMBLE, sizeof(readBuffer)); if (e == 0) { break; } i = (uint16_t)(e - readBuffer); parsePacket(&readBuffer[i], sizeof(readBuffer) - i, &type, payload, &payloadSize); numBytesWrite = 0; if (type == GET_DEVICE_ID) { memset(&data, 0x00, sizeof(packet_data_u)); memcpy(data.device_id, deviceID, 8); assemblyPacket(GET_DEVICE_ID, &data, packet, &packetSize); memcpy(writeBuffer, packet, packetSize); numBytesWrite = packetSize; } else if (type == GET_STATUS) { memset(&data, 0x00, sizeof(packet_data_u)); data.device_status.errors = ERROR_NONE; data.device_status.rtc = 0; assemblyPacket(GET_STATUS, &data, packet, &packetSize); memcpy(writeBuffer, packet, packetSize); numBytesWrite = packetSize; } else if (type == SET_LEDS_STATE) { led_state_s *led = (led_state_s *)payload; if (led->state == LED_TURN_ON) { if (led->pos == 0) LED_On(LED_D2); if (led->pos == 1) LED_On(LED_D3); if (led->pos == 2) LED_On(LED_D4); } else { if (led->pos == 0) LED_Off(LED_D2); if (led->pos == 1) LED_Off(LED_D3); if (led->pos == 2) LED_Off(LED_D4); } } else if (type == RESET_DEVICE) { LED_Off(LED_D2); LED_Off(LED_D3); LED_Off(LED_D4); memset(readBuffer, 0x00, sizeof(readBuffer)); readPos = 0; } else { memcpy(writeBuffer, &readBuffer[i], 20); numBytesWrite = 20; } // Clear packet's start marker - PREAMBLE memset(&readBuffer[i], 0x00, 1); // Send answer if (numBytesWrite > 0) { putUSBUSART(writeBuffer, numBytesWrite); } } while (1); } } CDCTxService(); }
/********************************************************************* * Function: void APP_DeviceAudioMIDITasks(void); * * Overview: Keeps the Custom HID demo running. * * PreCondition: The demo should have been initialized and started via * the APP_DeviceAudioMIDIInitialize() and APP_DeviceAudioMIDIStart() demos * respectively. * * Input: None * * Output: None * ********************************************************************/ void APP_DeviceAudioMIDITasks() { /* If the device is not configured yet, or the device is suspended, then * we don't need to run the demo since we can't send any data. */ if( (USBGetDeviceState() < CONFIGURED_STATE) || (USBIsDeviceSuspended() == true)) { return; } if(!USBHandleBusy(USBRxHandle)) { //We have received a MIDI packet from the host, process it and then // prepare to receive the next packet //INSERT MIDI PROCESSING CODE HERE //Get ready for next packet (this will overwrite the old data) USBRxHandle = USBRxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&ReceivedDataBuffer,64); } /* If the user button is pressed... */ if(BUTTON_IsPressed(BUTTON_DEVICE_AUDIO_MIDI) == true) { /* and we haven't sent a transmission in the past 100ms... */ if(msCounter == 0) { /* and we have sent the NOTE_OFF for the last note... */ if(sentNoteOff == true) { /* and we aren't currently trying to transmit data... */ if(!USBHandleBusy(USBTxHandle)) { //Then reset the 100ms counter msCounter = 100; midiData.Val = 0; //must set all unused values to 0 so go ahead // and set them all to 0 midiData.CableNumber = 0; midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON; midiData.DATA_0 = 0x90; //Note on midiData.DATA_1 = pitch; //pitch midiData.DATA_2 = 0x7F; //velocity USBTxHandle = USBTxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&midiData,4); /* we now need to send the NOTE_OFF for this note. */ sentNoteOff = false; } } } } else { if(msCounter == 0) { if(sentNoteOff == false) { if(!USBHandleBusy(USBTxHandle)) { //Debounce counter for 100ms msCounter = 100; midiData.Val = 0; //must set all unused values to 0 so go ahead // and set them all to 0 midiData.CableNumber = 0; midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON; midiData.DATA_0 = 0x90; //Note off midiData.DATA_1 = pitch++; //pitch midiData.DATA_2 = 0x00; //velocity if(pitch == 0x49) { pitch = 0x3C; } USBTxHandle = USBTxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&midiData,4); sentNoteOff = true; } } } } }