X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/8d993afc5388c5f3d0ff568c607f7fed6bb7390e..b120c4e4cda5b5ed12a61697b5ab33d4dd0a70e8:/Projects/USBtoSerial/USBtoSerial.c diff --git a/Projects/USBtoSerial/USBtoSerial.c b/Projects/USBtoSerial/USBtoSerial.c index 7a0f6866a..3f06acde9 100644 --- a/Projects/USBtoSerial/USBtoSerial.c +++ b/Projects/USBtoSerial/USBtoSerial.c @@ -1,21 +1,21 @@ /* LUFA Library Copyright (C) Dean Camera, 2010. - + dean [at] fourwalledcubicle [dot] com - www.fourwalledcubicle.com + www.lufa-lib.org */ /* Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) - Permission to use, copy, modify, distribute, and sell this + Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in + without fee, provided that the above copyright notice appear in all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this @@ -48,7 +48,7 @@ RingBuff_t USARTtoUSB_Buffer; */ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = { - .Config = + .Config = { .ControlInterfaceNumber = 0, @@ -72,7 +72,7 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = int main(void) { SetupHardware(); - + RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer); @@ -82,22 +82,25 @@ int main(void) for (;;) { /* Read bytes from the USB OUT endpoint into the USART transmit buffer */ - for (uint8_t DataBytesRem = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--) + int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); + if (!(ReceivedByte < 0) && !(RingBuffer_IsFull(&USBtoUSART_Buffer))) + RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte); + + /* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */ + RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); + if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200)) { - if (!(BUFFER_SIZE - USBtoUSART_Buffer.Count)) - break; - - RingBuffer_Insert(&USBtoUSART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)); + TIFR0 |= (1 << TOV0); + + /* Read bytes from the USART receive buffer into the USB IN endpoint */ + while (BufferCount--) + CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); } - - /* Read bytes from the USART receive buffer into the USB IN endpoint */ - while (USARTtoUSB_Buffer.Count) - CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); - - /* Load bytes from the USART transmit buffer into the USART */ - while (USBtoUSART_Buffer.Count) + + /* Load the next byte from the USART transmit buffer into the USART */ + if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); - + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } @@ -114,9 +117,11 @@ void SetupHardware(void) clock_prescale_set(clock_div_1); /* Hardware Initialization */ - Serial_Init(9600, false); LEDs_Init(); USB_Init(); + + /* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */ + TCCR0B = (1 << CS02); } /** Event handler for the library USB Connection event. */ @@ -134,10 +139,11 @@ void EVENT_USB_Device_Disconnect(void) /** Event handler for the library USB Configuration Changed event. */ void EVENT_USB_Device_ConfigurationChanged(void) { - LEDs_SetAllLEDs(LEDMASK_USB_READY); + bool ConfigSuccess = true; - if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface))) - LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); + + LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); } /** Event handler for the library USB Unhandled Control Request event. */ @@ -168,10 +174,10 @@ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCI switch (CDCInterfaceInfo->State.LineEncoding.ParityType) { case CDC_PARITY_Odd: - ConfigMask = ((1 << UPM11) | (1 << UPM10)); + ConfigMask = ((1 << UPM11) | (1 << UPM10)); break; case CDC_PARITY_Even: - ConfigMask = (1 << UPM11); + ConfigMask = (1 << UPM11); break; } @@ -190,9 +196,18 @@ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCI ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10)); break; } - - UCSR1A = (1 << U2X1); - UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1)); - UCSR1C = ConfigMask; + + /* 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)); } +