Skip to content

Commit

Permalink
Merge pull request #72 from dfu-programmer/libdfu
Browse files Browse the repository at this point in the history
Source code changes for Libdfu
  • Loading branch information
cinderblock committed Dec 18, 2022
2 parents 8aedabd + d6ed743 commit bc41bf0
Show file tree
Hide file tree
Showing 17 changed files with 201 additions and 81 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
AM_CFLAGS = -Wall
bin_PROGRAMS = dfu-programmer
dfu_programmer_SOURCES = main.c
dfu_programmer_SOURCES += libdfu.c
dfu_programmer_SOURCES += arguments.c
dfu_programmer_SOURCES += atmel.c
dfu_programmer_SOURCES += commands.c
Expand Down
2 changes: 1 addition & 1 deletion src/arguments.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
#define BL_EXTRA 2 /* Bootloader at top in separate memory area */
#define BL_SPECIFIC 3 /* Any value greater than this is a specific start address */

extern int debug; /* defined in main.c */
extern int debug; /* defined in libdfu.c */

#define ARGUMENTS_DEBUG_THRESHOLD 100

Expand Down
9 changes: 9 additions & 0 deletions src/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@

#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "dfu-device.h"
#include "atmel.h"

Expand Down Expand Up @@ -245,4 +249,9 @@ struct programmer_arguments {
int32_t parse_arguments( struct programmer_arguments *args,
const size_t argc,
char **argv );

#ifdef __cplusplus
}
#endif

#endif
2 changes: 1 addition & 1 deletion src/atmel.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
#define PROGRESS_END "] "
#define PROGRESS_ERROR " X "

extern int debug; /* defined in main.c */
extern int debug; /* defined in libdfu.c */

// ________ P R O T O T Y P E S _______________________________
static int32_t atmel_read_command( dfu_device_t *device,
Expand Down
8 changes: 8 additions & 0 deletions src/atmel.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "dfu-device.h"
#include "intel_hex.h"

Expand Down Expand Up @@ -179,4 +183,8 @@ int32_t atmel_user( dfu_device_t *device,

void atmel_print_device_info( FILE *stream, atmel_device_info_t *info );

#ifdef __cplusplus
}
#endif

#endif
10 changes: 10 additions & 0 deletions src/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@
#define __COMMANDS_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "arguments.h"
#include "dfu-device.h"

int32_t execute_command( dfu_device_t *device,
struct programmer_arguments *args );

#ifdef __cplusplus
}
#endif

#endif
8 changes: 8 additions & 0 deletions src/dfu-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <stdint.h>
#include <libusb-1.0/libusb.h>

#ifdef __cplusplus
extern "C" {
#endif

// Atmel device classes are now defined with one bit per class.
// This simplifies checking in functions which handle more than one class.
#define ADC_8051 (1<<0)
Expand All @@ -27,6 +31,10 @@ typedef struct {
uint16_t transaction;
} dfu_device_t;

#ifdef __cplusplus
}
#endif

#endif /* __DFU_DEVICE_H__ */

/******************* S T M 3 2 D F U C O M M A N D S ******************
Expand Down
7 changes: 4 additions & 3 deletions src/dfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,11 @@ struct libusb_device *dfu_device_init( const uint32_t vendor,
const uint32_t device_address,
dfu_device_t *dfu_device,
const bool initial_abort,
const bool honor_interfaceclass ) {
const bool honor_interfaceclass,
libusb_context *usb_context
) {
libusb_device **list;
size_t i,deviceCount;
extern libusb_context *usbContext;
int32_t retries = 4;

TRACE( "%s( %u, %u, %p, %s, %s )\n", __FUNCTION__, vendor, product,
Expand All @@ -320,7 +321,7 @@ struct libusb_device *dfu_device_init( const uint32_t vendor,
DEBUG( "%s(%08x, %08x)\n",__FUNCTION__, vendor, product );

retry:
deviceCount = libusb_get_device_list( usbContext, &list );
deviceCount = libusb_get_device_list( usb_context, &list );

for( i = 0; i < deviceCount; i++ ) {
libusb_device *device = list[i];
Expand Down
11 changes: 10 additions & 1 deletion src/dfu.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#include <stddef.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "dfu-device.h"

/* DFU states */
Expand Down Expand Up @@ -159,7 +163,8 @@ struct libusb_device
const uint32_t dev_addr,
dfu_device_t *device,
const bool initial_abort,
const bool honor_interfaceclass );
const bool honor_interfaceclass,
libusb_context *usb_context );
/* dfu_device_init is designed to find one of the usb devices which match
* the vendor and product parameters passed in.
*
Expand All @@ -186,4 +191,8 @@ char* dfu_state_to_string( const int32_t state );
* returns the state name or "unknown state"
*/

#ifdef __cplusplus
}
#endif

#endif
9 changes: 9 additions & 0 deletions src/intel_hex.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
size_t total_size; // the total size of the buffer
size_t page_size; // the size of a flash page
Expand Down Expand Up @@ -127,4 +131,9 @@ int32_t intel_flash_prep_buffer( intel_buffer_out_t *bout );
* return 0 on success, -1 if assigning data would extend flash above size
*/


#ifdef __cplusplus
}
#endif

#endif
106 changes: 106 additions & 0 deletions src/libdfu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* dfu-programmer
*
* $Id$
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <libusb-1.0/libusb.h>
#include <string.h>

#include "config.h"
#include "dfu-device.h"
#include "dfu.h"
#include "arguments.h"
#include "commands.h"
#include "atmel.h"
#include "libdfu.h"
#include "config.h"

// NOTE: Technically not thread safe... but since it's not changed when used as a library, it's safe.
int debug;

static const char *progname = PACKAGE;

int dfu_programmer(struct programmer_arguments * args)
{
int retval = SUCCESS;
dfu_device_t dfu_device;
struct libusb_device *device = NULL;
libusb_context *usbContext;

memset(&dfu_device, 0, sizeof(dfu_device));

if (libusb_init(&usbContext))
{
fprintf(stderr, "%s: can't init libusb.\n", progname);
return DEVICE_ACCESS_ERROR;
}

if (debug >= 200)
{
#if LIBUSB_API_VERSION >= 0x01000106
libusb_set_option(usbContext, LIBUSB_OPTION_LOG_LEVEL, debug);
#else
libusb_set_debug(usbContext, debug);
#endif
}

device = dfu_device_init(args->vendor_id, args->chip_id,
args->bus_id, args->device_address,
&dfu_device,
args->initial_abort,
args->honor_interfaceclass,
usbContext);

if (NULL == device)
{
fprintf(stderr, "%s: no device present.\n", progname);
retval = DEVICE_ACCESS_ERROR;
goto error;
}

retval = execute_command(&dfu_device, args);

error:
if (NULL != dfu_device.handle)
{
int rv;

rv = libusb_release_interface(dfu_device.handle, dfu_device.interface);
/* The RESET command sometimes causes the usb_release_interface command to fail.
It is not obvious why this happens but it may be a glitch due to the hardware
reset in the attached device. In any event, since reset causes a USB detach
this should not matter, so there is no point in raising an alarm.
*/
if (0 != rv && !(com_launch == args->command &&
args->com_launch_config.noreset == 0))
{
fprintf(stderr, "%s: failed to release interface %d.\n",
progname, dfu_device.interface);
retval = DEVICE_ACCESS_ERROR;
}
}

if (NULL != dfu_device.handle)
{
libusb_close(dfu_device.handle);
}

libusb_exit(usbContext);

return retval;
}
13 changes: 13 additions & 0 deletions src/libdfu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include "arguments.h"

int dfu_programmer(struct programmer_arguments * args);

#ifdef __cplusplus
}
#endif
75 changes: 2 additions & 73 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include <stdio.h>
#include <string.h>
#include <libusb-1.0/libusb.h>

#include "config.h"
#include "dfu-device.h"
#include "dfu.h"
#include "atmel.h"
#include "arguments.h"
#include "commands.h"


int debug;
libusb_context *usbContext;
#include "libdfu.h"

int main( int argc, char **argv )
{
static const char *progname = PACKAGE;
int retval = SUCCESS;
int status;
dfu_device_t dfu_device;
struct programmer_arguments args;
struct libusb_device *device = NULL;

memset( &args, 0, sizeof(args) );
memset( &dfu_device, 0, sizeof(dfu_device) );

status = parse_arguments(&args, argc, argv);
if( status < 0 ) {
Expand All @@ -54,59 +37,5 @@ int main( int argc, char **argv )
return SUCCESS;
}

if (libusb_init(&usbContext)) {
fprintf( stderr, "%s: can't init libusb.\n", progname );
return DEVICE_ACCESS_ERROR;
}

if( debug >= 200 ) {
#if LIBUSB_API_VERSION >= 0x01000106
libusb_set_option(usbContext, LIBUSB_OPTION_LOG_LEVEL, debug);
#else
libusb_set_debug(usbContext, debug );
#endif
}

device = dfu_device_init( args.vendor_id, args.chip_id,
args.bus_id, args.device_address,
&dfu_device,
args.initial_abort,
args.honor_interfaceclass );

if( NULL == device ) {
fprintf( stderr, "%s: no device present.\n", progname );
retval = DEVICE_ACCESS_ERROR;
goto error;
}

if( 0 != (retval = execute_command(&dfu_device, &args)) ) {
/* command issued a specific diagnostic already */
goto error;
}

error:
if( NULL != dfu_device.handle ) {
int rv;

rv = libusb_release_interface( dfu_device.handle, dfu_device.interface );
/* The RESET command sometimes causes the usb_release_interface command to fail.
It is not obvious why this happens but it may be a glitch due to the hardware
reset in the attached device. In any event, since reset causes a USB detach
this should not matter, so there is no point in raising an alarm.
*/
if( 0 != rv && !(com_launch == args.command &&
args.com_launch_config.noreset == 0) ) {
fprintf( stderr, "%s: failed to release interface %d.\n",
progname, dfu_device.interface );
retval = DEVICE_ACCESS_ERROR;
}
}

if( NULL != dfu_device.handle ) {
libusb_close(dfu_device.handle);
}

libusb_exit(usbContext);

return retval;
return dfu_programmer(&args);
}
Loading

0 comments on commit bc41bf0

Please sign in to comment.