/* * spreadspace avr utils * * * Copyright (C) 2013-2018 Christian Pointner * * This file is part of spreadspace avr utils. * * spreadspace avr utils is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * spreadspace avr utils is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with spreadspace avr utils. If not, see . */ #include #include "dualusbio.h" /* LUFA Library Copyright (C) Dean Camera, 2012. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ #include #include "lufa-descriptor-usbdualserial.h" USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface[] = { { .Config = { .ControlInterfaceNumber = INTERFACE_ID_CDC1_CCI, .DataINEndpoint = { .Address = CDC1_TX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .DataOUTEndpoint = { .Address = CDC1_RX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .NotificationEndpoint = { .Address = CDC1_NOTIFICATION_EPADDR, .Size = CDC_NOTIFICATION_EPSIZE, .Banks = 1, }, }, },{ .Config = { .ControlInterfaceNumber = INTERFACE_ID_CDC2_CCI, .DataINEndpoint = { .Address = CDC2_TX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .DataOUTEndpoint = { .Address = CDC2_RX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .NotificationEndpoint = { .Address = CDC2_NOTIFICATION_EPADDR, .Size = CDC_NOTIFICATION_EPSIZE, .Banks = 1, }, }, } }; void EVENT_USB_Device_ConfigurationChanged(void) { CDC_Device_ConfigureEndpoints(&(VirtualSerial_CDC_Interface[0])); CDC_Device_ConfigureEndpoints(&(VirtualSerial_CDC_Interface[1])); } void EVENT_USB_Device_ControlRequest(void) { CDC_Device_ProcessControlRequest(&(VirtualSerial_CDC_Interface[0])); CDC_Device_ProcessControlRequest(&(VirtualSerial_CDC_Interface[1])); } 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(&(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) if(USB_DeviceState == DEVICE_STATE_Unattached && USB_VBUS_GetStatus()) { USB_Disable(); USB_Init(); } #endif CDC_Device_USBTask(&(VirtualSerial_CDC_Interface[0])); CDC_Device_USBTask(&(VirtualSerial_CDC_Interface[1])); USB_USBTask(); } void dualusbio_make_stdio(uint8_t port) { 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) { if(port < 2 && usbio[port] == &(usb_stream[port])) return CDC_Device_BytesReceived(&(VirtualSerial_CDC_Interface[port])); return 0; } int16_t dualusbio_bytes_received_std(void) { return dualusbio_bytes_received(stdio_port); } 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; }