⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 AVR单片机USB下载器资料,资料包括原理图,下载器上用的M8单片机原程序.
💻 C
字号:
 /*
  USBasp - USB in-circuit programmer for Atmel AVR controllers

  Thomas Fischl <tfischl@gmx.de>

  License........: GNU GPL v2 (see Readme.txt)
  Target.........: ATMega8 at 12 MHz
  Creation Date..: 2005-02-20
  Last change....: 2007-07-23

  PC2 SCK speed option. GND  -> slow (8khz SCK),
                        open -> fast (375kHz SCK)
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>

#include "usbdrv.h"
#include "isp.h"
#include "clock.h"

#define USBASP_FUNC_CONNECT     1
#define USBASP_FUNC_DISCONNECT  2
#define USBASP_FUNC_TRANSMIT    3
#define USBASP_FUNC_READFLASH   4
#define USBASP_FUNC_ENABLEPROG  5
#define USBASP_FUNC_WRITEFLASH  6
#define USBASP_FUNC_READEEPROM  7
#define USBASP_FUNC_WRITEEEPROM 8
#define USBASP_FUNC_SETLONGADDRESS 9

#define PROG_STATE_IDLE         0
#define PROG_STATE_WRITEFLASH   1
#define PROG_STATE_READFLASH    2
#define PROG_STATE_READEEPROM   3
#define PROG_STATE_WRITEEEPROM  4

#define PROG_BLOCKFLAG_FIRST    1
#define PROG_BLOCKFLAG_LAST     2

#define ledRedOn()    PORTC &= ~(1 << PC1)
#define ledRedOff()   PORTC |= (1 << PC1)
#define ledGreenOn()  PORTC &= ~(1 << PC0)
#define ledGreenOff() PORTC |= (1 << PC0)

static uchar replyBuffer[8];

static uchar prog_state = PROG_STATE_IDLE;

static uchar prog_address_newmode = 0;
static unsigned long prog_address;
static unsigned int prog_nbytes = 0;
static unsigned int prog_pagesize;
static uchar prog_blockflags;
static uchar prog_pagecounter;


uchar usbFunctionSetup(uchar data[8]) {

  uchar len = 0;

  if(data[1] == USBASP_FUNC_CONNECT){

    /* set SCK speed */
    if ((PINC & (1 << PC2)) == 0) {
      ispSetSCKOption(ISP_SCK_SLOW);
    } else {
      ispSetSCKOption(ISP_SCK_FAST);
    }

    /* set compatibility mode of address delivering */
    prog_address_newmode = 0;

    ledRedOn();
    ispConnect();

  } else if (data[1] == USBASP_FUNC_DISCONNECT) {
    ispDisconnect();
    ledRedOff();

  } else if (data[1] == USBASP_FUNC_TRANSMIT) {
	// 将USB发来的四个数据data2-5传到SPI,同时将返回的四个数据回传。
    if( chip_mode == ATMEL_AVR )									// 2008.02.02 by bluerain
    {
	    replyBuffer[0] = ispTransmit(data[2]);
	    replyBuffer[1] = ispTransmit(data[3]);
	    replyBuffer[2] = ispTransmit(data[4]);
	    replyBuffer[3] = ispTransmit(data[5]);
	}
	else if( chip_mode == ATMEL_S51 )
	{
		if( data[2] == 0x24 )					// read lock bits
		{
  			replyBuffer[0] = ispTransmit(data[2]);
    		replyBuffer[1] = ispTransmit(data[3]);
    		replyBuffer[2] = ispTransmit(data[4]);
  			switch(ispTransmit(data[5])&0x1c)
  			{									// AT89S52 datasheet error
  				case(0x00):replyBuffer[3] = 0xe0;	break;
  				case(0x04):replyBuffer[3] = 0xe1;	break;
  				case(0x0c):replyBuffer[3] = 0xe2;	break;
  				case(0x1c):replyBuffer[3] = 0xe3;	break;
  				   default:							break;
  			}
  		}
  		else if( data[2] == 0x30 )				// read signature bytes
  		{
  			replyBuffer[0] = ispTransmit(0x28);
    		replyBuffer[1] = ispTransmit(data[3]);
    		replyBuffer[2] = ispTransmit(data[4]);
    		replyBuffer[3] = ispTransmit(data[5]);
  		}
  		else
  		{
  			replyBuffer[0] = ispTransmit(data[2]);
    		replyBuffer[1] = ispTransmit(data[3]);
    		replyBuffer[2] = ispTransmit(data[4]);
    		replyBuffer[3] = ispTransmit(data[5]);
    		// wait	500.16 ms                   					2008.03.08 by bluerain
    		clockWait(250); 					// wait 80 ms
    		clockWait(250); 					// wait 80 ms
    		clockWait(250); 					// wait 80 ms
    		clockWait(250); 					// wait 80 ms
    		clockWait(250); 					// wait 80 ms
    		clockWait(250); 					// wait 80 ms
    		clockWait(63); 						// wait 20.16 ms
    	}
	}
    len = 4;

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

    if (!prog_address_newmode)
      prog_address = (data[3] << 8) | data[2];

    prog_nbytes = (data[7] << 8) | data[6];
    prog_state = PROG_STATE_READFLASH;
    len = 0xff; /* multiple in */

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

    if (!prog_address_newmode)
       prog_address = (data[3] << 8) | data[2];

    prog_nbytes = (data[7] << 8) | data[6];
    prog_state = PROG_STATE_READEEPROM;
    len = 0xff; /* multiple in */

  } else if (data[1] == USBASP_FUNC_ENABLEPROG) {
    replyBuffer[0] = ispEnterProgrammingMode();
    len = 1;

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

    if (!prog_address_newmode)
      prog_address = (data[3] << 8) | data[2];

    if( chip_mode == ATMEL_S51 )						// 2008.03.23 by bluerain
    {
    	data[4] = 0x00;
    }
    prog_pagesize = data[4];
    prog_blockflags = data[5] & 0x0F;
    prog_pagesize += (((unsigned int)data[5] & 0xF0)<<4);
    if (prog_blockflags & PROG_BLOCKFLAG_FIRST) {
      prog_pagecounter = prog_pagesize;
    }
    prog_nbytes = (data[7] << 8) | data[6];
    prog_state = PROG_STATE_WRITEFLASH;
    len = 0xff; /* multiple out */

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

    if (!prog_address_newmode)
      prog_address = (data[3] << 8) | data[2];

    prog_pagesize = 0;
    prog_blockflags = 0;
    prog_nbytes = (data[7] << 8) | data[6];
    prog_state = PROG_STATE_WRITEEEPROM;
    len = 0xff; /* multiple out */

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

    /* set new mode of address delivering (ignore address delivered in commands) */
    prog_address_newmode = 1;
    /* set new address */
    prog_address = *((unsigned long*)&data[2]);
  }
