X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/189d0c7e669b6a3d07ed35c1eaa0bfc8cbc7a729..3ffa7543a05761a0c69144c9b66196b08d8f1249:/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c diff --git a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c index c48c33c08..92449a67d 100644 --- a/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c +++ b/Demos/Device/LowLevel/USBtoSerial/USBtoSerial.c @@ -36,10 +36,10 @@ * These values are set by the host via a class-specific request, and the physical USART should be reconfigured to match the * new settings each time they are changed by the host. */ -CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600, - .CharFormat = OneStopBit, - .ParityType = Parity_None, - .DataBits = 8 }; +CDC_Line_Coding_t LineEncoding = { .BaudRateBPS = 0, + .CharFormat = OneStopBit, + .ParityType = Parity_None, + .DataBits = 8 }; /** Ring (circular) buffer to hold the RX data - data from the host to the attached device on the serial port. */ RingBuff_t Rx_Buffer; @@ -81,15 +81,15 @@ void SetupHardware(void) clock_prescale_set(clock_div_1); /* Hardware Initialization */ + Serial_Init(9600, false); LEDs_Init(); - ReconfigureUSART(); - USB_Init(); + USB_Init(); } /** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and * starts the library USB task to begin the enumeration and USB management process. */ -void EVENT_USB_Connect(void) +void EVENT_USB_Device_Connect(void) { /* Indicate USB enumerating */ LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); @@ -98,7 +98,7 @@ void EVENT_USB_Connect(void) /** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via * the status LEDs and stops the USB management and CDC management tasks. */ -void EVENT_USB_Disconnect(void) +void EVENT_USB_Device_Disconnect(void) { /* Reset Tx and Rx buffers, device disconnected */ Buffer_Initialize(&Rx_Buffer); @@ -111,7 +111,7 @@ void EVENT_USB_Disconnect(void) /** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration * of the USB device after enumeration - the device endpoints are configured and the CDC management task started. */ -void EVENT_USB_ConfigurationChanged(void) +void EVENT_USB_Device_ConfigurationChanged(void) { /* Indicate USB connected and ready */ LEDs_SetAllLEDs(LEDMASK_USB_READY); @@ -137,16 +137,17 @@ void EVENT_USB_ConfigurationChanged(void) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); } + + /* Reset line encoding baud rate so that the host knows to send new values */ + LineEncoding.BaudRateBPS = 0; } -/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific +/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific * control requests that are not handled internally by the USB library (including the CDC control commands, * which are all issued via the control endpoint), so that they can be handled appropriately for the application. */ -void EVENT_USB_UnhandledControlPacket(void) +void EVENT_USB_Device_UnhandledControlRequest(void) { - uint8_t* LineCodingData = (uint8_t*)&LineCoding; - /* Process CDC specific control requests */ switch (USB_ControlRequest.bRequest) { @@ -157,7 +158,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearSETUP(); /* Write the line coding data to the control endpoint */ - Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(LineCoding)); + Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(LineEncoding)); /* Finalize the stream transfer to send the last packet or clear the host abort */ Endpoint_ClearOUT(); @@ -171,7 +172,7 @@ void EVENT_USB_UnhandledControlPacket(void) Endpoint_ClearSETUP(); /* Read the line coding data in from the host into the global struct */ - Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(LineCoding)); + Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(LineEncoding)); /* Finalize the stream transfer to clear the last packet from the host */ Endpoint_ClearIN(); @@ -192,9 +193,7 @@ void EVENT_USB_UnhandledControlPacket(void) CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code: */ - /* Acknowledge status stage */ - while (!(Endpoint_IsINReady())); - Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); } break; @@ -204,89 +203,90 @@ void EVENT_USB_UnhandledControlPacket(void) /** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */ void CDC_Task(void) { - if (USB_IsConnected) - { + /* Device must be connected and configured for the task to run */ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + #if 0 - /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232 - handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code: - */ + /* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232 + handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code: + */ - USB_Notification_Header_t Notification = (USB_Notification_Header_t) - { - .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), - .Notification = NOTIF_SerialState, - .wValue = 0, - .wIndex = 0, - .wLength = sizeof(uint16_t), - }; - - uint16_t LineStateMask; - - // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host + USB_Notification_Header_t Notification = (USB_Notification_Header_t) + { + .NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .Notification = NOTIF_SerialState, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(uint16_t), + }; - Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM); - Endpoint_Write_Stream_LE(&Notification, sizeof(Notification)); - Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask)); - Endpoint_ClearIN(); + uint16_t LineStateMask; + + // Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host + + Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM); + Endpoint_Write_Stream_LE(&Notification, sizeof(Notification)); + Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask)); + Endpoint_ClearIN(); #endif - /* Select the Serial Rx Endpoint */ - Endpoint_SelectEndpoint(CDC_RX_EPNUM); - - /* Check to see if a packet has been received from the host */ - if (Endpoint_IsOUTReceived()) + /* Select the Serial Rx Endpoint */ + Endpoint_SelectEndpoint(CDC_RX_EPNUM); + + /* Check to see if a packet has been received from the host */ + if (Endpoint_IsOUTReceived()) + { + /* Read the bytes in from the endpoint into the buffer while space is available */ + while (Endpoint_BytesInEndpoint() && (Rx_Buffer.Elements != BUFF_STATICSIZE)) { - /* Read the bytes in from the endpoint into the buffer while space is available */ - while (Endpoint_BytesInEndpoint() && (Rx_Buffer.Elements != BUFF_STATICSIZE)) - { - /* Store each character from the endpoint */ - Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte()); - } - - /* Check to see if all bytes in the current packet have been read */ - if (!(Endpoint_BytesInEndpoint())) - { - /* Clear the endpoint buffer */ - Endpoint_ClearOUT(); - } + /* Store each character from the endpoint */ + Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte()); } - /* Check if Rx buffer contains data - if so, send it */ - if (Rx_Buffer.Elements) - Serial_TxByte(Buffer_GetElement(&Rx_Buffer)); + /* Check to see if all bytes in the current packet have been read */ + if (!(Endpoint_BytesInEndpoint())) + { + /* Clear the endpoint buffer */ + Endpoint_ClearOUT(); + } + } + + /* Check if Rx buffer contains data - if so, send it */ + if (Rx_Buffer.Elements) + Serial_TxByte(Buffer_GetElement(&Rx_Buffer)); + + /* Select the Serial Tx Endpoint */ + Endpoint_SelectEndpoint(CDC_TX_EPNUM); - /* Select the Serial Tx Endpoint */ - Endpoint_SelectEndpoint(CDC_TX_EPNUM); + /* Check if the Tx buffer contains anything to be sent to the host */ + if ((Tx_Buffer.Elements) && LineEncoding.BaudRateBPS) + { + /* Wait until Serial Tx Endpoint Ready for Read/Write */ + Endpoint_WaitUntilReady(); + + /* Write the bytes from the buffer to the endpoint while space is available */ + while (Tx_Buffer.Elements && Endpoint_IsReadWriteAllowed()) + { + /* Write each byte retreived from the buffer to the endpoint */ + Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer)); + } + + /* Remember if the packet to send completely fills the endpoint */ + bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE); + + /* Send the data */ + Endpoint_ClearIN(); - /* Check if the Tx buffer contains anything to be sent to the host */ - if (Tx_Buffer.Elements) + /* If no more data to send and the last packet filled the endpoint, send an empty packet to release + * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */ + if (IsFull && !(Tx_Buffer.Elements)) { /* Wait until Serial Tx Endpoint Ready for Read/Write */ - while (!(Endpoint_IsReadWriteAllowed())); - - /* Write the bytes from the buffer to the endpoint while space is available */ - while (Tx_Buffer.Elements && Endpoint_IsReadWriteAllowed()) - { - /* Write each byte retreived from the buffer to the endpoint */ - Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer)); - } - - /* Remember if the packet to send completely fills the endpoint */ - bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE); - - /* Send the data */ + Endpoint_WaitUntilReady(); + + /* Send an empty packet to terminate the transfer */ Endpoint_ClearIN(); - - /* If no more data to send and the last packet filled the endpoint, send an empty packet to release - * the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */ - if (IsFull && !(Tx_Buffer.Elements)) - { - /* Wait until Serial Tx Endpoint Ready for Read/Write */ - while (!(Endpoint_IsReadWriteAllowed())); - - /* Send an empty packet to terminate the transfer */ - Endpoint_ClearIN(); - } } } } @@ -296,12 +296,11 @@ void CDC_Task(void) */ ISR(USART1_RX_vect, ISR_BLOCK) { + uint8_t ReceivedByte = UDR1; + /* Only store received characters if the USB interface is connected */ - if (USB_IsConnected) - { - /* Character received, store it into the buffer */ - Buffer_StoreElement(&Tx_Buffer, UDR1); - } + if ((USB_DeviceState == DEVICE_STATE_Configured) && LineEncoding.BaudRateBPS) + Buffer_StoreElement(&Tx_Buffer, ReceivedByte); } /** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */ @@ -310,21 +309,21 @@ void ReconfigureUSART(void) uint8_t ConfigMask = 0; /* Determine parity - non odd/even parity mode defaults to no parity */ - if (LineCoding.ParityType == Parity_Odd) + if (LineEncoding.ParityType == Parity_Odd) ConfigMask = ((1 << UPM11) | (1 << UPM10)); - else if (LineCoding.ParityType == Parity_Even) + else if (LineEncoding.ParityType == Parity_Even) ConfigMask = (1 << UPM11); /* Determine stop bits - 1.5 stop bits is set as 1 stop bit due to hardware limitations */ - if (LineCoding.CharFormat == TwoStopBits) + if (LineEncoding.CharFormat == TwoStopBits) ConfigMask |= (1 << USBS1); /* Determine data size - 5, 6, 7, or 8 bits are supported */ - if (LineCoding.DataBits == 6) + if (LineEncoding.DataBits == 6) ConfigMask |= (1 << UCSZ10); - else if (LineCoding.DataBits == 7) + else if (LineEncoding.DataBits == 7) ConfigMask |= (1 << UCSZ11); - else if (LineCoding.DataBits == 8) + else if (LineEncoding.DataBits == 8) ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10)); /* Enable double speed, gives better error percentages at 8MHz */ @@ -337,5 +336,5 @@ void ReconfigureUSART(void) UCSR1C = ConfigMask; /* Set the USART baud rate register to the desired baud rate value */ - UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)LineCoding.BaudRateBPS); + UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)LineEncoding.BaudRateBPS); }