summaryrefslogtreecommitdiff
path: root/lib/dualusbio.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dualusbio.c')
-rw-r--r--lib/dualusbio.c146
1 files changed, 88 insertions, 58 deletions
diff --git a/lib/dualusbio.c b/lib/dualusbio.c
index d774d6a..27d72ea 100644
--- a/lib/dualusbio.c
+++ b/lib/dualusbio.c
@@ -34,69 +34,73 @@
#include <LUFA/Drivers/USB/USB.h>
#include "lufa-descriptor-usbdualserial.h"
-USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
- {
- .Config =
- {
- .ControlInterfaceNumber = 0,
-
- .DataINEndpointNumber = CDC1_TX_EPNUM,
- .DataINEndpointSize = CDC_TXRX_EPSIZE,
- .DataINEndpointDoubleBank = false,
-
- .DataOUTEndpointNumber = CDC1_RX_EPNUM,
- .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
- .DataOUTEndpointDoubleBank = false,
-
- .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
- .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
- .NotificationEndpointDoubleBank = false,
- },
- };
-
-USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
- {
- .Config =
- {
- .ControlInterfaceNumber = 2,
-
- .DataINEndpointNumber = CDC2_TX_EPNUM,
- .DataINEndpointSize = CDC_TXRX_EPSIZE,
- .DataINEndpointDoubleBank = false,
-
- .DataOUTEndpointNumber = CDC2_RX_EPNUM,
- .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
- .DataOUTEndpointDoubleBank = false,
-
- .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
- .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
- .NotificationEndpointDoubleBank = false,
- },
- };
+USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface[] =
+ {
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 0,
+
+ .DataINEndpointNumber = CDC1_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC1_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ },{
+ .Config =
+ {
+ .ControlInterfaceNumber = 2,
+
+ .DataINEndpointNumber = CDC2_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC2_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ }
+ };
void EVENT_USB_Device_ConfigurationChanged(void)
{
- CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface);
- CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface);
+ CDC_Device_ConfigureEndpoints(&(VirtualSerial_CDC_Interface[0]));
+ CDC_Device_ConfigureEndpoints(&(VirtualSerial_CDC_Interface[1]));
}
void EVENT_USB_Device_ControlRequest(void)
{
- CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
- CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
+ CDC_Device_ProcessControlRequest(&(VirtualSerial_CDC_Interface[0]));
+ CDC_Device_ProcessControlRequest(&(VirtualSerial_CDC_Interface[1]));
}
-FILE usbio_port1;
-FILE usbio_port2;
+
+static int dummy_putchar(char DataByte, FILE *Stream) { return 0; }
+static int dummy_getchar(FILE *Stream) { return 0; }
+static FILE dummy_stream = FDEV_SETUP_STREAM(dummy_putchar, dummy_getchar, _FDEV_SETUP_RW);
+static FILE usb_stream[2];
+FILE* usbio[2] = { &dummy_stream, &dummy_stream };
+static uint8_t stdio_port = 255;
+
void dualusbio_init(void)
{
USB_Init();
- CDC_Device_CreateStream(&VirtualSerial1_CDC_Interface, &usbio_port1);
- CDC_Device_CreateStream(&VirtualSerial2_CDC_Interface, &usbio_port2);
+ CDC_Device_CreateStream(&(VirtualSerial_CDC_Interface[0]), &usb_stream[0]);
+ CDC_Device_CreateStream(&(VirtualSerial_CDC_Interface[1]), &usb_stream[1]);
}
-
void dualusbio_task(void)
{
#if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)
@@ -106,24 +110,50 @@ void dualusbio_task(void)
}
#endif
- CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
- CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
+ CDC_Device_USBTask(&(VirtualSerial_CDC_Interface[0]));
+ CDC_Device_USBTask(&(VirtualSerial_CDC_Interface[1]));
USB_USBTask();
}
void dualusbio_make_stdio(uint8_t port)
{
- switch(port) {
- case 1: stdin = stdout = stderr = &usbio_port1; break;
- case 2: stdin = stdout = stderr = &usbio_port2; break;
- }
+ stdio_port = port;
+
+ if(port < 2 && usbio[port] == &(usb_stream[port]))
+ stdin = stdout = stderr = &(usb_stream[port]);
+ else
+ stdin = stdout = stderr = &dummy_stream;
}
int16_t dualusbio_bytes_received(uint8_t port)
{
- switch(port) {
- case 1: return CDC_Device_BytesReceived(&VirtualSerial1_CDC_Interface);
- case 2: return CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface);
- }
+ if(port < 2 && usbio[port] == &(usb_stream[port]))
+ return CDC_Device_BytesReceived(&(VirtualSerial_CDC_Interface[port]));
+
return 0;
}
+
+void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ uint8_t p;
+ for(p = 0; p < 2; p++) {
+ if(CDCInterfaceInfo == &(VirtualSerial_CDC_Interface[p])) {
+ if(CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) {
+ usbio[p] = &(usb_stream[p]);
+ if(p == stdio_port) stdin = stdout = stderr = &(usb_stream[p]);
+ } else {
+ usbio[p] = &dummy_stream;
+ if(p == stdio_port) stdin = stdout = stderr = &dummy_stream;
+ }
+
+ break;
+ }
+ }
+}
+
+void EVENT_USB_Device_Disconnect(void)
+{
+ usbio[0] = &dummy_stream;
+ usbio[1] = &dummy_stream;
+ stdin = stdout = stderr = &dummy_stream;
+}