diff options
Diffstat (limited to 'usb-dual-serial/usb-dual-serial.c')
-rw-r--r-- | usb-dual-serial/usb-dual-serial.c | 476 |
1 files changed, 238 insertions, 238 deletions
diff --git a/usb-dual-serial/usb-dual-serial.c b/usb-dual-serial/usb-dual-serial.c index a58f278..02b50be 100644 --- a/usb-dual-serial/usb-dual-serial.c +++ b/usb-dual-serial/usb-dual-serial.c @@ -1,238 +1,238 @@ -/*
- * spreadspace avr utils
- *
- *
- * Copyright (C) 2013-2014 Christian Pointner <equinox@spreadspace.org>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-
-#include <avr/io.h>
-#include <avr/wdt.h>
-#include <avr/interrupt.h>
-#include <avr/power.h>
-
-#include "util.h"
-#include "led.h"
-
-/*
- LUFA Library
- Copyright (C) Dean Camera, 2012.
-
- dean [at] fourwalledcubicle [dot] com
- www.lufa-lib.org
-*/
-#include <LUFA/Drivers/USB/USB.h>
-#include <LUFA/Drivers/Peripheral/Serial.h>
-#include <LUFA/Drivers/Misc/RingBuffer.h>
-#include "lufa-descriptor-usbdualserial.h"
-
-static RingBuffer_t USBtoUSART_Buffer;
-static uint8_t USBtoUSART_Buffer_Data[128];
-static RingBuffer_t USARTtoUSB_Buffer;
-static uint8_t USARTtoUSB_Buffer_Data[128];
-
-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,
- },
- };
-
-void EVENT_USB_Device_ConfigurationChanged(void)
-{
- CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface);
- CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface);
-}
-
-void EVENT_USB_Device_ControlRequest(void)
-{
- CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
- CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
-}
-
-void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
-{
- if(CDCInterfaceInfo != &VirtualSerial1_CDC_Interface)
- return;
-
- uint8_t ConfigMask = 0;
-
- switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
- {
- case CDC_PARITY_Odd:
- ConfigMask = ((1 << UPM11) | (1 << UPM10));
- break;
- case CDC_PARITY_Even:
- ConfigMask = (1 << UPM11);
- break;
- }
-
- if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
- ConfigMask |= (1 << USBS1);
-
- switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
- {
- case 6:
- ConfigMask |= (1 << UCSZ10);
- break;
- case 7:
- ConfigMask |= (1 << UCSZ11);
- break;
- case 8:
- ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
- break;
- }
-
- /* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
- UCSR1B = 0;
- UCSR1A = 0;
- UCSR1C = 0;
-
- /* Set the new baud rate before configuring the USART */
- UBRR1 = SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
-
- /* Reconfigure the USART in double speed mode for a wider baud rate range at the expense of accuracy */
- UCSR1C = ConfigMask;
- UCSR1A = (1 << U2X1);
- UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
-}
-
-ISR(USART1_RX_vect, ISR_BLOCK)
-{
- uint8_t ReceivedByte = UDR1;
-
- if (USB_DeviceState == DEVICE_STATE_Configured)
- RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
-}
-
-void usbserial_init(void)
-{
- RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
- RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));
- TCCR0B = (1 << CS02);
-}
-
-void usbserial_task(void)
-{
- if (!(RingBuffer_IsFull(&USBtoUSART_Buffer))) {
- int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface);
- if (!(ReceivedByte < 0))
- RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
- }
-
- uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
- if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75))) {
- TIFR0 |= (1 << TOV0);
- while (BufferCount--) {
- if (CDC_Device_SendByte(&VirtualSerial1_CDC_Interface, RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
- break;
-
- RingBuffer_Remove(&USARTtoUSB_Buffer);
- }
- }
-
- if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
- Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));
-}
-/* end LUFA CDC-ACM specific definitions*/
-
-
-
-FILE usb_stream;
-
-void stdio_init(void)
-{
- CDC_Device_CreateStream(&VirtualSerial2_CDC_Interface, &usb_stream);
- stdin = &usb_stream;
- stdout = &usb_stream;
- stderr = &usb_stream;
-}
-
-void handle_cmd(uint8_t cmd)
-{
- switch(cmd) {
- case '0': led_off(); break;
- case '1': led_on(); break;
- case 't': led_toggle(); break;
- case 'r': reset2bootloader(); break;
- default: printf("unknown command\r\n"); return;
- }
- printf("ok\r\n");
-}
-
-int main(void)
-{
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- cpu_init();
- led_init();
- USB_Init();
- stdio_init();
- usbserial_init();
- sei();
-
- for(;;) {
- int16_t BytesReceived = CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface);
- while(BytesReceived > 0) {
- int ReceivedByte = fgetc(stdin);
- if(ReceivedByte != EOF) {
- handle_cmd(ReceivedByte);
- }
- BytesReceived--;
- }
-
- usbserial_task();
- CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
- CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
- USB_USBTask();
- }
-}
+/* + * spreadspace avr utils + * + * + * Copyright (C) 2013-2014 Christian Pointner <equinox@spreadspace.org> + * + * 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 <http://www.gnu.org/licenses/>. + */ + + +#include <avr/io.h> +#include <avr/wdt.h> +#include <avr/interrupt.h> +#include <avr/power.h> + +#include "util.h" +#include "led.h" + +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ +#include <LUFA/Drivers/USB/USB.h> +#include <LUFA/Drivers/Peripheral/Serial.h> +#include <LUFA/Drivers/Misc/RingBuffer.h> +#include "lufa-descriptor-usbdualserial.h" + +static RingBuffer_t USBtoUSART_Buffer; +static uint8_t USBtoUSART_Buffer_Data[128]; +static RingBuffer_t USARTtoUSB_Buffer; +static uint8_t USARTtoUSB_Buffer_Data[128]; + +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, + }, + }; + +void EVENT_USB_Device_ConfigurationChanged(void) +{ + CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface); + CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface); +} + +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface); + CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface); +} + +void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if(CDCInterfaceInfo != &VirtualSerial1_CDC_Interface) + return; + + uint8_t ConfigMask = 0; + + switch (CDCInterfaceInfo->State.LineEncoding.ParityType) + { + case CDC_PARITY_Odd: + ConfigMask = ((1 << UPM11) | (1 << UPM10)); + break; + case CDC_PARITY_Even: + ConfigMask = (1 << UPM11); + break; + } + + if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits) + ConfigMask |= (1 << USBS1); + + switch (CDCInterfaceInfo->State.LineEncoding.DataBits) + { + case 6: + ConfigMask |= (1 << UCSZ10); + break; + case 7: + ConfigMask |= (1 << UCSZ11); + break; + case 8: + ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10)); + break; + } + + /* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */ + UCSR1B = 0; + UCSR1A = 0; + UCSR1C = 0; + + /* Set the new baud rate before configuring the USART */ + UBRR1 = SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + + /* Reconfigure the USART in double speed mode for a wider baud rate range at the expense of accuracy */ + UCSR1C = ConfigMask; + UCSR1A = (1 << U2X1); + UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1)); +} + +ISR(USART1_RX_vect, ISR_BLOCK) +{ + uint8_t ReceivedByte = UDR1; + + if (USB_DeviceState == DEVICE_STATE_Configured) + RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte); +} + +void usbserial_init(void) +{ + RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data)); + RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data)); + TCCR0B = (1 << CS02); +} + +void usbserial_task(void) +{ + if (!(RingBuffer_IsFull(&USBtoUSART_Buffer))) { + int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface); + if (!(ReceivedByte < 0)) + RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte); + } + + uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); + if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75))) { + TIFR0 |= (1 << TOV0); + while (BufferCount--) { + if (CDC_Device_SendByte(&VirtualSerial1_CDC_Interface, RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError) + break; + + RingBuffer_Remove(&USARTtoUSB_Buffer); + } + } + + if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) + Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer)); +} +/* end LUFA CDC-ACM specific definitions*/ + + + +FILE usb_stream; + +void stdio_init(void) +{ + CDC_Device_CreateStream(&VirtualSerial2_CDC_Interface, &usb_stream); + stdin = &usb_stream; + stdout = &usb_stream; + stderr = &usb_stream; +} + +void handle_cmd(uint8_t cmd) +{ + switch(cmd) { + case '0': led_off(); break; + case '1': led_on(); break; + case 't': led_toggle(); break; + case 'r': reset2bootloader(); break; + default: printf("unknown command\r\n"); return; + } + printf("ok\r\n"); +} + +int main(void) +{ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + cpu_init(); + led_init(); + USB_Init(); + stdio_init(); + usbserial_init(); + sei(); + + for(;;) { + int16_t BytesReceived = CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface); + while(BytesReceived > 0) { + int ReceivedByte = fgetc(stdin); + if(ReceivedByte != EOF) { + handle_cmd(ReceivedByte); + } + BytesReceived--; + } + + usbserial_task(); + CDC_Device_USBTask(&VirtualSerial1_CDC_Interface); + CDC_Device_USBTask(&VirtualSerial2_CDC_Interface); + USB_USBTask(); + } +} |