/** Task to read in data received from the attached CDC device and print it to the serial port. */ void CDCHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; /* Select the data IN pipe */ Pipe_SelectPipe(CDC_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (Pipe_IsINReceived()) { /* Re-freeze IN pipe after the packet has been received */ Pipe_Freeze(); /* Check if data is in the pipe */ if (Pipe_IsReadWriteAllowed()) { /* Get the length of the pipe data, and create a new buffer to hold it */ uint16_t BufferLength = Pipe_BytesInPipe(); uint8_t Buffer[BufferLength]; /* Read in the pipe data to the temporary buffer */ Pipe_Read_Stream_LE(Buffer, BufferLength, NULL); /* Print out the buffer contents to the USART */ for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++) putchar(Buffer[BufferByte]); } /* Clear the pipe after it is read, ready for the next packet */ Pipe_ClearIN(); } /* Re-freeze IN pipe after use */ Pipe_Freeze(); /* Select and unfreeze the notification pipe */ Pipe_SelectPipe(CDC_NOTIFICATION_PIPE); Pipe_Unfreeze(); /* Check if a packet has been received */ if (Pipe_IsINReceived()) { /* Discard the unused event notification */ Pipe_ClearIN(); } /* Freeze notification IN pipe after use */ Pipe_Freeze(); }
/** Sends or receives the transaction's data stage to or from the attached device, reading or * writing to the nominated buffer. * * \param[in] SCSICommandBlock Pointer to a SCSI command block structure being sent to the attached device * \param[in,out] BufferPtr Pointer to the data buffer to read from or write to * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_SendReceiveData(CommandBlockWrapper_t* const SCSICommandBlock, void* BufferPtr) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; uint16_t BytesRem = SCSICommandBlock->DataTransferLength; /* Check the direction of the SCSI command data stage */ if (SCSICommandBlock->Flags & COMMAND_DIRECTION_DATA_IN) { /* Wait until the device has replied with some data */ if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Read in the block data from the pipe */ if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Acknowledge the packet */ Pipe_ClearIN(); } else { /* Select the OUT data pipe for data transmission */ Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Write the block data to the pipe */ if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Acknowledge the packet */ Pipe_ClearOUT(); while (!(Pipe_IsOUTReady())) { if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } } /* Freeze used pipe after use */ Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) { uint8_t PrevPipeNumber = Pipe_GetCurrentPipe(); for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) { Pipe_SelectPipe(PNum); if (Pipe_IsConfigured() && (Pipe_BoundEndpointNumber() == (EndpointAddress & PIPE_EPNUM_MASK))) return true; } Pipe_SelectPipe(PrevPipeNumber); return false; }
static uint8_t SImage_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, SI_PIMA_Container_t* const PIMAHeader) { uint8_t ErrorCode; PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++; Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) return ErrorCode; uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); if (ParamBytes) { if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) return ErrorCode; } Pipe_ClearOUT(); Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, PIMA_Container_t* const PIMAHeader) { uint8_t ErrorCode; if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) return PIPE_RWSTREAM_DeviceDisconnected; if (SIInterfaceInfo->State.IsSessionOpen) PIMAHeader->TransactionID = SIInterfaceInfo->State.TransactionID++; Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) return ErrorCode; uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); if (ParamBytes) { if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError) return ErrorCode; } Pipe_ClearOUT(); Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) { if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) return; Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber); Pipe_SetPipeToken(PIPE_TOKEN_IN); Pipe_Unfreeze(); if (Pipe_IsINReceived()) { USB_Request_Header_t Notification; Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NO_STREAM_CALLBACK); if ((Notification.bRequest == NOTIF_SerialState) && (Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))) { Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost), NO_STREAM_CALLBACK); } Pipe_ClearIN(); EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo); } Pipe_Freeze(); }
bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event) { if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) return HOST_SENDCONTROL_DeviceDisconnected; bool DataReady = false; Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipe.Address); Pipe_Unfreeze(); if (Pipe_IsINReceived()) { if (Pipe_BytesInPipe()) { Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL); DataReady = true; } if (!(Pipe_BytesInPipe())) Pipe_ClearIN(); } Pipe_Freeze(); return DataReady; }
static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint16_t ParameterLength) { /* Need to reserve the amount of bytes given in the header for the complete payload */ uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength]; USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE), .bRequest = 0, .wValue = 0, .wIndex = 0, .wLength = sizeof(CommandBuffer) }; /* Copy over the HCI command header to the allocated buffer */ memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader)); /* Zero out the parameter section of the response to ensure that any padding bytes do not expose private RAM contents */ memset(&CommandBuffer[sizeof(HCICommandHeader)], 0x00, HCICommandHeader.ParameterLength); /* Copy over the command parameters (if any) to the command buffer - note, the number of actual source parameter bytes may differ to those in the header; any difference in length is filled with 0x00 padding bytes */ memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParameterLength); Pipe_SelectPipe(PIPE_CONTROLPIPE); return USB_Host_SendControlRequest(CommandBuffer); }
/** Routine to send the current CBW to the device, and increment the Tag value as needed. * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_SendCommand(void) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; /* Each transmission should have a unique tag value, excluding values 0 and 0xFFFFFFFF */ if (++MassStore_Tag == 0xFFFFFFFF) MassStore_Tag = 1; /* Select the OUT data pipe for CBW transmission */ Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Write the CBW command to the OUT pipe */ if ((ErrorCode = Pipe_Write_Stream_LE(&SCSICommandBlock, sizeof(CommandBlockWrapper_t))) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Send the data in the OUT pipe to the attached device */ Pipe_ClearOUT(); while(!(Pipe_IsOUTReady())); /* Freeze pipe after use */ Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, MS_CommandStatusWrapper_t* const SCSICommandStatus) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) return ErrorCode; Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t), NULL)) != PIPE_RWSTREAM_NoError) { return ErrorCode; } Pipe_ClearIN(); Pipe_Freeze(); if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass) ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED; return ErrorCode; }
static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, MS_CommandBlockWrapper_t* const SCSICommandBlock, const void* const BufferPtr) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; SCSICommandBlock->Signature = MS_CBW_SIGNATURE; SCSICommandBlock->Tag = ++MSInterfaceInfo->State.TransactionTag; if (MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF) MSInterfaceInfo->State.TransactionTag = 1; Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t), NULL)) != PIPE_RWSTREAM_NoError) return ErrorCode; Pipe_ClearOUT(); Pipe_WaitUntilReady(); Pipe_Freeze(); if ((BufferPtr != NULL) && ((ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr)) != PIPE_RWSTREAM_NoError)) { Pipe_Freeze(); return ErrorCode; } return ErrorCode; }
/** ISR to handle the reloading of the PWM timer with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK) { uint8_t PrevPipe = Pipe_GetCurrentPipe(); /* Check that the USB bus is ready for the next sample to write */ if (Audio_Host_IsReadyForNextSample(&Speaker_Audio_Interface)) { int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue; /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000; /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ 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 #endif Audio_Host_WriteSample16(&Speaker_Audio_Interface, AudioSample); Audio_Host_WriteSample16(&Speaker_Audio_Interface, AudioSample); } Pipe_SelectPipe(PrevPipe); }
static uint8_t Bluetooth_SendHCICommand(void* Parameters, uint8_t ParamLength) { uint8_t CommandBuffer[sizeof(HCICommandHeader) + HCICommandHeader.ParameterLength]; USB_HostRequest = (USB_Host_Request_Header_t) { bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE), bRequest: 0, wValue: 0, wIndex: 0, wLength: sizeof(CommandBuffer) }; memset(CommandBuffer, 0x00, sizeof(CommandBuffer)); memcpy(CommandBuffer, &HCICommandHeader, sizeof(HCICommandHeader)); if (ParamLength) memcpy(&CommandBuffer[sizeof(HCICommandHeader)], Parameters, ParamLength); return USB_Host_SendControlRequest(CommandBuffer); } static bool Bluetooth_GetNextHCIEventHeader(void) { Pipe_SelectPipe(BLUETOOTH_EVENTS_PIPE); Pipe_Unfreeze(); if (!(Pipe_ReadWriteAllowed())) return false; Pipe_Read_Stream_LE(&HCIEventHeader, sizeof(HCIEventHeader)); return true; }
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) { if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) return PIPE_RWSTREAM_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address); Pipe_Unfreeze(); if (Pipe_BytesInPipe()) { Pipe_ClearOUT(); if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) { Pipe_Freeze(); return ErrorCode; } } Pipe_Freeze(); return PIPE_READYWAIT_NoError; }
/** Function to send the PIMA command container to the attached still image device. */ void SImage_SendBlockHeader(void) { /* Unfreeze the data OUT pipe ready for data transmission */ Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Write the PIMA block to the data OUT pipe */ Pipe_Write_Stream_LE(&PIMA_SendBlock, PIMA_COMMAND_SIZE(0), NULL); /* If the block type is a command, send its parameters (if any) */ if (PIMA_SendBlock.Type == PIMA_CONTAINER_CommandBlock) { /* Determine the size of the parameters in the block via the data length attribute */ uint8_t ParamBytes = (PIMA_SendBlock.DataLength - PIMA_COMMAND_SIZE(0)); /* Check if any parameters in the command block */ if (ParamBytes) { /* Write the PIMA parameters to the data OUT pipe */ Pipe_Write_Stream_LE(&PIMA_SendBlock.Params, ParamBytes, NULL); } /* Send the PIMA command block to the attached device */ Pipe_ClearOUT(); } /* Freeze pipe after use */ Pipe_Freeze(); }
/** Routine to receive the current CSW from the device. * * \param[out] SCSICommandStatus Pointer to a destination where the returned status data should be stored * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum, or MASS_STORE_SCSI_COMMAND_FAILED if the SCSI command fails */ static uint8_t MassStore_GetReturnedStatus(CommandStatusWrapper_t* const SCSICommandStatus) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; /* If an error in the command occurred, abort */ if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Load in the CSW from the attached device */ if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Clear the data ready for next reception */ Pipe_ClearIN(); /* Freeze the IN pipe after use */ Pipe_Freeze(); /* Check to see if command failed */ if (SCSICommandStatus->Status != Command_Pass) ErrorCode = MASS_STORE_SCSI_COMMAND_FAILED; return ErrorCode; }
/** Task to read and process the HID report descriptor and HID reports from the device and display the * results onto the board LEDs. */ void MouseHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; /* Select and unfreeze mouse data pipe */ Pipe_SelectPipe(MOUSE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (Pipe_IsINReceived()) { /* Check if data has been received from the attached mouse */ if (Pipe_IsReadWriteAllowed()) { /* Create buffer big enough for the report */ uint8_t MouseReport[Pipe_BytesInPipe()]; /* Load in the mouse report */ Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL); /* Process the read in mouse report from the device */ ProcessMouseReport(MouseReport); } /* Clear the IN endpoint, ready for next data packet */ Pipe_ClearIN(); } /* Freeze mouse data pipe */ Pipe_Freeze(); }
/** Reads in and processes the next report from the attached device, displaying the report * contents on the board LEDs and via the serial port. */ void ReadNextReport(void) { USB_MouseReport_Data_t MouseReport; uint8_t LEDMask = LEDS_NO_LEDS; /* Select mouse data pipe */ Pipe_SelectPipe(MOUSE_DATA_IN_PIPE); /* Unfreeze keyboard data pipe */ Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (!(Pipe_IsINReceived())) { /* No packet received (no movement), turn off LEDs */ LEDs_SetAllLEDs(LEDS_NO_LEDS); /* Refreeze HID data IN pipe */ Pipe_Freeze(); return; } /* Ensure pipe contains data before trying to read from it */ if (Pipe_IsReadWriteAllowed()) { /* Read in mouse report data */ Pipe_Read_Stream_LE(&MouseReport, sizeof(MouseReport)); /* Alter status LEDs according to mouse X movement */ if (MouseReport.X > 0) LEDMask |= LEDS_LED1; else if (MouseReport.X < 0) LEDMask |= LEDS_LED2; /* Alter status LEDs according to mouse Y movement */ if (MouseReport.Y > 0) LEDMask |= LEDS_LED3; else if (MouseReport.Y < 0) LEDMask |= LEDS_LED4; /* Alter status LEDs according to mouse button position */ if (MouseReport.Button) LEDMask = LEDS_ALL_LEDS; LEDs_SetAllLEDs(LEDMask); /* Print mouse report data through the serial port */ printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X, MouseReport.Y, MouseReport.Button); } /* Clear the IN endpoint, ready for next data packet */ Pipe_ClearIN(); /* Refreeze mouse data pipe */ Pipe_Freeze(); }
/** Reads in and processes the next report from the attached device, displaying the report * contents on the board LEDs and via the serial port. */ void ReadNextReport(void) { USB_KeyboardReport_Data_t KeyboardReport; /* Select keyboard data pipe */ Pipe_SelectPipe(KEYBOARD_DATAPIPE); /* Unfreeze keyboard data pipe */ Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (!(Pipe_IsINReceived())) { /* Refreeze HID data IN pipe */ Pipe_Freeze(); return; } /* Ensure pipe contains data before trying to read from it */ if (Pipe_IsReadWriteAllowed()) { /* Read in keyboard report data */ Pipe_Read_Stream_LE(&KeyboardReport, sizeof(KeyboardReport)); /* Indicate if the modifier byte is non-zero (special key such as shift is being pressed) */ LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0); /* Check if a key has been pressed */ if (KeyboardReport.KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Retrieve pressed key character if alphanumeric */ if ((KeyboardReport.KeyCode[0] >= 0x04) && (KeyboardReport.KeyCode[0] <= 0x1D)) PressedKey = (KeyboardReport.KeyCode[0] - 0x04) + 'A'; else if ((KeyboardReport.KeyCode[0] >= 0x1E) && (KeyboardReport.KeyCode[0] <= 0x27)) PressedKey = (KeyboardReport.KeyCode[0] - 0x1E) + '0'; else if (KeyboardReport.KeyCode[0] == 0x2C) PressedKey = ' '; else if (KeyboardReport.KeyCode[0] == 0x28) PressedKey = '\n'; /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } } /* Clear the IN endpoint, ready for next data packet */ Pipe_ClearIN(); /* Refreeze keyboard data pipe */ Pipe_Freeze(); }
bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) { uint8_t PrevPipeNumber = Pipe_GetCurrentPipe(); for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) { Pipe_SelectPipe(PNum); if (!(Pipe_IsConfigured())) continue; if (Pipe_GetBoundEndpointAddress() == EndpointAddress) return true; } Pipe_SelectPipe(PrevPipeNumber); return false; }
static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, MS_CommandBlockWrapper_t* const SCSICommandBlock, void* BufferPtr) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; uint16_t BytesRem = SCSICommandBlock->DataTransferLength; if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN) { if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) { Pipe_Freeze(); return ErrorCode; } Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) return ErrorCode; Pipe_ClearIN(); } else { Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) return ErrorCode; Pipe_ClearOUT(); while (!(Pipe_IsOUTReady())) { if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; } } Pipe_Freeze(); return ErrorCode; }
/** ISR to handle the reloading of the endpoint with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK) { uint8_t PrevPipe = Pipe_GetCurrentPipe(); Pipe_SelectPipe(AUDIO_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Check if the current pipe can be written to (device ready for more data) */ if (Pipe_IsOUTReady()) { int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue; /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000; /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ 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 #endif Pipe_Write_16_LE(AudioSample); Pipe_Write_16_LE(AudioSample); if (!(Pipe_IsReadWriteAllowed())) Pipe_ClearOUT(); } Pipe_Freeze(); Pipe_SelectPipe(PrevPipe); }
void Pipe_ClearPipes(void) { for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) { Pipe_SelectPipe(PNum); (&AVR32_USBB.upcfg0)[PNum] = 0; (&AVR32_USBB.upcon0clr)[PNum] = -1; USB_Pipe_FIFOPos[PNum] = &AVR32_USBB_SLAVE[PNum * 0x10000]; Pipe_DisablePipe(); } }
static int CDC_putchar(char c, FILE *stream) { Pipe_SelectPipe(CDC_DATAPIPE_OUT); if (Pipe_WaitUntilReady()) return -1; Pipe_Write_Byte(c); Pipe_ClearIN(); return 0; }
/** Sends or receives the transaction's data stage to or from the attached device, reading or * writing to the nominated buffer. * * \param BufferPtr Pointer to the data buffer to read from or write to * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_SendReceiveData(void* BufferPtr) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; uint16_t BytesRem = SCSICommandBlock.Header.DataTransferLength; /* Check the direction of the SCSI command data stage */ if (SCSICommandBlock.Header.Flags & COMMAND_DIRECTION_DATA_IN) { /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); /* Read in the block data from the pipe */ if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Acknowledge the packet */ Pipe_ClearIN(); } else { /* Select the OUT data pipe for data transmission */ Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Write the block data to the pipe */ if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError) return ErrorCode; /* Acknowledge the packet */ Pipe_ClearOUT(); while (!(Pipe_IsOUTReady())); } /* Freeze used pipe after use */ Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
void CALLBACK_Bluetooth_SendPacket(BT_StackConfig_t* const StackState, const uint8_t Type, const uint16_t Length) { /* Determine the type of packet being sent, use appropriate pipe */ switch (Type) { case BLUETOOTH_PACKET_HCICommand: USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_DEVICE), .bRequest = 0, .wValue = 0, .wIndex = 0, .wLength = Length }; /* HCI commands must be sent over the Control pipe */ Pipe_SelectPipe(PIPE_CONTROLPIPE); USB_Host_SendControlRequest(StackState->Config.PacketBuffer); break; case BLUETOOTH_PACKET_HCIData: Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); /* HCI data packets must be sent over the Data OUT pipe */ Pipe_Unfreeze(); Pipe_Write_Stream_LE(StackState->Config.PacketBuffer, Length, NULL); Pipe_ClearOUT(); Pipe_Freeze(); break; } // RGB_SetColour(RGB_ALIAS_Connected); } void EVENT_Bluetooth_InitComplete(BT_StackConfig_t* const StackState) { /* Save the local BDADDR of the connected Bluetooth adapter for later use */ // eeprom_update_block(BluetoothAdapter_Stack.State.HCI.LocalBDADDR, BluetoothAdapter_LastLocalBDADDR, sizeof(BDADDR_t)); }
uint8_t SImage_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, void* Buffer, const uint16_t Bytes) { uint8_t ErrorCode; Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NO_STREAM_CALLBACK); Pipe_Freeze(); return ErrorCode; }
bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber, const uint16_t Size, const uint8_t Banks) { Pipe_SelectPipe(Number); Pipe_EnablePipe(); UPCFG1X = 0; UPCFG0X = ((Type << EPTYPE0) | Token | (EndpointNumber << PEPNUM0)); UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); return Pipe_IsConfigured(); }
void Pipe_ClearPipes(void) { UPINT = 0; for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) { Pipe_SelectPipe(PNum); UPIENX = 0; UPINTX = 0; UPCFG1X = 0; Pipe_DisablePipe(); } }
void Pipe_ConfigurePipe_P(const uint8_t PipeNum, const uint16_t PipeSize, const uint8_t UPCFG0Xdata, const uint8_t UPCFG1Xdata) { Pipe_SelectPipe(PipeNum); Pipe_EnablePipe(); UPCFG0X = UPCFG0Xdata; UPCFG1X = ((UPCFG1X & (1 << ALLOC)) | UPCFG1Xdata | Pipe_BytesToEPSizeMask(PipeSize)); UPCFG2X = 0; Pipe_AllocateMemory(); }