Hi,
I am trying to replicate the following piece of C++ code in Python using
pyusb.
All sensors use Feature reports of 1+32 Bytes length. The first byte is not
really part of the
report, but it is the report number. It is always 0 for all sensors of this
type. I have included the Algorithm recommended.
Feature Out reports
Byte Name Description
0 Rpt# Report number, always 0 for all sensors
1 GnS 0 = Set configuration parameter
1 = Get configuration parameter
2 Tgt Location of the parameter
0 = RAM (volatile parameter)
1 = Flash (nonvolatile parameter)
2 = CPU
3 = Sensor
4 = other
3 Size Number of Data Bytes
4 Index LSB
5 Index MSB Index to the selected configuration parameter
e.g. parameter number, or sensor register address
6-32 Data Parameter value. The exact meaning depends on the parameter.
Feature In reports
Byte Name Description
0 Rpt# Report number, always 0 for all Oak sensors
1 Status 0xFF
2-32 Data Parameter value. The exact meaning depends on the parameter.
Details can be found in the sensor datasheet.
= report contains valid data, Oak device is ready to receive a new
command all other values = report contains invalid data.
This happens typically when the feature In report is
requested,before the device had enough time to prepare the data.
*The manuafacturer's General(recommended) Algorithm to write a Parameter
which their codes does not adhere to completely*
Repeat
Read Feature In Report
(optional delay)
Until Byte 1 of the report is 0xFF
Write Feature Out report
Repeat
Read Feature In Report
(optional delay)
Until Byte 1 of the report is 0xFF
this is, the device is ready to receive a new command through a feature
out report
The actual transfer of the command for safety, wait until the device has
finished processing this command.
//*************************************************************************************************
/// \param[in] deviceHandle The device handle
/// \param[in] ledMode The LED blinking mode to set
/// \param[in] persistent Should the setting be persistent (i.e. saved in
Flash) or not (saved in ROM)
/// \return A status code for the operation
//*************************************************************************************************
EOakStatus setLedMode(int deviceHandle, EOakLedMode ledMode, bool
persistent)
{
OakFeatureReport report = { 0 , persistent ? 1 : 0, 1, 1, 0, (unsigned
char)(ledMode), 0 };
return sendReportAndWaitForReply(deviceHandle, report);
}
//*************************************************************************************************
///
///
/// \param[in] deviceHandle The device handle
/// \param[in,out] report The report to send. On function exit, this
variable contains
/// the reply received from the device
/// \return A status code for the operation
//*************************************************************************************************
EOakStatus sendReportAndWaitForReply(int deviceHandle, OakFeatureReport
report)
{
static OakFeatureReport tempReport; // static to avoid realloaction at
every function call...
// read feature report until the devil is ready to receive on (i.e when
byte 0 is 0xff)
EOakStatus status;
do
{
status = readFeatureReport(deviceHandle, tempReport);
if (eOakStatusOK != status) return status;
} while (0xff != tempReport[0]);
status = sendFeatureReport(deviceHandle, report);
if (eOakStatusOK != status) return status;
// wait until we got a valid feature report as a reply (i.e. one with
first byte set to 0xff
do
{ while True:
reply = self.dev.ctrl_transfer(0x07, 0x03,0, 1,None)
if reply[0] != 0:
_debug('Did not get report.')
break
else:
report = struct.unpack('32B', reply[1])
_debug('Report length:', len(report))
_debug(report)
if report[0] == 0xff:
break
status = readFeatureReport(deviceHandle, report);
if (eOakStatusOK != status) return status;
} while (0xff != report[0]);
return eOakStatusOK;
}
//*************************************************************************************************
/// \param[in] deviceHandle a handle to the device
/// \param[in] report The report to send
/// \return A status code for the operation
//*************************************************************************************************
EOakStatus sendFeatureReport(int deviceHandle, OakFeatureReport report)
{
struct hiddev_usage_ref_multi uref;
uref.uref.report_type = HID_REPORT_TYPE_FEATURE;
uref.uref.report_id = 0;
uref.uref.field_index = 0;
uref.uref.usage_index = 0;
uref.num_values = kFeatureReportSize;
for (int i = 0; i < kFeatureReportSize; ++i)
uref.values[i] = int(report[i]);
if (ioctl(deviceHandle, HIDIOCSUSAGES, &uref) == -1) return
eOakStatusWriteError;
struct hiddev_report_info rinfo;
rinfo.report_type = HID_REPORT_TYPE_FEATURE;
rinfo.report_id = 0;
rinfo.num_fields = 1;
if (ioctl(deviceHandle, HIDIOCSREPORT, &rinfo) == -1) return
eOakStatusWriteError;
return eOakStatusOK;
}
//*************************************************************************************************
/// \param[in] deviceHandle The device handle
/// \param[out] report The read report
/// \return A status code for the operation
//*************************************************************************************************
EOakStatus readFeatureReport(int deviceHandle, OakFeatureReport report)
{
struct hiddev_report_info rinfo;
rinfo.report_type = HID_REPORT_TYPE_FEATURE;
rinfo.report_id = 0;
rinfo.num_fields = 1;
if (ioctl(deviceHandle, HIDIOCGREPORT, &rinfo) == -1) return
eOakStatusReadError;
struct hiddev_usage_ref_multi uref;
uref.uref.report_type = HID_REPORT_TYPE_FEATURE;
uref.uref.report_id = 0;
uref.uref.field_index = 0;
uref.uref.usage_index = 0;
uref.num_values = kFeatureReportSize;
if (ioctl(deviceHandle, HIDIOCGUSAGES, &uref) == -1) return
eOakStatusReadError;
for (int i = 0; i < kFeatureReportSize; ++i)
report[i] = (unsigned char)(uref.values[i]);
return eOakStatusOK;
}
Having dug into the depths that is libusb10, I notice both use ioctl() to
speak to the USB device so they are both pretty similar
in how they work or should if my code worked.
This is as far as* my code* in my most recent attempt speak to rather than
just read from a USB device - just the bit that does an initialisation of
the device
It results in a pipe error
while True:
reply = self.dev.ctrl_transfer(0x07, 0x03,0, 1,None)
if reply[0] != 0:
_debug('Device should return zero in first byte - report
code')
break
else:
# if correctly initialised we should get a 0xff
report = struct.unpack('32B', reply[1])
_debug('Report length:', len(report))
_debug(report)
if report[0] == 0xff:
break
Sorry for length of email
regards
Eric Hewett
eric.hew...@gmail.com
Twitter: @ehewett
Website: www.erichewett.com
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
pyusb-users mailing list
pyusb-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pyusb-users