//设置信息缓冲区指针
  usbMsgPtr = replyBuffer;
//如果长度为零表示无返回数据,如果为0xff表示有多个数据,其余方式为数据量。
  return len;
}


uchar usbFunctionRead(uchar *data, uchar len) {

  uchar i;

  /* check if programmer is in correct read state */
  if ((prog_state != PROG_STATE_READFLASH) &&
      (prog_state != PROG_STATE_READEEPROM)) {
    return 0xff;
  }

  /* fill packet */
  for (i = 0; i < len; i++) {
    if (prog_state == PROG_STATE_READFLASH) {
      data[i] = ispReadFlash(prog_address);
    } else {
      data[i] = ispReadEEPROM(prog_address);
    }
    prog_address++;
  }

  /* last packet? */
  if (len < 8) {
    prog_state = PROG_STATE_IDLE;
  }

  return len;
}


uchar usbFunctionWrite(uchar *data, uchar len) {

  uchar retVal = 0;
  uchar i;

  /* check if programmer is in correct write state */
  if ((prog_state != PROG_STATE_WRITEFLASH) &&
      (prog_state != PROG_STATE_WRITEEEPROM)) {
    return 0xff;
  }


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

    if (prog_state == PROG_STATE_WRITEFLASH) {
      /* Flash */

      if (prog_pagesize == 0) {
	/* not paged */
	ispWriteFlash(prog_address, data[i], 1);
      } else {
	/* paged */
	ispWriteFlash(prog_address, data[i], 0);
	prog_pagecounter --;
	if (prog_pagecounter == 0) {
	  ispFlushPage(prog_address, data[i]);
	  prog_pagecounter = prog_pagesize;
	}
      }

    } else {
      /* EEPROM */
      ispWriteEEPROM(prog_address, data[i]);
    }

    prog_nbytes --;

    if (prog_nbytes == 0) {
      prog_state = PROG_STATE_IDLE;
      if ((prog_blockflags & PROG_BLOCKFLAG_LAST) &&
	  (prog_pagecounter != prog_pagesize)) {

	/* last block and page flush pending, so flush it now */
	ispFlushPage(prog_address, data[i]);
      }

	  retVal = 1; // Need to return 1 when no more data is to be received
    }

    prog_address ++;
  }

  return retVal;
}


int main(void)
{
  uchar   i, j;

  PORTD = 0;
  PORTB = 0;		/* no pullups on USB and ISP pins */
  DDRD = ~(1 << 2);	/* all outputs except PD2 = INT0 */

  DDRB = ~0;            /* output SE0 for USB reset */
  j = 0;
  while(--j){           /* USB Reset by device only required on Watchdog Reset */
      i = 0;
      while(--i);       /* delay >10ms for USB reset */
  }
  DDRB = 0;             /* all USB and ISP pins inputs */

  DDRC = 0x03;          /* all inputs except PC0, PC1 */
  PORTC = 0xfe;

  clockInit();          /* init timer */

  ispSetSCKOption(ISP_SCK_FAST);

  usbInit();
  sei();
  for(;;){	        /* main event loop */
    usbPoll();
  }
  return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -