Skip to content

Commit

Permalink
gpdevboard: Now reset all devices from bootloader to normal mode befo…
Browse files Browse the repository at this point in the history
…re initiating discovery, so we don't have devices change ID under us. Fixes #71.
azonenberg committed May 21, 2017
1 parent 163b1f5 commit 7cfbfd9
Showing 2 changed files with 47 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/gpdevboard/gpdevboard.h
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ typedef struct libusb_device_handle* hdevice;
bool USBSetup();
void USBCleanup(hdevice hdev);

bool ResetDevicesInBootloader();
hdevice OpenDevice(uint16_t idVendor, uint16_t idProduct, int nboard);
bool GetStringDescriptor(hdevice hdev, uint8_t index, std::string &desc);
bool SendInterruptTransfer(hdevice hdev, const uint8_t* buf, size_t size);
69 changes: 46 additions & 23 deletions src/gpdevboard/utils.cpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <cmath>
#include <cstring>
#include <libusb-1.0/libusb.h>

#include <log.h>
#include "gpdevboard.h"
@@ -27,6 +28,8 @@

using namespace std;

static bool g_devicesResetFromBootloader = false;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Status check

@@ -54,6 +57,39 @@ bool CheckStatus(hdevice hdev)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialization

/**
@brief If any devices are in bootloader, move them to normal mode
*/
bool ResetDevicesInBootloader()
{
//Set up libusb
if(!USBSetup())
return false;

LogVerbose("Resetting any devices in bootloader mode\n");
LogIndenter li;

//Find all of the devices in "white" (bootloader) mode
vector<hdevice> handles;
for(int i=100; i>=0; i--)
{
hdevice hdev = OpenDevice(0x0f0f, 0x8006, i);
if(hdev)
handles.push_back(hdev);
}

//Switch all of them into normal mode
for(auto h : handles)
{
SwitchMode(h);
libusb_close(h);
}

g_devicesResetFromBootloader = true;

return true;
}

/**
@brief Connect to the board, but don't change anything
@@ -63,44 +99,31 @@ bool CheckStatus(hdevice hdev)
*/
hdevice OpenBoard(int nboard, bool test)
{
//Set up libusb
if(!USBSetup())
return NULL;

LogNotice("Searching for developer board at index %d\n", nboard);
LogIndenter li;

//Try opening the board in "white" mode first
hdevice hdev = OpenDevice(0x0f0f, 0x8006, nboard);
bool switching = false;
if(hdev)
if(!g_devicesResetFromBootloader)
{
//Change the board into "orange" mode
LogVerbose("Switching developer board from bootloader mode\n");
if(!SwitchMode(hdev))
if(!ResetDevicesInBootloader())
return NULL;

//Takes a while to switch and re-enumerate
switching = true;
}

LogNotice("Searching for developer board at index %d\n", nboard);
LogIndenter li;

//Try up to ten times to open the board if we're switching mode.
//Stop after the first failure if we're not switching b/c there's no point.
hdevice hdev = NULL;

//Try up to ten times to open the board
for(int i=0; i<10; i++)
{
hdev = OpenDevice(0x0f0f, 0x0006, nboard);
if(hdev || !switching)
if(hdev)
break;

// usleep is only guaranteed to work with <1000000 us of sleeping
usleep(1000 * 1000 - 1);
}

//By this point, it should be in "orange" mode
//By this point, it should be in "orange" mode even if it wasn't initially
if(!hdev)
{
if(switching)
LogError("Device failed to switch mode\n");
if(!test)
LogError("No device found, giving up\n");
return NULL;

0 comments on commit 7cfbfd9

Please sign in to comment.