/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and * stops the library USB task management process. */ void EVENT_USB_Host_DeviceUnattached(void) { puts_P(PSTR(ESC_FG_GREEN "\r\nDevice Unattached.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); }
/** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and * stops the library USB task management process. */ void EVENT_USB_Host_DeviceUnattached(void) { puts_P(PSTR("\r\nDevice Unattached.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); }
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and * starts the library USB task to begin the enumeration and USB management process. */ void EVENT_USB_Host_DeviceAttached(void) { puts_P(PSTR(ESC_FG_GREEN "Device Attached.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Still Image Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (SImage_Host_ConfigurePipes(&DigitalCamera_SI_Interface, ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Still Image Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Still Image Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: puts_P(PSTR("Opening Session...\r\n")); if (SImage_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError) { puts_P(PSTR("Could not open PIMA session.\r\n")); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Turning off Device...\r\n")); SImage_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL); if (SImage_Host_ReceiveResponse(&DigitalCamera_SI_Interface)) { puts_P(PSTR("Could not turn off device.\r\n")); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Device Off.\r\n")); puts_P(PSTR("Closing Session...\r\n")); if (SImage_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError) { puts_P(PSTR("Could not close PIMA session.\r\n")); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } SImage_Host_USBTask(&DigitalCamera_SI_Interface); USB_USBTask(); } }
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and * starts the library USB task to begin the enumeration and USB management process. */ void EVENT_USB_Host_DeviceAttached(void) { puts_P(PSTR("Device Attached.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "CDC Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface, ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid CDC Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("CDC Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface)) { /* Echo received bytes from the attached device through the USART */ int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface); if (!(ReceivedByte < 0)) putchar(ReceivedByte); } break; } CDC_Host_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Mouse Host Demo running.\r\n" ESC_FG_WHITE)); sei(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Mouse_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Mouse Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Mouse_HID_Interface)) { uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport); uint8_t LEDMask = LEDS_NO_LEDS; for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { if (ReportItem->Value) LEDMask = LEDS_ALL_LEDS; } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && (ReportItem->Attributes.Usage.Usage == USAGE_SCROLL_WHEEL) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t); if (WheelDelta) LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4)); } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && ((ReportItem->Attributes.Usage.Usage == USAGE_X) || (ReportItem->Attributes.Usage.Usage == USAGE_Y)) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t); if (DeltaMovement) { if (ReportItem->Attributes.Usage.Usage == USAGE_X) LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2); else LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4); } } } LEDs_SetAllLEDs(LEDMask); } break; } HID_Host_USBTask(&Mouse_HID_Interface); USB_USBTask(); } }
/** Task to print device information through the serial port, and open/close a test PIMA session with the * attached Still Image device. */ void StillImageHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; uint8_t ErrorCode; /* Indicate device busy via the status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); puts_P(PSTR("Retrieving Device Info...\r\n")); PIMA_SendBlock = (PIMA_Container_t) { .DataLength = PIMA_COMMAND_SIZE(0), .Type = PIMA_CONTAINER_CommandBlock, .Code = PIMA_OPERATION_GETDEVICEINFO, .TransactionID = 0x00000000, .Params = {}, }; /* Send the GETDEVICEINFO block */ SImage_SendBlockHeader(); /* Receive the response data block */ if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError) { ShowCommandError(ErrorCode, false); USB_Host_SetDeviceConfiguration(0); return; } /* Calculate the size of the returned device info data structure */ uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0)); /* Create a buffer large enough to hold the entire device info */ uint8_t DeviceInfo[DeviceInfoSize]; /* Read in the data block data (containing device info) */ SImage_ReadData(DeviceInfo, DeviceInfoSize); /* Once all the data has been read, the pipe must be cleared before the response can be sent */ Pipe_ClearIN(); /* Create a pointer for walking through the info dataset */ uint8_t* DeviceInfoPos = DeviceInfo; /* Skip over the data before the unicode device information strings */ DeviceInfoPos += 8; // Skip to VendorExtensionDesc String DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String DeviceInfoPos += 2; // Skip over FunctionalMode DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Operations Array DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Events Array DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Device Properties Array DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Capture Formats Array DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Image Formats Array /* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */ char Manufacturer[*DeviceInfoPos]; UnicodeToASCII(DeviceInfoPos, Manufacturer); printf_P(PSTR(" Manufacturer: %s\r\n"), Manufacturer); DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Manufacturer String /* Extract and convert the Model Unicode string to ASCII and print it through the USART */ char Model[*DeviceInfoPos]; UnicodeToASCII(DeviceInfoPos, Model); printf_P(PSTR(" Model: %s\r\n"), Model); DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Model String /* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */ char DeviceVersion[*DeviceInfoPos]; UnicodeToASCII(DeviceInfoPos, DeviceVersion); printf_P(PSTR(" Device Version: %s\r\n"), DeviceVersion); /* Receive the final response block from the device */ if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError) { ShowCommandError(ErrorCode, false); USB_Host_SetDeviceConfiguration(0); return; } /* Verify that the command completed successfully */ if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK)) { ShowCommandError(PIMA_ReceivedBlock.Code, true); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Opening Session...\r\n")); PIMA_SendBlock = (PIMA_Container_t) { .DataLength = PIMA_COMMAND_SIZE(1), .Type = PIMA_CONTAINER_CommandBlock, .Code = PIMA_OPERATION_OPENSESSION, .TransactionID = 0x00000000, .Params = {0x00000001}, }; /* Send the OPENSESSION block, open a session with an ID of 0x0001 */ SImage_SendBlockHeader(); /* Receive the response block from the device */ if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError) { ShowCommandError(ErrorCode, false); USB_Host_SetDeviceConfiguration(0); return; } /* Verify that the command completed successfully */ if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK)) { ShowCommandError(PIMA_ReceivedBlock.Code, true); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Closing Session...\r\n")); PIMA_SendBlock = (PIMA_Container_t) { .DataLength = PIMA_COMMAND_SIZE(1), .Type = PIMA_CONTAINER_CommandBlock, .Code = PIMA_OPERATION_CLOSESESSION, .TransactionID = 0x00000001, .Params = {0x00000001}, }; /* Send the CLOSESESSION block, close the session with an ID of 0x0001 */ SImage_SendBlockHeader(); /* Receive the response block from the device */ if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError) { ShowCommandError(ErrorCode, false); USB_Host_SetDeviceConfiguration(0); return; } /* Verify that the command completed successfully */ if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK)) { ShowCommandError(PIMA_ReceivedBlock.Code, true); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Done.\r\n")); /* Indicate device no longer busy */ LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_Host_SetDeviceConfiguration(0); } /** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode * strings which contain ASCII printable characters only. * * \param[in] UnicodeString Pointer to a Unicode encoded input string * \param[out] Buffer Pointer to a buffer where the converted ASCII string should be stored */ void UnicodeToASCII(uint8_t* UnicodeString, char* Buffer) { /* Get the number of characters in the string, skip to the start of the string data */ uint8_t CharactersRemaining = *(UnicodeString++); /* Loop through the entire unicode string */ while (CharactersRemaining--) { /* Load in the next unicode character (only the lower byte, as only Unicode coded ASCII is supported) */ *(Buffer++) = *UnicodeString; /* Jump to the next unicode character */ UnicodeString += 2; } /* Null terminate the string */ *Buffer = 0; } /** Displays a PIMA command error via the device's serial port. * * \param[in] ErrorCode Error code of the function which failed to complete successfully * \param[in] ResponseCodeError Indicates if the error is due to a command failed indication from the device, or a communication failure */ void ShowCommandError(uint8_t ErrorCode, bool ResponseCodeError) { const char* FailureType = ((ResponseCodeError) ? PSTR("Response Code != OK") : PSTR("Transaction Fail")); printf_P(PSTR(ESC_FG_RED "Command Error (%S).\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), FailureType, ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_ERROR); }
void main(void) { clock_prescale_set(clock_div_1); // Timer 0 settings for approx. millisecond tracking TCCR0A = _BV(WGM01); TCCR0B = CLOCKSEL; TIMSK0 = _BV(OCIE0A); OCR0A = TICKS; // UART //PORTD |= _BV(PORTD0); //DDRD |= _BV(DDD1); UBRR0 = UBRR_VALUE; #if USE_2X UCSR0A = _BV(U2X0); #endif UCSR0B = _BV(TXEN0); // LED indicator DDRC |= _BV(DDC5); PORTC |= _BV(PORTC5); stdout = &uart_io; // Start up nRF905_init(); // Set address of this device nRF905_setListenAddress(RXADDR); // Interrupts on sei(); uint8_t counter = 0; uint32_t sent = 0; uint32_t replies = 0; uint32_t timeouts = 0; uint32_t invalids = 0; while(1) { // Make data char data[NRF905_MAX_PAYLOAD] = {0}; sprintf_P(data, PSTR("test %hhu"), counter); counter++; packetStatus = PACKET_NONE; printf_P(PSTR("Sending data: %s\n"), data); uint32_t startTime = millis(); // Send the data (send fails if other transmissions are going on, keep trying until success) and enter RX mode on completion while(!nRF905_TX(TXADDR, data, sizeof(data), NRF905_NEXTMODE_RX)); sent++; puts_P(PSTR("Data sent, waiting for reply...")); uint8_t success; // Wait for reply with timeout uint32_t sendStartTime = millis(); while(1) { success = packetStatus; if(success != PACKET_NONE) break; else if(millis() - sendStartTime > TIMEOUT) break; } if(success == PACKET_NONE) { puts_P(PSTR("Ping timed out")); timeouts++; } else if(success == PACKET_INVALID) { // Got a corrupted packet puts_P(PSTR("Invalid packet!")); invalids++; } else { // If success toggle LED and send ping time over UART uint16_t totalTime = millis() - startTime; PORTC ^= _BV(PORTC5); replies++; printf_P(PSTR("Ping time: %ums\n"), totalTime); // Get the ping data uint8_t replyData[NRF905_MAX_PAYLOAD]; nRF905_read(replyData, sizeof(replyData)); // Print out ping contents printf_P(PSTR("Data from server: ")); for(uint8_t i=0;i<sizeof(replyData);i++) printf_P(PSTR("%c"), replyData[i]); puts_P(PSTR("")); } printf_P(PSTR("Totals: %lu Sent, %lu Replies, %lu Timeouts, %lu Invalid\n------\n"), sent, replies, timeouts, invalids); _delay_ms(1000); } }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface * request to switch to the interface alternate setting with the Bidirectional protocol */ if (PrinterAltSetting) { if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } } puts_P(PSTR("Retrieving Device ID...\r\n")); char DeviceIDString[300]; if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString); puts_P(PSTR("Printer Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }