uint8_t Pipe_Write_Stream_LE(const void* Data, uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t* DataStream = (uint8_t*)Data; uint8_t ErrorCode; if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; while (Length--) { if (!(Pipe_ReadWriteAllowed())) { Pipe_ClearCurrentBank(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return PIPE_RWSTREAM_ERROR_CallbackAborted; #endif if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } Pipe_Write_Byte(*(DataStream++)); } return PIPE_RWSTREAM_ERROR_NoError; }
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; }
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; }
uint8_t Pipe_Read_Stream_BE(void* Buffer, uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , uint8_t (* const Callback)(void) #endif ) { uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1); uint8_t ErrorCode; while (Length) { if (!(Pipe_ReadWriteAllowed())) { Pipe_ClearCurrentBank(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return ENDPOINT_RWSTREAM_ERROR_CallbackAborted; #endif if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } *(DataStream--) = Pipe_Read_Byte(); Length--; if (!(USB_IsConnected)) return PIPE_RWSTREAM_ERROR_DeviceDisconnected; else if (Pipe_IsStalled()) return PIPE_RWSTREAM_ERROR_PipeStalled; } return PIPE_RWSTREAM_ERROR_NoError; }
uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, uint16_t Length, uint16_t* const BytesProcessed) { uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); uint16_t BytesInTransfer = 0; uint8_t ErrorCode; Pipe_SetPipeToken(TEMPLATE_TOKEN); if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; if (BytesProcessed != NULL) { Length -= *BytesProcessed; TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); } while (Length) { if (!(Pipe_IsReadWriteAllowed())) { TEMPLATE_CLEAR_PIPE(); if (BytesProcessed != NULL) { *BytesProcessed += BytesInTransfer; return PIPE_RWSTREAM_IncompleteTransfer; } if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } else { TEMPLATE_TRANSFER_BYTE(DataStream); TEMPLATE_BUFFER_MOVE(DataStream, 1); Length--; BytesInTransfer++; } } return PIPE_RWSTREAM_NoError; }
uint8_t Pipe_Null_Stream(uint16_t Length, uint16_t* const BytesProcessed) { uint8_t ErrorCode; uint16_t BytesInTransfer = 0; Pipe_SetPipeToken(PIPE_TOKEN_OUT); if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; if (BytesProcessed != NULL) Length -= *BytesProcessed; while (Length) { if (!(Pipe_IsReadWriteAllowed())) { Pipe_ClearOUT(); if (BytesProcessed != NULL) { *BytesProcessed += BytesInTransfer; return PIPE_RWSTREAM_IncompleteTransfer; } USB_USBTask(); if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } else { Pipe_Write_8(0); Length--; BytesInTransfer++; } } return PIPE_RWSTREAM_NoError; }
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 the given data directly to the printer via the data endpoints, for the sending of print commands in printer * languages accepted by the attached printer (e.g. PCL). * * \param[in] PrinterCommands Pointer to the data to send to the attached printer * \param[in] CommandSize Size of the data to send to the attached printer * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ uint8_t Printer_SendData(const void* const PrinterCommands, const uint16_t CommandSize) { uint8_t ErrorCode; Pipe_SelectPipe(PRINTER_DATA_OUT_PIPE); Pipe_Unfreeze(); if ((ErrorCode = Pipe_Write_Stream_LE(PrinterCommands, CommandSize, NULL)) != PIPE_RWSTREAM_NoError) return ErrorCode; Pipe_ClearOUT(); Pipe_WaitUntilReady(); Pipe_Freeze(); return PIPE_RWSTREAM_NoError; }
/** Sends a packet to the remote device on the specified channel. * * \param[in] Data Pointer to a buffer where the data is to be sourced from * \param[in] DataLen Length of the data to send * \param[in] ACLChannel ACL channel information structure containing the destination channel's information, NULL * to send to the remote device's signaling channel * * \return A value from the \ref BT_SendPacket_ErrorCodes_t enum */ uint8_t Bluetooth_SendPacket(void* Data, const uint16_t DataLen, Bluetooth_Channel_t* const ACLChannel) { BT_ACL_Header_t ACLPacketHeader; BT_DataPacket_Header_t DataHeader; /* A remote device must be connected before a packet transmission is attempted */ if (!(Bluetooth_Connection.IsConnected)) return BT_SENDPACKET_NotConnected; /* If the destination channel is not the signaling channel and it is not currently fully open, abort */ if ((ACLChannel != NULL) && (ACLChannel->State != BT_Channel_Open)) return BT_SENDPACKET_ChannelNotOpen; /* Fill out the packet's header from the remote device connection information structure */ ACLPacketHeader.ConnectionHandle = (Bluetooth_Connection.ConnectionHandle | BT_ACL_FIRST_AUTOFLUSH); ACLPacketHeader.DataLength = sizeof(DataHeader) + DataLen; DataHeader.PayloadLength = DataLen; DataHeader.DestinationChannel = (ACLChannel == NULL) ? BT_CHANNEL_SIGNALING : ACLChannel->RemoteNumber; Pipe_SelectPipe(BLUETOOTH_DATA_OUT_PIPE); Pipe_WaitUntilReady(); Pipe_Unfreeze(); /* Write the packet contents to the pipe so that it can be sent to the remote device */ Pipe_Write_Stream_LE(&ACLPacketHeader, sizeof(ACLPacketHeader)); Pipe_Write_Stream_LE(&DataHeader, sizeof(DataHeader)); Pipe_Write_Stream_LE(Data, DataLen); Pipe_ClearOUT(); Pipe_Freeze(); BT_ACL_DEBUG(2, ""); BT_ACL_DEBUG(2, "Packet Sent"); BT_ACL_DEBUG(2, "-- Connection Handle: 0x%04X", (ACLPacketHeader.ConnectionHandle & 0x0FFF)); BT_ACL_DEBUG(2, "-- Data Length: 0x%04X", ACLPacketHeader.DataLength); BT_ACL_DEBUG(2, "-- Destination Channel: 0x%04X", DataHeader.DestinationChannel); BT_ACL_DEBUG(2, "-- Payload Length: 0x%04X", DataHeader.PayloadLength); return BT_SENDPACKET_NoError; }
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) { uint8_t portnum = MIDIInterfaceInfo->Config.PortNumber; uint8_t ErrorCode; if ((USB_HostState[portnum] != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) return PIPE_RWSTREAM_DeviceDisconnected; Pipe_SelectPipe(portnum,MIDIInterfaceInfo->Config.DataOUTPipeNumber); if (Pipe_BytesInPipe(portnum)) { Pipe_ClearOUT(portnum); if ((ErrorCode = Pipe_WaitUntilReady(portnum)) != PIPE_READYWAIT_NoError) return ErrorCode; } return PIPE_READYWAIT_NoError; }
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) { if (USB_HostState != HOST_STATE_Configured) return PIPE_RWSTREAM_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipeNumber); if (Pipe_BytesInPipe()) { Pipe_ClearOUT(); if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) return ErrorCode; } return PIPE_READYWAIT_NoError; }
/** Routine to send the current CBW to the device, and increment the Tag value as needed. * * \param[in] SCSICommandBlock Pointer to a SCSI command block structure to send to the attached device * \param[in,out] BufferPtr Pointer to a buffer for the data to send or receive to/from the device, or NULL if no data * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ static uint8_t MassStore_SendCommand(CommandBlockWrapper_t* const SCSICommandBlock, void* BufferPtr) { uint8_t ErrorCode = PIPE_RWSTREAM_NoError; /* Each transmission should have a unique tag value, increment before use */ SCSICommandBlock->Tag = ++MassStore_Tag; /* Wrap Tag value when invalid - MS class defines tag values of 0 and 0xFFFFFFFF to be invalid */ 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(); /* Wait until command has been sent */ Pipe_WaitUntilReady(); /* Freeze pipe after use */ Pipe_Freeze(); /* Send data if any */ if ((BufferPtr != NULL) && ((ErrorCode = MassStore_SendReceiveData(SCSICommandBlock, BufferPtr)) != PIPE_READYWAIT_NoError)) { Pipe_Freeze(); return ErrorCode; } return ErrorCode; }
static int CDC_getchar(FILE *stream) { int c; Pipe_SelectPipe(CDC_DATAPIPE_IN); for (;;) { if (Pipe_WaitUntilReady()) return -1; if (!(Pipe_BytesInPipe())) { Pipe_ClearOUT(); } else { c = Pipe_Read_Byte(); break; } } return c; }
uint8_t Pipe_Discard_Stream(uint16_t Length #if !defined(NO_STREAM_CALLBACKS) , StreamCallbackPtr_t Callback #endif ) { uint8_t ErrorCode; Pipe_SetPipeToken(PIPE_TOKEN_IN); if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; #if defined(FAST_STREAM_TRANSFERS) uint8_t BytesRemToAlignment = (Pipe_BytesInPipe() & 0x07); if (Length >= 8) { Length -= BytesRemToAlignment; switch (BytesRemToAlignment) { default: do { if (!(Pipe_IsReadWriteAllowed())) { Pipe_ClearIN(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return PIPE_RWSTREAM_CallbackAborted; #endif if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } Length -= 8; Pipe_Discard_Byte(); case 7: Pipe_Discard_Byte(); case 6: Pipe_Discard_Byte(); case 5: Pipe_Discard_Byte(); case 4: Pipe_Discard_Byte(); case 3: Pipe_Discard_Byte(); case 2: Pipe_Discard_Byte(); case 1: Pipe_Discard_Byte(); } while (Length >= 8); } } #endif while (Length) { if (!(Pipe_IsReadWriteAllowed())) { Pipe_ClearIN(); #if !defined(NO_STREAM_CALLBACKS) if ((Callback != NULL) && (Callback() == STREAMCALLBACK_Abort)) return PIPE_RWSTREAM_CallbackAborted; #endif if ((ErrorCode = Pipe_WaitUntilReady())) return ErrorCode; } else { Pipe_Discard_Byte(); Length--; } } return PIPE_RWSTREAM_NoError; }
uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) { uint8_t ErrorCode; uint16_t AccessoryProtocol; if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful) return ErrorCode; if (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) return AOA_ERROR_LOGICAL_CMD_FAILED; for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++) { if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful) return ErrorCode; } USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), .bRequest = AOA_REQ_StartAccessoryMode, .wValue = 0, .wIndex = 0, .wLength = 0, }; Pipe_SelectPipe(PIPE_CONTROLPIPE); return USB_Host_SendControlRequest(NULL); } static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) { USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE), .bRequest = AOA_REQ_GetAccessoryProtocol, .wValue = 0, .wIndex = 0, .wLength = sizeof(uint16_t), }; Pipe_SelectPipe(PIPE_CONTROLPIPE); return USB_Host_SendControlRequest(Protocol); } static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, const uint8_t StringIndex) { const char* String = ((char**)&AOAInterfaceInfo->Config.PropertyStrings)[StringIndex]; if (String == NULL) String = ""; USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), .bRequest = AOA_REQ_SendString, .wValue = 0, .wIndex = StringIndex, .wLength = (strlen(String) + 1), }; Pipe_SelectPipe(PIPE_CONTROLPIPE); return USB_Host_SendControlRequest((char*)String); } uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, const uint8_t* const Buffer, const uint16_t Length) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return PIPE_READYWAIT_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); Pipe_Freeze(); return ErrorCode; } uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, const char* const String) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return PIPE_READYWAIT_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); Pipe_Freeze(); return ErrorCode; } uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, const uint8_t Data) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return PIPE_READYWAIT_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if (!(Pipe_IsReadWriteAllowed())) { Pipe_ClearOUT(); if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) return ErrorCode; } Pipe_Write_8(Data); Pipe_Freeze(); return PIPE_READYWAIT_NoError; } uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return 0; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if (Pipe_IsINReceived()) { if (!(Pipe_BytesInPipe())) { Pipe_ClearIN(); Pipe_Freeze(); return 0; } else { Pipe_Freeze(); return Pipe_BytesInPipe(); } } else { Pipe_Freeze(); return 0; } } int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return -1; int16_t ReceivedByte = -1; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipeNumber); Pipe_Unfreeze(); if (Pipe_IsINReceived()) { if (Pipe_BytesInPipe()) ReceivedByte = Pipe_Read_8(); if (!(Pipe_BytesInPipe())) Pipe_ClearIN(); } Pipe_Freeze(); return ReceivedByte; } uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) { if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) return PIPE_READYWAIT_DeviceDisconnected; uint8_t ErrorCode; Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipeNumber); Pipe_Unfreeze(); if (!(Pipe_BytesInPipe())) return PIPE_READYWAIT_NoError; bool BankFull = !(Pipe_IsReadWriteAllowed()); Pipe_ClearOUT(); if (BankFull) { if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) return ErrorCode; Pipe_ClearOUT(); } Pipe_Freeze(); return PIPE_READYWAIT_NoError; } #if defined(FDEV_SETUP_STREAM) void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, FILE* const Stream) { *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW); fdev_set_udata(Stream, AOAInterfaceInfo); } void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, FILE* const Stream) { *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW); fdev_set_udata(Stream, AOAInterfaceInfo); }