Skip to content

Commit 81a59a1

Browse files
committed
Merge pull request #494 from xlz/mostly-usb-fixes
Mostly usb fixes
2 parents 045e12b + a325695 commit 81a59a1

File tree

7 files changed

+101
-32
lines changed

7 files changed

+101
-32
lines changed

examples/Protonect.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ void sigint_handler(int s)
4848
protonect_shutdown = true;
4949
}
5050

51+
bool protonect_paused = false;
52+
libfreenect2::Freenect2Device *devtopause;
53+
54+
//Doing non-trivial things in signal handler is bad. If you want to pause,
55+
//do it in another thread.
56+
//Though libusb operations are generally thread safe, I cannot guarantee
57+
//everything above is thread safe when calling start()/stop() while
58+
//waitForNewFrame().
59+
void sigusr1_handler(int s)
60+
{
61+
if (devtopause == 0)
62+
return;
63+
/// [pause]
64+
if (protonect_paused)
65+
devtopause->start();
66+
else
67+
devtopause->stop();
68+
protonect_paused = !protonect_paused;
69+
/// [pause]
70+
}
71+
5172
//The following demostrates how to create a custom logger
5273
/// [logger]
5374
#include <fstream>
@@ -91,6 +112,7 @@ int main(int argc, char *argv[])
91112
std::string program_path(argv[0]);
92113
std::cerr << "Environment variables: LOGFILE=<protonect.log>" << std::endl;
93114
std::cerr << "Usage: " << program_path << " [gl | cl | cpu] [<device serial>] [-noviewer]" << std::endl;
115+
std::cerr << "To pause and unpause: pkill -USR1 Protonect" << std::endl;
94116
size_t executable_name_idx = program_path.rfind("Protonect");
95117

96118
std::string binpath = "/";
@@ -193,7 +215,12 @@ int main(int argc, char *argv[])
193215
return -1;
194216
}
195217

218+
devtopause = dev;
219+
196220
signal(SIGINT,sigint_handler);
221+
#ifdef SIGUSR1
222+
signal(SIGUSR1, sigusr1_handler);
223+
#endif
197224
protonect_shutdown = false;
198225

199226
/// [listeners]

include/internal/libfreenect2/protocol/command.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
#define KCMD_READ_FIRMWARE_VERSIONS 0x02
3333
#define KCMD_INIT_STREAMS 0x09
34-
#define KCMD_READ_DATA_0x14 0x14
34+
#define KCMD_READ_HARDWARE_INFO 0x14
3535
#define KCMD_READ_STATUS 0x16
3636
#define KCMD_READ_DATA_PAGE 0x22
3737
#define KCMD_READ_DATA_0x26 0x26
@@ -43,7 +43,8 @@
4343
#define KCMD_0x47 0x47
4444

4545
// observed in sensor stop/shutdown sequence
46-
#define KCMD_0x0A 0x0A
46+
#define KCMD_STOP 0x0A
47+
#define KCMD_SHUTDOWN 0x00
4748

4849
namespace libfreenect2
4950
{
@@ -166,7 +167,7 @@ struct CommandWith4Params : public Command<CommandId, MaxResponseLength, 4>
166167

167168
typedef CommandWith0Params<0x02, 0x200> ReadFirmwareVersionsCommand;
168169

169-
typedef CommandWith0Params<KCMD_READ_DATA_0x14, 0x5C> ReadData0x14Command;
170+
typedef CommandWith0Params<KCMD_READ_HARDWARE_INFO, 0x5C> ReadHardwareInfoCommand;
170171

171172
typedef CommandWith0Params<KCMD_INIT_STREAMS, 0x00> InitStreamsCommand;
172173

@@ -192,7 +193,8 @@ typedef CommandWith1Param<KCMD_SET_STREAMING, 0x00, 0x01> SetStreamEnabledComman
192193
typedef CommandWith4Params<KCMD_0x46, 0x00, 0x00, 0x00003840, 0x00000037, 0x00> Unknown0x46Command;
193194
typedef CommandWith0Params<KCMD_0x47, 0x10> Unknown0x47Command;
194195

195-
typedef CommandWith0Params<KCMD_0x0A, 0x00> Unknown0x0ACommand;
196+
typedef CommandWith0Params<KCMD_STOP, 0x00> StopCommand;
197+
typedef CommandWith0Params<KCMD_SHUTDOWN, 0x00> ShutdownCommand;
196198

197199
typedef CommandWith4Params<KCMD_SET_MODE, 0x00, 0x00> SetModeDisabledCommand;
198200
typedef CommandWith4Params<KCMD_SET_MODE, 0x00, 0x01> SetModeEnabledCommand;

include/internal/libfreenect2/protocol/response.h

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class SerialNumberResponse
4646
public:
4747
SerialNumberResponse(const unsigned char *data, int length)
4848
{
49-
char *c = new char[length / 2];
49+
char *c = new char[length / 2 + 1]();
5050

5151
for(int i = 0, j = 0; i < length; i += 2, ++j)
5252
{
@@ -70,18 +70,16 @@ class FirmwareVersionResponse
7070
private:
7171
struct FWSubsystemVersion
7272
{
73-
uint16_t minor;
74-
uint16_t major;
75-
uint16_t build;
76-
uint16_t revision;
77-
uint16_t reserved0[4];
73+
uint32_t maj_min;
74+
uint32_t revision;
75+
uint32_t build;
76+
uint32_t reserved0;
7877

7978
FWSubsystemVersion()
8079
{
81-
major = 0;
82-
minor = 0;
83-
build = 0;
80+
maj_min = 0;
8481
revision = 0;
82+
build = 0;
8583
}
8684
};
8785

@@ -92,24 +90,23 @@ class FirmwareVersionResponse
9290
int n = length / sizeof(FWSubsystemVersion);
9391
const FWSubsystemVersion *sv = reinterpret_cast<const FWSubsystemVersion *>(data);
9492

95-
for(int i = 0; i < n && sv->major > 0; ++i, ++sv)
93+
for(int i = 0; i < 7 && i < n; ++i)
9694
{
97-
versions_.push_back(*sv);
95+
versions_.push_back(sv[i]);
9896
}
9997
}
10098

10199
std::string toString()
102100
{
103101
FWSubsystemVersion max;
104-
for(int i = 0; i < versions_.size(); ++i)
102+
std::stringstream version_string;
103+
// the main blob's index
104+
int i = 3;
105+
if (i < versions_.size())
105106
{
106-
max.major = std::max<uint16_t>(max.major, versions_[i].major);
107-
max.minor = std::max<uint16_t>(max.minor, versions_[i].minor);
108-
max.build = std::max<uint16_t>(max.build, versions_[i].build);
109-
max.revision = std::max<uint16_t>(max.revision, versions_[i].revision);
107+
const FWSubsystemVersion &ver = versions_[i];
108+
version_string << (ver.maj_min >> 16) << "." << (ver.maj_min & 0xffff) << "." << ver.revision << "." << ver.build;
110109
}
111-
std::stringstream version_string;
112-
version_string << max.major << "." << max.minor << "." << max.build << "." << max.revision << "." << versions_.size();
113110

114111
return version_string.str();
115112
}

include/libfreenect2/libfreenect2.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,20 @@ If you are finished and no longer need to receive more frames, you can stop
224224
the device and exit.
225225
226226
@snippet Protonect.cpp stop
227+
228+
Pause the Device
229+
----------------
230+
231+
You can also temporarily pause the device with
232+
[stop()](@ref libfreenect2::Freenect2Device::stop) and
233+
[start()](@ref libfreenect2::Freenect2Device::start).
234+
235+
@snippet Protonect.cpp pause
236+
237+
Doing this during `waitForNewFrame()` should be thread safe, and tests also
238+
show well. But a guarantee of thread safety has not been checked yet.
239+
240+
THE END.
227241
*/
228242

229243
namespace libfreenect2

src/command_transaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ CommandTransaction::Result::~Result()
4949

5050
void CommandTransaction::Result::allocate(size_t size)
5151
{
52-
if (capacity < size)
52+
if (capacity != size)
5353
{
5454
deallocate();
5555
data = new unsigned char[size];

src/libfreenect2.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,9 @@ void Freenect2DeviceImpl::start()
683683
command_tx_.execute(ReadFirmwareVersionsCommand(nextCommandSeq()), firmware_result);
684684
firmware_ = FirmwareVersionResponse(firmware_result.data, firmware_result.length).toString();
685685

686-
command_tx_.execute(ReadData0x14Command(nextCommandSeq()), result);
687-
LOG_DEBUG << "ReadData0x14 response";
688-
LOG_DEBUG << GenericResponse(result.data, result.length).toString();
686+
command_tx_.execute(ReadHardwareInfoCommand(nextCommandSeq()), result);
687+
//The hardware version is currently useless. It is only used to select the
688+
//IR normalization table, but we don't have that.
689689

690690
command_tx_.execute(ReadSerialNumberCommand(nextCommandSeq()), serial_result);
691691
std::string new_serial = SerialNumberResponse(serial_result.data, serial_result.length).toString();
@@ -749,17 +749,28 @@ void Freenect2DeviceImpl::start()
749749
rgb_camera_params_.my_x0y0 = rgb_p->my_x0y0; // 1
750750
setColorCameraParams(rgb_camera_params_);
751751

752-
command_tx_.execute(ReadStatus0x090000Command(nextCommandSeq()), result);
753-
LOG_DEBUG << "ReadStatus0x090000 response";
754-
LOG_DEBUG << GenericResponse(result.data, result.length).toString();
752+
command_tx_.execute(SetModeEnabledWith0x00640064Command(nextCommandSeq()), result);
753+
command_tx_.execute(SetModeDisabledCommand(nextCommandSeq()), result);
754+
755+
for (uint32_t status = 0, last = 0; (status & 1) == 0; last = status)
756+
{
757+
command_tx_.execute(ReadStatus0x090000Command(nextCommandSeq()), result);
758+
if (result.length < sizeof(uint32_t))
759+
continue; //TODO should report error
760+
status = *reinterpret_cast<const uint32_t *>(result.data);
761+
if (status != last)
762+
LOG_DEBUG << "status 0x090000: " << status;
763+
if ((status & 1) == 0)
764+
this_thread::sleep_for(chrono::milliseconds(100));
765+
}
755766

756767
command_tx_.execute(InitStreamsCommand(nextCommandSeq()), result);
757768

758769
usb_control_.setIrInterfaceState(UsbControl::Enabled);
759770

760771
command_tx_.execute(ReadStatus0x090000Command(nextCommandSeq()), result);
761-
LOG_DEBUG << "ReadStatus0x090000 response";
762-
LOG_DEBUG << GenericResponse(result.data, result.length).toString();
772+
if (result.length >= sizeof(uint32_t))
773+
LOG_DEBUG << "status 0x090000: " << *reinterpret_cast<const uint32_t *>(result.data);
763774

764775
command_tx_.execute(SetStreamEnabledCommand(nextCommandSeq()), result);
765776

@@ -813,8 +824,14 @@ void Freenect2DeviceImpl::stop()
813824
usb_control_.setIrInterfaceState(UsbControl::Disabled);
814825

815826
CommandTransaction::Result result;
816-
command_tx_.execute(Unknown0x0ACommand(nextCommandSeq()), result);
827+
command_tx_.execute(SetModeEnabledWith0x00640064Command(nextCommandSeq()), result);
828+
command_tx_.execute(SetModeDisabledCommand(nextCommandSeq()), result);
829+
command_tx_.execute(StopCommand(nextCommandSeq()), result);
817830
command_tx_.execute(SetStreamDisabledCommand(nextCommandSeq()), result);
831+
command_tx_.execute(SetModeEnabledCommand(nextCommandSeq()), result);
832+
command_tx_.execute(SetModeDisabledCommand(nextCommandSeq()), result);
833+
command_tx_.execute(SetModeEnabledCommand(nextCommandSeq()), result);
834+
command_tx_.execute(SetModeDisabledCommand(nextCommandSeq()), result);
818835

819836
usb_control_.setVideoTransferFunctionState(UsbControl::Disabled);
820837

@@ -837,6 +854,11 @@ void Freenect2DeviceImpl::close()
837854
stop();
838855
}
839856

857+
CommandTransaction::Result result;
858+
command_tx_.execute(SetModeEnabledWith0x00640064Command(nextCommandSeq()), result);
859+
command_tx_.execute(SetModeDisabledCommand(nextCommandSeq()), result);
860+
command_tx_.execute(ShutdownCommand(nextCommandSeq()), result);
861+
840862
if(pipeline_->getRgbPacketProcessor() != 0)
841863
pipeline_->getRgbPacketProcessor()->setFrameListener(0);
842864

src/opencl_depth_packet_processor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
#define REG_OPENCL_FILE ""
5454
#endif
5555

56+
#include <cstdlib>
57+
5658
namespace libfreenect2
5759
{
5860

@@ -141,6 +143,11 @@ class OpenCLDepthPacketProcessorImpl: public WithPerfLogging
141143
, programBuilt(false)
142144
, programInitialized(false)
143145
{
146+
#if _BSD_SOURCE || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
147+
setenv("OCL_IGNORE_SELF_TEST", "1", 0);
148+
setenv("OCL_STRICT_CONFORMANCE", "0", 0);
149+
#endif
150+
144151
newIrFrame();
145152
newDepthFrame();
146153

0 commit comments

Comments
 (0)