Example #1
0
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
	  return 0;

	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);

	if (Endpoint_IsOUTReceived())
	{
		if (!(Endpoint_BytesInEndpoint()))
		{
			Endpoint_ClearOUT();
			return 0;
		}
		else
		{
			return Endpoint_BytesInEndpoint();
		}
	}
	else
	{
		return 0;
	}
}
uint8_t TEMPLATE_FUNC_NAME (void* const Buffer,
                            uint16_t Length)
{
	uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));

	Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN);

	if (!(Length))
	  Endpoint_ClearOUT();

	while (Length)
	{
		uint8_t USB_DeviceState_LCL = USB_DeviceState;

		if (USB_DeviceState_LCL == DEVICE_STATE_Unattached)
		  return ENDPOINT_RWCSTREAM_DeviceDisconnected;
		else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended)
		  return ENDPOINT_RWCSTREAM_BusSuspended;
		else if (Endpoint_IsSETUPReceived())
		  return ENDPOINT_RWCSTREAM_HostAborted;

		if (Endpoint_IsOUTReceived())
		{
			while (Length && Endpoint_BytesInEndpoint())
			{
				TEMPLATE_TRANSFER_BYTE(DataStream);
				TEMPLATE_BUFFER_MOVE(DataStream, 1);
				Length--;
			}

			Endpoint_ClearOUT();
		}
	}

	while (!(Endpoint_IsINReady()))
	{
		uint8_t USB_DeviceState_LCL = USB_DeviceState;

		if (USB_DeviceState_LCL == DEVICE_STATE_Unattached)
		  return ENDPOINT_RWCSTREAM_DeviceDisconnected;
		else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended)
		  return ENDPOINT_RWCSTREAM_BusSuspended;
	}

	return ENDPOINT_RWCSTREAM_NoError;
}
Example #3
0
/** Handler for unknown V2 protocol commands. This discards all sent data and returns a
 *  STATUS_CMD_UNKNOWN status back to the host.
 *
 *  \param[in] V2Command  Issued V2 Protocol command byte from the host
 */
static void V2Protocol_UnknownCommand(const uint8_t V2Command)
{
	/* Discard all incoming data */
	while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
	{
		Endpoint_ClearOUT();
		Endpoint_WaitUntilReady();
	}

	Endpoint_ClearOUT();
	Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

	Endpoint_Write_Byte(V2Command);
	Endpoint_Write_Byte(STATUS_CMD_UNKNOWN);
	Endpoint_ClearIN();
}
Example #4
0
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;

	uint8_t ErrorCode;

	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);

	if (Endpoint_BytesInEndpoint())
	{
		Endpoint_ClearIN();

		if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
		  return ErrorCode;
	}

	return ENDPOINT_READYWAIT_NoError;
}
Example #5
0
int USBSerial::readRXEndpoint(void)
{
        Endpoint_SelectEndpoint(CDC_RX_EPADDR);
        
        if (Endpoint_IsOUTReceived()) {
                if (Endpoint_BytesInEndpoint()) {
                        return (unsigned char)Endpoint_Read_8();
                } else {
                        Endpoint_ClearOUT();
                        __asm__("nop\n\t""nop\n\t");
                        __asm__("nop\n\t""nop\n\t");
                        if (Endpoint_IsOUTReceived()) {
                                return (unsigned char)Endpoint_Read_8();
                        }
                }
        }
        
        return -1;
}
uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
	uint8_t status = 0;
	if ((USB_DeviceState == DEVICE_STATE_Configured) &&	(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS != 0))
	{
		Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);

		if (Endpoint_BytesInEndpoint())
		{
			Endpoint_ClearIN();
		}

		status = ENDPOINT_READYWAIT_NoError;
	}
	else
	{
		status = ENDPOINT_RWSTREAM_DeviceDisconnected;
	}

	return status;
}
Example #7
0
uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
	
	while (Length)
	{
		while (!(Endpoint_IsSetupOUTReceived()));
		
		while (Length && Endpoint_BytesInEndpoint())
		{
			*(DataStream--) = Endpoint_Read_Byte();
			
			Length--;
		}
		
		Endpoint_ClearSetupOUT();
	}
	
	while (!(Endpoint_IsSetupINReady()));

	return ENDPOINT_RWCSTREAM_ERROR_NoError;
}
Example #8
0
uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
{
	uint8_t* DataStream = (uint8_t*)Buffer;
	
	while (Length)
	{
		if (Endpoint_IsOUTReceived())
		{
			while (Length && Endpoint_BytesInEndpoint())
			{
				*(DataStream++) = Endpoint_Read_Byte();
				Length--;
			}
			
			Endpoint_ClearOUT();
		}
	}
	
	while (!(Endpoint_IsINReady()));
	
	return ENDPOINT_RWCSTREAM_NoError;
}
int16_t CDC_Device_ReceiveByte(
						USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
{
	int16_t Rx_bytes = -1;
	if ((USB_DeviceState == DEVICE_STATE_Configured) &&	(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS != 0))
	{
		Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address);

		if (Endpoint_IsOUTReceived())
		{
			if (Endpoint_BytesInEndpoint())
			{
				Rx_bytes = Endpoint_Read_8();
			}
			else
			{
				Endpoint_ClearOUT();
			}

		}

	}
	return Rx_bytes;
}
Example #10
0
static bool
USB_BulkWorker()
{
    uint8_t cmdBuf[XUM_CMDBUF_SIZE], statusBuf[XUM_STATUSBUF_SIZE];
    int8_t status;

    /*
     * If we are not connected to the host or a command has not yet
     * been sent, no more processing is required.
     */
    if (USB_DeviceState != DEVICE_STATE_Configured)
        return false;
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    if (!Endpoint_IsReadWriteAllowed())
        return false;

#ifdef DEBUG
    // Dump the status of both endpoints before getting the command
    Endpoint_SelectEndpoint(XUM_BULK_IN_ENDPOINT);
    DEBUGF(DBG_INFO, "bsti %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
    Endpoint_SelectEndpoint(XUM_BULK_OUT_ENDPOINT);
    DEBUGF(DBG_INFO, "bsto %x %x %x %x %x %x %x %x\n",
        Endpoint_GetCurrentEndpoint(),
        Endpoint_BytesInEndpoint(), Endpoint_IsEnabled(),
        Endpoint_IsReadWriteAllowed(), Endpoint_IsConfigured(),
        Endpoint_IsINReady(), Endpoint_IsOUTReceived(), Endpoint_IsStalled());
#endif

    // Read in the command from the host now that one is ready.
    if (!USB_ReadBlock(cmdBuf, sizeof(cmdBuf))) {
        board_set_status(STATUS_ERROR);
        return false;
    }

    // Allow commands to leave the extended status untouched
    memset(statusBuf, 0, sizeof(statusBuf));

    /*
     * Decode and process the command.
     * usbHandleBulk() stores its extended result in the output buffer,
     * up to XUM_STATUSBUF_SIZE.
     *
     * Return values:
     *   >0: completed ok, send the return value and extended status
     *    0: completed ok, don't send any status
     *   -1: error, no status
     */
    status = usbHandleBulk(cmdBuf, statusBuf);
    if (status > 0) {
        statusBuf[0] = status;
        USB_WriteBlock(statusBuf, sizeof(statusBuf));
    } else if (status < 0) {
        DEBUGF(DBG_ERROR, "usbblk err\n");
        board_set_status(STATUS_ERROR);
        Endpoint_StallTransaction();
        return false;
    }

    return true;
}
Example #11
0
uint8_t Endpoint_Discard_Stream(uint16_t Length
#if !defined(NO_STREAM_CALLBACKS)
                                , StreamCallbackPtr_t Callback
#endif
								)
{
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

	#if defined(FAST_STREAM_TRANSFERS)
	uint8_t BytesRemToAlignment = (Endpoint_BytesInEndpoint() & 0x07);

	if (Length >= 8)
	{
		Length -= BytesRemToAlignment;

		switch (BytesRemToAlignment)
		{
			default:
				do
				{
					if (!(Endpoint_IsReadWriteAllowed()))
					{
						Endpoint_ClearOUT();

						#if !defined(NO_STREAM_CALLBACKS)
						if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
						  return ENDPOINT_RWSTREAM_CallbackAborted;
						#endif

						if ((ErrorCode = Endpoint_WaitUntilReady()))
						  return ErrorCode;
					}

					Length -= 8;
					
					Endpoint_Discard_Byte();
			case 7: Endpoint_Discard_Byte();
			case 6: Endpoint_Discard_Byte();
			case 5: Endpoint_Discard_Byte();
			case 4: Endpoint_Discard_Byte();
			case 3: Endpoint_Discard_Byte();
			case 2: Endpoint_Discard_Byte();
			case 1:	Endpoint_Discard_Byte();
				} while (Length >= 8);	
		}
	}
	#endif

	while (Length)
	{
		if (!(Endpoint_IsReadWriteAllowed()))
		{
			Endpoint_ClearOUT();

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_CallbackAborted;
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			Endpoint_Discard_Byte();
			Length--;
		}
	}
	
	return ENDPOINT_RWSTREAM_NoError;
}
Example #12
0
/** Task to handle the generation of MIDI note change events in response to presses of the board joystick, and send them
 *  to the host.
 */
void MIDI_Task(void)
{
	static uint8_t PrevJoystickStatus;

	/* Device must be connected and configured for the task to run */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);

	if (Endpoint_IsINReady())
	{
		uint8_t MIDICommand = 0;
		uint8_t MIDIPitch;

		uint8_t JoystickStatus  = Joystick_GetStatus();
		uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);

		/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
		uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));

		if (JoystickChanges & JOY_LEFT)
		{
			MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
			MIDIPitch   = 0x3C;
		}

		if (JoystickChanges & JOY_UP)
		{
			MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
			MIDIPitch   = 0x3D;
		}

		if (JoystickChanges & JOY_RIGHT)
		{
			MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
			MIDIPitch   = 0x3E;
		}

		if (JoystickChanges & JOY_DOWN)
		{
			MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
			MIDIPitch   = 0x3F;
		}

		if (JoystickChanges & JOY_PRESS)
		{
			MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
			MIDIPitch   = 0x3B;
		}

		/* Check if a MIDI command is to be sent */
		if (MIDICommand)
		{
			MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
				{
					.Event       = MIDI_EVENT(0, MIDICommand),

					.Data1       = MIDICommand | Channel,
					.Data2       = MIDIPitch,
					.Data3       = MIDI_STANDARD_VELOCITY,
				};

			/* Write the MIDI event packet to the endpoint */
			Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);

			/* Send the data in the endpoint to the host */
			Endpoint_ClearIN();
		}

		/* Save previous joystick value for next joystick change detection */
		PrevJoystickStatus = JoystickStatus;
	}

	/* Select the MIDI OUT stream */
	Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);

	/* Check if a MIDI command has been received */
	if (Endpoint_IsOUTReceived())
	{
		MIDI_EventPacket_t MIDIEvent;

		/* Read the MIDI event packet from the endpoint */
		Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);

		/* Check to see if the sent command is a note on message with a non-zero velocity */
		if ((MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && (MIDIEvent.Data3 > 0))
		{
			/* Change LEDs depending on the pitch of the sent note */
			LEDs_SetAllLEDs(MIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2);
		}
		else
		{
			/* Turn off all LEDs in response to non Note On messages */
			LEDs_SetAllLEDs(LEDS_NO_LEDS);
		}

		/* If the endpoint is now empty, clear the bank */
		if (!(Endpoint_BytesInEndpoint()))
		{
			/* Clear the endpoint ready for new packet */
			Endpoint_ClearOUT();
		}
	}
}
Example #13
0
void OnyxWalker_Task(void) {

    unsigned short now = MY_GetTicks();
    if (now < lastTicks) {
        ++numWraps;
        LCD_DrawUint(numWraps, WIDTH-7, 3);
    }
    if (now - lastVolts > 15000) {
        lastVolts = now;
        ++voltBlink;
        if ((power_cvolts > 1320 && !power_failure) || (voltBlink & 1)) {
            LCD_DrawFrac(power_cvolts, 2, 0, 3);
            LCD_DrawChar(' ', 6, 3);
            LCD_DrawChar('V', 7, 3);
            PORTC &= ~(1 << 6);
        }
        else {
            LCD_DrawChar(' ', 0, 3);
            for (unsigned char i = 1; i != 8; ++i) {
                LCD_DrawChar('-', i, 3);
            }
            if (!(voltBlink & 15) && power_cvolts > 0) {
                PORTC |= (1 << 6);
            }
            else {
                PORTC &= ~(1 << 6);
            }
        }
    }
    lastTicks = now;
    LCD_Flush();
    if (lastTicks - last_cvolts > 10000) {
        power_tick();
        last_cvolts = lastTicks;
    }

    if (USB_DeviceState != DEVICE_STATE_Configured) {
        return;
    }

    /* see if host has requested data */
    Endpoint_SelectEndpoint(DATA_RX_EPNUM);
    Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
    epic = Endpoint_IsConfigured();
    epiir = epic && Endpoint_IsINReady();
    epirwa = epiir && Endpoint_IsReadWriteAllowed();
    if (epirwa && (in_packet_ptr || (now - last_flush > FLUSH_TICK_INTERVAL))) {
        last_flush = now;
        if (in_packet_ptr == 0) {
            in_packet_ptr = 1;  //  repeat the last received serial
        }
        //  send packet in
        for (unsigned char ch = 0; ch < in_packet_ptr; ++ch) {
            Endpoint_Write_8(in_packet[ch]);
        }
        Endpoint_ClearIN();
        in_packet_ptr = 0;
    }

    /* see if there's data from the host */
    Endpoint_SelectEndpoint(DATA_TX_EPNUM);
    Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
    MY_SetLed(LED_act, false);
    if (Endpoint_IsConfigured() && 
        Endpoint_IsOUTReceived() && 
        Endpoint_IsReadWriteAllowed()) {
        uint8_t n = Endpoint_BytesInEndpoint();
        if (n > sizeof(out_packet)) {
            MY_Failure("OUT too big", n, sizeof(out_packet));
        }
        out_packet_ptr = 0;
        MY_SetLed(LED_act, true);
        while (n > 0) {
            epic = Endpoint_Read_8();
            out_packet[out_packet_ptr++] = epic;
            --n;
        }
        Endpoint_ClearOUT();
        dispatch_out();
    }
}
Example #14
0
/** Function to manage CDC data transmission and reception to and from the host. */
void CDC_Task(void)
{
	char*       ReportString    = NULL;
	static bool ActionSent      = false;

	/* 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:
	 */
	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

	Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
	Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
	Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
	Endpoint_ClearIN();
#endif

	/* Determine if a joystick action has occurred 
	if (JoyStatus_LCL & JOY_UP)
	  ReportString = "Joystick Up\r\n";
	else if (JoyStatus_LCL & JOY_DOWN)
	  ReportString = "Joystick Down\r\n";
	else if (JoyStatus_LCL & JOY_LEFT)
	  ReportString = "Joystick Left\r\n";
	else if (JoyStatus_LCL & JOY_RIGHT)
	  ReportString = "Joystick Right\r\n";
	else if (JoyStatus_LCL & JOY_PRESS)
	  ReportString = "Joystick Pressed\r\n";
	else */
	  ActionSent = false;

	/* Flag management - Only allow one string to be sent per action */
	if ((ReportString != NULL) && (ActionSent == false) && sport.BaudRateBPS)
	{
		ActionSent = true;

		/* Select the Serial Tx Endpoint */
		Endpoint_SelectEndpoint(CDC_TX_EPNUM);

		/* Write the String to the Endpoint */
		Endpoint_Write_Stream_LE(ReportString, strlen(ReportString), NULL);

		/* Remember if the packet to send completely fills the endpoint */
		bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);

		/* Finalize the stream transfer to send the last packet */
		Endpoint_ClearIN();

		/* If 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)
		{
			/* Wait until the endpoint is ready for another packet */
			Endpoint_WaitUntilReady();

			/* Send an empty packet to ensure that the host does not buffer data sent to it */
			Endpoint_ClearIN();
		}
	}

	/* Select the Serial Rx Endpoint */
	Endpoint_SelectEndpoint(CDC_RX_EPNUM);

	/* Throw away any received data from the host */
	if (Endpoint_IsOUTReceived())
	  Endpoint_ClearOUT();
}
/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */
void CDC_Task(void)
{
	/* 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:
	*/

	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
	
	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())
	{
		/* 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();
		}
	}
	
	/* 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);

	/* 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();

		/* 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 */
			Endpoint_WaitUntilReady();
				
			/* Send an empty packet to terminate the transfer */
			Endpoint_ClearIN();
		}
	}
}

/** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received
 *  character into the Tx_Buffer circular buffer for later transmission to the host.
 */
ISR(USART1_RX_vect, ISR_BLOCK)
{
	uint8_t ReceivedByte = UDR1;
	
	/* Only store received characters if the USB interface is connected */
	if ((USB_DeviceState == DEVICE_STATE_Configured)) {// && LineEncoding.BaudRateBPS
	  Buffer_StoreElement(&Tx_Buffer, ReceivedByte);
	}
}
uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE Buffer,
                            uint16_t Length
                            __CALLBACK_PARAM)
{
	uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length));
	uint8_t  ErrorCode;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;

	#if defined(FAST_STREAM_TRANSFERS)
	uint8_t BytesRemToAlignment = (Endpoint_BytesInEndpoint() & 0x07);

	if (Length >= 8)
	{
		Length -= BytesRemToAlignment;

		switch (BytesRemToAlignment)
		{
			default:
				do
				{
					if (!(Endpoint_IsReadWriteAllowed()))
					{
						TEMPLATE_CLEAR_ENDPOINT();

						#if !defined(NO_STREAM_CALLBACKS)
						if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
						  return ENDPOINT_RWSTREAM_CallbackAborted;
						#endif

						if ((ErrorCode = Endpoint_WaitUntilReady()))
						  return ErrorCode;
					}

					Length -= 8;
					
					TEMPLATE_TRANSFER_BYTE(DataStream);
			case 7: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 6: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 5: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 4: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 3: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 2: TEMPLATE_TRANSFER_BYTE(DataStream);
			case 1:	TEMPLATE_TRANSFER_BYTE(DataStream);
				} while (Length >= 8);	
		}
	}
	#endif

	while (Length)
	{
		if (!(Endpoint_IsReadWriteAllowed()))
		{
			TEMPLATE_CLEAR_ENDPOINT();

			#if !defined(NO_STREAM_CALLBACKS)
			if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort))
			  return ENDPOINT_RWSTREAM_CallbackAborted;
			#endif

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			TEMPLATE_TRANSFER_BYTE(DataStream);
			Length--;
		}
	}

	return ENDPOINT_RWSTREAM_NoError;
}
Example #17
0
////////////////////
// Fill data from USB to the RingBuffer and vice-versa
void
CDC_Task(void)
{
  static char inCDC_TASK = 0;

  if(!USB_IsConnected)
    return;

#ifdef ARM

  if(!inCDC_TASK){ // USB -> RingBuffer

    inCDC_TASK = 1;
    output_flush_func = CDC_Task;
    input_handle_func(DISPLAY_USB);
    inCDC_TASK = 0;
  }

	if(TTY_Tx_Buffer.nbytes) {
		uint16_t i=0;

		while(TTY_Tx_Buffer.nbytes && i<DATABUFFERSIZEOUT) {

			 usbBufferOut[i++]=rb_get(&TTY_Tx_Buffer);
		}

		while (CDCDSerialDriver_Write(usbBufferOut,i, 0, 0) != USBD_STATUS_SUCCESS);

	}


#else
  Endpoint_SelectEndpoint(CDC_RX_EPNUM);          // First data in

  if(!inCDC_TASK && Endpoint_ReadWriteAllowed()){ // USB -> RingBuffer

    while (Endpoint_BytesInEndpoint()) {          // Discard data on buffer full
      rb_put(&TTY_Rx_Buffer, Endpoint_Read_Byte());
    }
    Endpoint_ClearCurrentBank(); 
    inCDC_TASK = 1;
    output_flush_func = CDC_Task;
    input_handle_func(DISPLAY_USB);
    inCDC_TASK = 0;
  }


  Endpoint_SelectEndpoint(CDC_TX_EPNUM);          // Then data out
  if(TTY_Tx_Buffer.nbytes && Endpoint_ReadWriteAllowed()) {

    cli();
    while(TTY_Tx_Buffer.nbytes &&
          (Endpoint_BytesInEndpoint() < USB_BUFSIZE))
      Endpoint_Write_Byte(rb_get(&TTY_Tx_Buffer));
    sei();
    
    Endpoint_ClearCurrentBank();                  // Send the data

  }
#endif
}