Example #1
0
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
                                    const MIDI_EventPacket_t* const Event)
{
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;

	uint8_t ErrorCode;

	Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);

	if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError)
	  return ErrorCode;

	if (!(Endpoint_IsReadWriteAllowed()))
	  Endpoint_ClearIN();

	return ENDPOINT_RWSTREAM_NoError;
}
void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
{
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);

	if (Endpoint_IsReadWriteAllowed())
	{
		if (MS_Device_ReadInCommandBlock(MSInterfaceInfo))
		{
			if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN)
			  Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);

			bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo);

			MSInterfaceInfo->State.CommandStatus.Status              = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail;
			MSInterfaceInfo->State.CommandStatus.Signature           = CPU_TO_LE32(MS_CSW_SIGNATURE);
			MSInterfaceInfo->State.CommandStatus.Tag                 = MSInterfaceInfo->State.CommandBlock.Tag;
			MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength;

			if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue)))
			  Endpoint_StallTransaction();

			MS_Device_ReturnCommandStatus(MSInterfaceInfo);
		}
	}

	if (MSInterfaceInfo->State.IsMassStoreReset)
	{
		Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
		Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);

		Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpointNumber);
		Endpoint_ClearStall();
		Endpoint_ResetDataToggle();
		Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpointNumber);
		Endpoint_ClearStall();
		Endpoint_ResetDataToggle();

		MSInterfaceInfo->State.IsMassStoreReset = false;
	}
}
Example #3
0
/** Reads data from the host */
void ReceiveDataFromHost(void)
{
	/* Select the OUT Endpoint */
	Endpoint_SelectEndpoint(OUT_EP);

	/* Check if the OUT EP contains a packet */
	if (Endpoint_IsOUTReceived())
	{
		/* Check to see if the packet contains data */
		if (Endpoint_IsReadWriteAllowed())
		{
			/* Read in data from the host */
			Endpoint_Read_Stream_LE(&dataReceived, sizeof(dataReceived));
		}

		/* Handshake the OUT Endpoint - clear endpoint and get ready for next transfer */
		Endpoint_ClearOUT();
	}
}
Example #4
0
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, const uint8_t Data)
{
	if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;

	Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpointNumber);

	if (!(Endpoint_IsReadWriteAllowed()))
	{	
		Endpoint_ClearIN();

		uint8_t ErrorCode;

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

	Endpoint_Write_Byte(Data);
	return ENDPOINT_READYWAIT_NoError;
}
Example #5
0
/** Mouse task. This generates the next mouse HID report for the host, and transmits it via the
 *  mouse IN endpoint when the host is ready for more data.
 */
