Commit 2028e82e authored by Dean Camera's avatar Dean Camera
Browse files

Fixed CDC class Send_Device_*_P() and Send_Host_*_P() variant functions not...

Fixed CDC class Send_Device_*_P() and Send_Host_*_P() variant functions not compiled out for UC3 architecture.
parent e2d1b437
...@@ -116,6 +116,7 @@ ...@@ -116,6 +116,7 @@
#define pgm_read_byte(x) *x #define pgm_read_byte(x) *x
#define memcmp_P(...) memcmp(__VA_ARGS__) #define memcmp_P(...) memcmp(__VA_ARGS__)
#define memcpy_P(...) memcpy(__VA_ARGS__) #define memcpy_P(...) memcpy(__VA_ARGS__)
#define strlen_P(...) strlen(__VA_ARGS__)
// ================================================= // =================================================
typedef uint32_t uint_reg_t; typedef uint32_t uint_reg_t;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* - Fixed CDC Device class driver's internal serial stream created by \ref CDC_Device_CreateStream not returning the written * - Fixed CDC Device class driver's internal serial stream created by \ref CDC_Device_CreateStream not returning the written
* character after a successful write (thanks to NicoHood) * character after a successful write (thanks to NicoHood)
* - Fixed incorrect endpoint bank setup on the UC3 architecture (thanks to Andrus Aaslaid) * - Fixed incorrect endpoint bank setup on the UC3 architecture (thanks to Andrus Aaslaid)
* - Fixed CDC_Device_Send*_P() and CDC_Host_Send*_P() variant functions not compiled out for UC3 architecture
* - Library Applications: * - Library Applications:
* - Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan) * - Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan)
* - Fixed bootloaders accepting flash writes to the bootloader region (thanks to NicoHood) * - Fixed bootloaders accepting flash writes to the bootloader region (thanks to NicoHood)
......
...@@ -155,16 +155,6 @@ uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo ...@@ -155,16 +155,6 @@ uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo
return Endpoint_Write_Stream_LE(String, strlen(String), NULL); return Endpoint_Write_Stream_LE(String, strlen(String), NULL);
} }
uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const char* const String)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
}
uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const void* const Buffer, const void* const Buffer,
const uint16_t Length) const uint16_t Length)
...@@ -176,16 +166,28 @@ uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, ...@@ -176,16 +166,28 @@ uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
return Endpoint_Write_Stream_LE(Buffer, Length, NULL); return Endpoint_Write_Stream_LE(Buffer, Length, NULL);
} }
uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, #if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
const void* const Buffer, uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const uint16_t Length) const char* const String)
{ {
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected; return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
return Endpoint_Write_PStream_LE(Buffer, Length, NULL); return Endpoint_Write_PStream_LE(String, strlen_P(String), NULL);
} }
uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const void* const Buffer,
const uint16_t Length)
{
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
return ENDPOINT_RWSTREAM_DeviceDisconnected;
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
return Endpoint_Write_PStream_LE(Buffer, Length, NULL);
}
#endif
uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const uint8_t Data) const uint8_t Data)
...@@ -306,51 +308,51 @@ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDC ...@@ -306,51 +308,51 @@ void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDC
} }
#if defined(FDEV_SETUP_STREAM) #if defined(FDEV_SETUP_STREAM)
void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
FILE* const Stream) FILE* const Stream)
{ {
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW); *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo); fdev_set_udata(Stream, CDCInterfaceInfo);
} }
void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
FILE* const Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Device_putchar(char c, void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
FILE* Stream) FILE* const Stream)
{ {
return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : c; *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW);
} fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Device_getchar(FILE* Stream) static int CDC_Device_putchar(char c,
{ FILE* Stream)
int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); {
return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : c;
}
if (ReceivedByte < 0) static int CDC_Device_getchar(FILE* Stream)
return _FDEV_EOF; {
int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
return ReceivedByte; if (ReceivedByte < 0)
} return _FDEV_EOF;
static int CDC_Device_getchar_Blocking(FILE* Stream) return ReceivedByte;
{ }
int16_t ReceivedByte;
while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0) static int CDC_Device_getchar_Blocking(FILE* Stream)
{ {
if (USB_DeviceState == DEVICE_STATE_Unattached) int16_t ReceivedByte;
return _FDEV_EOF;
CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0)
USB_USBTask(); {
} if (USB_DeviceState == DEVICE_STATE_Unattached)
return _FDEV_EOF;
return ReceivedByte; CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream));
} USB_USBTask();
}
return ReceivedByte;
}
#endif #endif
void CDC_Device_Event_Stub(void) void CDC_Device_Event_Stub(void)
......
...@@ -182,27 +182,25 @@ ...@@ -182,27 +182,25 @@
void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when
* called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
* becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
* for multiple bytes to be packed into a single endpoint packet, increasing data throughput. * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
* *
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
* the call will fail. * the call will fail.
* *
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
* \param[in] Buffer Pointer to a buffer containing the data to send to the device. * \param[in] String Pointer to the null terminated string to send to the host.
* \param[in] Length Length of the data to send to the host.
* *
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/ */
uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const void* const Buffer, const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is
* function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank
* bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows * becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
* for multiple bytes to be packed into a single endpoint packet, increasing data throughput. * for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
* *
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
...@@ -214,41 +212,51 @@ ...@@ -214,41 +212,51 @@
* *
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/ */
uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const void* const Buffer, const void* const Buffer,
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when /** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected
* the function is called, the string is discarded. Bytes will be queued for transmission to the host until either * when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either
* the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to
* the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
* *
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
* the call will fail. * the call will fail.
* *
* \note This function does not exist on architectures that do not have a separate flash memory space.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
* \param[in] String Pointer to the null terminated string to send to the host. * \param[in] String Pointer to the null terminated string to send to the host.
* *
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/ */
uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, #if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
#endif
/** Sends a given null terminated string from PROGMEM space to the attached USB host, if connected. If a host is not connected /** Sends a given data buffer from PROGMEM space to the attached USB host, if connected. If a host is not connected when the
* when the function is called, the string is discarded. Bytes will be queued for transmission to the host until either * function is called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint
* the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to * bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows
* the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. * for multiple bytes to be packed into a single endpoint packet, increasing data throughput.
* *
* \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or
* the call will fail. * the call will fail.
* *
* \note This function does not exist on architectures that do not have a separate flash memory space.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state.
* \param[in] String Pointer to the null terminated string to send to the host. * \param[in] Buffer Pointer to a buffer containing the data to send to the device.
* \param[in] Length Length of the data to send to the host.
* *
* \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum.
*/ */
uint8_t CDC_Device_SendString_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, #if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); uint8_t CDC_Device_SendData_P(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo,
const void* const Buffer,
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
#endif
/** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the
* byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the
......
...@@ -276,9 +276,8 @@ uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ...@@ -276,9 +276,8 @@ uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
return USB_Host_SendControlRequest(NULL); return USB_Host_SendControlRequest(NULL);
} }
uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const void* const Buffer, const char* const String)
const uint16_t Length)
{ {
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected; return PIPE_READYWAIT_DeviceDisconnected;
...@@ -288,13 +287,13 @@ uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ...@@ -288,13 +287,13 @@ uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
Pipe_Unfreeze(); Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL);
Pipe_Freeze(); Pipe_Freeze();
return ErrorCode; return ErrorCode;
} }
uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const void* const Buffer, const void* const Buffer,
const uint16_t Length) const uint16_t Length)
{ {
...@@ -306,45 +305,48 @@ uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, ...@@ -306,45 +305,48 @@ uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
Pipe_Unfreeze(); Pipe_Unfreeze();
ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL); ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL);
Pipe_Freeze(); Pipe_Freeze();
return ErrorCode; return ErrorCode;
} }
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, #if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
const char* const String) uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
{ const char* const String)
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) {
return PIPE_READYWAIT_DeviceDisconnected; if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode; uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
Pipe_Unfreeze(); Pipe_Unfreeze();
ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL);
Pipe_Freeze(); Pipe_Freeze();
return ErrorCode; return ErrorCode;
} }
uint8_t CDC_Host_SendString_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint8_t CDC_Host_SendData_P(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const char* const String) const void* const Buffer,
{ const uint16_t Length)
if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) {
return PIPE_READYWAIT_DeviceDisconnected; if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive))
return PIPE_READYWAIT_DeviceDisconnected;
uint8_t ErrorCode; uint8_t ErrorCode;
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address);
Pipe_Unfreeze(); Pipe_Unfreeze();
ErrorCode = Pipe_Write_PStream_LE(String, strlen_P(String), NULL); ErrorCode = Pipe_Write_PStream_LE(Buffer, Length, NULL);
Pipe_Freeze(); Pipe_Freeze();
return ErrorCode; return ErrorCode;
} }
#endif
uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const uint8_t Data) const uint8_t Data)
...@@ -456,51 +458,51 @@ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ...@@ -456,51 +458,51 @@ uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo)
} }
#if defined(FDEV_SETUP_STREAM) #if defined(FDEV_SETUP_STREAM)
void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
FILE* const Stream) FILE* const Stream)
{ {
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW); *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo); fdev_set_udata(Stream, CDCInterfaceInfo);
} }
void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
FILE* const Stream)
{
*Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Host_putchar(char c, void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
FILE* Stream) FILE* const Stream)
{ {
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW);
} fdev_set_udata(Stream, CDCInterfaceInfo);
}
static int CDC_Host_getchar(FILE* Stream) static int CDC_Host_putchar(char c,
{ FILE* Stream)
int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); {
return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0;
}
if (ReceivedByte < 0) static int CDC_Host_getchar(FILE* Stream)
return _FDEV_EOF; {
int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
return ReceivedByte; if (ReceivedByte < 0)
} return _FDEV_EOF;
static int CDC_Host_getchar_Blocking(FILE* Stream) return ReceivedByte;
{ }
int16_t ReceivedByte;
while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0) static int CDC_Host_getchar_Blocking(FILE* Stream)
{ {
if (USB_HostState == HOST_STATE_Unattached) int16_t ReceivedByte;
return _FDEV_EOF;
CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0)
USB_USBTask(); {
} if (USB_HostState == HOST_STATE_Unattached)
return _FDEV_EOF;
return ReceivedByte; CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream));
} USB_USBTask();
}
return ReceivedByte;
}
#endif #endif
void CDC_Host_Event_Stub(void) void CDC_Host_Event_Stub(void)
......
...@@ -183,6 +183,22 @@ ...@@ -183,6 +183,22 @@
uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the
* function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe
* bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows
* for multiple bytes to be packed into a single pipe packet, increasing data throughput.
*
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the
* call will fail.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
* \param[in] String Pointer to the null terminated string to send to the device.
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.
*/
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo,
const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is
* called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank
* becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for * becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for
...@@ -201,55 +217,47 @@ ...@@ -201,55 +217,47 @@
const void* const Buffer, const void* const Buffer,
const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given data buffer from PROGMEM space to the attached USB device, if connected. If a device is not connected when the /** Sends a given null terminated string from PROGMEM space to the attached USB device, if connected. If a device is not connected
* function is called, the string is discarded. Bytes will be queued for transmission to the host until either the pipe * when the function is called, the string is discarded. Bytes will be queued for transmission to the device until either
* bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows * the pipe bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to
* for multiple bytes to be packed into a single pipe packet, increasing data throughput. * the device. This allows for multiple bytes to be packed into a single pipe packet, increasing data throughput.
* *
* \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or
* the call will fail. * the call will fail.
* *
* \note This function does not exist on architectures that do not have a separate flash memory space.
*
* \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state.
* \param[in] Buffer Pointer to a buffer containing the data to send to the device. * \param[in] String Pointer to the null terminated string to send to the host.
* \param[in] Length Length of the data to send to the host.
* *
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum.