Merge pull request #236 from ACascarino/feature/set_idle_work
Add swlocks to HID files, and correct operation of SetIdle
This commit is contained in:
@@ -10,6 +10,10 @@ lib_xua Change Log
|
|||||||
* CHANGED: Renamed the HID API file xua_hid_report_descriptor.h to
|
* CHANGED: Renamed the HID API file xua_hid_report_descriptor.h to
|
||||||
xua_hid_report.h
|
xua_hid_report.h
|
||||||
|
|
||||||
|
* Changes to dependencies:
|
||||||
|
|
||||||
|
- lib_locks: Added dependency 2.1.0
|
||||||
|
|
||||||
2.1.1
|
2.1.1
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ DEPENDENT_MODULES = lib_logging(>=3.0.0) \
|
|||||||
lib_xassert(>=4.0.0) \
|
lib_xassert(>=4.0.0) \
|
||||||
lib_xud(>=2.0.1) \
|
lib_xud(>=2.0.1) \
|
||||||
lib_spdif(>=4.0.0) \
|
lib_spdif(>=4.0.0) \
|
||||||
lib_mic_array(>=4.0.0)
|
lib_mic_array(>=4.0.0) \
|
||||||
|
lib_locks(>=2.0.3)
|
||||||
|
|
||||||
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
|
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
|
||||||
-O3 \
|
-O3 \
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2021 XMOS LIMITED.
|
// Copyright 2011-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include "xua.h"
|
#include "xua.h"
|
||||||
#if XUA_USB_EN
|
#if XUA_USB_EN
|
||||||
@@ -93,7 +93,7 @@ unsigned int fb_clocks[4];
|
|||||||
void XUA_Buffer(
|
void XUA_Buffer(
|
||||||
register chanend c_aud_out,
|
register chanend c_aud_out,
|
||||||
#if (NUM_USB_CHAN_IN > 0)
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
register chanend c_aud_in,
|
register chanend c_aud_in,
|
||||||
#endif
|
#endif
|
||||||
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
|
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
|
||||||
chanend c_aud_fb,
|
chanend c_aud_fb,
|
||||||
@@ -198,7 +198,7 @@ unsafe{volatile unsigned * unsafe masterClockFreq_ptr;}
|
|||||||
*/
|
*/
|
||||||
void XUA_Buffer_Ep(register chanend c_aud_out,
|
void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||||
#if (NUM_USB_CHAN_IN > 0)
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
register chanend c_aud_in,
|
register chanend c_aud_in,
|
||||||
#endif
|
#endif
|
||||||
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
|
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
|
||||||
chanend c_aud_fb,
|
chanend c_aud_fb,
|
||||||
@@ -373,15 +373,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if( 0 < HID_CONTROLS )
|
||||||
UserHIDInit();
|
|
||||||
|
|
||||||
while (!hidIsReportDescriptorPrepared())
|
while (!hidIsReportDescriptorPrepared())
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Get the a report - we don't really care which it is, so long as there's some data we can grab. */
|
UserHIDInit();
|
||||||
int hidReportLength = (int) UserHIDGetData(hidGetNextValidReportId(0), g_hidData);
|
unsigned hid_ready_flag = 0U;
|
||||||
|
unsigned hid_ready_id = 0U;
|
||||||
XUD_SetReady_In(ep_hid, g_hidData, hidReportLength);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -392,6 +390,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
timer tmr;
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
XUD_Result_t result;
|
XUD_Result_t result;
|
||||||
@@ -448,9 +448,9 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
if(receivedSampleFreq != AUDIO_STOP_FOR_DFU)
|
if(receivedSampleFreq != AUDIO_STOP_FOR_DFU)
|
||||||
{
|
{
|
||||||
sampleFreq = receivedSampleFreq;
|
sampleFreq = receivedSampleFreq;
|
||||||
#ifdef FB_TOLERANCE_TEST
|
#ifdef FB_TOLERANCE_TEST
|
||||||
expected_fb = ((sampleFreq * 0x2000) / frameTime);
|
expected_fb = ((sampleFreq * 0x2000) / frameTime);
|
||||||
#endif
|
#endif
|
||||||
/* Reset FB */
|
/* Reset FB */
|
||||||
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
|
||||||
* to stabilise (i.e. sofCount == 128 to fire) */
|
* to stabilise (i.e. sofCount == 128 to fire) */
|
||||||
@@ -711,7 +711,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
#endif
|
#endif
|
||||||
sofCount++;
|
sofCount++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if (NUM_USB_CHAN_IN > 0)
|
#if (NUM_USB_CHAN_IN > 0)
|
||||||
/* Sent audio packet DEVICE -> HOST */
|
/* Sent audio packet DEVICE -> HOST */
|
||||||
@@ -719,8 +719,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
{
|
{
|
||||||
/* Inform stream that buffer sent */
|
/* Inform stream that buffer sent */
|
||||||
SET_SHARED_GLOBAL0(g_aud_to_host_flag, bufferIn+1);
|
SET_SHARED_GLOBAL0(g_aud_to_host_flag, bufferIn+1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NUM_USB_CHAN_OUT > 0)
|
#if (NUM_USB_CHAN_OUT > 0)
|
||||||
@@ -740,8 +740,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
{
|
{
|
||||||
XUD_SetReady_In(ep_aud_fb, (fb_clocks, unsigned char[]), 3);
|
XUD_SetReady_In(ep_aud_fb, (fb_clocks, unsigned char[]), 3);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
/* Received Audio packet HOST -> DEVICE. Datalength written to length */
|
/* Received Audio packet HOST -> DEVICE. Datalength written to length */
|
||||||
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
|
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
|
||||||
@@ -752,175 +752,165 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
|
|
||||||
/* Sync with decouple thread */
|
/* Sync with decouple thread */
|
||||||
SET_SHARED_GLOBAL0(g_aud_from_host_flag, 1);
|
SET_SHARED_GLOBAL0(g_aud_from_host_flag, 1);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
case XUD_GetData_Select(c_midi_from_host, ep_midi_from_host, length, result):
|
case XUD_GetData_Select(c_midi_from_host, ep_midi_from_host, length, result):
|
||||||
|
|
||||||
if((result == XUD_RES_OKAY) && (length > 0))
|
if((result == XUD_RES_OKAY) && (length > 0))
|
||||||
{
|
|
||||||
/* Get buffer data from host - MIDI OUT from host always into a single buffer */
|
|
||||||
midi_data_remaining_to_device = length;
|
|
||||||
|
|
||||||
midi_from_host_rdptr = midi_from_host_buffer;
|
|
||||||
|
|
||||||
if (midi_data_remaining_to_device)
|
|
||||||
{
|
{
|
||||||
read_via_xc_ptr(datum, midi_from_host_rdptr);
|
/* Get buffer data from host - MIDI OUT from host always into a single buffer */
|
||||||
outuint(c_midi, datum);
|
midi_data_remaining_to_device = length;
|
||||||
midi_from_host_rdptr += 4;
|
|
||||||
midi_data_remaining_to_device -= 4;
|
midi_from_host_rdptr = midi_from_host_buffer;
|
||||||
|
|
||||||
|
if (midi_data_remaining_to_device)
|
||||||
|
{
|
||||||
|
read_via_xc_ptr(datum, midi_from_host_rdptr);
|
||||||
|
outuint(c_midi, datum);
|
||||||
|
midi_from_host_rdptr += 4;
|
||||||
|
midi_data_remaining_to_device -= 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
/* MIDI IN to host */
|
/* MIDI IN to host */
|
||||||
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, result):
|
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, result):
|
||||||
|
|
||||||
/* The buffer has been sent to the host, so we can ack the midi thread */
|
/* The buffer has been sent to the host, so we can ack the midi thread */
|
||||||
if (midi_data_collected_from_device != 0)
|
if (midi_data_collected_from_device != 0)
|
||||||
{
|
{
|
||||||
/* Swap the collecting and sending buffer */
|
/* Swap the collecting and sending buffer */
|
||||||
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
|
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
|
||||||
|
|
||||||
/* Request to send packet */
|
/* Request to send packet */
|
||||||
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
|
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
|
||||||
|
|
||||||
/* Mark as waiting for host to poll us */
|
/* Mark as waiting for host to poll us */
|
||||||
midi_waiting_on_send_to_host = 1;
|
midi_waiting_on_send_to_host = 1;
|
||||||
/* Reset the collected data count */
|
/* Reset the collected data count */
|
||||||
midi_data_collected_from_device = 0;
|
midi_data_collected_from_device = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
midi_waiting_on_send_to_host = 0;
|
midi_waiting_on_send_to_host = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
/* IAP OUT from host. Datalength writen to tmp */
|
/* IAP OUT from host. Datalength writen to tmp */
|
||||||
case XUD_GetData_Select(c_iap_from_host, ep_iap_from_host, length, result):
|
case XUD_GetData_Select(c_iap_from_host, ep_iap_from_host, length, result):
|
||||||
|
|
||||||
if((result == XUD_RES_OKAY) && (length > 0))
|
if((result == XUD_RES_OKAY) && (length > 0))
|
||||||
{
|
|
||||||
iap_data_remaining_to_device = length;
|
|
||||||
|
|
||||||
if(iap_data_remaining_to_device)
|
|
||||||
{
|
{
|
||||||
// Send length first so iAP thread knows how much data to expect
|
iap_data_remaining_to_device = length;
|
||||||
// Don't expect ack from this to make it simpler
|
|
||||||
outuint(c_iap, iap_data_remaining_to_device);
|
|
||||||
|
|
||||||
/* Send out first byte in buffer */
|
if(iap_data_remaining_to_device)
|
||||||
datum_iap = iap_from_host_buffer[0];
|
{
|
||||||
outuint(c_iap, datum_iap);
|
// Send length first so iAP thread knows how much data to expect
|
||||||
|
// Don't expect ack from this to make it simpler
|
||||||
|
outuint(c_iap, iap_data_remaining_to_device);
|
||||||
|
|
||||||
/* Set read ptr to next byte in buffer */
|
/* Send out first byte in buffer */
|
||||||
iap_from_host_rdptr = 1;
|
datum_iap = iap_from_host_buffer[0];
|
||||||
iap_data_remaining_to_device -= 1;
|
outuint(c_iap, datum_iap);
|
||||||
|
|
||||||
|
/* Set read ptr to next byte in buffer */
|
||||||
|
iap_from_host_rdptr = 1;
|
||||||
|
iap_data_remaining_to_device -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
/* IAP IN to host */
|
/* IAP IN to host */
|
||||||
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, result):
|
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, result):
|
||||||
|
|
||||||
if(result == XUD_RES_RST)
|
if(result == XUD_RES_RST)
|
||||||
{
|
{
|
||||||
XUD_ResetEndpoint(ep_iap_to_host, null);
|
XUD_ResetEndpoint(ep_iap_to_host, null);
|
||||||
#ifdef IAP_INT_EP
|
#ifdef IAP_INT_EP
|
||||||
XUD_ResetEndpoint(ep_iap_to_host_int, null);
|
XUD_ResetEndpoint(ep_iap_to_host_int, null);
|
||||||
#endif
|
#endif
|
||||||
iap_send_reset(c_iap);
|
iap_send_reset(c_iap);
|
||||||
iap_draining_chan = 1; // Drain c_iap until a reset is sent back
|
iap_draining_chan = 1; // Drain c_iap until a reset is sent back
|
||||||
iap_data_collected_from_device = 0;
|
iap_data_collected_from_device = 0;
|
||||||
iap_data_remaining_to_device = -1;
|
iap_data_remaining_to_device = -1;
|
||||||
iap_expected_data_length = 0;
|
iap_expected_data_length = 0;
|
||||||
iap_from_host_rdptr = 0;
|
iap_from_host_rdptr = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Send out an iAP packet to host, ACK last msg from iAP to let it know we can move on..*/
|
/* Send out an iAP packet to host, ACK last msg from iAP to let it know we can move on..*/
|
||||||
iap_send_ack(c_iap);
|
iap_send_ack(c_iap);
|
||||||
}
|
}
|
||||||
break; /* IAP IN to host */
|
break; /* IAP IN to host */
|
||||||
|
|
||||||
#ifdef IAP_INT_EP
|
#ifdef IAP_INT_EP
|
||||||
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, result):
|
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, result):
|
||||||
|
|
||||||
/* Do nothing.. */
|
/* Do nothing.. */
|
||||||
/* Note, could get a reset notification here, but deal with it in the case above */
|
/* Note, could get a reset notification here, but deal with it in the case above */
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IAP_EA_NATIVE_TRANS
|
#ifdef IAP_EA_NATIVE_TRANS
|
||||||
/* iAP EA Native Transport OUT from host */
|
/* iAP EA Native Transport OUT from host */
|
||||||
case XUD_GetData_Select(c_iap_ea_native_out, ep_iap_ea_native_out, iap_ea_native_rx_length, result):
|
case XUD_GetData_Select(c_iap_ea_native_out, ep_iap_ea_native_out, iap_ea_native_rx_length, result):
|
||||||
if ((result == XUD_RES_OKAY) && iap_ea_native_rx_length > 0)
|
if ((result == XUD_RES_OKAY) && iap_ea_native_rx_length > 0)
|
||||||
{
|
{
|
||||||
// Notify EA Protocol user code we have iOS app data from XUD
|
// Notify EA Protocol user code we have iOS app data from XUD
|
||||||
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_DATA);
|
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_DATA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* iAP EA Native Transport IN to host */
|
/* iAP EA Native Transport IN to host */
|
||||||
case XUD_SetData_Select(c_iap_ea_native_in, ep_iap_ea_native_in, result):
|
case XUD_SetData_Select(c_iap_ea_native_in, ep_iap_ea_native_in, result):
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case XUD_RES_RST:
|
case XUD_RES_RST:
|
||||||
XUD_ResetEndpoint(ep_iap_ea_native_in, null);
|
XUD_ResetEndpoint(ep_iap_ea_native_in, null);
|
||||||
// Notify user code of USB reset to allow any state to be cleared
|
// Notify user code of USB reset to allow any state to be cleared
|
||||||
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
|
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
|
||||||
// Set up the control flag to send to EA Protocol user code when it responds
|
// Set up the control flag to send to EA Protocol user code when it responds
|
||||||
iap_ea_native_control_flag = EA_NATIVE_RESET;
|
iap_ea_native_control_flag = EA_NATIVE_RESET;
|
||||||
iap_ea_native_control_to_send = 1;
|
iap_ea_native_control_to_send = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XUD_RES_OKAY: // EA Protocol user data successfully passed to XUD
|
case XUD_RES_OKAY: // EA Protocol user data successfully passed to XUD
|
||||||
// Notify user code
|
// Notify user code
|
||||||
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
|
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
|
||||||
// Set up the control flag to send to EA Protocol user code when it responds
|
// Set up the control flag to send to EA Protocol user code when it responds
|
||||||
iap_ea_native_control_flag = EA_NATIVE_DATA_SENT;
|
iap_ea_native_control_flag = EA_NATIVE_DATA_SENT;
|
||||||
iap_ea_native_control_to_send = 1;
|
iap_ea_native_control_to_send = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
//::
|
//::
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if( 0 < HID_CONTROLS )
|
||||||
/* HID Report Data */
|
/* HID Report Data */
|
||||||
case (hidIsChangePending(0U) || !HidIsSetIdleSilenced(0U)) => XUD_SetData_Select(c_hid, ep_hid, result):
|
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||||
{
|
hid_ready_flag = 0U;
|
||||||
timer tmr;
|
|
||||||
unsigned reportTime;
|
unsigned reportTime;
|
||||||
tmr :> reportTime;
|
tmr :> reportTime;
|
||||||
|
hidCaptureReportTime(hid_ready_id, reportTime);
|
||||||
for(unsigned id = hidIsReportIdInUse(); id < hidGetReportIdLimit(); ++id) {
|
hidCalcNextReportTime(hid_ready_id);
|
||||||
if(0U == id || (hidIsChangePending(id) || !HidIsSetIdleSilenced(id))) {
|
hidClearChangePending(hid_ready_id);
|
||||||
hidCaptureReportTime(id, reportTime);
|
break;
|
||||||
int hidDataLength = (int) UserHIDGetData(id, g_hidData);
|
|
||||||
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
|
|
||||||
hidCalcNextReportTime(id);
|
|
||||||
hidClearChangePending(id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MIDI
|
#ifdef MIDI
|
||||||
/* Received word from MIDI thread - Check for ACK or Data */
|
/* Received word from MIDI thread - Check for ACK or Data */
|
||||||
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
case midi_get_ack_or_data(c_midi, is_ack, datum):
|
||||||
if (is_ack)
|
if (is_ack)
|
||||||
{
|
{
|
||||||
/* An ack from the midi/uart thread means it has accepted some data we sent it
|
/* An ack from the midi/uart thread means it has accepted some data we sent it
|
||||||
* we are okay to send another word */
|
* we are okay to send another word */
|
||||||
if (midi_data_remaining_to_device <= 0)
|
if (midi_data_remaining_to_device <= 0)
|
||||||
{
|
{
|
||||||
/* We have read an entire packet - Mark ready to receive another */
|
/* We have read an entire packet - Mark ready to receive another */
|
||||||
@@ -985,7 +975,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
if (is_ack_iap)
|
if (is_ack_iap)
|
||||||
{
|
{
|
||||||
/* An ack from the iap/uart thread means it has accepted some data we sent it
|
/* An ack from the iap/uart thread means it has accepted some data we sent it
|
||||||
* we are okay to send another word */
|
* we are okay to send another word */
|
||||||
if (iap_data_remaining_to_device == 0)
|
if (iap_data_remaining_to_device == 0)
|
||||||
{
|
{
|
||||||
/* We have read an entire packet - Mark ready to receive another */
|
/* We have read an entire packet - Mark ready to receive another */
|
||||||
@@ -1018,7 +1008,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Too many events from device - drop
|
// Too many events from device - drop
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Once we have the whole message, sent it to host */
|
/* Once we have the whole message, sent it to host */
|
||||||
@@ -1056,7 +1046,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
# if IAP_EA_NATIVE_TRANS
|
# if IAP_EA_NATIVE_TRANS
|
||||||
/* Change of EA Native Transport interface setting */
|
/* Change of EA Native Transport interface setting */
|
||||||
case inuint_byref(c_iap_ea_native_ctrl, iap_ea_native_interface_alt_setting):
|
case inuint_byref(c_iap_ea_native_ctrl, iap_ea_native_interface_alt_setting):
|
||||||
/* Handshake */
|
/* Handshake */
|
||||||
@@ -1114,6 +1104,26 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
#if ( 0 < HID_CONTROLS )
|
||||||
|
if (!hid_ready_flag)
|
||||||
|
{
|
||||||
|
for (unsigned id = hidIsReportIdInUse(); id < hidGetReportIdLimit(); id++)
|
||||||
|
{
|
||||||
|
if ( hidIsChangePending(id) || !HidIsSetIdleSilenced(id) )
|
||||||
|
{
|
||||||
|
int hidDataLength = (int) UserHIDGetData(id, g_hidData);
|
||||||
|
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
|
||||||
|
|
||||||
|
hid_ready_id = id;
|
||||||
|
hid_ready_flag = 1U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
//::
|
//::
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1121,7 +1131,6 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* XUA_USB_EN */
|
#endif /* XUA_USB_EN */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019-2021 XMOS LIMITED.
|
// Copyright 2019-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
#include "xua_hid.h"
|
#include "xua_hid.h"
|
||||||
#include "xua_hid_report.h"
|
#include "xua_hid_report.h"
|
||||||
|
|
||||||
|
#define DEBUG_UNIT HID_XC
|
||||||
|
#define DEBUG_PRINT_ENABLE_HID_XC 0
|
||||||
|
#include "debug_print.h"
|
||||||
|
|
||||||
#if( 0 < HID_CONTROLS )
|
#if( 0 < HID_CONTROLS )
|
||||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
||||||
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
||||||
@@ -37,26 +41,26 @@ XUD_Result_t HidInterfaceClassRequests(
|
|||||||
|
|
||||||
unsigned HidIsSetIdleSilenced( const unsigned id )
|
unsigned HidIsSetIdleSilenced( const unsigned id )
|
||||||
{
|
{
|
||||||
unsigned isSilenced = hidIsIdleActive( id );
|
unsigned isSilenced = hidIsIdleActive( id );
|
||||||
|
|
||||||
if( !isSilenced ) {
|
if( !isSilenced ) {
|
||||||
unsigned currentTime;
|
unsigned currentTime;
|
||||||
// Use inline assembly to access the time without creating a side-effect.
|
// Use inline assembly to access the time without creating a side-effect.
|
||||||
// The mapper complains if the time comes from an XC timer because this function is called in the guard of a select case.
|
// The mapper complains if the time comes from an XC timer because this function is called in the guard of a select case.
|
||||||
// Appearently the use of a timer creates a side-effect that prohibits the operation of the select functionality.
|
// Appearently the use of a timer creates a side-effect that prohibits the operation of the select functionality.
|
||||||
asm volatile( "gettime %0" : "=r" ( currentTime ));
|
asm volatile( "gettime %0" : "=r" ( currentTime ));
|
||||||
isSilenced = ( 0U == hidGetReportPeriod( id ) || ( timeafter( hidGetNextReportTime( id ), currentTime )));
|
isSilenced = ( 0U == hidGetReportPeriod( id ) || ( timeafter( hidGetNextReportTime( id ), currentTime )));
|
||||||
}
|
}
|
||||||
|
|
||||||
return isSilenced;
|
return isSilenced;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Calculate the timer value for sending the next HID Report.
|
* \brief Calculate the timer value for sending the next HID Report.
|
||||||
*
|
*
|
||||||
* With regard to Section 7.2.4 Set_Idle Request of the USB Device Class Definition for Human
|
* With regard to Section 7.2.4 Set_Idle Request of the USB Device Class Definition for Human
|
||||||
* Interface Devices (HID) Version 1.11, I've interpreted 'currently executing period' and
|
* Interface Devices (HID) Version 1.11, 'currently executing period' and 'current period' have
|
||||||
* 'current period' to mean the previously established Set Idle duration if one has been
|
* been interpreted to mean the previously established Set Idle duration if one has been
|
||||||
* established or the polling interval from the HID Report Descriptor if a Set Idle duration
|
* established or the polling interval from the HID Report Descriptor if a Set Idle duration
|
||||||
* has not been established.
|
* has not been established.
|
||||||
*
|
*
|
||||||
@@ -147,8 +151,6 @@ static void HidUpdateReportPeriod( unsigned reportId, unsigned reportDuration )
|
|||||||
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, reportDuration * MS_IN_TICKS );
|
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, reportDuration * MS_IN_TICKS );
|
||||||
hidSetNextReportTime( reportId, nextReportTime );
|
hidSetNextReportTime( reportId, nextReportTime );
|
||||||
currentPeriod = reportDuration * MS_IN_TICKS;
|
currentPeriod = reportDuration * MS_IN_TICKS;
|
||||||
} else {
|
|
||||||
currentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hidSetReportPeriod( reportId, currentPeriod );
|
hidSetReportPeriod( reportId, currentPeriod );
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -9,15 +9,20 @@
|
|||||||
#include "descriptor_defs.h"
|
#include "descriptor_defs.h"
|
||||||
#include "xua_hid_report.h"
|
#include "xua_hid_report.h"
|
||||||
#include "hid_report_descriptor.h"
|
#include "hid_report_descriptor.h"
|
||||||
|
#include "swlock.h"
|
||||||
|
|
||||||
|
|
||||||
#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 )
|
#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 )
|
||||||
#define HID_REPORT_DESCRIPTOR_ITEM_COUNT ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t* ))
|
#define HID_REPORT_DESCRIPTOR_ITEM_COUNT ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t* ))
|
||||||
#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( HID_REPORT_DESCRIPTOR_ITEM_COUNT * \
|
#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( HID_REPORT_DESCRIPTOR_ITEM_COUNT * \
|
||||||
( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE ))
|
( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE ))
|
||||||
|
|
||||||
|
swlock_t hidStaticVarLock = SWLOCK_INITIAL_VALUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each element in s_hidChangePending corresponds to an element in hidReports.
|
* Each element in s_hidChangePending corresponds to an element in hidReports.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned s_hidChangePending[ HID_REPORT_COUNT ];
|
static unsigned s_hidChangePending[ HID_REPORT_COUNT ];
|
||||||
static unsigned char s_hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ];
|
static unsigned char s_hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ];
|
||||||
static size_t s_hidReportDescriptorLength;
|
static size_t s_hidReportDescriptorLength;
|
||||||
@@ -131,33 +136,42 @@ static unsigned hidGetUsagePage( const unsigned id );
|
|||||||
*/
|
*/
|
||||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr );
|
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr );
|
||||||
|
|
||||||
|
unsigned hidIsReportIdInUse ( void ) {
|
||||||
|
return !hidIsReportIdValid(0U);
|
||||||
|
}
|
||||||
|
|
||||||
void hidCalcNextReportTime( const unsigned id )
|
void hidCalcNextReportTime( const unsigned id )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidNextReportTime[ idx ] = s_hidReportTime[ idx ] + s_hidCurrentPeriod[ idx ];
|
s_hidNextReportTime[ idx ] = s_hidReportTime[ idx ] + s_hidCurrentPeriod[ idx ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidCaptureReportTime( const unsigned id, const unsigned time )
|
void hidCaptureReportTime( const unsigned id, const unsigned time )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidReportTime[ idx ] = time;
|
s_hidReportTime[ idx ] = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidClearChangePending( const unsigned id )
|
void hidClearChangePending( const unsigned id )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if(( id == 0U ) || ( id == hidGetElementReportId( hidReports[ idx ]->location ))) {
|
if(( id == 0U ) || ( id == hidGetElementReportId( hidReports[ idx ]->location ))) {
|
||||||
s_hidChangePending[ idx ] = 0U;
|
s_hidChangePending[ idx ] = 0U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned hidGetElementBitLocation( const unsigned short location )
|
static unsigned hidGetElementBitLocation( const unsigned short location )
|
||||||
@@ -203,74 +217,56 @@ static unsigned hidGetItemType( const unsigned char header )
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidGetNextReportTime( const unsigned id ) {
|
unsigned hidGetNextReportTime( const unsigned id ) {
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
|
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for ( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
retVal = s_hidNextReportTime[ idx ];
|
retVal = s_hidNextReportTime[ idx ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidIsReportDescriptorPrepared( void )
|
|
||||||
{
|
|
||||||
return s_hidReportDescriptorPrepared;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* hidGetReportDescriptor( void )
|
unsigned char* hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
unsigned char* retVal = NULL;
|
unsigned char* retVal = NULL;
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
|
|
||||||
if( s_hidReportDescriptorPrepared ) {
|
if( s_hidReportDescriptorPrepared ) {
|
||||||
retVal = s_hidReportDescriptor;
|
retVal = s_hidReportDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hidGetReportDescriptorLength( void )
|
size_t hidGetReportDescriptorLength( void )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
size_t retVal = ( s_hidReportDescriptorPrepared ) ? s_hidReportDescriptorLength : 0U;
|
size_t retVal = ( s_hidReportDescriptorPrepared ) ? s_hidReportDescriptorLength : 0U;
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidGetReportIdLimit ( void ) {
|
unsigned hidGetReportIdLimit ( void ) {
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
|
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||||
if( reportId >= retVal ) {
|
if( reportId >= retVal ) {
|
||||||
retVal = reportId + 1;
|
retVal = reportId + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retVal;
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
|
||||||
|
|
||||||
unsigned hidIsReportIdInUse ( void ) {
|
|
||||||
if ( hidGetElementReportId( hidReports[ 0 ]->location ) ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
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;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
||||||
size_t retIndex = 0;
|
size_t retIndex = 0;
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||||
if( reportId == idPrev ) {
|
if( reportId == idPrev ) {
|
||||||
@@ -279,7 +275,9 @@ unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hidGetElementReportId( hidReports[ retIndex ]->location );
|
unsigned retVal = hidGetElementReportId( hidReports[ retIndex ]->location );
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HID_CONFIGURABLE_ELEMENT_COUNT ( sizeof hidConfigurableElements / sizeof ( USB_HID_Report_Element_t* ))
|
#define HID_CONFIGURABLE_ELEMENT_COUNT ( sizeof hidConfigurableElements / sizeof ( USB_HID_Report_Element_t* ))
|
||||||
@@ -294,7 +292,10 @@ unsigned hidGetReportItem(
|
|||||||
{
|
{
|
||||||
unsigned retVal = HID_STATUS_BAD_ID;
|
unsigned retVal = HID_STATUS_BAD_ID;
|
||||||
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
|
|
||||||
unsigned bBit = hidGetElementBitLocation( element.location );
|
unsigned bBit = hidGetElementBitLocation( element.location );
|
||||||
unsigned bByte = hidGetElementByteLocation( element.location );
|
unsigned bByte = hidGetElementByteLocation( element.location );
|
||||||
unsigned bId = hidGetElementReportId( element.location );
|
unsigned bId = hidGetElementReportId( element.location );
|
||||||
@@ -320,6 +321,7 @@ unsigned hidGetReportItem(
|
|||||||
|
|
||||||
size_t hidGetReportLength( const unsigned id )
|
size_t hidGetReportLength( const unsigned id )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
size_t retVal = 0U;
|
size_t retVal = 0U;
|
||||||
if( s_hidReportDescriptorPrepared ) {
|
if( s_hidReportDescriptorPrepared ) {
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
@@ -328,11 +330,13 @@ size_t hidGetReportLength( const unsigned id )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidGetReportPeriod( const unsigned id )
|
unsigned hidGetReportPeriod( const unsigned id )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
@@ -340,10 +344,13 @@ unsigned hidGetReportPeriod( const unsigned id )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidGetReportTime( const unsigned id ) {
|
unsigned hidGetReportTime( const unsigned id )
|
||||||
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
|
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
@@ -351,55 +358,85 @@ unsigned hidGetReportTime( const unsigned id ) {
|
|||||||
retVal = s_hidReportTime[ idx ];
|
retVal = s_hidReportTime[ idx ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned hidGetUsagePage( const unsigned id )
|
static unsigned hidGetUsagePage( const unsigned id )
|
||||||
{
|
{
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
|
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
retVal = hidReports[ idx ]->item.data[ 0 ];
|
retVal = hidReports[ idx ]->item.data[ 0 ];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidIsChangePending( const unsigned id )
|
unsigned hidIsChangePending( const unsigned id )
|
||||||
{
|
{
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
|
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == 0U && s_hidChangePending[ idx ] != 0U ) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
retVal = 1;
|
|
||||||
} else if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
|
||||||
retVal = ( s_hidChangePending[ idx ] != 0U );
|
retVal = ( s_hidChangePending[ idx ] != 0U );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidIsIdleActive( const unsigned id )
|
unsigned hidIsIdleActive( const unsigned id )
|
||||||
{
|
{
|
||||||
unsigned retVal = 0U;
|
unsigned retVal = 0U;
|
||||||
if( 0U == id ) {
|
|
||||||
retVal = 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == 0U ) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
retVal &= ( s_hidIdleActive[ idx ] != 0U );
|
|
||||||
} else if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
|
||||||
retVal = ( s_hidIdleActive[ idx ] != 0U );
|
retVal = ( s_hidIdleActive[ idx ] != 0U );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retVal;
|
swlock_release(&hidStaticVarLock);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned hidIsReportDescriptorPrepared( void )
|
||||||
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
|
unsigned retVal = s_hidReportDescriptorPrepared;
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned hidIsReportIdValid ( unsigned id ) {
|
||||||
|
size_t retVal = 0;
|
||||||
|
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
|
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||||
|
if( reportId == id ) {
|
||||||
|
retVal = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidPrepareReportDescriptor( void )
|
void hidPrepareReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
if( !s_hidReportDescriptorPrepared ) {
|
if( !s_hidReportDescriptorPrepared ) {
|
||||||
s_hidReportDescriptorLength = 0U;
|
s_hidReportDescriptorLength = 0U;
|
||||||
unsigned char* ptr = s_hidReportDescriptor;
|
unsigned char* ptr = s_hidReportDescriptor;
|
||||||
@@ -410,49 +447,60 @@ void hidPrepareReportDescriptor( void )
|
|||||||
|
|
||||||
s_hidReportDescriptorPrepared = 1U;
|
s_hidReportDescriptorPrepared = 1U;
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidReportInit( void )
|
void hidReportInit( void )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( unsigned idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( unsigned idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
s_hidCurrentPeriod[ idx ] = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
s_hidCurrentPeriod[ idx ] = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS * HID_REPORT_COUNT;
|
||||||
}
|
}
|
||||||
memset( s_hidIdleActive, 0, sizeof( s_hidIdleActive ) );
|
memset( s_hidIdleActive, 0, sizeof( s_hidIdleActive ) );
|
||||||
memset( s_hidChangePending, 0, sizeof( s_hidChangePending ) );
|
memset( s_hidChangePending, 0, sizeof( s_hidChangePending ) );
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidResetReportDescriptor( void )
|
void hidResetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
s_hidReportDescriptorPrepared = 0U;
|
s_hidReportDescriptorPrepared = 0U;
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidSetChangePending( const unsigned id )
|
void hidSetChangePending( const unsigned id )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidChangePending[ idx ] = 1U;
|
s_hidChangePending[ idx ] = 1U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidSetIdle( const unsigned id, const unsigned state )
|
void hidSetIdle( const unsigned id, const unsigned state )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidIdleActive[ idx ] = ( state != 0U );
|
s_hidIdleActive[ idx ] = ( state != 0U );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidSetNextReportTime( const unsigned id, const unsigned time )
|
void hidSetNextReportTime( const unsigned id, const unsigned time )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidNextReportTime[ idx ] = time;
|
s_hidNextReportTime[ idx ] = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hidSetReportItem(
|
unsigned hidSetReportItem(
|
||||||
@@ -478,7 +526,10 @@ unsigned hidSetReportItem(
|
|||||||
retVal = HID_STATUS_BAD_HEADER;
|
retVal = HID_STATUS_BAD_HEADER;
|
||||||
} else {
|
} else {
|
||||||
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
|
|
||||||
unsigned bBit = hidGetElementBitLocation( element.location );
|
unsigned bBit = hidGetElementBitLocation( element.location );
|
||||||
unsigned bByte = hidGetElementByteLocation( element.location );
|
unsigned bByte = hidGetElementByteLocation( element.location );
|
||||||
unsigned bId = hidGetElementReportId( element.location );
|
unsigned bId = hidGetElementReportId( element.location );
|
||||||
@@ -501,7 +552,9 @@ unsigned hidSetReportItem(
|
|||||||
element.item.data[ dataIdx ] = 0U;
|
element.item.data[ dataIdx ] = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
*hidConfigurableElements[ elementIdx ] = element;
|
*hidConfigurableElements[ elementIdx ] = element;
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
retVal = HID_STATUS_GOOD;
|
retVal = HID_STATUS_GOOD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -510,18 +563,19 @@ unsigned hidSetReportItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidSetReportPeriod( const unsigned id, const unsigned period )
|
void hidSetReportPeriod( const unsigned id, const unsigned period )
|
||||||
{
|
{
|
||||||
|
swlock_acquire(&hidStaticVarLock);
|
||||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||||
s_hidCurrentPeriod[ idx ] = period;
|
s_hidCurrentPeriod[ idx ] = period;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swlock_release(&hidStaticVarLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
|
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
|
||||||
@@ -796,4 +850,4 @@ unsigned hidReportValidate( void )
|
|||||||
} else {
|
} else {
|
||||||
return hidReportValidateInfoStruct( &info );
|
return hidReportValidateInfoStruct( &info );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019-2021 XMOS LIMITED.
|
// Copyright 2019-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,6 +113,45 @@ typedef struct
|
|||||||
unsigned short location;
|
unsigned short location;
|
||||||
} USB_HID_Report_Element_t;
|
} USB_HID_Report_Element_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Calculate the next time to respond with a HID Report.
|
||||||
|
*
|
||||||
|
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||||
|
* a duration of zero or greater than the default reporting interval,
|
||||||
|
* the device sends HID Reports periodically or when the value of the
|
||||||
|
* payload has changed.
|
||||||
|
*
|
||||||
|
* This function calculates the time for sending the next periodic
|
||||||
|
* HID Report.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||||
|
* A value of zero means the application does not use Report IDs.
|
||||||
|
*/
|
||||||
|
void hidCalcNextReportTime( const unsigned id );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Capture the time of sending the current HID Report.
|
||||||
|
*
|
||||||
|
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||||
|
* a duration of zero or greater than the default reporting interval,
|
||||||
|
* the device sends HID Reports periodically or when the value of the
|
||||||
|
* payload has changed.
|
||||||
|
*
|
||||||
|
* This function captures the time when the HID Report was sent so that
|
||||||
|
* a subsequent call to HidCalNextReportTime() can calculate the time
|
||||||
|
* to send the next periodic HID Report.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||||
|
* A value of zero means the application does not use Report IDs.
|
||||||
|
*
|
||||||
|
* @param[in] time The time when the HID Report for the given \a id was sent.
|
||||||
|
*/
|
||||||
|
void hidCaptureReportTime( const unsigned id, const unsigned time );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Register that a previously changed HID Report data has been sent
|
* \brief Register that a previously changed HID Report data has been sent
|
||||||
* to the USB Host.
|
* to the USB Host.
|
||||||
@@ -134,22 +173,24 @@ typedef struct
|
|||||||
* HID data has been reported to the USB Host.
|
* HID data has been reported to the USB Host.
|
||||||
*
|
*
|
||||||
* \warning This function will fail silently if given an id that is not
|
* \warning This function will fail silently if given an id that is not
|
||||||
* either the value zero, or a Report ID that is in use.
|
* either the value zero (in the case that Report IDs are not in use),
|
||||||
|
* or a Report ID that is in use.
|
||||||
*
|
*
|
||||||
* \param[in] id A HID Report ID.
|
* \param[in] id A HID Report ID.
|
||||||
* Zero clears the pending status of all Report IDs.
|
|
||||||
* Use zero if the application does not use Report IDs.
|
* Use zero if the application does not use Report IDs.
|
||||||
*/
|
*/
|
||||||
void hidClearChangePending( const unsigned id );
|
void hidClearChangePending( const unsigned id );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Indicate if the HID Report descriptor has been prepared
|
* @brief Get the next valid report ID - iterator style.
|
||||||
*
|
*
|
||||||
* \returns A Boolean indicating whether the HID Report descriptor has been prepared.
|
* This function will loop around and start returning the first report ID again once it has
|
||||||
* \retval True The HID Report descriptor has been prepared.
|
* returned all valid report IDs.
|
||||||
* \retval False The HID Report descriptor has not been prepared.
|
*
|
||||||
|
* @param idPrev The previous returned id, or 0 if this is the first call
|
||||||
|
* @return unsigned The next valid report ID.
|
||||||
*/
|
*/
|
||||||
unsigned hidIsReportDescriptorPrepared( void );
|
unsigned hidGetNextValidReportId ( unsigned idPrev );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the HID Report descriptor
|
* @brief Get the HID Report descriptor
|
||||||
@@ -190,44 +231,6 @@ size_t hidGetReportDescriptorLength( void );
|
|||||||
*/
|
*/
|
||||||
unsigned hidGetReportIdLimit ( void );
|
unsigned hidGetReportIdLimit ( void );
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Does the application use Report IDs?
|
|
||||||
*
|
|
||||||
* If the application is not using Report IDs, then the id value that is passed around
|
|
||||||
* everywhere can just be zero. Otherwise zero is an invalid ID that has a special meaning
|
|
||||||
* in some cases (read the documentation for each function).
|
|
||||||
*
|
|
||||||
* @return Boolean
|
|
||||||
* @retval 1 Report IDs are in use
|
|
||||||
* @retval 0 Report IDs are not in use
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* This function will loop around and start returning the first report ID again once it has
|
|
||||||
* returned all valid report IDs.
|
|
||||||
*
|
|
||||||
* @param idPrev The previous returned id, or 0 if this is the first call
|
|
||||||
* @return unsigned The next valid report ID.
|
|
||||||
*/
|
|
||||||
unsigned hidGetNextValidReportId ( unsigned idPrev );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a HID Report descriptor item
|
* @brief Get a HID Report descriptor item
|
||||||
*
|
*
|
||||||
@@ -265,45 +268,6 @@ unsigned hidGetReportItem(
|
|||||||
unsigned char data[]);
|
unsigned char data[]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Calculate the next time to respond with a HID Report.
|
|
||||||
*
|
|
||||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
|
||||||
* a duration of zero or greater than the default reporting interval,
|
|
||||||
* the device sends HID Reports periodically or when the value of the
|
|
||||||
* payload has changed.
|
|
||||||
*
|
|
||||||
* This function calculates the time for sending the next periodic
|
|
||||||
* HID Report.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
|
||||||
* A value of zero means the application does not use Report IDs.
|
|
||||||
*/
|
|
||||||
void hidCalcNextReportTime( const unsigned id );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Capture the time of sending the current HID Report.
|
|
||||||
*
|
|
||||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
|
||||||
* a duration of zero or greater than the default reporting interval,
|
|
||||||
* the device sends HID Reports periodically or when the value of the
|
|
||||||
* payload has changed.
|
|
||||||
*
|
|
||||||
* This function captures the time when the HID Report was sent so that
|
|
||||||
* a subsequent call to HidCalNextReportTime() can calculate the time
|
|
||||||
* to send the next periodic HID Report.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
*
|
|
||||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
|
||||||
* A value of zero means the application does not use Report IDs.
|
|
||||||
*
|
|
||||||
* @param[in] time The time when the HID Report for the given \a id was sent.
|
|
||||||
*/
|
|
||||||
void hidCaptureReportTime( const unsigned id, const unsigned time );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the time to send the next HID Report for the given \a id
|
* @brief Get the time to send the next HID Report for the given \a id
|
||||||
*
|
*
|
||||||
@@ -378,18 +342,16 @@ unsigned hidGetReportTime( const unsigned id );
|
|||||||
* whether unreported HID data exists for that Report ID.
|
* whether unreported HID data exists for that Report ID.
|
||||||
*
|
*
|
||||||
* \warning This function will return zero if given an id that is not
|
* \warning This function will return zero if given an id that is not
|
||||||
* either the value zero, or a Report ID that is in use.
|
* either the value zero (in the case that Report IDs are not in use),
|
||||||
|
* or a Report ID that is in use.
|
||||||
*
|
*
|
||||||
* \param[in] id A HID Report ID.
|
* \param[in] id A HID Report ID.
|
||||||
* Zero reports the pending status of all Report IDs.
|
|
||||||
* Use zero if the application does not use Report IDs.
|
* Use zero if the application does not use Report IDs.
|
||||||
*
|
*
|
||||||
* \returns A Boolean indicating whether the given \a id has a changed
|
* \returns A Boolean indicating whether the given \a id has a changed
|
||||||
* HID Report not yet sent to the USB Host.
|
* HID Report not yet sent to the USB Host.
|
||||||
* \retval True The given \a id has changed HID Report data.
|
* \retval True The given \a id has changed HID Report data.
|
||||||
* For an \a id of zero, some HID Report has changed data.
|
|
||||||
* \retval False The given \a id does not have changed HID Report data.
|
* \retval False The given \a id does not have changed HID Report data.
|
||||||
* For an \a id of zero, no HID Report has changed data.
|
|
||||||
*/
|
*/
|
||||||
unsigned hidIsChangePending( const unsigned id );
|
unsigned hidIsChangePending( const unsigned id );
|
||||||
|
|
||||||
@@ -399,16 +361,48 @@ unsigned hidIsChangePending( const unsigned id );
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||||
* A value of zero returns the collective Idle state.
|
|
||||||
*
|
*
|
||||||
* \returns A Boolean indicating whether the HID Report for the given \a id is idle.
|
* \returns A Boolean indicating whether the HID Report for the given \a id is idle.
|
||||||
* \retval True The HID Report is idle.
|
* \retval True The HID Report is idle.
|
||||||
* For an \a id of zero, all HID Reports are idle.
|
|
||||||
* \retval False The HID Report is not idle.
|
* \retval False The HID Report is not idle.
|
||||||
* For an \a id of zero, at least one HID Report is not idle.
|
|
||||||
*/
|
*/
|
||||||
unsigned hidIsIdleActive( const unsigned id );
|
unsigned hidIsIdleActive( const unsigned id );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Indicate if the HID Report descriptor has been prepared
|
||||||
|
*
|
||||||
|
* \returns A Boolean indicating whether the HID Report descriptor has been prepared.
|
||||||
|
* \retval True The HID Report descriptor has been prepared.
|
||||||
|
* \retval False The HID Report descriptor has not been prepared.
|
||||||
|
*/
|
||||||
|
unsigned hidIsReportDescriptorPrepared( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Does the application use Report IDs?
|
||||||
|
*
|
||||||
|
* If the application is not using Report IDs, then the id value that is passed around
|
||||||
|
* everywhere can just be zero. Otherwise zero is an invalid ID.
|
||||||
|
*
|
||||||
|
* @return Boolean
|
||||||
|
* @retval 1 Report IDs are in use
|
||||||
|
* @retval 0 Report IDs are not in use
|
||||||
|
*/
|
||||||
|
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 this 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 Prepare the USB HID Report descriptor
|
* @brief Prepare the USB HID Report descriptor
|
||||||
*
|
*
|
||||||
@@ -454,7 +448,8 @@ void hidResetReportDescriptor( void );
|
|||||||
* Host.
|
* Host.
|
||||||
*
|
*
|
||||||
* \warning This function will fail silently if given an id that is not
|
* \warning This function will fail silently if given an id that is not
|
||||||
* either the value zero, or a Report ID that is in use.
|
* either the value zero (in the case that Report IDs are not in use),
|
||||||
|
* or a Report ID that is in use.
|
||||||
*
|
*
|
||||||
* \param[in] id A HID Report ID.
|
* \param[in] id A HID Report ID.
|
||||||
* Use zero if the application does not use Report IDs.
|
* Use zero if the application does not use Report IDs.
|
||||||
|
|||||||
7
module_locks/README.rst
Normal file
7
module_locks/README.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module_locks Readme
|
||||||
|
===================
|
||||||
|
|
||||||
|
:scope: Dummy module
|
||||||
|
:description: Allows compiling legacy_tests in lib_xua with lib_locks. sc_i2c is used in the tests and it requires module_locks from sc_util, but the definitions in sc_utils conflict with the ones in lib_locks.
|
||||||
|
:keywords: dummy
|
||||||
|
:boards: XMOS Dev Kit
|
||||||
1
module_locks/module_build_info
Normal file
1
module_locks/module_build_info
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# Dummy module used in legacy_tests. See README.rst for more details.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -775,7 +775,6 @@ void test_initial_modification_with_subsequent_verification_2( void )
|
|||||||
//setIdle and associated timing functionality tests
|
//setIdle and associated timing functionality tests
|
||||||
void test_set_idle( void )
|
void test_set_idle( void )
|
||||||
{
|
{
|
||||||
unsigned reportIdAll = 0;
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -785,23 +784,16 @@ void test_set_idle( void )
|
|||||||
setIdle = hidIsIdleActive( reportId2 );
|
setIdle = hidIsIdleActive( reportId2 );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||||
|
|
||||||
setIdle = hidIsIdleActive( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
|
||||||
|
|
||||||
hidSetIdle( reportId, 1 );
|
hidSetIdle( reportId, 1 );
|
||||||
setIdle = hidIsIdleActive( reportId );
|
setIdle = hidIsIdleActive( reportId );
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||||
|
|
||||||
setIdle = hidIsIdleActive( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
|
||||||
|
|
||||||
setIdle = hidIsIdleActive( reportId2 );
|
setIdle = hidIsIdleActive( reportId2 );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_set_all_idle( void )
|
void test_set_all_idle( void )
|
||||||
{
|
{
|
||||||
unsigned reportIdAll = 0;
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -811,22 +803,15 @@ void test_set_all_idle( void )
|
|||||||
setIdle = hidIsIdleActive( reportId2 );
|
setIdle = hidIsIdleActive( reportId2 );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||||
|
|
||||||
setIdle = hidIsIdleActive( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
|
||||||
|
|
||||||
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
||||||
hidSetIdle( reportId, 1 );
|
hidSetIdle( reportId, 1 );
|
||||||
setIdle = hidIsIdleActive( reportId );
|
setIdle = hidIsIdleActive( reportId );
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||||
}
|
}
|
||||||
|
|
||||||
setIdle = hidIsIdleActive( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_change_pending( void )
|
void test_change_pending( void )
|
||||||
{
|
{
|
||||||
unsigned reportIdAll = 0;
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -836,39 +821,26 @@ void test_change_pending( void )
|
|||||||
changePending = hidIsChangePending( reportId2 );
|
changePending = hidIsChangePending( reportId2 );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||||
|
|
||||||
changePending = hidIsChangePending( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
|
||||||
|
|
||||||
hidSetChangePending( reportId );
|
hidSetChangePending( reportId );
|
||||||
changePending = hidIsChangePending( reportId );
|
changePending = hidIsChangePending( reportId );
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||||
|
|
||||||
changePending = hidIsChangePending( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
|
||||||
|
|
||||||
changePending = hidIsChangePending( reportId2 );
|
changePending = hidIsChangePending( reportId2 );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_change_pending_all( void )
|
void test_change_pending_all( void )
|
||||||
{
|
{
|
||||||
unsigned reportIdAll = 0;
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
|
|
||||||
unsigned changePending = hidIsChangePending( reportId );
|
unsigned changePending = hidIsChangePending( reportId );
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||||
|
|
||||||
changePending = hidIsChangePending( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
|
||||||
|
|
||||||
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
||||||
hidSetChangePending( reportId );
|
hidSetChangePending( reportId );
|
||||||
changePending = hidIsChangePending( reportId );
|
changePending = hidIsChangePending( reportId );
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||||
}
|
}
|
||||||
|
|
||||||
changePending = hidIsChangePending( reportIdAll );
|
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_report_time( void )
|
void test_report_time( void )
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2022 XMOS LIMITED.
|
||||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user