void Mouse_HID_Task(void)
{
	uint8_t JoyStatus_LCL = Joystick_GetStatus();

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

	/* Check if board button is pressed, if so mouse mode enabled */
	if (Buttons_GetStatus() & BUTTONS_BUTTON1)
	{
		if (JoyStatus_LCL & JOY_UP)
		  MouseReportData.Y =  1;
		else if (JoyStatus_LCL & JOY_DOWN)
		  MouseReportData.Y = -1;

		if (JoyStatus_LCL & JOY_RIGHT)
		  MouseReportData.X =  1;
		else if (JoyStatus_LCL & JOY_LEFT)
		  MouseReportData.X = -1;

		if (JoyStatus_LCL & JOY_PRESS)
		  MouseReportData.Button  = (1 << 0);
	}

	/* Select the Mouse Report Endpoint */
	Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);

	/* Check if Mouse Endpoint Ready for Read/Write */
	if (Endpoint_IsReadWriteAllowed())
	{
		/* Write Mouse Report Data */
		Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData));

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

		/* Clear the report data afterwards */
		memset(&MouseReportData, 0, sizeof(MouseReportData));
	}
}
Example #6
0
uint8_t PRNT_Device_SendByte(USB_ClassInfo_PRNT_Device_t* const PRNTInterfaceInfo,
                             const uint8_t Data)
{
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return ENDPOINT_RWSTREAM_DeviceDisconnected;

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

	if (!(Endpoint_IsReadWriteAllowed()))
	{
		Endpoint_ClearIN();

		uint8_t ErrorCode;

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

	Endpoint_Write_8(Data);
	return ENDPOINT_READYWAIT_NoError;
}
Example #7
0
static void tx_task(void)
{
	if (USB_DeviceState != DEVICE_STATE_Configured)
		return;

	Endpoint_SelectEndpoint(OUT_EPADDR);
	if (Endpoint_IsOUTReceived() && csma_tx_allowed() && spi_tx_prepare()) {
		if (Endpoint_IsReadWriteAllowed()) {
			if (!(data[front].flags & FLAG_TX_READY)) {
				Endpoint_Read_Stream_LE(&data[front], sizeof(data[front]), NULL);
				data[front].flags |= FLAG_TX_READY;
				adf_set_tx_mode();
				spi_tx_start();
			} else {
				Endpoint_Read_Stream_LE(&data[back], sizeof(data[back]), NULL);
				data[back].flags |= FLAG_TX_READY;
			}
			Endpoint_ClearOUT();
		}
	}
}
Example #8
0
void USBSerial::flush()
{
	uint8_t prevEndpoint = Endpoint_GetCurrentEndpoint();
	
	Endpoint_SelectEndpoint(CDC_TX_EPADDR);
	bool IsFull = !Endpoint_IsReadWriteAllowed();
	Endpoint_ClearIN();
	
	/* Send an empty packet to ensure that the host does not buffer data sent to it */
	if (IsFull) {
		while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) {
			USB_USBTask();
		}
		Endpoint_ClearIN();
	}
	//Endpoint_WaitUntilReady();
	while (!Endpoint_IsINReady() && USB_DeviceState == DEVICE_STATE_Configured) {
		USB_USBTask();
	}
	
	Endpoint_SelectEndpoint(prevEndpoint);
}
Example #9
0
void usb_keyboard_press(uint8_t key, uint8_t modifier)
{
	USB_KeyboardReport_Data_t        KeyboardReportData;

	// setup keyboard report data
	memset(&KeyboardReportData, 0, sizeof(USB_KeyboardReport_Data_t));

	// modifier
	KeyboardReportData.Modifier = modifier;
	KeyboardReportData.KeyCode[0] = key;

	Endpoint_SelectEndpoint(KEYBOARD_IN_EPADDR);

	if ( Endpoint_IsReadWriteAllowed() )
	{
		Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData), NULL);
		Endpoint_ClearIN();		
	}

	_delay_ms(200);

}
Example #10
0
uint8_t Endpoint_Null_Stream(uint16_t Length,
                             uint16_t* const BytesProcessed)
{
	uint8_t  ErrorCode;
	uint16_t BytesInTransfer = 0;
	
	if ((ErrorCode = Endpoint_WaitUntilReady()))
	  return ErrorCode;
	  
	if (BytesProcessed != NULL)
	  Length -= *BytesProcessed;

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

			if (BytesProcessed != NULL)
			{
				*BytesProcessed += BytesInTransfer;
				return ENDPOINT_RWSTREAM_IncompleteTransfer;
			}

			if ((ErrorCode = Endpoint_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
			Endpoint_Write_8(0);

			Length--;
			BytesInTransfer++;
		}
	}
	
	return ENDPOINT_RWSTREAM_NoError;
}
Example #11
0
/** Task to manage the Audio interface, reading in ADC samples from the microphone, and them to the host. */
void USB_Audio_Task(void)
{
	/* Device must be connected and configured for the task to run */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	/* Check to see if the streaming interface is selected, if not the host is not receiving audio */
	if (!(StreamingAudioInterfaceSelected))
	  return;

	/* Select the audio stream endpoint */
	Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
	
	/* Check if the current endpoint can be written to and that the next sample should be stored */
	if (Endpoint_IsINReady() && (TIFR0 & (1 << OCF0A)))
	{
		/* Clear the sample reload timer */
		TIFR0 |= (1 << OCF0A);

		/* Audio sample is ADC value scaled to fit the entire range */
		int16_t AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult());
		
		#if defined(MICROPHONE_BIASED_TO_HALF_RAIL)
		/* Microphone is biased to half rail voltage, subtract the bias from the sample value */
		AudioSample -= (SAMPLE_MAX_RANGE / 2);
		#endif

		/* Write the sample to the buffer */
		Endpoint_Write_Word_LE(AudioSample);

		/* Check to see if the bank is now full */
		if (!(Endpoint_IsReadWriteAllowed()))
		{
			/* Send the full packet to the host */
			Endpoint_ClearIN();
		}
	}
}
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 #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
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 #15
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;
}
void hidTask(void)
{
    // Only process HID tasks if the device is configured and ready
    if (USB_DeviceState != DEVICE_STATE_Configured)
        return;

    // GenericHID -------------------------------------------------------------

    // Select the OUT end-point
    Endpoint_SelectEndpoint(GENERIC_OUT_EPADDR);

    // Check to see if a packet has been sent from the host and we have nothing waiting to send
    if (Endpoint_IsOUTReceived() && waitingToSend == 0)
    {
#ifdef USART_DEBUG
        printf("Packet received on OUT End-point\r\n");
#endif

        // Check to see if the end-point is ready for reading
        if (Endpoint_IsReadWriteAllowed())
        {
            // Read the report data from the control end-point
            Endpoint_Read_Stream_LE(&hidReceiveBuffer, sizeof(hidReceiveBuffer), NULL);

#ifdef USART_DEBUG
            uint8_t counter;
            printf("Dumping hex from OUT End-point (from host)\r\n");

            for (counter = 0; counter < GENERIC_EPSIZE; counter++)
            {
                printf("%02x ", hidReceiveBuffer[counter]);
                if (!((counter+1) % 8)) printf("\r\n");
            }
            printf("\r\n");
#endif

            // Process GenericHID packet header
            switch(hidReceiveBuffer[0])
            {
            // Command group 0x01: System command group
            case RPF_COMMANDGROUP_SYSTEM:
#ifdef USART_DEBUG
                printf("Command group 0x01: System command group\r\n");
#endif
                waitingToSend = systemCommandGroup(hidReceiveBuffer, hidSendBuffer);
                break;

            // Command group 0x02: Input/output command group
            case RPF_COMMANDGROUP_IO:
#ifdef USART_DEBUG
                printf("Command group 0x02: Input/output command group\r\n");
#endif
                break;

            // Command group 0x03: ADC command group
            case RPF_COMMANDGROUP_ADC:
#ifdef USART_DEBUG
                printf("Command group 0x03: ADC command group\r\n");
#endif
                break;

            // Command group 0x04: User defined command group
            case RPF_COMMANDGROUP_USER:
#ifdef USART_DEBUG
                printf("Command group 0x04: User defined command group\r\n");
#endif
                break;

            // Command group 0x05: PWM command group
            case RPF_COMMANDGROUP_PWM:
#ifdef USART_DEBUG
                printf("Command group 0x05: PWM command group\r\n");
#endif
                break;

            // Command group 0x06: SPI command group
            case RPF_COMMANDGROUP_SPI:
#ifdef USART_DEBUG
                printf("Command group 0x06: SPI command group\r\n");
#endif
                break;

            // Command group 0x07: I2C command group
            case RPF_COMMANDGROUP_I2C:
#ifdef USART_DEBUG
                printf("Command group 0x07: I2C command group\r\n");
#endif
                break;

            // Command group 0x08: USART command group
            case RPF_COMMANDGROUP_USART:
#ifdef USART_DEBUG
                printf("Command group 0x08: USART command group\r\n");
#endif
                break;

            default:
#ifdef USART_DEBUG
                printf("Host requested non-existent command group %d\r\n", hidReceiveBuffer[0]);
#endif
                break;
            }
        }

        // Finalize the stream transfer to send the last packet
        Endpoint_ClearOUT();
    }

    // Select the IN end-point
    Endpoint_SelectEndpoint(GENERIC_IN_EPADDR);

    // Check to see if the host is ready to accept another packet and that we have one to send
    if (Endpoint_IsINReady() && waitingToSend == 1)
    {
#ifdef USART_DEBUG
        printf("Sending packet on IN End-point\r\n");
#endif

        // Write Generic Report Data
        Endpoint_Write_Stream_LE(&hidSendBuffer, sizeof(hidSendBuffer), NULL);

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

        // Clear the waiting to send flag
        waitingToSend = 0;

        // Turn on the Tx activity indicator
        activityIndicatorTx = 1;

#ifdef USART_DEBUG
        uint8_t counter;
        printf("Dumping hex from IN End-point (to host)\r\n");

        for (counter = 0; counter < GENERIC_EPSIZE; counter++)
        {
            printf("%02x ", hidSendBuffer[counter]);
            if (!((counter+1) % 8)) printf("\r\n");
        }
        printf("\r\n");
#endif
    }

    // Joystick ---------------------------------------------------------------

    // Select the Joystick Report End-point
    Endpoint_SelectEndpoint(JOYSTICK_EPADDR);

    // Check to see if the host is ready for another joystick packet
    if (Endpoint_IsINReady())
    {
        USB_JoystickReport_Data_t joystickReportData;

        // Create the next HID report to send to the host
        generateJoystickReport(&joystickReportData);

        // Write Joystick Report Data
        Endpoint_Write_Stream_LE(&joystickReportData, sizeof(joystickReportData), NULL);

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

        // Clear the report data afterwards */
        memset(&joystickReportData, 0, sizeof(joystickReportData));
    }
}
Example #17
0
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
 *  and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual
 *  reading and writing of the data.
 *
 *  \param[in] MSInterfaceInfo  Pointer to the Mass Storage class interface structure that the command is associated with
 *  \param[in] IsDataRead  Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
 *
 *  \return Boolean true if the command completed successfully, false otherwise.
 */
static bool SCSI_Command_ReadWrite_10 (USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const bool IsDataRead)
{
	uint32_t BlockAddress;
	uint16_t TotalBlocks;
	//uint8_t buffer[VIRTUAL_MEMORY_BLOCK_SIZE];

	/* Check if the disk is write protected or not */
	if ((IsDataRead == DATA_WRITE) && DISK_READ_ONLY)
	{
		/* Block address is invalid, update SENSE key and return command fail */
		SCSI_SET_SENSE(SCSI_SENSE_KEY_DATA_PROTECT, SCSI_ASENSE_WRITE_PROTECTED, SCSI_ASENSEQ_NO_QUALIFIER);

		return false;
	}

	/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
	//BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
	BlockAddress = (MSInterfaceInfo->State.CommandBlock.SCSICommandData[2] << 24) + (MSInterfaceInfo->State.CommandBlock.SCSICommandData[3] << 16) + (MSInterfaceInfo->State.CommandBlock.SCSICommandData[4] << 8) + MSInterfaceInfo->State.CommandBlock.SCSICommandData[5];

	/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
	//TotalBlocks  = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
	TotalBlocks = (MSInterfaceInfo->State.CommandBlock.SCSICommandData[7] << 8) + MSInterfaceInfo->State.CommandBlock.SCSICommandData[8];

	/* Check if the block address is outside the maximum allowable value for the LUN */
	if (BlockAddress >= LUN_MEDIA_BLOCKS)
	{
		/* Block address is invalid, update SENSE key and return command fail */
		SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, SCSI_ASENSEQ_NO_QUALIFIER);

		return false;
	}

#if (TOTAL_LUNS > 1)
	/* Adjust the given block address to the real media address based on the selected LUN */
	BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS);
#endif
	
	/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
#if 0
	if (IsDataRead == DATA_READ)
	{
		int i;
		for(i=0;i<TotalBlocks;i++)
		{
			while(!Endpoint_IsReadWriteAllowed());
			MassStorage_Read(((BlockAddress+i)*VIRTUAL_MEMORY_BLOCK_SIZE), buffer, VIRTUAL_MEMORY_BLOCK_SIZE);
			Endpoint_Write_Stream_LE(buffer, VIRTUAL_MEMORY_BLOCK_SIZE,NULL);
			Endpoint_ClearIN();
		}
	}
	else
	{
		int i;
		for(i=0;i<TotalBlocks;i++)
		{
			while(!Endpoint_IsReadWriteAllowed());
			Endpoint_Read_Stream_LE(buffer,VIRTUAL_MEMORY_BLOCK_SIZE,NULL);
			Endpoint_ClearOUT();
			MassStorage_Write((BlockAddress+i)*VIRTUAL_MEMORY_BLOCK_SIZE,buffer, VIRTUAL_MEMORY_BLOCK_SIZE);
		}
	}
#else
	uint32_t startaddr;
	uint16_t blocks, dummyblocks;

	startaddr = MassStorage_GetAddressInImage(BlockAddress, TotalBlocks, &blocks);
	if (blocks == 0)
		dummyblocks = TotalBlocks;
	else if (blocks < TotalBlocks)
		dummyblocks = TotalBlocks - blocks;
	else
		dummyblocks = 0;
	Endpoint_Streaming((uint8_t*) startaddr, VIRTUAL_MEMORY_BLOCK_SIZE, blocks, dummyblocks);
#endif
	/* Update the bytes transferred counter and succeed the command */
	MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t) TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);

	return true;
}
/** 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);
	}
}
Example #19
0
/** Task to manage the Mass Storage interface, reading in Command Block Wrappers from the host, processing the SCSI commands they
 *  contain, and returning Command Status Wrappers back to the host to indicate the success or failure of the last issued command.
 */
void MassStorage_Task(void)
{
	/* Device must be connected and configured for the task to run */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;
	  
	/* Select the Data Out Endpoint */
	Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
	
	/* Check to see if a command from the host has been issued */
	if (Endpoint_IsReadWriteAllowed())
	{
		/* Indicate busy */
		LEDs_SetAllLEDs(LEDMASK_USB_BUSY);

		/* Process sent command block from the host */
		if (ReadInCommandBlock())
		{
			/* Check direction of command, select Data IN endpoint if data is from the device */
			if (CommandBlock.Flags & COMMAND_DIRECTION_DATA_IN)
			  Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);

			/* Decode the received SCSI command, set returned status code */
			CommandStatus.Status = SCSI_DecodeSCSICommand() ? Command_Pass : Command_Fail;		

			/* Load in the CBW tag into the CSW to link them together */
			CommandStatus.Tag = CommandBlock.Tag;

			/* Load in the data residue counter into the CSW */
			CommandStatus.DataTransferResidue = CommandBlock.DataTransferLength;
			
			/* Stall the selected data pipe if command failed (if data is still to be transferred) */
			if ((CommandStatus.Status == Command_Fail) && (CommandStatus.DataTransferResidue))
			  Endpoint_StallTransaction();

			/* Return command status block to the host */
			ReturnCommandStatus();

			/* Indicate ready */
			LEDs_SetAllLEDs(LEDMASK_USB_READY);
		}
		else
		{
			/* Indicate error reading in the command block from the host */
			LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
		}
	}

	/* Check if a Mass Storage Reset occurred */
	if (IsMassStoreReset)
	{
		/* Reset the data endpoint banks */
		Endpoint_ResetFIFO(MASS_STORAGE_OUT_EPNUM);
		Endpoint_ResetFIFO(MASS_STORAGE_IN_EPNUM);
		
		Endpoint_SelectEndpoint(MASS_STORAGE_OUT_EPNUM);
		Endpoint_ClearStall();
		Endpoint_ResetDataToggle();
		Endpoint_SelectEndpoint(MASS_STORAGE_IN_EPNUM);
		Endpoint_ClearStall();
		Endpoint_ResetDataToggle();

		/* Clear the abort transfer flag */
		IsMassStoreReset = false;
	}
}