Update Studio Integration DLL, to include package logging.
[pub/USBasp.git] / Demos / Host / LowLevel / VirtualSerialHost / VirtualSerialHost.c
index 6d9d79c..faff196 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2010.
+     Copyright (C) Dean Camera, 2015.
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
 
   dean [at] fourwalledcubicle [dot] com
            www.lufa-lib.org
 */
 
 /*
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2015  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
 
   Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
@@ -18,7 +18,7 @@
   advertising or publicity pertaining to distribution of the
   software without specific, written prior permission.
 
   advertising or publicity pertaining to distribution of the
   software without specific, written prior permission.
 
-  The author disclaim all warranties with regard to this
+  The author disclaims all warranties with regard to this
   software, including all implied warranties of merchantability
   and fitness.  In no event shall the author be liable for any
   special, indirect or consequential damages or any damages
   software, including all implied warranties of merchantability
   and fitness.  In no event shall the author be liable for any
   special, indirect or consequential damages or any damages
@@ -46,11 +46,12 @@ int main(void)
        puts_P(PSTR(ESC_FG_CYAN "CDC Host Demo running.\r\n" ESC_FG_WHITE));
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        puts_P(PSTR(ESC_FG_CYAN "CDC Host Demo running.\r\n" ESC_FG_WHITE));
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
-       sei();
+       GlobalInterruptEnable();
 
        for (;;)
        {
 
        for (;;)
        {
-               CDC_Host_Task();
+               CDCHost_Task();
+
                USB_USBTask();
        }
 }
                USB_USBTask();
        }
 }
@@ -58,17 +59,22 @@ int main(void)
 /** Configures the board hardware and chip peripherals for the demo's functionality. */
 void SetupHardware(void)
 {
 /** Configures the board hardware and chip peripherals for the demo's functionality. */
 void SetupHardware(void)
 {
+#if (ARCH == ARCH_AVR8)
        /* Disable watchdog if enabled by bootloader/fuses */
        MCUSR &= ~(1 << WDRF);
        wdt_disable();
 
        /* Disable clock division */
        clock_prescale_set(clock_div_1);
        /* Disable watchdog if enabled by bootloader/fuses */
        MCUSR &= ~(1 << WDRF);
        wdt_disable();
 
        /* Disable clock division */
        clock_prescale_set(clock_div_1);
+#endif
 
        /* Hardware Initialization */
 
        /* Hardware Initialization */
-       SerialStream_Init(9600, false);
+       Serial_Init(9600, false);
        LEDs_Init();
        USB_Init();
        LEDs_Init();
        USB_Init();
+
+       /* Create a stdio stream for the serial port for stdin and stdout */
+       Serial_CreateStream(NULL);
 }
 
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
 }
 
 /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
@@ -94,13 +100,67 @@ void EVENT_USB_Host_DeviceUnattached(void)
  */
 void EVENT_USB_Host_DeviceEnumerationComplete(void)
 {
  */
 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" ESC_FG_WHITE), 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;
+       }
+
+       CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 9600,
+                                           .CharFormat  = CDC_LINEENCODING_OneStopBit,
+                                           .ParityType  = CDC_PARITY_None,
+                                           .DataBits    = 8                            };
+
+       USB_ControlRequest = (USB_Request_Header_t)
+       {
+               .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
+               .bRequest      = CDC_REQ_SetLineEncoding,
+               .wValue        = 0,
+               .wIndex        = 0,
+               .wLength       = sizeof(LineEncoding),
+       };
+
+       /* Set the Line Encoding of the CDC interface within the device, so that it is ready to accept data */
+       Pipe_SelectPipe(PIPE_CONTROLPIPE);
+       if (USB_Host_SendControlRequest(&LineEncoding) != HOST_SENDCONTROL_Successful)
+       {
+               printf_P(PSTR(ESC_FG_RED "Control Error (Set Line Encoding).\r\n"
+                                        " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
+
+               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+               return;
+       }
+
+       puts_P(PSTR("CDC Device Enumerated.\r\n"));
        LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
 /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
 void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
 {
        LEDs_SetAllLEDs(LEDMASK_USB_READY);
 }
 
 /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */
 void EVENT_USB_Host_HostError(const uint8_t ErrorCode)
 {
-       USB_ShutDown();
+       USB_Disable();
 
        printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
                                 " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
 
        printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n"
                                 " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode);
@@ -123,102 +183,57 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
        LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
 }
 
-/** Task to set the configuration of the attached device after it has been enumerated, and to read in
- *  data received from the attached CDC device and print it to the serial port.
+/** Task to read in data received from the attached CDC device and print it to the serial port.
  */
  */
-void CDC_Host_Task(void)
+void CDCHost_Task(void)
 {
 {
-       uint8_t ErrorCode;
+       if (USB_HostState != HOST_STATE_Configured)
+         return;
 
 
-       switch (USB_HostState)
+       /* Select the data IN pipe */
+       Pipe_SelectPipe(CDC_DATA_IN_PIPE);
+       Pipe_Unfreeze();
+
+       /* Check to see if a packet has been received */
+       if (Pipe_IsINReceived())
        {
        {
-               case HOST_STATE_Addressed:
-                       puts_P(PSTR("Getting Config Data.\r\n"));
-
-                       /* 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" ESC_FG_WHITE), ErrorCode);
-
-                               /* Indicate error via status LEDs */
-                               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-                               /* Wait until USB device disconnected */
-                               USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-                               break;
-                       }
-
-                       /* 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);
-
-                               /* Indicate error via status LEDs */
-                               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-
-                               /* Wait until USB device disconnected */
-                               USB_HostState = HOST_STATE_WaitForDeviceRemoval;
-                               break;
-                       }
-
-                       puts_P(PSTR("CDC Device Enumerated.\r\n"));
-
-                       USB_HostState = HOST_STATE_Configured;
-                       break;
-               case HOST_STATE_Configured:
-                       /* Select the data IN pipe */
-                       Pipe_SelectPipe(CDC_DATA_IN_PIPE);
-                       Pipe_Unfreeze();
-
-                       /* Check to see if a packet has been received */
-                       if (Pipe_IsINReceived())
-                       {
-                               /* Re-freeze IN pipe after the packet has been received */
-                               Pipe_Freeze();
-
-                               /* Check if data is in the pipe */
-                               if (Pipe_IsReadWriteAllowed())
-                               {
-                                       /* Get the length of the pipe data, and create a new buffer to hold it */
-                                       uint16_t BufferLength = Pipe_BytesInPipe();
-                                       uint8_t  Buffer[BufferLength];
-
-                                       /* Read in the pipe data to the temporary buffer */
-                                       Pipe_Read_Stream_LE(Buffer, BufferLength);
-
-                                       /* Print out the buffer contents to the USART */
-                                       for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
-                                         putchar(Buffer[BufferByte]);
-                               }
-
-                               /* Clear the pipe after it is read, ready for the next packet */
-                               Pipe_ClearIN();
-                       }
-
-                       /* Re-freeze IN pipe after use */
-                       Pipe_Freeze();
-
-                       /* Select and unfreeze the notification pipe */
-                       Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
-                       Pipe_Unfreeze();
-
-                       /* Check if a packet has been received */
-                       if (Pipe_IsINReceived())
-                       {
-                               /* Discard the unused event notification */
-                               Pipe_ClearIN();
-                       }
-
-                       /* Freeze notification IN pipe after use */
-                       Pipe_Freeze();
-
-                       break;
+               /* Re-freeze IN pipe after the packet has been received */
+               Pipe_Freeze();
+
+               /* Check if data is in the pipe */
+               if (Pipe_IsReadWriteAllowed())
+               {
+                       /* Get the length of the pipe data, and create a new buffer to hold it */
+                       uint16_t BufferLength = Pipe_BytesInPipe();
+                       uint8_t  Buffer[BufferLength];
+
+                       /* Read in the pipe data to the temporary buffer */
+                       Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
+
+                       /* Print out the buffer contents to the USART */
+                       for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
+                         putchar(Buffer[BufferByte]);
+               }
+
+               /* Clear the pipe after it is read, ready for the next packet */
+               Pipe_ClearIN();
        }
        }
+
+       /* Re-freeze IN pipe after use */
+       Pipe_Freeze();
+
+       /* Select and unfreeze the notification pipe */
+       Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
+       Pipe_Unfreeze();
+
+       /* Check if a packet has been received */
+       if (Pipe_IsINReceived())
+       {
+               /* Discard the unused event notification */
+               Pipe_ClearIN();
+       }
+
+       /* Freeze notification IN pipe after use */
+       Pipe_Freeze();
 }
 
 }