From fa21da41f0e24682cb9ae956cf3072091c9155f1 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 29 May 2012 22:43:10 +0000 Subject: fixed multi byte receive for spi git-svn-id: https://svn.spreadspace.org/avr/trunk@44 aa12f405-d877-488e-9caf-2d797e2a1cc7 --- usb-spi/usb-spi.c | 149 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 77 insertions(+), 72 deletions(-) diff --git a/usb-spi/usb-spi.c b/usb-spi/usb-spi.c index db85730..950f4f3 100644 --- a/usb-spi/usb-spi.c +++ b/usb-spi/usb-spi.c @@ -112,24 +112,24 @@ static uint8_t SPItoUSB_Buffer_Data[128]; * within a device can be differentiated from one another. */ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = - { - .Config = - { - .ControlInterfaceNumber = 0, + { + .Config = + { + .ControlInterfaceNumber = 0, - .DataINEndpointNumber = CDC_TX_EPNUM, - .DataINEndpointSize = CDC_TXRX_EPSIZE, - .DataINEndpointDoubleBank = false, + .DataINEndpointNumber = CDC_TX_EPNUM, + .DataINEndpointSize = CDC_TXRX_EPSIZE, + .DataINEndpointDoubleBank = false, - .DataOUTEndpointNumber = CDC_RX_EPNUM, - .DataOUTEndpointSize = CDC_TXRX_EPSIZE, - .DataOUTEndpointDoubleBank = false, + .DataOUTEndpointNumber = CDC_RX_EPNUM, + .DataOUTEndpointSize = CDC_TXRX_EPSIZE, + .DataOUTEndpointDoubleBank = false, - .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM, - .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE, - .NotificationEndpointDoubleBank = false, - }, - }; + .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM, + .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE, + .NotificationEndpointDoubleBank = false, + }, + }; /** Main program entry point. This routine contains the overall program flow, including initial @@ -137,69 +137,74 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = */ int main(void) { - SetupHardware(); - - RingBuffer_InitBuffer(&USBtoSPI_Buffer, USBtoSPI_Buffer_Data, sizeof(USBtoSPI_Buffer_Data)); - RingBuffer_InitBuffer(&SPItoUSB_Buffer, SPItoUSB_Buffer_Data, sizeof(SPItoUSB_Buffer_Data)); - - sei(); - - for (;;) - { - /* Only try to read in bytes from the CDC interface if the transmit buffer is not full */ - if (!(RingBuffer_IsFull(&USBtoSPI_Buffer))) - { - int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); - - /* Read bytes from the USB OUT endpoint into the SPI transmit buffer */ - if (!(ReceivedByte < 0)) - RingBuffer_Insert(&USBtoSPI_Buffer, ReceivedByte); - } - - /* Check if the SPI receive buffer flush timer has expired or the buffer is nearly full */ - uint16_t BufferCount = RingBuffer_GetCount(&SPItoUSB_Buffer); - if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(SPItoUSB_Buffer_Data) * .75))) - { - /* Clear flush timer expiry flag */ - TIFR0 |= (1 << TOV0); - - /* Read bytes from the SPI receive buffer into the USB IN endpoint */ - while (BufferCount--) - { - /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */ - if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface, - RingBuffer_Peek(&SPItoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError) - { - break; - } - - /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */ - RingBuffer_Remove(&SPItoUSB_Buffer); - } - } - - /* Load the next byte from the SPI transmit buffer into the SPI Interface */ - if (!(RingBuffer_IsEmpty(&USBtoSPI_Buffer))) - SPI_TransferBuffer(); - - CDC_Device_USBTask(&VirtualSerial_CDC_Interface); - USB_USBTask(); - } + SetupHardware(); + + RingBuffer_InitBuffer(&USBtoSPI_Buffer, USBtoSPI_Buffer_Data, sizeof(USBtoSPI_Buffer_Data)); + RingBuffer_InitBuffer(&SPItoUSB_Buffer, SPItoUSB_Buffer_Data, sizeof(SPItoUSB_Buffer_Data)); + + sei(); + + for (;;) + { + + int16_t BytesReceived = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface); + while(BytesReceived > 0) + { + if(!(RingBuffer_IsFull(&USBtoSPI_Buffer))) + { + int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); + /* Read bytes from the USB OUT endpoint into the SPI transmit buffer */ + if (!(ReceivedByte < 0)) + RingBuffer_Insert(&USBtoSPI_Buffer, ReceivedByte); + + BytesReceived--; + } + } + + /* Check if the SPI receive buffer flush timer has expired or the buffer is nearly full */ + uint16_t BufferCount = RingBuffer_GetCount(&SPItoUSB_Buffer); + if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(SPItoUSB_Buffer_Data) * .75))) + { + /* Clear flush timer expiry flag */ + TIFR0 |= (1 << TOV0); + + /* Read bytes from the SPI receive buffer into the USB IN endpoint */ + while (BufferCount--) + { + /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */ + if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface, + RingBuffer_Peek(&SPItoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError) + { + break; + } + + /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */ + RingBuffer_Remove(&SPItoUSB_Buffer); + } + } + + /* Load the next byte from the SPI transmit buffer into the SPI Interface */ + if (!(RingBuffer_IsEmpty(&USBtoSPI_Buffer))) + SPI_TransferBuffer(); + + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); + USB_USBTask(); + } } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware(void) { - /* Disable watchdog if enabled by bootloader/fuses */ - MCUSR &= ~(1 << WDRF); - wdt_disable(); + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); cpu_init(); led_init(); - USB_Init(); + USB_Init(); - /* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */ - TCCR0B = (1 << CS02); + /* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */ + TCCR0B = (1 << CS02); /* Initialize SPI Interfaces configure Direction of SS / PB0 , MOSI and SCLK as Output */ @@ -242,9 +247,9 @@ void EVENT_USB_Device_Disconnect(void) /** Event handler for the library USB Configuration Changed event. */ void EVENT_USB_Device_ConfigurationChanged(void) { - bool ConfigSuccess = true; + bool ConfigSuccess = true; - ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); + ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); led_toggle(); _delay_ms(10); @@ -254,7 +259,7 @@ void EVENT_USB_Device_ConfigurationChanged(void) /** Event handler for the library USB Control Request reception event. */ void EVENT_USB_Device_ControlRequest(void) { - CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); + CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); } /** Event handler for the CDC Class driver Line Encoding Changed event. -- cgit v1.2.3