Commit d97db112 authored by Dean Camera's avatar Dean Camera
Browse files

Added support to the MIDI Class drivers for packed data, where multiple MIDI...

Added support to the MIDI Class drivers for packed data, where multiple MIDI events are packed into a single USB packet. Added new MIDI Class driver flush routines to override packing behaviour.
parent 60e96412
......@@ -158,6 +158,7 @@ void CheckJoystickMovement(void)
};
MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
MIDI_Device_Flush(&Keyboard_MIDI_Interface);
}
PrevJoystickStatus = JoystickStatus;
......
......@@ -203,6 +203,7 @@ void CheckJoystickMovement(void)
};
MIDI_Host_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
MIDI_Host_Flush(&Keyboard_MIDI_Interface);
}
PrevJoystickStatus = JoystickStatus;
......
......@@ -158,7 +158,7 @@ uint8_t ProcessConfigurationDescriptor(void)
}
else
{
/* Only configure the OUT data pipe if the data endpoints haev not shown to be bidirectional */
/* Only configure the OUT data pipe if the data endpoints have not shown to be bidirectional */
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress)))
{
/* Configure the data OUT pipe */
......
......@@ -158,7 +158,7 @@ uint8_t ProcessConfigurationDescriptor(void)
}
else
{
/* Only configure the OUT data pipe if the data endpoints haev not shown to be bidirectional */
/* Only configure the OUT data pipe if the data endpoints have not shown to be bidirectional */
if (!(Pipe_IsEndpointBound(EndpointData->EndpointAddress)))
{
/* Configure the data OUT pipe */
......
......@@ -155,7 +155,9 @@
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB host, if connected. If a host is not connected when the function is called, the
* string is discarded.
* 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 host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
......@@ -170,7 +172,9 @@
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** 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.
* byte 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 host. This allows for multiple bytes to be
* packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
......
......@@ -79,12 +79,33 @@ uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInter
if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != ENDPOINT_RWSTREAM_NoError)
return ErrorCode;
Endpoint_ClearIN();
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearIN();
}
return ENDPOINT_RWSTREAM_NoError;
}
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
return ENDPOINT_RWSTREAM_DeviceDisconnected;
uint8_t ErrorCode;
Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpointNumber);
if (Endpoint_BytesInEndpoint())
{
Endpoint_ClearIN();
if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError)
return ErrorCode;
}
return ENDPOINT_READYWAIT_NoError;
}
bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if (USB_DeviceState != DEVICE_STATE_Configured)
......@@ -96,7 +117,9 @@ bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInter
return false;
Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
Endpoint_ClearOUT();
if (!(Endpoint_IsReadWriteAllowed()))
Endpoint_ClearOUT();
return true;
}
......
......@@ -104,7 +104,9 @@
*/
void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded.
/** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the
* endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple
* MIDI events to be packed into a single endpoint packet, increasing data throughput.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
......@@ -117,7 +119,18 @@
uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Receives a MIDI event packet from the host.
/** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the
* \ref MIDI_Device_SendEventPacket() function's packing behaviour, to flush queued events.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains
* multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event.
*
* \note This function must only be called when the Device state machine is in the DEVICE_STATE_Configured state or
* the call will fail.
......
......@@ -175,7 +175,9 @@
uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
/** Sends a given string to the attached USB device, if connected. If a device is not connected when the function is called, the
* string is discarded.
* 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 host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
......@@ -189,8 +191,10 @@
uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, char* Data, const uint16_t Length)
ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Sends a given byte to the attached USB device, if connected. If a host is not connected when the function is called, the
* byte is discarded.
/** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the
* byte 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 host. This allows for multiple bytes to be
* packed into a single pipe packet, increasing data throughput.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
* call will fail.
......
......@@ -122,6 +122,26 @@ static uint8_t DComp_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const Current
return DESCRIPTOR_SEARCH_NotFound;
}
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;
}
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, MIDI_EventPacket_t* const Event)
{
if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive))
......@@ -136,7 +156,8 @@ uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterface
if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK)) != PIPE_RWSTREAM_NoError)
return ErrorCode;
Pipe_ClearOUT();
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearOUT();
}
return PIPE_RWSTREAM_NoError;
......@@ -153,7 +174,9 @@ bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterface
return false;
Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NO_STREAM_CALLBACK);
Pipe_ClearIN();
if (!(Pipe_IsReadWriteAllowed()))
Pipe_ClearIN();
return true;
}
......
......@@ -125,6 +125,17 @@
uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo,
MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2);
/** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the
* \ref MIDI_Host_SendEventPacket() function's packing behaviour, to flush queued events. Events are queued into the
* pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI
* events to be packed into a single pipe packet, increasing data throughput.
*
* \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state
*
* \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum
*/
uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo);
/** Receives a MIDI event packet from the device.
*
* \note This function must only be called when the Host state machine is in the HOST_STATE_Configured state or the
......
......@@ -14,6 +14,9 @@
* to a target
* - Added new TemperatureDataLogger application, a USB data logger which writes to the device's dataflash and appears to
* the host as a standard Mass Storage device when inserted
* - Added MIDI event packing support to the MIDI Device and Host mode Class drivers, allowing for multiple MIDI events to
* sent or received in packed form in a single USB packet
* - Added new MIDI send buffer flush routines to the MIDI Device and Host mode Class drivers, to flush packed events
*
* <b>Changed:</b>
* - Slowed down bit-banged PDI programming in the AVRISP project slightly to prevent transmission errors
......
......@@ -12,7 +12,17 @@
*
* \section Sec_MigrationXXXXXX Migrating from 091223 to XXXXXX
*
* <i>There is no migration information for this release.</i>
* <b>Host Mode</b>
* - The MIDI Host Class driver send and receive routines now operate on packed events, where multiple MIDI events may be
* packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send
* pipe bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually
* flush the queued event(s) to the device by calling \ref MIDI_Host_Flush().
*
* <b>Device Mode</b>
* - The MIDI Device Class driver send and receive routines now operate on packed events, where multiple MIDI events may be
* packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send
* endpoint bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually
* flush the queued event(s) to the host by calling \ref MIDI_Device_Flush().
*
* \section Sec_Migration091223 Migrating from 091122 to 091223
*
......
......@@ -226,6 +226,9 @@ void XPROGTarget_EnableTargetTPI(void)
/** Disables the target's PDI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetPDI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
#if defined(XPROG_VIA_HARDWARE_USART)
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A |= (1 << TXC1) | (1 << RXC1);
......@@ -249,6 +252,9 @@ void XPROGTarget_DisableTargetPDI(void)
/** Disables the target's TPI interface, exits programming mode and starts the target's application. */
void XPROGTarget_DisableTargetTPI(void)
{
/* Switch to Rx mode to ensure that all pending transmissions are complete */
XPROGTarget_SetRxMode();
#if defined(XPROG_VIA_HARDWARE_USART)
/* Turn off receiver and transmitter of the USART, clear settings */
UCSR1A |= (1 << TXC1) | (1 << RXC1);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment