📄 atmel.c
字号:
/* * dfu.c * * DFU download utility * * Copyright Brad Hards and Bas Vermeulen * *//* * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <usb.h>#include "dfu.h"#define DEBUG 1#define USB_DIR_IN 0x80#define USB_DIR_OUT 0x00#define STATUS_SUCCESS 1#define STATUS_UNSUCCESSFUL -1#define STATUS_INVALID_PARAMETER -9999#define USB_SUCCESS(a) (a >= 0)#define ATMEL_EXTWRITE 0x0E#define ATMEL_GETMODE 0x33#define ATMEL_GETFWVER 0x33#define TIMEOUT 100struct at76c503a_device_id { char *name; int idVendor; int idProduct;};static struct at76c503a_device_id atmel_device_ids[] = { {"at76c503a", 0x03eb, 0x7605 }, {"at76c505", 0x03eb, 0x7606 }, {"at76c505-2958", 0x03eb, 0x7613 }, {"at76c505A", 0x03eb, 0x7614 },};/************************************************************* GetMIB command is used from the driver to obtain the Regulatory Domain from the device.*************************************************************/int AtmelGetFwVersion(usb_dev_handle * dev, unsigned char *version){ int result; result = usb_control_msg(dev, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, /* Request Type */ ATMEL_GETFWVER, /* Request */ 0x08 << 8, /* Value */ 0, /* Index */ version, /* Buffer */ 4, /* Size */ TIMEOUT); return result;}int AtmelGetModeOfOperation(usb_dev_handle * dev, unsigned char *mode){ int result; result = usb_control_msg(dev, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, /* Request Type */ ATMEL_GETMODE, /* Request */ 0x0001, /* Value */ 0, /* Index */ mode, /* Buffer */ 1, /* Size */ TIMEOUT); return result;}int AtmelFirmwareUpgrade(char *filename){ struct usb_bus *bus; struct usb_device *device; usb_dev_handle *dev; char name[20]; unsigned char *firmware = NULL; unsigned char IsInDfuMode = 0; unsigned int fwsize; unsigned char AtmelMode = 0; unsigned char version[4]; unsigned char oldversion[4]; int status; int devnum; /* Initialize USB subsystem */ usb_init(); /* Enumerate all busses */ usb_find_busses(); /* Enumerate all devices */ usb_find_devices(); /* Find the right Vendor/Product pair */ for (bus = usb_busses; bus; bus = bus->next) for (device = bus->devices; device; device = device->next) for (devnum = 0; devnum < (sizeof(atmel_device_ids)/ sizeof(struct at76c503a_device_id)); devnum++) { if ((device->descriptor.idVendor == atmel_device_ids[devnum].idVendor) && (device->descriptor.idProduct == atmel_device_ids[devnum].idProduct)) { /* Read the Firmware file */ fwsize = ReadFirmware(filename, &firmware); if( fwsize >= 65536 ) { printf("Invalid Firmware file Length ! - Aborting ...\n"); return -1; } /* Open the USB device */ dev = usb_open(device); switch(devnum) { case 0: if(usb_get_driver_np(dev, 0, name, 8)== 0){ usb_detach_kernel_driver_np(dev, 0); } break; case 1: if(usb_get_driver_np(dev, 0, name, 8)== 0){ usb_detach_kernel_driver_np(dev, 0); } break; case 2: if(usb_get_driver_np(dev, 0, name, 8)== 0){ usb_detach_kernel_driver_np(dev, 0); } break; case 3: if(usb_get_driver_np(dev, 0, name, 9)== 0){ usb_detach_kernel_driver_np(dev, 0); } break; default: printf("There is no driver to detach\n"); break; } printf("Driver is Detached - Firmware Upgrade Procedure begins for %s\n", atmel_device_ids[devnum].name); /* Claim the interface */ usb_claim_interface(dev, 0); status = AtmelGetModeOfOperation(dev, &AtmelMode);#if 0 printf("Status = %i\n", status);#endif if ((USB_SUCCESS(status))) { switch (AtmelMode){ case 1 : status = AtmelGetFwVersion(dev, oldversion); if (!(USB_SUCCESS(status))) { printf("ATMEL - DFU : No Firmware Version Available - Aborting\n"); return -1; } else { IsInDfuMode = 1; DFUDetach(dev); if ((USB_SUCCESS(status))) { sleep(1); usb_reset(dev); // usb_claim_interface(dev, 0); DownloadFirmware(dev, firmware, fwsize); sleep(1); usb_reset(dev); } else { printf("ATMEL - DFU: Detach Command Failed - Aborting\n"); return -1; } } break; case 3 : DownloadFirmware(dev, firmware, fwsize); sleep(1); usb_reset(dev); //usb_claim_interface(dev, 0); break; default: printf("ATMEL - DFU: Non Flash Device ( EEPROM )- Aborting\n"); usb_close(dev); return -1; } } else { printf("ATMEL - DFU: Non Flash Device - Aborting\n"); usb_close(dev); return -1; } status = AtmelGetModeOfOperation(dev, &AtmelMode); if ((USB_SUCCESS(status))) { if(AtmelMode != 1) { printf("ATMEL - DFU : Firmware Upgrade Failed !!!\n"); usb_close(dev); return -1; } } status = AtmelGetFwVersion(dev, version); if ((USB_SUCCESS(status))) { printf("ATMEL - DFU : Firmware Upgrade Succeeded\n"); if( IsInDfuMode ) { printf("ATMEL - DFU : OLD Firmware Version : %d.%d.%d.%d\n", oldversion[0], oldversion[1], oldversion[2], oldversion[3]); } printf("ATMEL - DFU : NEW Firmware Version : %d.%d.%d.%d\n", version[0], version[1], version[2], version[3]); } else { printf("ATMEL - DFU : No Firmware Version - Upgrade Failed !!!\n"); usb_close(dev); return -1; } /* Close the USB device */ usb_close(dev); return 0; } } printf("No device detected - did you plug it in?\n"); return -ENODEV;}/* Main */#ifdef CONSOLE_APPint main(int argc, char *argv[]){ int uid; char filename[200]; int res; uid = getuid(); if(uid != 0){ printf("You Must Be root to Run atmelup\n"); return -EPERM; } if(argc == 2) { strcpy(filename, argv[1]); res = AtmelFirmwareUpgrade(filename); if ( res != 0 ) { printf("atmelup: Something Wicked Happened\n"); return -1; } }else { printf("atmelup: Invalid Number of Arguments\n"); return -1; } return 0;}#endif // CONSOLE_APP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -