From 653a3bdc8b5fc7938d633bf158fbc38dd9b8624c Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 22 Jun 2015 02:13:15 +0200 Subject: improved dual usbio - fully working now --- lib/dualusbio.c | 146 +++++++++++++++++++++++++++++++--------------------- lib/dualusbio.h | 3 +- usb-led2/Makefile | 2 +- usb-led2/usb-led2.c | 22 ++++---- 4 files changed, 102 insertions(+), 71 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 #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; +} diff --git a/lib/dualusbio.h b/lib/dualusbio.h index 0f07ea6..a5a68a0 100644 --- a/lib/dualusbio.h +++ b/lib/dualusbio.h @@ -26,8 +26,7 @@ #include #include -extern FILE usbio_port1; -extern FILE usbio_port2; +extern FILE* usbio[]; void dualusbio_init(void); void dualusbio_task(void); diff --git a/usb-led2/Makefile b/usb-led2/Makefile index 616bf62..f8cfc68 100644 --- a/usb-led2/Makefile +++ b/usb-led2/Makefile @@ -38,7 +38,7 @@ LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENAB LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT LUFA_OPTS += -D USB_MANUFACTURER="L\"equinox\"" -D USB_MANUFACTURER_LEN=7 -LUFA_OPTS += -D USB_PRODUCT="L\"spreadspace usb-led example\"" -D USB_PRODUCT_LEN=27 +LUFA_OPTS += -D USB_PRODUCT="L\"spreadspace usb-led2 example\"" -D USB_PRODUCT_LEN=28 LUFA_COMPONENTS := USB USBCLASS diff --git a/usb-led2/usb-led2.c b/usb-led2/usb-led2.c index 345f076..74d5bf2 100644 --- a/usb-led2/usb-led2.c +++ b/usb-led2/usb-led2.c @@ -31,15 +31,15 @@ #include "led.h" #include "dualusbio.h" -void handle_cmd1(uint8_t cmd) +void handle_cmd(uint8_t cmd) { switch(cmd) { case '0': led_off(); break; case '1': led_on(); break; case 't': led_toggle(); break; - default: fprintf(&usbio_port1, "1: error\r\n"); return; + default: printf("std: error\r\n"); return; } - fprintf(&usbio_port1, "1: ok\r\n"); + printf("std: ok\r\n"); } void handle_cmd2(uint8_t cmd) @@ -48,9 +48,9 @@ void handle_cmd2(uint8_t cmd) case '0': led_on(); break; case '1': led_off(); break; case 't': led_toggle(); break; - default: fprintf(&usbio_port2, "2: error\r\n"); return; + default: fprintf(usbio[1], "2: error\r\n"); return; } - fprintf(&usbio_port2, "2: ok\r\n"); + fprintf(usbio[1], "2: ok\r\n"); } int main(void) @@ -63,19 +63,21 @@ int main(void) dualusbio_init(); sei(); + dualusbio_make_stdio(0); + for(;;) { - int16_t BytesReceived = dualusbio_bytes_received(1); + int16_t BytesReceived = dualusbio_bytes_received(0); while(BytesReceived > 0) { - int ReceivedByte = fgetc(&usbio_port1); + int ReceivedByte = fgetc(stdin); if(ReceivedByte != EOF) { - handle_cmd1(ReceivedByte); + handle_cmd(ReceivedByte); } BytesReceived--; } - BytesReceived = dualusbio_bytes_received(2); + BytesReceived = dualusbio_bytes_received(1); while(BytesReceived > 0) { - int ReceivedByte = fgetc(&usbio_port2); + int ReceivedByte = fgetc(usbio[1]); if(ReceivedByte != EOF) { handle_cmd2(ReceivedByte); } -- cgit v1.2.3