搜索
bottom↓
回复: 170

USB Boot Loader for ATMega 8 (软USB实现)

[复制链接]

出0入0汤圆

发表于 2006-7-6 21:27:43 | 显示全部楼层 |阅读模式
This is another USB boot loader. It is small enough to fit into the 2 kB boot block of an ATMega 8. This boot loader is ideal for prototyping: No need to connect a programmer, just set a jumper and the programmer is built into the target!



http://www.fischl.de/avrusbboot/



Author: Thomas Fischl





相关资料



点击此处下载armok01122508.rar

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2006-7-6 22:28:36 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2006-7-6 22:51:54 | 显示全部楼层
真厉害哦!昨天我还在想这个问题呢

出0入0汤圆

发表于 2006-7-7 13:53:28 | 显示全部楼层
水货!

出0入0汤圆

发表于 2006-7-7 17:03:05 | 显示全部楼层
经过我的证明是可行的,比我通过的其它的方法实现的要简单的多。



D:\avrusbboot\software>usbboot

usage: avrusbboot filename.hex



D:\avrusbboot\software>usbboot usbasp.hex

found 4 busses

Pagesize: 64

Write page at adresse: 0

Write page at adresse: 64

Write page at adresse: 128

Write page at adresse: 192

Write page at adresse: 256

Write page at adresse: 320

Write page at adresse: 384

Write page at adresse: 448

Write page at adresse: 512

Write page at adresse: 576

Write page at adresse: 640

Write page at adresse: 704

Write page at adresse: 768

Write page at adresse: 832

Write page at adresse: 896

Write page at adresse: 960

Write page at adresse: 1024

Write page at adresse: 1088

Write page at adresse: 1152

Write page at adresse: 1216

Write page at adresse: 1280

Write page at adresse: 1344

Write page at adresse: 1408

Write page at adresse: 1472

Write page at adresse: 1536

Write page at adresse: 1600

Write page at adresse: 1664

Write page at adresse: 1728

Write page at adresse: 1792

Write page at adresse: 1856

Write page at adresse: 1920

Write page at adresse: 1984

Write page at adresse: 2048

Write page at adresse: 2112

Write page at adresse: 2176

Write page at adresse: 2240

Write page at adresse: 2304

Write page at adresse: 2368

Write page at adresse: 2432

Write page at adresse: 2496

Write page at adresse: 2560

Write page at adresse: 2624

Write page at adresse: 2688

Write page at adresse: 2752

Write page at adresse: 2816

Write page at adresse: 2880

Write page at adresse: 2944

Write page at adresse: 3008

Write page at adresse: 3072

Write page at adresse: 3136

Write page at adresse: 3200

Write page at adresse: 3264

Write page at adresse: 3328

Write page at adresse: 3392

Write page at adresse: 3456

Write page at adresse: 3520

Write page at adresse: 3584

Write page at adresse: 3648

Write page at adresse: 3712

Write page at adresse: 3776

Write page at adresse: 3840

Write page at adresse: 3904

Write page at adresse: 3968

Write page at adresse: 4032

Write page at adresse: 4096

Write page at adresse: 4160



D:\avrusbboot\software>

出0入0汤圆

 楼主| 发表于 2006-9-17 15:44:30 | 显示全部楼层
已用于“AVR-CDC - a USB to Serial Converter(软USB实现通用串口(用CDC类))”固件升级

出0入0汤圆

 楼主| 发表于 2006-9-17 15:45:32 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2006-9-17 15:50:01 | 显示全部楼层
用于AVRDoper固件生级

出0入0汤圆

 楼主| 发表于 2006-9-17 15:51:08 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2006-9-17 16:08:41 | 显示全部楼层
AvrUSBBoot_Atmega16.hex

点击此处下载armok01128947.rar

AvrUSBBoot_Atmega8.hex

点击此处下载armok01128948.rar

出0入0汤圆

 楼主| 发表于 2006-9-17 16:12:56 | 显示全部楼层
PC端程序AvrUSBboot.exe

点击此处下载armok01128949.rar

出0入0汤圆

 楼主| 发表于 2006-9-17 16:17:22 | 显示全部楼层
电路采用和AVRCDC一样的电路,升级时将PC1短接到地

出0入0汤圆

 楼主| 发表于 2006-9-17 16:43:27 | 显示全部楼层
很少人回贴,是不是没人感兴趣啊

出0入0汤圆

发表于 2006-9-17 17:25:14 | 显示全部楼层
请问一下,AvrUSBboot.exe 安装时出现“没有找到MF42CD.DLL,因此这个程序未能启动。重新安装应用程序可能会修复此问题。”

出0入0汤圆

发表于 2006-9-17 17:28:18 | 显示全部楼层
呵呵,好东东来的,怎么会每人感兴趣。此物一出,串口isp可以退休了-:)

出0入0汤圆

 楼主| 发表于 2006-9-17 17:35:36 | 显示全部楼层
是因为我的软件未打包的原因,待会儿我的软件打包后重新上传

出0入0汤圆

 楼主| 发表于 2006-9-17 18:05:04 | 显示全部楼层
完整软件包AvrUsbBoot

点击此处下载armok01128959.rar

出0入0汤圆

 楼主| 发表于 2006-9-17 19:28:38 | 显示全部楼层
【13楼】 hualang0929 华狼

问题解决了没有

出0入0汤圆

发表于 2006-9-17 21:25:05 | 显示全部楼层
搞定,谢谢lz

出0入0汤圆

发表于 2006-9-22 10:08:12 | 显示全部楼层
不懂

出0入104汤圆

发表于 2006-10-9 11:59:36 | 显示全部楼层
请楼主将USB Boot Loader for ATMega 8 工程打包后上传,谢谢.

出0入0汤圆

发表于 2006-10-9 12:30:05 | 显示全部楼层
这么牛?那可以用USB对产品升级了,哈哈,好东西!

出0入0汤圆

发表于 2006-10-9 16:13:59 | 显示全部楼层
这个本人也测试过,没问题!

出0入0汤圆

发表于 2006-10-9 22:24:17 | 显示全部楼层
我也不懂,刚玩AVR一个多月,一直用并口ISP下载。前两天试着焊了个JTAG,最简单那种,连Reset都没接,跑起来也让我挺惊喜的,原来AVR的JTAG这么爽!



这个USB的东西是不是就是用AVR的Bootloader的自编程功能? 不明白它是用来做什么的。

“用于AVRDoper固件生级”是不是说用那个软件将监控程序写到片子的Bootloader,这样就可以让片子自己绐自己编程了?那编程的时候也是用上面那个软件吗?



是不是都是用上面那个软件,将PC1短接到地的时候就是升级监控程序(bootloader), 断开的时候就是编程(写入flash) ?



谢谢!

出0入0汤圆

 楼主| 发表于 2006-10-9 23:26:12 | 显示全部楼层
回【24楼】 icer

通过USB接口实现AVR的Bootloader的自编程功能



将PC1短接到地的时候,进行自编程,断开时运行芯片中的应用程序。

和串口的Bootloader类似,不同的是,一个通过串口实现,另一个通过USB接口实现。

进行自编程之前要先将【9楼】的代码烧到芯片中。
-----此内容被shaoshunda于2006-10-09,23:36:48编辑过

出0入0汤圆

发表于 2006-10-10 09:05:30 | 显示全部楼层
请问楼主:



    是不是每次用这个USB升级mega8程序之前,都要先将9楼的对应程序烧入芯片??

出0入0汤圆

 楼主| 发表于 2006-10-10 09:10:27 | 显示全部楼层
回【26楼】 likelovelike 李科

和串口的Bootloader一样,只需烧写一次。

出0入0汤圆

 楼主| 发表于 2006-10-10 09:13:09 | 显示全部楼层
最近实现免跳线USB Bootloader

出0入0汤圆

发表于 2006-10-10 16:59:17 | 显示全部楼层
谢谢! 继续关注!

出0入0汤圆

发表于 2006-10-10 18:39:38 | 显示全部楼层
请问编译环境是什么?

我只有AVR+Gcc

出0入0汤圆

发表于 2006-10-11 20:03:33 | 显示全部楼层

出0入0汤圆

发表于 2006-10-11 20:23:43 | 显示全部楼层
pc端怎么编程?

出0入0汤圆

发表于 2006-10-11 22:05:56 | 显示全部楼层
非常感谢。

出0入0汤圆

发表于 2006-10-12 09:18:32 | 显示全部楼层
有没有针对M128的?

出0入0汤圆

 楼主| 发表于 2006-10-12 21:58:27 | 显示全部楼层
免跳线USB Bootloader



先打开PC端软件,如下图



接着连接硬件,连接后PC端软件状态如下图



下载代码截图

出0入0汤圆

 楼主| 发表于 2006-10-12 22:34:41 | 显示全部楼层
免跳线USB Bootloader



因网络问题,PC端软件只上传可执行文件,DLL文件采用【16楼】

点击此处下载armok01131724.rar



AvrUSBBoot_Atmega8.hex

点击此处下载armok01131725.rar

AvrUSBBoot_Atmega16.hex

点击此处下载armok01131726.rar

出0入104汤圆

发表于 2006-10-13 00:51:48 | 显示全部楼层
免跳线USB Bootloader



main.c

/*

  AVRUSBBoot - USB bootloader for Atmel AVR controllers



  Thomas Fischl <tfischl@gmx.de>



  License:

  The project is built with AVR USB driver by Objective Development, which is

  published under a proprietary Open Source license. To conform with this

  license, USBasp is distributed under the same license conditions. See

  documentation.



  Target.........: ATMega8 at 12 MHz

  Creation Date..: 2006-03-18

  Last change....: 2006-06-25



  To adapt the bootloader to your hardware, you have to modify the following files:

  - bootloaderconfig.h:

    Define the condition when the bootloader should be started

  - usbconfig.h:

    Define the used data line pins. You have to adapt USB_CFG_IOPORT, USB_CFG_DMINUS_BIT and

    USB_CFG_DPLUS_BIT to your hardware. The rest should be left unchanged.

*/



#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/pgmspace.h>

#include <avr/wdt.h>

#include <avr/boot.h>



#include "usbdrv.h"

#include "bootloaderconfig.h"



#define USBBOOT_FUNC_WRITE_PAGE         2

#define USBBOOT_FUNC_LEAVE_BOOT         1

#define USBBOOT_FUNC_GET_PAGESIZE       3



#define STATE_IDLE                      0

#define STATE_WRITE_PAGE                1



#define mega8_APP_END                0x1800



static uchar replyBuffer[8];

static uchar state = STATE_IDLE;

static unsigned int page_address;

static unsigned int page_offset;



static uchar led;

static uchar time_flag=0;

static uchar time_coutn=0;





void leaveBootloader(void) {

      cli();

      boot_rww_enable();

      GICR = (1 << IVCE);  /* enable change of interrupt vectors */

      GICR = (0 << IVSEL); /* move interrupts to application flash section */

      PORTC = 0b11111101;  

      asm("ldi r30,0");

      asm("ldi r31,0");          

      asm("ijmp ");          

}



//定时器T1匹配中断A服务程序

// actual value: 12MHz 99.925mSec (0.1%)

SIGNAL(SIG_OUTPUT_COMPARE1A)

{

    sei();

        if(led)

          PORTC =0b00000001;        // led_g on  led_r off

        else

          PORTC =0b00000010;        // led_g off led_r on

        led =!led;

        if(!(time_flag))

                time_coutn++;

        else

                time_coutn=0;

}



uchar   usbFunctionSetup(uchar data[8])

{

    uchar len = 0;

       



    if ((data[1] == USBBOOT_FUNC_LEAVE_BOOT) || (time_coutn == 50) ){

      leaveBootloader();

    } else if (data[1] == USBBOOT_FUNC_WRITE_PAGE) {



      state = STATE_WRITE_PAGE;

          

      time_flag=1;

          

      page_address = (data[3] << 8) | data[2]; /* page address */

      page_offset = 0;

          

      if(page_address < mega8_APP_END){

      eeprom_busy_wait();

      cli();

      boot_page_erase(page_address); /* erase page */

      sei();

      boot_spm_busy_wait(); /* wait until page is erased */

          }

          

      len = 0xff; /* multiple out */



    } else if (data[1] == USBBOOT_FUNC_GET_PAGESIZE) {



      replyBuffer[0] = SPM_PAGESIZE >> 8;

      replyBuffer[1] = SPM_PAGESIZE & 0xff;

      len = 2;



    }



    usbMsgPtr = replyBuffer;



    return len;

}





uchar usbFunctionWrite(uchar *data, uchar len)

{



  uchar i;



  /* check if we are in correct state */

  if (state != STATE_WRITE_PAGE)

    return 0xff;

  

  for (i = 0; i < len; i+=2) {



    cli();   

    boot_page_fill(page_address + page_offset, data | (data[i + 1] << 8));

    sei();

    page_offset += 2;



    /* check if we are at the end of a page */

    if (page_offset >= SPM_PAGESIZE) {

       

      if(page_address < mega8_APP_END){

      /* write page */

      cli();

      boot_page_write(page_address);

      sei();

      boot_spm_busy_wait();

      }

      state = STATE_IDLE;

      return 1;

    }



  }

  

  return 0;

}



int main(void)

{

    /* initialize hardware */

    DDRD  = 0;                    

    PORTB = 0b11111111;

    PORTC = 0b11111110; //pc1_0 led_g led_r

    DDRC  = 0b00000011; //led output

    PORTD = 0b11110011;

    DDRB  = 0;



    GICR = (1 << IVCE);  /* enable change of interrupt vectors */

    GICR = (1 << IVSEL); /* move interrupts to boot flash section */



//TIMER1 initialize - prescale:1024

// WGM: 12) Normal, TOP=0xFFFF

// desired value: 100mSec

// actual value: 99.925mSec (0.1%)

//定时T1初始化

        TIMSK  = 0x10;                            // 中断允许

        ICR1   = (12000000/1024/10)*2;            // 12Mhz =100ms输入匹配值

        TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10); //WGM: 12 prescale:1024 启动定时器

       

    usbInit();

       

    sei();

    for(;;){    /* main event loop */

        usbPoll();

    }

    return 0;

}


-----此内容被andy于2006-10-13,00:55:15编辑过

出0入0汤圆

 楼主| 发表于 2006-10-14 13:17:37 | 显示全部楼层
最近实现“免驱动免跳线”USB Bootloader

出0入0汤圆

发表于 2006-10-14 20:36:26 | 显示全部楼层
哦。真不错。顶一下!!

出0入0汤圆

发表于 2006-10-26 15:31:48 | 显示全部楼层
TO 红日:



   usbasp是非常不错的一个软件包,能否将usbdrv.h如何在自己程序使用说明一下么?

   还有一个比较难开口的要求,能否将你得上位机程序代码公开一下1!

   我想写一个用usbdrv.h来做数据采集的东西1!

   谢谢1!!



li780713@126.com

出0入0汤圆

 楼主| 发表于 2006-10-26 16:30:39 | 显示全部楼层
等有空的时候贴代码

出0入0汤圆

发表于 2006-10-26 20:03:11 | 显示全部楼层
TO:shaoshunda

   没想到楼主也在,那谢谢你了!

   请尽快帮我贴出来,对usbdrv.h在自己程序里如何使用说明一下。谢谢了!!!

哈哈哈

出0入0汤圆

发表于 2006-10-26 21:02:26 | 显示全部楼层
PC端目前都是用libusb的驱动,可是我觉得这个驱动不是很稳定。

装上之后,U盘弹出的图标就没有了,卸载后就又正常了。

出0入0汤圆

 楼主| 发表于 2006-10-27 00:11:50 | 显示全部楼层
PC端源代码,采用VC++6.0 编写

点击此处下载armok01133419.rar

固件源代码

点击此处下载armok01133420.rar

出0入0汤圆

发表于 2006-10-28 22:24:18 | 显示全部楼层
请问andy和楼主,免跳线Bootloader的原理是什么?我看上面贴出的main.c代码,没有理解到底是怎么回事。



我猜测实现免跳线Bootloader的思路是:



先启动上位机程序,反复尝试和bootloader通讯,bootloader启动后等待一定的时间(只要时间大于上位机尝试通讯的间隔的二倍或以上即可),如果检测到上位机软件的通讯数据,则双方握手,开始升级Flash。如果bootloader等待时间比较长,比如5秒,则上位机可以不用自动尝试通讯,可以手工启动升级过程。



我的理解正确吗?对应的逻辑在main.c中的哪个部分呢?谢谢!

出0入0汤圆

 楼主| 发表于 2006-10-29 17:40:59 | 显示全部楼层
【45楼】 dumm

你的理解是对的,在固件上andy用了定时器,而我只用了两个变量。

至于说通讯协议完全可以自己定,因为已经有了源代码。
-----此内容被shaoshunda于2006-10-29,17:43:26编辑过

出0入0汤圆

发表于 2006-10-29 22:11:08 | 显示全部楼层
谢谢shaoshunda!研究了你对官方代码的修改,很巧妙!



我在UsbAsp上成功安装并启动了bootloader,可是从bootloader跳到用户程序(UsbAsp程序)的时候似乎没有重新初始化USB,因此UsbAsp不能正常工作。我还在研究如何解决这个问题。

出0入0汤圆

发表于 2006-11-8 21:04:45 | 显示全部楼层
记号

出0入0汤圆

发表于 2006-12-31 01:54:34 | 显示全部楼层
比ISP快多了,下载14K 到M16大约两秒。两秒啊!





谢谢 shaoshunda ,感谢你的共享,期待你的“免驱动免跳线”USB Bootloader 。
-----此内容被Bromi于2006-12-31,02:04:19编辑过

出0入0汤圆

发表于 2007-1-1 15:09:14 | 显示全部楼层
弱弱的问一下,必须使用12M外部晶振吗

出0入0汤圆

 楼主| 发表于 2007-1-1 21:27:44 | 显示全部楼层
回【50楼】 greeham

必须使用12M外部晶振

出0入0汤圆

 楼主| 发表于 2007-1-9 12:36:14 | 显示全部楼层
“免驱动免跳线”USB Bootloader

采用HID类,无需LibUSB0驱动。

增加了Bootloader保护功能.



PC端软件及固件:

点击此处下载armok01140898.rar

已经ATMega16测试成功,ATMega8未经测试。

出0入0汤圆

发表于 2007-1-9 13:02:13 | 显示全部楼层
狂顶

出0入0汤圆

发表于 2007-1-9 14:35:04 | 显示全部楼层
晕死,52楼没有源码,白高兴了

出0入0汤圆

 楼主| 发表于 2007-1-10 10:08:10 | 显示全部楼层
晚上贴代码。看来没什么人感兴趣。

出0入0汤圆

发表于 2007-1-10 10:14:25 | 显示全部楼层
好定西,帮你顶
-----此内容被zhifeng于2007-01-10,10:14:53编辑过

出0入0汤圆

发表于 2007-1-10 17:58:17 | 显示全部楼层
不错,顶,等代码。谢谢。

出0入0汤圆

发表于 2007-1-10 18:09:29 | 显示全部楼层
正在学 VC++, 如果上位机代码也贴出来就更好,感谢shaoshunda大哥。

出0入0汤圆

发表于 2007-1-10 18:56:34 | 显示全部楼层
支持一下,也想做个玩玩

出0入0汤圆

 楼主| 发表于 2007-1-10 23:30:55 | 显示全部楼层
文件传不上来,明天再传

出0入0汤圆

发表于 2007-1-11 09:36:33 | 显示全部楼层
请问楼主,这个东东是做什么用的呀?

出0入0汤圆

 楼主| 发表于 2007-1-11 09:43:22 | 显示全部楼层
回【61楼】 shabby

通过USB在线升级

出0入0汤圆

 楼主| 发表于 2007-1-11 09:45:05 | 显示全部楼层
免驱动固件源码

点击此处下载armok01141119.rar

出0入0汤圆

发表于 2007-1-11 11:00:58 | 显示全部楼层
好东东.顶下

出0入0汤圆

发表于 2007-1-12 00:12:03 | 显示全部楼层
好。不用驱程好,顶一下。

pc端的源码也有吗?

出0入0汤圆

发表于 2007-2-23 20:19:57 | 显示全部楼层
不错,正在研究USB相关程序,能提供那个免驱动的PC端Source吗?

出0入0汤圆

发表于 2007-2-25 14:51:43 | 显示全部楼层
好东西!顶!收藏!

出0入0汤圆

发表于 2007-2-25 23:26:00 | 显示全部楼层
to shaoshunda



我用VC写免驱动的PC端时,发现执行函数

。。。。。。。。。。。。。。。。。。。。。

int usbSetReport(usbDevice_t *device, int reportType, char *buffer, int len)

{

HANDLE  handle = (HANDLE)device;

BOOLEAN rval = 0;

DWORD   bytesWritten;



    switch(reportType){

    case USB_HID_REPORT_TYPE_INPUT:

        break;

    case USB_HID_REPORT_TYPE_OUTPUT:

        rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);

        break;

    case USB_HID_REPORT_TYPE_FEATURE:

        rval = HidD_SetFeature(handle, buffer, len);

        break;

    }

    return rval == 0 ? USB_ERROR_IO : 0;

}

。。。。。。。。。。。。。。。。。。。。。。。。。

上面的  rval = HidD_SetFeature(handle, buffer, len);



总是返回为FALSE,是怎么回事呀?能够指点一下吗?

出0入0汤圆

发表于 2007-2-26 23:49:52 | 显示全部楼层
支持楼主,好贴要顶上去...

出0入0汤圆

 楼主| 发表于 2007-2-27 09:31:33 | 显示全部楼层
【68楼】 ldz2000

rval = HidD_SetFeature(handle, buffer, len); 中的len要和固件中报告描述符中的REPORT_COUNT一致

出0入0汤圆

发表于 2007-2-27 10:54:29 | 显示全部楼层
哈,多谢shaoshunda提醒.



确实如此,长度不能随便指定,要符合报告描述符中的Report_count长度描述!

出0入0汤圆

发表于 2007-2-27 13:45:08 | 显示全部楼层
多谢了。

如果还有FLASH空间最好能留出软USB数据输入输出的程序接口供其它程序调用。

出0入0汤圆

发表于 2007-2-27 14:02:51 | 显示全部楼层
收下

出0入0汤圆

发表于 2007-3-2 12:52:45 | 显示全部楼层
这2天有空试了一下,固件写入成功,用isp读出验证没有问题。

可是无法从bootloader 转到固件应用,研究中。。。

出0入0汤圆

发表于 2007-3-4 13:34:17 | 显示全部楼层
真是奇怪,我用的SL 的isp程序

如果把bootrst 选择框选中的话,每次都能进入bootloader , 却无法进入应用部分

如果不选bootrst 的话 可以进入bootloader(很奇怪。。) ,用bootloader写入一次固件后,重新插拔可以进入应用,再也不能进入bootloader了,成了1次性的bootloader...



可是从bootloader固件代码上看,BOOT_DOG每次poll增加1,直到溢出,每次溢出BOOT_FLG增加1,当BOOT_FLG大于3时,会跳出bootloader到应用。可是似乎确不起作用。。。

出0入0汤圆

发表于 2007-3-5 10:41:27 | 显示全部楼层
原来 【47楼】 dumm  已经发现这个问题了。



用bootloader下载后,应用的初始化代码都失效了。设备的vid,pid都没变化。

我调用了usbDisconnect() 并延时一段时间,仍然没有效果。



不知道 dumm 有没有解决这个问题?

出0入0汤圆

 楼主| 发表于 2007-3-5 13:41:41 | 显示全部楼层
回【76楼】 icefire



bootloader的代码无需修改。

只要修改应用程序代码,具体修改如下



static void hardwareInit(void)

{

uchar    i, j;



    /* activate pull-ups except on USB lines */

    USB_CFG_IOPORT   = (uchar)~((1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT));

    /* all pins input except USB (-> USB reset) */

#ifdef USB_CFG_PULLUP_IOPORT    /* use usbDeviceConnect()/usbDeviceDisconnect() if available */

    USBDDR    = 0;    /* we do RESET by deactivating pullup */

    usbDeviceDisconnect();

#else

    USBDDR    = (1<<USB_CFG_DMINUS_BIT)|(1<<USB_CFG_DPLUS_BIT);

#endif



    j = 0;

    while(--j){          /* USB Reset by device only required on Watchdog Reset */

        i = 0;

        while(--i);      /* delay >10ms for USB reset */

    }

#ifdef USB_CFG_PULLUP_IOPORT

    usbDeviceConnect();

#else

    USBDDR    = 0;      /*  remove USB reset condition */

#endif

}

//**************************************************************************

int main(void)

{

//    uchar       n = 0;



    wdt_enable(WDTO_1S);



    hardwareInit();



    usbInit();



    sei();



    for(;;){    /* main event loop */

        wdt_reset();

        usbPoll();

    }

    return 0;

}

出0入0汤圆

发表于 2007-3-5 15:58:53 | 显示全部楼层
谢谢,收下

出0入0汤圆

发表于 2007-3-6 11:08:16 | 显示全部楼层
回 【77楼】 shaoshunda



楼主的思路和我一样,我的简单些,结果是一样的,无效。应该是usbDeviceDisconnect()没起作用,一会再去看看usb规范。现象和过程如下,启动pc端,插入usb,pc端激活,退出pc端,等待usb超时跳出bootloader,再次启动pc端(只是为了证实设备是否已经移出)



过程中,用bushound 抓包如下,

Device  Phase  Data                                                                                                    Description       Cmd.Phase.Ofs(rep)  Time        

------  -----  ------------------------------------------------------------------------------------------------------  ----------------  ------------------  ------------

  27.0  CTL    80 06 00 01  00 00 12 00                                                                                GET DESCRIPTOR           1.1.0        03:02:52.503  

  27.0  DI     12 01 01 01  00 00 00 08  36 16 df 05  00 01 01 02  00 01                                               ........6.......         1.2.0        03:02:52.508  

  27.0  CTL    80 06 00 02  00 00 09 00                                                                                GET DESCRIPTOR           2.1.0        03:02:52.508  

  27.0  DI     09 02 1b 00  01 01 00 80  0a                                                                            .........                2.2.0        03:02:52.513  

  27.0  CTL    80 06 00 02  00 00 1b 00                                                                                GET DESCRIPTOR           3.1.0        03:02:52.513  

  27.0  DI     09 02 1b 00  01 01 00 80  0a 09 04 00  00 00 03 00  00 00 09 21  01 01 00 01  22 18 00                  ................         3.2.0        03:02:52.520  

  27.0  CTL    00 09 01 00  00 00 00 00                                                                                SET CONFIG               4.1.0        03:02:52.520  

  27.0  CTL    21 0a 00 00  00 00 00 00                                                                                SET IDLE                 5.1.0        03:02:52.523  

  27.0  CTL    81 06 00 22  00 00 58 00                                                                                GET DESCRIPTOR           6.1.0        03:02:52.526  

  27.0  DI     06 00 ff 09  01 a1 01 15  00 26 ff 00  75 08 85 01  95 83 09 00  b2 02 01 c0                            .........&..u...         6.2.0        03:02:52.534  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR           7.1.0        03:02:52.556  

  27.0  CTL    80 06 02 03  09 04 02 02                                                                                GET DESCRIPTOR           8.1.0        03:02:52.561  

  27.0  CTL    a1 01 01 03  00 00 84 00                                                                                GET REPORT               9.1.0        03:02:52.566  

  27.0  DI     01 00 40                                                                                                ..@                      9.2.0        03:02:52.571  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR          10.1.0        03:02:52.575  

  27.0  CTL    80 06 02 03  09 04 02 02                                                                                GET DESCRIPTOR          11.1.0        03:02:52.580  

  27.0  CTL    a1 01 01 03  00 00 84 00                                                                                GET REPORT              12.1.0        03:02:52.597  

  27.0  DI     01 00 40                                                                                                ..@                     12.2.0        03:02:52.602  



。。。。。。。。。。。。。。。。。。。省略。。。



  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         166.1.0        03:02:54.199  

  27.0  CTL    80 06 02 03  09 04 02 02                                                                                GET DESCRIPTOR         167.1.0        03:02:54.204  

  27.0  CTL    a1 01 01 03  00 00 84 00                                                                                GET REPORT             168.1.0        03:02:54.222  

  27.0  DI     01 00 40                                                                                                ..@                    168.2.0        03:02:54.227  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         169.1.0        03:02:54.230  

  27.0  CTL    80 06 02 03  09 04 02 02                                                                                GET DESCRIPTOR         170.1.0        03:02:54.235  

  27.0  CTL    a1 01 01 03  00 00 84 00                                                                                GET REPORT             171.1.0        03:02:54.253  

  27.0  DI     01 00 40                                                                                                ..@                    171.2.0        03:02:54.258  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         172.1.0        03:02:54.261  

  27.0  CTL    80 06 02 03  09 04 02 02                                                                                GET DESCRIPTOR         173.1.0        03:02:54.266  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         174.1.0        03:03:37.075  

  27.0  USTS   05 00 00 c0                                                                                             no response            174.2.0        03:03:37.078  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         175.1.0        03:03:37.086  

  27.0  USTS   05 00 00 c0                                                                                             no response            175.2.0        03:03:37.089  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         176.1.0        03:03:37.101  

  27.0  USTS   05 00 00 c0                                                                                             no response            176.2.0        03:03:37.104  

  27.0  CTL    80 06 01 03  09 04 02 02                                                                                GET DESCRIPTOR         177.1.0        03:03:37.117  

  27.0  USTS   05 00 00 c0                                                                                             no response            177.2.0        03:03:37.120  



可见,系统并未检测到设备拔出了(固件模拟的)。

出0入0汤圆

发表于 2007-3-6 18:20:25 | 显示全部楼层
真是奇怪。。明明把D- D+ 都设置为输出低电平,并延时了,系统怎么就检测不到设备脱机呢?

出0入0汤圆

发表于 2007-3-6 18:56:00 | 显示全部楼层

出0入0汤圆

发表于 2007-3-8 19:37:03 | 显示全部楼层
shaoshunda 大哥,请问您的 HID 类的PC端源码能发布吗??



谢谢~~



另外请教一个菜鸟级问题:如果我想通过USB来通讯(采集数据,读写外部Flash等),而不是对BootLoader编程,那么PC端的程序还需要改动吗???

出0入0汤圆

 楼主| 发表于 2007-3-8 20:41:46 | 显示全部楼层
回【82楼】 dvhome

你可以参考开源项目“Automator”

PC端源码,固件源码,电路图

点击此处下载armok01145978.zip

网址http://www.obdev.at/products/avrusb/automator.html

出0入0汤圆

发表于 2007-3-8 21:37:25 | 显示全部楼层
shaoshunda大哥:你贴上来的automator代码看不懂啊~是用SDK写的吧??



你做的使用MFC的 HID 端的源码可以发一份上来吗??谢谢~~

出0入0汤圆

发表于 2007-3-8 22:13:32 | 显示全部楼层
shaoshunda大哥:我现在想先实现一下功能,有一些基础上的问题不明白,请你给我扫扫盲~



我想实现:

          启动AVR时,检测是否连在PC上,如果是,则初始化为 HID 设备,从PC端发送数据过来,由AVR写入到外部的串行Flash中去。



          如果经过1秒的检测,没有连接在PC USB上,那么就转到应用程序中执行~~~





现存在一下几个问题不是很清楚:

    一、由于发送过来的数据比较多,能不能分多次发送过来??比如先发128Byte,然后AVR写入到Flash,这个过程PC端等待,等AVR写完以后,发送一个信号,PC端继续发剩下的数据……



    二、USB的连接检测,能不能在应用程序中做检测??占用资源会不会很多???





谢谢~





shaoshunda大哥,我有一个不情之请,你能留一个Email吗??我想弄这个AVR-USB不是一天两天了,一直是苦于没有高人指点,无从学起~~今天看到你的帖子,我茅塞顿开,以前很多不明白的东西都有了一个基本的概念,但我知道,在接下来的过程中还会遇到很多的问题,我很想得到你这样的高手指点~~~

出0入0汤圆

 楼主| 发表于 2007-3-8 22:25:45 | 显示全部楼层
【83楼】的源码中的核心代码HID部分,是usb-windows.c



/* Name: usb-windows.c

* Project: usbcalls library

* Author: Christian Starkjohann

* Creation Date: 2006-02-02

* Tabsize: 4

* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH

* License: Proprietary, free under certain conditions. See Documentation.

* This Revision: $Id: usb-windows.c 137 2006-02-20 18:04:09Z cs $

*/



/*

General Description:

This module implements USB HID report receiving and sending with native

Windows API functions. If you compile with MinGW, no software from Microsoft

(no DDK) is needed. We supply the missing types and function prototypes in

hidsdi.h.

*/



#include <stdio.h>

#include <windows.h>

#include <setupapi.h>

#include "hidsdi.h"

#include <ddk/hidpi.h>



#include "usbcalls.h"



#ifdef DEBUG

#define DEBUG_PRINT(arg)    printf arg

#else

#define DEBUG_PRINT(arg)

#endif



/* ------------------------------------------------------------------------ */



static void convertUniToAscii(char *buffer)

{

unsigned short  *uni = (void *)buffer;

char            *ascii = buffer;



    while(*uni != 0){

        if(*uni >= 256){

            *ascii++ = '?';

        }else{

            *ascii++ = *uni++;

        }

    }

    *ascii++ = 0;

}



int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs)

