Code Search for Developers
 
 
  

Samba.cpp from Make Controller at Krugle


Show Samba.cpp syntax highlighted

/*
 * Copyright (C) 2005 Erik Gilling, all rights reserved
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation, version 2.
 */

/****************************************************************************
**
** Qt SAM7X Uploader.
** Qt/C++ification by MakingThings 2006.
**
****************************************************************************/

#include "Samba.h"
#include "stdio.h"
#include "errno.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "sys/stat.h"
// #include "loader128_data.h"
#include "loader256_data.h"

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

#include <QThread>

#ifdef Q_WS_WIN
#include "guid829.h"
#endif

// from sam7utils/samba.c

static const char *eprocs[] = {
  /* 000 */ "",
  /* 001 */ "ARM946E-S",
  /* 010 */ "ARM7TDMI",
  /* 011 */ "",
  /* 100 */ "ARM920T",
  /* 101 */ "ARM926EJ-S",
  /* 110 */ "",
  /* 111 */ ""
};


#define K 1024

const int nvpsizs[] = {
  /* 0000 */ 0,
  /* 0001 */ 8 * K,
  /* 0010 */ 16 * K,
  /* 0011 */ 32 * K,
  /* 0100 */ -1,
  /* 0101 */ 64 * K,
  /* 0110 */ -1,
  /* 0111 */ 128 * K,
  /* 1000 */ -1,
  /* 1001 */ 256 * K,
  /* 1010 */ 512 * K,
  /* 1011 */ -1,
  /* 1100 */ 1024 * K,
  /* 1101 */ -1,
  /* 1110 */ 2048 * K,
  /* 1111 */ -1
};

const int sramsizs[] = {
  /* 0000 */ -1,
  /* 0001 */ 1 * K,
  /* 0010 */ 2 * K,
  /* 0011 */ -1,
  /* 0100 */ 112 * K,
  /* 0101 */ 4 * K,
  /* 0110 */ 80 * K,
  /* 0111 */ 160 * K,
  /* 1000 */ 8 * K,
  /* 1001 */ 16 * K,
  /* 1010 */ 32 * K,
  /* 1011 */ 64 * K,
  /* 1100 */ 128 * K,
  /* 1101 */ 256 * K,
  /* 1110 */ 96 * K,
  /* 1111 */ 512 * K
};

const struct { unsigned id; const char *name; } archs[] = {
  {AT91_ARCH_AT75Cxx,      "AT75Cxx"},
  {AT91_ARCH_AT91x40,      "AT91x40"},
  {AT91_ARCH_AT91x63,      "AT91x63"},
  {AT91_ARCH_AT91x55,      "AT91x55"},
  {AT91_ARCH_AT91x42,      "AT91x42"},
  {AT91_ARCH_AT91x92,      "AT91x92"},
  {AT91_ARCH_AT91x34,      "AT91x34"},
  {AT91_ARCH_AT91SAM7Axx,  "AT91SAM7Axx"},
  {AT91_ARCH_AT91SAM7Sxx,  "AT91SAM7Sxx"},
  {AT91_ARCH_AT91SAM7XC,   "AT91SAM7XC"},
  {AT91_ARCH_AT91SAM7SExx, "AT91SAM7SExx"},
  {AT91_ARCH_AT91SAM7Lxx,  "AT91SAM7Lxx"},
  {AT91_ARCH_AT91SAM7Xxx,  "AT91SAM7Xxx"},
  {AT91_ARCH_AT91SAM9xx,   "AT91SAM9xx"}
};

// Other stuff

Samba::Samba( MessageInterface* messageInterface )
{
	this->messageInterface = messageInterface;
	
	#ifdef Q_WS_WIN
	BulkUSB = 0;
	#endif
}


Samba::Status Samba::connect()
{
	if ( usbOpen( ) < 0 )
	  return ERROR_INITIALIZING;
	return OK;
}

Samba::Status Samba::disconnect()
{
	// messageInterface->message( 3, "  Disconnecting.\n" );
  // messageInterface->sleepMs( 100 );
  usbClose( );
  return OK;
}

Samba::Status Samba::flashUpload( char* bin_file )
{
  struct stat stbuf;
  size_t loader_len;
  size_t file_len;
  size_t i;
  uint8_t *buff;
  void* file_fd;
  int read_len;
  int ps = samba_chip_info.page_size;
  uint8_t *loader_data;
  int block = 0;

  if( ps == 256 ) 
  {
    loader_data = loader256_data;
    loader_len = sizeof( loader256_data );
  } else {
    printf( "no loader for %d byte pages\n", ps );
    return ERROR_INCORRECT_CHIP_INFO;
  }

  if( stat( bin_file, &stbuf ) < 0 ) {
    printf( "%s not found\n", bin_file );
    return ERROR_COULDNT_FIND_FILE;
  }

  file_len = stbuf.st_size;

  if( (buff = (uint8_t *) malloc( ps ) ) == NULL ) {
    printf( "can't alocate buffer of size 0x%x\n",  ps );
    goto error0;
  }

  if( this->sendFile( 0x00201600, loader_data, loader_len ) < 0 ) {
    printf( "could not upload samba.bin\n" );
    goto error1;
  }
  
  if( (file_fd = fileOpen( bin_file ) ) == 0 ) {
    printf( "could not open %s\n", bin_file );
    return ERROR_COULDNT_OPEN_FILE ;
  }

  messageInterface->message( 3, "    " );

  for( i=0 ; i<file_len ; i+=ps ) {
    /* set page # */
    if( writeWord( 0x00201400+ps, i/ps ) < 0 ) {
      printf( "could not write page %d address\n", (int) i/ps );
      goto error2;
    }
    
    read_len = ((int)(file_len-i) < ps)?file_len-i:ps;
    /* XXX need to implement safe read */
    int r;
    if( ( r = fileRead( file_fd, (char*)buff, read_len ) ) < read_len ) {
      printf( "could not read 0x%x bytes from file, just got %d\n", read_len, r );
      goto error2;
    }

    if( sendFile( 0x00201400, buff, ps ) < 0 ) {
      printf( "could not send page %d\n", (int) i/ps );
      goto error2;
    }

    if( go( 0x00201600 ) < 0 ) {
      printf( "could not send go command for page %d\n", (int) i/ps );
      goto error2;
    }
    
    //(Every 20k)
    if ( (++block)%20==0 )
      messageInterface->message( 1, "." );
  }
  
  free( buff );
  fileClose( file_fd );
 
  
  messageInterface->message( 3, "\n" );

  return OK;

 error2:
  fileClose( file_fd );

 error1:
  free( buff );

 error0:
  return ERROR_SENDING_FILE;
}

Samba::Status Samba::bootFromFlash( )
{
  /* 
   * word: 5A is key to send any message, 
   *       02 is GPNVM2 to boot from Flash, 
   *       0B is "set this bit"
   */
  uint32_t val;
  
  do {
    if( readWord( 0xffffff68, &val ) < 0 ) {
      return ERROR_SETTING_BOOT_BIT;
    }
  } while( !val & 0x1 );

  if( writeWord( 0xFFFFFF64, 0x5A00020B ) < 0 ) {
    printf( "Couldn't flip the bit to boot from Flash.\n" );
    return ERROR_SETTING_BOOT_BIT;
  }
  return OK;
}

int Samba::init( )
{
  
  uint32_t chipid;
  uint16_t response;

  sendCommand( "N#", &response, sizeof( response ) );

/*  if( sendCommand( "N#", &response, sizeof( response ) ) < 0 ) {
    printf( "can't init boot program: %s\n", strerror( errno ) );
    return -1;
  }
*/

  if( readWord( 0xfffff240, &chipid ) < 0 ) {
    return -1;
  }

  samba_chip_info.version = AT91_CHIPID_VERSION( chipid );
  samba_chip_info.eproc = AT91_CHIPID_EPROC( chipid );
  samba_chip_info.nvpsiz = nvpsizs[AT91_CHIPID_NVPSIZ( chipid )];
  samba_chip_info.nvpsiz2 = nvpsizs[AT91_CHIPID_NVPSIZ2( chipid )];
  samba_chip_info.sramsiz = sramsizs[AT91_CHIPID_SRAMSIZ( chipid )];
  samba_chip_info.arch = AT91_CHIPID_ARCH( chipid );
  
  if( samba_chip_info.arch == AT91_ARCH_AT91SAM7Sxx ) 
  {
    switch( samba_chip_info.nvpsiz) 
    {
    case 32*K:
      samba_chip_info.page_size = 128;
      samba_chip_info.lock_bits = 8;
      break;

    case 64*K:
      samba_chip_info.page_size = 128;
      samba_chip_info.lock_bits = 16;
      break;

    case 128*K:
      samba_chip_info.page_size = 256;
      samba_chip_info.lock_bits = 8;
      break;

    case 256*K:
      samba_chip_info.page_size = 256;
      samba_chip_info.lock_bits = 16;
      break;

    default:
      printf( "unknown sam7s flash size %d\n", samba_chip_info.nvpsiz );
      return -1;
    }

  } 
  else if( samba_chip_info.arch == AT91_ARCH_AT91SAM7Xxx || samba_chip_info.arch == AT91_ARCH_AT91SAM7XC )
	{
    switch( samba_chip_info.nvpsiz ) {
    case 128*K:
      samba_chip_info.page_size = 256;
      samba_chip_info.lock_bits = 8;
      break;

    case 256*K:
      samba_chip_info.page_size = 256;
      samba_chip_info.lock_bits = 16;
      break;

    default:
      printf( "unknown sam7x srflashsize %d\n", samba_chip_info.nvpsiz );
      return -1;
    }
  } 
  else 
  {
    printf( "Page size info of %s not known\n", 
	    at91ArchStr( samba_chip_info.arch ) );
    return -1;
  }

  printf("Chip Version: %d\n", samba_chip_info.version );
  printf("Embedded Processor: %s\n", eprocs[samba_chip_info.eproc] );
  printf("NVRAM Region 1 Size: %d K\n", samba_chip_info.nvpsiz / K );
  printf("NVRAM Region 2 Size: %d K\n", samba_chip_info.nvpsiz2 / K );
  printf("SRAM Size: %d K\n", samba_chip_info.sramsiz / K );
  printf("Series: %s\n", at91ArchStr( samba_chip_info.arch ) );
  printf("Page Size: %d bytes\n", samba_chip_info.page_size );
  printf("Lock Regions: %d\n", samba_chip_info.lock_bits );

  return 0;
}

int Samba::readWord( uint32_t addr, uint32_t *value )
{
  char cmd[64];
  int err;

  snprintf( cmd, 64, "w%08X,4#", (unsigned int) addr );

  err = sendCommand( cmd, value, 4 );
  //*value = ntohl( *value );
	#ifdef __BIG_ENDIAN__
	*value = ( ( *value & 0x000000FF ) << 24 ) |
					( ( *value & 0x0000FF00 ) << 8 )  | 
					( ( *value & 0x00FF0000 ) >> 8 )  | 
					( ( *value & 0xFF000000 ) >> 24 );
	#endif

  return err; 
}

int Samba::sendFile( uint32_t addr, uint8_t *buff, int len )
{
  char cmd[64];
  int i=0;

  snprintf( cmd, 64, "S%X,%X#", (unsigned int) addr, (unsigned int) len );

  if( usbWrite( cmd, strlen( cmd ) ) < 0 ) {
    return -1;
  }

  uSleep( 2000 );
  
  for( i=0 ; i<len ; i+=64 ) 
  {
    if( usbWrite( (char*)buff+i, (len-i < 64)? len-i : 64 ) < 0 )
    {
      return -1;
    }
    uSleep( 2000 );
  }
  
  return 0;
}

int Samba::writeWord( uint32_t addr, uint32_t value )
{
  char cmd[64];

  snprintf( cmd, 64, "W%08X,%08X#", (unsigned int) addr,
	    (unsigned int) value );

  return sendCommand( cmd, NULL, 0 );
}

int Samba::go( uint32_t addr )
{
  char cmd[64];
  snprintf( cmd, 64, "G%08X#", (unsigned int) addr );

  return sendCommand( cmd, NULL, 0 );
}

int Samba::sendCommand( char *cmd, void *response, int response_len )
{
  
  if( usbWrite( cmd, strlen( cmd ) ) < 0 ) {
    return -1;
  }
  
  uSleep( 2000 );
    
  if( response_len == 0 ) {
    return 0;
  }

  if( usbRead( (char*)response, response_len ) < 0 ) {
    return -1;
  }

  uSleep( 2000 );
  
  return 0;
}

const char* Samba::at91ArchStr( int id )
{
  int i;
  for( i=0 ; i<(int)(sizeof(archs)/sizeof(*archs)) ; i++ ) {
    if( (int)archs[i].id == id ) {
      return archs[i].name;
    }
  }
  return "";
}

void Samba::uSleep( int usecs )
{
  #ifdef Q_WS_WIN
    Sleep( usecs / 1000 );
  #endif
  #ifdef Q_WS_MAC
    usleep( usecs );
  #endif

}

void* Samba::fileOpen( char* name )
{
  #ifdef Q_WS_WIN
    HANDLE f = ::CreateFileA( name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if ( f == INVALID_HANDLE_VALUE ) 
    {
      return 0;
    }
    return (void*)f;
  #endif
  #ifdef Q_WS_MAC
    int file_fd;
    if( (file_fd = open( bin_file, O_RDONLY )) < 0 ) 
    {
      printf( "can't open %s\n", bin_file );
      return 0;
    }
    return (void*)file_fd;
  #endif
}

int Samba::fileRead( void* file_fd, char* buff, int length )
{
  int r = 1;
  #ifdef Q_WS_WIN
    DWORD read;
    if ( !::ReadFile( (HANDLE)file_fd, buff, length, &read, NULL ) )
      return -1;
    return (int)read;
  #endif
  #ifdef Q_WS_MAC
    if( ( r = read( (int)file_fd, buff, length ) ) < length )
      return -1;
  #endif
  return r;
}


void Samba::fileClose( void* file_fd )
{
  #ifdef Q_WS_WIN
    CloseHandle( (HANDLE)file_fd );
  #endif
  #ifdef Q_WS_MAC
    close( (int)file_fd );
  #endif
}

/*
 * USB FUNCTIONS BELOW
 */

int Samba::usbOpen( )
{
  // Mac-only
  #ifdef Q_WS_MAC
  masterPort = 0;
  usbDev = NULL;
  intf = NULL;
  inPipeRef = 0;
  outPipeRef = 0;

  // from io_iokit.c
  kern_return_t err;
  CFMutableDictionaryRef matchingDictionary = 0;
  CFNumberRef numberRef;
  SInt32 idVendor = 0x03eb;
  SInt32 idProduct = 0x6124;
  io_iterator_t iterator = 0;
  io_service_t usbDeviceRef;
	
	if( ( err = IOMasterPort( MACH_PORT_NULL, &masterPort ) ) ) 
	{
	  messageInterface->message( 2, "could not create master port, err = %08x\n", err );
    //printf( "could not create master port, err = %08x\n", err );
		return -1;
  }
	
	if( !(matchingDictionary = IOServiceMatching(kIOUSBDeviceClassName)) )
	{
		mainDialog->writeToConsole( "usb> could not create matching dictionary.\n" );
    //printf( "could not create matching dictionary\n" );
		return -1;
  }
	
	if( !(numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idVendor)) )
	{
		mainDialog->writeToConsole( "usb> could not create CFNumberRef for vendor.\n" );
    //printf( "could not create CFNumberRef for vendor\n" );
		return -1;
  }
	CFDictionaryAddValue( matchingDictionary, CFSTR(kUSBVendorID), numberRef);
  CFRelease( numberRef );
  numberRef = 0;
	
	if( !(numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &idProduct)) )
	{
		mainDialog->writeToConsole( "usb> could not create CFNumberRef for product.\n" );
    //printf( "could not create CFNumberRef for product\n" );
		return -1;
  }
  CFDictionaryAddValue( matchingDictionary, CFSTR(kUSBProductID), numberRef);
  CFRelease( numberRef );
  numberRef = 0;
	
	err = IOServiceGetMatchingServices( masterPort, matchingDictionary, &iterator );
  matchingDictionary = 0;  // consumed by the above call

  if( (usbDeviceRef = IOIteratorNext( iterator ) ) )
	{
		mainDialog->writeToConsole( "usb> Found boot agent.\n" );
    //printf( "usb> Found boot agent\n" );

    do_dev( usbDeviceRef );
		
		IOObjectRelease(usbDeviceRef);
		IOObjectRelease(iterator);
		return init();
		
  } else
	{
		mainDialog->writeToConsole( "usb> Cannot find boot agent.\n" );
    //printf( "cannot find boot agent\n" );
		usbClose( );
		IOObjectRelease(usbDeviceRef);
		IOObjectRelease(iterator);
  }

  return 0;
	#endif /* Mac-only UsbConnection::init( ) */
    
  // Windows-only
  #ifdef Q_WS_WIN
  
  char /*message[100], */buffer[2], temp[2];

  // messageInterface->message( 3, "  Opening.\n" );
  // messageInterface->sleepMs( 100 );

  int result = testOpen();
  
  if (result == FC_DRIVER_NOT_FOUND ) {
    messageInterface->message( 2, "  Cannot find boot agent.\n" );
    disconnect();
    return -1;
  } else if (result != FC_OK) {
  	messageInterface->message( 2, "  Cannot open USB.\n" );
    disconnect();
    return -1;
  }
  
  // messageInterface->message( 3, "  Flushing.\n" );
  // messageInterface->sleepMs( 100 );
  
  // Flush buffer
  usbFlushOut();


  // messageInterface->message( 3, "  Writing useless command.\n" );
  // messageInterface->sleepMs( 100 );

  // Put Normal PutData mode for the target
  buffer[0] = 'N';
  buffer[1] = '#';
  if (usbWrite( (char*)buffer, 2 ) != FC_OK ) {
  	messageInterface->message( 2, "usb> Error initializing - could not find boot agent.\n" );
    return -1;
  }

  // No errors test because 2 case possible : 0 byte or 2 bytes to flush... (depends if the board reset or not)
  //messageInterface->message( 3, "  Reading useless command.\n" );
  //messageInterface->sleepMs( 100 );
  usbRead((char*)temp,2);

  // messageInterface->message( 2, "usb> Found boot agent.\n" );
  // messageInterface->sleepMs( 100 );
  BulkUSB = 1; // BulkUSB Mode

  messageInterface->message( 3, "  Initializing\n" );
  // messageInterface->sleepMs( 100 );

  return init();
  
  #endif /* Windows-only usbInit( ) */
}


int Samba::usbWrite( char* buffer, int length )
{
  // Mac-only...
  #ifdef Q_WS_MAC
  if( (*intf)->WritePipe( intf, outPipeRef, buffer, (UInt32) length ) != kIOReturnSuccess )
    mainDialog->writeToConsole( "usb> Write error.\n" );

  return length;
  #endif /* Mac-only usbWrite( ) */
  
  // Windows-only...
  #ifdef Q_WS_WIN
  if(m_hPipeOut == INVALID_HANDLE_VALUE)
    return FC_ERROR;

  if( !buffer || !length )
    return FC_NOT_INITIALIZED;

  DWORD dwBytesWritten;

  if(! ::WriteFile(m_hPipeOut, buffer, length, &dwBytesWritten, NULL))
  {
    //DWORD dwErr = ::GetLastError();
    return FC_DRIVER_ERROR;
  }

  return FC_OK;
  #endif  /* Windows-only usbWrite( ) */
}

int Samba::usbRead( char* buffer, int length )
{
  // Mac-only...
  #ifdef Q_WS_MAC
  UInt32 size = length;

  if( (*intf)->ReadPipe( intf, inPipeRef, buffer, &size ) != kIOReturnSuccess )
    mainDialog->writeToConsole( "usb> Read error.\n" );
  
  return (int)size;
  #endif  /* Mac-only usbWrite( ) */

  // Windows-only...
  #ifdef Q_WS_WIN
  int timeout = 0;
  DWORD oldValue = 0;
  if(m_hPipeIn == INVALID_HANDLE_VALUE)
    return FC_ERROR;

  if(!buffer || !length)
    return FC_NOT_INITIALIZED;

  DWORD dwBytesRead;

  DWORD dwBytesToRead = length;
  DWORD dwOffset = 0;
  oldValue = dwBytesToRead;

  do
  {
    if( ! ::ReadFile(m_hPipeIn, ((BYTE *) buffer) + dwOffset, dwBytesToRead, &dwBytesRead, NULL))
    {
      //DWORD dwErr = ::GetLastError();
      return FC_DRIVER_ERROR;
    }

    dwBytesToRead -= dwBytesRead;
    dwOffset += dwBytesRead;
	if (dwBytesRead == 0)
		return FC_DRIVER_ERROR;
  } while((dwBytesToRead != 0) && (timeout != 5));

  
  if (dwBytesToRead != 0)
    return FC_DRIVER_ERROR;

  return FC_OK;
  #endif  /* Windows-only usbRead( ) */
}

