forked from PAWPAW-Mirror/lib_xua
Fix the handling of setidle requests
This commit is contained in:
@@ -374,15 +374,15 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if( 0 < HID_CONTROLS )
|
||||||
UserHIDInit();
|
UserHIDInit();
|
||||||
{
|
|
||||||
while (!hidIsReportDescriptorPrepared())
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Get the last report - we don't really care which it is, so long as there's some data we can grab. */
|
while (!hidIsReportDescriptorPrepared())
|
||||||
int hidReportLength = (int) UserHIDGetData(hidGetReportIdLimit() - 1, g_hidData);
|
;
|
||||||
|
|
||||||
|
/* Get the a report - we don't really care which it is, so long as there's some data we can grab. */
|
||||||
|
int hidReportLength = (int) UserHIDGetData(hidGetNextValidReportId(0), g_hidData);
|
||||||
|
|
||||||
|
XUD_SetReady_In(ep_hid, g_hidData, hidReportLength);
|
||||||
|
|
||||||
XUD_SetReady_In(ep_hid, g_hidData, hidReportLength);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (AUDIO_CLASS == 1)
|
#if (AUDIO_CLASS == 1)
|
||||||
|
|||||||
@@ -129,6 +129,31 @@ static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, con
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Configure a hid report's next report time and idle status based on a setidle request
|
||||||
|
*
|
||||||
|
* \param[in] reportId -- The report ID to modify
|
||||||
|
* \param[in] reportDuration -- The duration of the setidle request
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void HidUpdateReportPeriod( unsigned reportId, unsigned reportDuration ) {
|
||||||
|
unsigned currentPeriod = hidGetReportPeriod( reportId );
|
||||||
|
|
||||||
|
hidSetIdle( reportId, ( 0U == duration ) || ( ENDPOINT_INT_INTERVAL_IN_HID < duration ));
|
||||||
|
|
||||||
|
if( hidIsIdleActive( reportId )) {
|
||||||
|
unsigned reportTime = hidGetReportTime( reportId );
|
||||||
|
unsigned reportToSetIdleInterval = HidCalcReportToSetIdleInterval( reportTime );
|
||||||
|
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, reportDuration * MS_IN_TICKS );
|
||||||
|
hidSetNextReportTime( reportId, nextReportTime );
|
||||||
|
currentPeriod = reportDuration * MS_IN_TICKS;
|
||||||
|
} else {
|
||||||
|
currentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
hidSetReportPeriod( reportId, currentPeriod );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Process a Set Idle request
|
* \brief Process a Set Idle request
|
||||||
*
|
*
|
||||||
@@ -166,22 +191,24 @@ static XUD_Result_t HidProcessSetIdleRequest( XUD_ep c_ep0_out, XUD_ep c_ep0_in,
|
|||||||
|
|
||||||
Any Interface value other than INTERFACE_NUMBER_HID indicates an error by the USB Host.
|
Any Interface value other than INTERFACE_NUMBER_HID indicates an error by the USB Host.
|
||||||
*/
|
*/
|
||||||
if(( 0U == reportId ) && ( INTERFACE_NUMBER_HID == interfaceNum )) {
|
if( INTERFACE_NUMBER_HID == interfaceNum ) {
|
||||||
hidSetIdle( reportId, ( 0U == duration ) || ( ENDPOINT_INT_INTERVAL_IN_HID < duration ));
|
if( hidIsReportIdValid( reportId ) ) {
|
||||||
|
HidUpdateReportPeriod( reportId, duration );
|
||||||
|
|
||||||
unsigned currentPeriod = hidGetReportPeriod( reportId );
|
result = XUD_DoSetRequestStatus( c_ep0_in );
|
||||||
if( hidIsIdleActive( reportId )) {
|
|
||||||
unsigned reportTime = hidGetReportTime( reportId );
|
|
||||||
unsigned reportToSetIdleInterval = HidCalcReportToSetIdleInterval( reportTime );
|
|
||||||
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, duration * MS_IN_TICKS );
|
|
||||||
hidSetNextReportTime( reportId, nextReportTime );
|
|
||||||
currentPeriod = duration * MS_IN_TICKS;
|
|
||||||
} else {
|
|
||||||
currentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
|
||||||
}
|
}
|
||||||
|
else if ( reportId == 0U ) {
|
||||||
|
// Wildcard request - set all report IDs to idle
|
||||||
|
unsigned startReportId = hidGetNextValidReportId(reportId);
|
||||||
|
|
||||||
hidSetReportPeriod( reportId, currentPeriod );
|
reportId = startReportId;
|
||||||
result = XUD_DoSetRequestStatus( c_ep0_in );
|
do {
|
||||||
|
HidUpdateReportPeriod( reportId, duration );
|
||||||
|
reportId = hidGetNextValidReportId( reportId );
|
||||||
|
} while( reportId != startReportId);
|
||||||
|
|
||||||
|
result = XUD_DoSetRequestStatus( c_ep0_in );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -254,6 +254,20 @@ unsigned hidIsReportIdInUse ( void ) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned hidIsReportIdValid ( unsigned id ) {
|
||||||
|
size_t retVal = 0;
|
||||||
|
|
||||||
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
|
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||||
|
if( reportId == id ) {
|
||||||
|
retVal = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
||||||
size_t retIndex = 0;
|
size_t retIndex = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,20 @@ unsigned hidGetReportIdLimit ( void );
|
|||||||
*/
|
*/
|
||||||
unsigned hidIsReportIdInUse ( void );
|
unsigned hidIsReportIdInUse ( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Is the provided report ID valid for passing to other functions.
|
||||||
|
*
|
||||||
|
* e.g If Report IDs are not in use, then only 0 will return true.
|
||||||
|
* e.g If Report IDs are in use, then 0 will return false and the report IDs that
|
||||||
|
* are in use will return true when passed to thsi function.
|
||||||
|
*
|
||||||
|
* @param id The ID to check
|
||||||
|
* @return boolean
|
||||||
|
* @retval 0 The report ID is not valid, other functions may fail silently
|
||||||
|
* @retval 1 The report ID is valid and can be used as the argument to other functions
|
||||||
|
*/
|
||||||
|
unsigned hidIsReportIdValid ( unsigned id );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the next valid report ID - iterator style.
|
* @brief Get the next valid report ID - iterator style.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -79,6 +79,30 @@ void test_get_next_valid_report_id( void ) {
|
|||||||
TEST_ASSERT_EQUAL_UINT( 1, reportId );
|
TEST_ASSERT_EQUAL_UINT( 1, reportId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_is_report_id_valid( void ) {
|
||||||
|
unsigned isValid = 0;
|
||||||
|
|
||||||
|
unsigned reportId = 0;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 0, isValid );
|
||||||
|
|
||||||
|
reportId = 1;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 1, isValid );
|
||||||
|
|
||||||
|
reportId = 2;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 1, isValid );
|
||||||
|
|
||||||
|
reportId = 3;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 1, isValid );
|
||||||
|
|
||||||
|
reportId = 4;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 0, isValid );
|
||||||
|
}
|
||||||
|
|
||||||
// Basic report descriptor tests
|
// Basic report descriptor tests
|
||||||
void test_unprepared_hidGetReportDescriptor( void )
|
void test_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ void test_get_next_valid_report_id( void ) {
|
|||||||
TEST_ASSERT_EQUAL_UINT( 0, reportId );
|
TEST_ASSERT_EQUAL_UINT( 0, reportId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_is_report_id_valid( void ) {
|
||||||
|
unsigned isValid = 0;
|
||||||
|
|
||||||
|
unsigned reportId = 0;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 1, isValid );
|
||||||
|
|
||||||
|
reportId = 1;
|
||||||
|
isValid = hidIsReportIdValid( reportId );
|
||||||
|
TEST_ASSERT_EQUAL_UINT( 0, isValid );
|
||||||
|
}
|
||||||
|
|
||||||
// Basic report descriptor tests
|
// Basic report descriptor tests
|
||||||
void test_unprepared_hidGetReportDescriptor( void )
|
void test_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user