{

GUID                                hidGuid;        /* GUID for HID driver */

HDEVINFO                            deviceInfoList;

SP_DEVICE_INTERFACE_DATA            deviceInfo;

SP_DEVICE_INTERFACE_DETAIL_DATA     *deviceDetails = NULL;

DWORD                               size;

int                                 i, openFlag = 0;  /* may be FILE_FLAG_OVERLAPPED */

int                                 errorCode = USB_ERROR_NOTFOUND;

HANDLE                              handle = INVALID_HANDLE_VALUE;

HIDD_ATTRIBUTES                     deviceAttributes;

                               

    HidD_GetHidGuid(&hidGuid);

    deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

    deviceInfo.cbSize = sizeof(deviceInfo);

    for(i=0;;i++){

        if(handle != INVALID_HANDLE_VALUE){

            CloseHandle(handle);

            handle = INVALID_HANDLE_VALUE;

        }

        if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))

            break;  /* no more entries */

        /* first do a dummy call just to determine the actual size required */

        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);

        if(deviceDetails != NULL)

            free(deviceDetails);

        deviceDetails = malloc(size);

        deviceDetails->cbSize = sizeof(*deviceDetails);

        /* this call is for real: */

        SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL);

        DEBUG_PRINT(("checking HID path \"%s\"
", deviceDetails->DevicePath));

        /* attempt opening for R/W -- we don't care about devices which can't be accessed */

        handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);

        if(handle == INVALID_HANDLE_VALUE){

            DEBUG_PRINT(("opening failed: %d
", (int)GetLastError()));

            /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */

            continue;

        }

        deviceAttributes.Size = sizeof(deviceAttributes);

        HidD_GetAttributes(handle, &deviceAttributes);

        DEBUG_PRINT(("device attributes: vid=%d pid=%d
", deviceAttributes.VendorID, deviceAttributes.ProductID));

        if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)

            continue;   /* ignore this device */

        errorCode = USB_ERROR_NOTFOUND;

        if(vendorName != NULL && productName != NULL){

            char    buffer[512];

            if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){

                DEBUG_PRINT(("error obtaining vendor name
"));

                errorCode = USB_ERROR_IO;

                continue;

            }

            convertUniToAscii(buffer);

            DEBUG_PRINT(("vendorName = \"%s\"
", buffer));

            if(strcmp(vendorName, buffer) != 0)

                continue;

            if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){

                DEBUG_PRINT(("error obtaining product name
"));

                errorCode = USB_ERROR_IO;

                continue;

            }

            convertUniToAscii(buffer);

            DEBUG_PRINT(("productName = \"%s\"
", buffer));

            if(strcmp(productName, buffer) != 0)

                continue;

        }

        break;  /* we have found the device we are looking for! */

    }

    SetupDiDestroyDeviceInfoList(deviceInfoList);

    if(deviceDetails != NULL)

        free(deviceDetails);

    if(handle != INVALID_HANDLE_VALUE){

        *device = (usbDevice_t *)handle;

        errorCode = 0;

    }

    return errorCode;

}



/* ------------------------------------------------------------------------ */



void    usbCloseDevice(usbDevice_t *device)

{

    CloseHandle((HANDLE)device);

}



/* ------------------------------------------------------------------------ */



int usbSetReport(usbDevice_t *device, int reportType, char *buffer, int len)

{

HANDLE  handle = (HANDLE)device;

BOOLEAN rval = 0;

DWORD   bytesWritten;



    switch(reportType){

    case USB_HID_REPORT_TYPE_INPUT:

        break;

    case USB_HID_REPORT_TYPE_OUTPUT:

        rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);

        break;

    case USB_HID_REPORT_TYPE_FEATURE:

        rval = HidD_SetFeature(handle, buffer, len);

        break;

    }

    return rval == 0 ? USB_ERROR_IO : 0;

}



/* ------------------------------------------------------------------------ */



int usbGetReport(usbDevice_t *device, int reportType, int reportNumber, char *buffer, int *len)

{

HANDLE  handle = (HANDLE)device;

BOOLEAN rval = 0;

DWORD   bytesRead;



    switch(reportType){

    case USB_HID_REPORT_TYPE_INPUT:

        buffer[0] = reportNumber;

        rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);

        if(rval)

            *len = bytesRead;

        break;

    case USB_HID_REPORT_TYPE_OUTPUT:

        break;

    case USB_HID_REPORT_TYPE_FEATURE:

        buffer[0] = reportNumber;

        rval = HidD_GetFeature(handle, buffer, *len);

        break;

    }

    return rval == 0 ? USB_ERROR_IO : 0;

}



/* ------------------------------------------------------------------------ */



至于界面,你可以使用VC的MFC编写也可以用C++ Builder

上面的代码应该不会很复杂,关键要理解HID的协议部份。



关于我的MFC源码帖子上其实已经有了,在【44楼】

只不过是将libusb0的驱动部分改为HID,使用的就以上源码

出0入0汤圆

 楼主| 发表于 2007-3-8 22:37:20 | 显示全部楼层
回【85楼】 dvhome

高手可不敢当,我的代码也是写得七七八八的。

一直没空整理,没敢再发代码。

shaoshunda@126.com

QQ:21279489

出0入0汤圆

发表于 2007-3-9 10:23:54 | 显示全部楼层
我下了最新的 AVRDoper



使用WinAVR 编译  



avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c usbdrv/usbdrv.c -o usbdrv/usbdrv.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -x assembler-with-cpp -c usbdrv/usbdrvasm.S -o usbdrv/usbdrvasm.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c usbdrv/oddebug.c -o usbdrv/oddebug.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c hvprog.c -o hvprog.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c isp.c -o isp.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c serial.c -o serial.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c stk500protocol.c -o stk500protocol.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c timer.c -o timer.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c utils.c -o utils.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c vreg.c -o vreg.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -c main.c -o main.o

avr-gcc -Wall -Os -Iusbdrv -I. -mmcu=atmega8 -DDEBUG_LEVEL=0 -o main.bin usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o hvprog.o isp.o serial.o stk500protocol.o timer.o utils.o vreg.o main.o

rm -f main.hex main.eep.hex

avr-objcopy -j .text -j .data -O ihex main.bin main.hex

./checksize main.bin 8192 1024

F:\AVRDoper\firmware\checksize: awk: command not found

F:\AVRDoper\firmware\checksize: [: -gt: unary operator expected

ROM:  bytes (data=)

F:\AVRDoper\firmware\checksize: [: -gt: unary operator expected

RAM:  bytes





感觉后面部分好像不对??(我一直使用IAR,GCC的没有弄过~不懂~)



是不是我的编译器太老了???

WinAVR User Manual - 20060421

出0入0汤圆

发表于 2007-3-9 23:47:21 | 显示全部楼层
【88楼】 dvhome  



你的没问题,已经生成main.hex了



错误原因是没安装awk , linux下都有的东西,不影响编译,只是少了统计数据而已。





usb重新初始化 仍然不成功。。。

出0入0汤圆

发表于 2007-3-12 17:20:05 | 显示全部楼层
好貼子,謝謝主,頂頂頂!!!

出0入0汤圆

发表于 2007-5-15 13:15:56 | 显示全部楼层
不错,效果还可以,楼主能否给个简单的USB通讯例子?

出0入0汤圆

发表于 2007-6-13 22:25:40 | 显示全部楼层
请问楼主:

能否将免驱动免跳线Firmware源代码共享一下呢?



我将【52楼】提供的hex文件烧录到M8上,试过是OK.



但我将【63楼】的源码下载到本地,自己编译出一版Hex文件,试过不行!!!!



能否将【52楼】提供的Hex文件所对应的源代码也上传????



谢谢了~~~~

出0入0汤圆

发表于 2007-6-15 20:58:13 | 显示全部楼层
好东西,收下了。有空研究阿

出0入0汤圆

发表于 2007-6-26 18:32:29 | 显示全部楼层
好东西,我来顶一下!

出0入0汤圆

发表于 2007-6-28 11:46:44 | 显示全部楼层
虽然我现在还看不明白是什么意思,但是还是先顶一下,呵呵

出0入0汤圆

发表于 2008-6-4 09:00:32 | 显示全部楼层
好东西,收下,谢谢!!

出0入0汤圆

发表于 2008-6-4 09:47:13 | 显示全部楼层
mark,谢谢

出0入0汤圆

发表于 2008-6-4 09:59:35 | 显示全部楼层
mark,学习下

出0入0汤圆

发表于 2008-6-4 13:32:26 | 显示全部楼层
很有用,谢谢了

出0入0汤圆

发表于 2008-12-31 14:35:04 | 显示全部楼层
好东西啊.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-14 03:38

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表