int Samba::usbClose( )
{
   // Mac-only...
  #ifdef Q_WS_MAC
  if( intf ) {
    (*intf)->USBInterfaceClose(intf);
    (*intf)->Release(intf);
    intf = NULL;
  }

  if( usbDev ) {
    (*usbDev)->USBDeviceClose(usbDev);
    (*usbDev)->Release(usbDev);
    usbDev = NULL;
  }
  
  return 0;
  #endif /* Mac-only UsbConnection::cleanup( ) */
	
  // Windows-only
  #ifdef Q_WS_WIN
  if(m_hPipeIn != INVALID_HANDLE_VALUE)
    ::CloseHandle(m_hPipeIn);
  if(m_hPipeOut != INVALID_HANDLE_VALUE)
    ::CloseHandle(m_hPipeOut);

  m_hPipeIn = INVALID_HANDLE_VALUE;
  m_hPipeOut = INVALID_HANDLE_VALUE;

  return FC_OK;
  #endif  // end: Windows-only disconnect()	
}

// Windows-only...
#ifdef Q_WS_WIN

BOOL Samba::GetUsbDeviceFileName(LPGUID  pGuid, WCHAR **outNameBuf)
{
  HANDLE hDev = OpenUsbDevice(pGuid, outNameBuf);

  if(hDev != INVALID_HANDLE_VALUE)
  {
    CloseHandle(hDev);
    return TRUE;
  }
  return FALSE;
}


int Samba::testOpen( )
{
  WCHAR *sDeviceName;

  WCHAR *sPipeNameIn;
  WCHAR *sPipeNameOut;

  // messageInterface->message( 3, "  Getting usb device name\n" );
  // messageInterface->sleepMs( 100 );
  
  if(! GetUsbDeviceFileName( (LPGUID) &GUID_CLASS_I82930_BULK, &sDeviceName))
    return FC_DRIVER_NOT_FOUND;

  // messageInterface->message( 3, "  Got usb device name\n" );
  // messageInterface->sleepMs( 100 );

  sPipeNameIn  = (WCHAR *) malloc(::wcslen(sDeviceName) * 2 + 20);
  sPipeNameOut = (WCHAR *) malloc(::wcslen(sDeviceName) * 2 + 20);
  ::wcscpy(sPipeNameIn, sDeviceName);                    
  ::wcscat(sPipeNameIn, L"\\PIPE01");

  ::wcscpy(sPipeNameOut, sDeviceName);
  ::wcscat(sPipeNameOut, L"\\PIPE00");
  free(sDeviceName);

  // messageInterface->message( 3, "  Opening Pipes\n" );
  // messageInterface->sleepMs( 100 );

  m_hPipeIn = ::CreateFile(sPipeNameIn, 
                           GENERIC_READ | GENERIC_WRITE,
                           FILE_SHARE_READ,
						   NULL,
						   OPEN_EXISTING, 
                           0, 
						   NULL);

  m_hPipeOut = ::CreateFile(sPipeNameOut, 
                            GENERIC_WRITE,
                            FILE_SHARE_WRITE,
							NULL,
							OPEN_EXISTING, 
                            0,
							NULL);


  if( (m_hPipeIn == INVALID_HANDLE_VALUE) || (m_hPipeOut == INVALID_HANDLE_VALUE) )
  {
    usbClose();
	int i =GetLastError();
    return i;
  }

  return FC_OK;
}

int Samba::usbFlushOut( )
{
  if(m_hPipeOut == INVALID_HANDLE_VALUE)
    return FC_ERROR;

  ::FlushFileBuffers(m_hPipeOut);
  return FC_OK;	
}

HANDLE Samba::OpenUsbDevice(LPGUID  pGuid, WCHAR **outNameBuf)
{
  HANDLE hOut = INVALID_HANDLE_VALUE;

  ULONG                    NumberDevices;
  HDEVINFO                 hardwareDeviceInfo;
  SP_INTERFACE_DEVICE_DATA deviceInfoData;
  ULONG                    i;
  BOOLEAN                  done;

  //
  // Open a handle to the plug and play dev node.
  // SetupDiGetClassDevs() returns a device information set that contains info on all
  // installed devices of a specified class.
  //
  hardwareDeviceInfo = SetupDiGetClassDevs (
                         pGuid,
                         NULL,            // Define no enumerator (global)
                         NULL,            // Define no
                         (DIGCF_PRESENT | // Only Devices present
                         DIGCF_INTERFACEDEVICE)); // Function class devices.

  //
  // Take a wild guess at the number of devices we have;
  // Be prepared to realloc and retry if there are more than we guessed
  //
  NumberDevices = 4;
  done = FALSE;
  deviceInfoData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

  i=0;
  while(!done) 
  {
    NumberDevices *= 2;

    for(; i < NumberDevices; i++) 
    {
      // SetupDiEnumDeviceInterfaces() returns information about device interfaces
      // exposed by one or more devices. Each call returns information about one interface;
      // the routine can be called repeatedly to get information about several interfaces
      // exposed by one or more devices.
      if(SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
                                      0, // We don't care about specific PDOs
                                      pGuid,
                                      i,
                                      &deviceInfoData)) 
      {
        hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, outNameBuf);
        if(hOut != INVALID_HANDLE_VALUE) 
        {
          done = TRUE;
          break;
        }
      } 
      else 
      {
        if(ERROR_NO_MORE_ITEMS == GetLastError()) 
        {
           done = TRUE;
           break;
        }
      }
    }
  }

  // SetupDiDestroyDeviceInfoList() destroys a device information set
  // and frees all associated memory.
  SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);

  return hOut;
}

HANDLE Samba::OpenOneDevice (HDEVINFO HardwareDeviceInfo,
                                  PSP_INTERFACE_DEVICE_DATA DeviceInfoData,
                                  WCHAR **devName)
{
  PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = NULL;
  ULONG                            predictedLength = 0;
  ULONG                            requiredLength = 0;

  HANDLE hOut = INVALID_HANDLE_VALUE;

  //
  // allocate a function class device data structure to receive the
  // goods about this particular device.
  //
  SetupDiGetInterfaceDeviceDetail(HardwareDeviceInfo,
                                  DeviceInfoData,
                                  NULL,  // probing so no output buffer yet
                                  0,     // probing so output buffer length of zero
                                  &requiredLength,
                                  NULL); // not interested in the specific dev-node

  predictedLength = requiredLength;

  functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (predictedLength);
  functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);

  //
  // Retrieve the information from Plug and Play.
  //
  if (! SetupDiGetInterfaceDeviceDetail(HardwareDeviceInfo,
                                        DeviceInfoData,
                                        functionClassDeviceData,
                                        predictedLength,
                                        &requiredLength,
                                        NULL))
  {
    free(functionClassDeviceData);
    return INVALID_HANDLE_VALUE;
  }

  *devName = wcsdup(functionClassDeviceData->DevicePath);
  //strcpy(devName, functionClassDeviceData->DevicePath) ;

  hOut = CreateFile( functionClassDeviceData->DevicePath,
                     GENERIC_READ | GENERIC_WRITE,
                     FILE_SHARE_READ | FILE_SHARE_WRITE,
                     NULL,          // no SECURITY_ATTRIBUTES structure
                     OPEN_EXISTING, // No special create flags
                     FILE_ATTRIBUTE_NORMAL,             // No special attributes
                     NULL);         // No template file

  free(functionClassDeviceData);
  return hOut;
}

#endif




See more files for this project here

Make Controller

The Make Controller is an open microcontroller platform for Makers of all kinds, by MakingThings. This project maintains the official firmware for the board and source for the software tools used with the board.

Project homepage: http://sourceforge.net/projects/makingthings
Programming language(s): C,C#,C++
License: other

  .externalToolBuilders/
    qmake.launch
  debug/
    ctest.exe
    ctestee.bin
    moc_CTestThread.cpp
    moc_CTestWindow.cpp
    test.bin
  io_win32/
    FCPipe.cpp
    FCPipe.h
    FCPipeUSB.cpp
    FCPipeUSB.h
    FC_Error.h
    SAM-BA.dll
    SAMBADLL.cpp
    SAMBADLL.h
    timer.cpp
    timer.h
    xmodem.cpp
    xmodem.h
  release/
    ctest.exe
    moc_CTestThread.cpp
    moc_CTestWindow.cpp
  .cdtproject
  .project
  CTestThread.cpp
  CTestThread.h
  CTestWindow.cpp
  CTestWindow.h
  CTestee.cpp
  CTestee.h
  CTester.cpp
  CTester.h
  Makefile
  Makefile.Debug
  Makefile.Release
  MessageInterface.h
  Osc.cpp
  Osc.h
  PacketInterface.h
  PacketUdp.cpp
  PacketUdp.h
  Samba.cpp
  Samba.h
  SetupAPI.Lib
  SetupAPI.h
  ctest.pro
  ctest.ui
  guid829.h
  loader256_data.h
  main.cpp
  object_script.ctest.Debug
  object_script.ctest.Release
  test.bin
  ui_ctest.h