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

📄 main.c

📁 使用ATTiny26的USBasp,简单AVR编程软件
💻 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)
*/
/*idn修改
  Target.........: ATtiny26 at 16 MHz
  Last change....: 2008-02-03

  PA2 SCK speed option. open -> FAST 250kHz SCK 好象并不正确4M时钟都通信失败。
                        GND  -> SLOW 966Hz SCK 可能也不正确,不过至少1M时钟正常,
*/

#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()    PORTA &= ~(1 << PA1)
#define ledRedOff()   PORTA |= (1 << PA1)
#define ledGreenOn()  PORTA &= ~(1 << PA0)
#define ledGreenOff() PORTA |= (1 << PA0)

static uchar replyBuffer[8];


register uchar prog_state asm("r13");
register uchar prog_address_newmode asm("r12");
register unsigned long prog_address asm("r8");
register unsigned int prog_nbytes asm("r6");
register unsigned int prog_pagesize asm("r4");
register uchar prog_blockflags asm("r3");
register uchar prog_pagecounter asm("r2");


uchar usbFunctionSetup(uchar data[8]) {

  uchar len = 0;
	uchar tmpprog_state;
  if(data[1] == USBASP_FUNC_CONNECT){

    /* set SCK speed */

    /* 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) {
    *(unsigned long *)replyBuffer=ispTransmit32(*(unsigned long *)&data[2]);
    len = 4;

  } else if (data[1] == USBASP_FUNC_READFLASH) {
    
    tmpprog_state = PROG_STATE_READFLASH;
    goto multiple_out;

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

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

//prog_pagesize = *(unsigned int*)&data[4];
//    prog_pagesize += (((unsigned int)data[5] & 0xF0)<<4);
    prog_blockflags = data[5] & 0x0F;
		uchar tmp=data[5] & 0xF0;
    asm volatile("ldd	%A0, Z+4	\n\t"
				"mov	%B0, %1	\n\t"
				"swap %B0	\n\t"
				:"=r"(prog_pagesize):"r"(tmp),"0"(prog_pagesize));
    if (prog_blockflags & PROG_BLOCKFLAG_FIRST) {
      prog_pagecounter = prog_pagesize;
    }
    tmpprog_state = PROG_STATE_WRITEFLASH;
    goto multiple_out;

  } else if (data[1] == USBASP_FUNC_READEEPROM) {
    
    tmpprog_state = PROG_STATE_READEEPROM;
    goto multiple_out;

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

    prog_pagesize = 0;
    prog_blockflags = 0;
    tmpprog_state = PROG_STATE_WRITEEEPROM;
multiple_out:
    prog_state=tmpprog_state;
    if (!prog_address_newmode){
//      prog_address = *((unsigned int*)&data[2]);
    		asm volatile("ldd	%A0, Z+2	\n\t"
						"ldd	%B0, Z+3	\n\t"
						"clr	%C0	\n\t"
						"clr	%D0	\n\t"
						:"=r"(prog_address):);
		}
    prog_nbytes = *((unsigned int*)&data[6]);
    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;

  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++) {
    uchar rval;
    if (prog_state == PROG_STATE_READFLASH) {
      rval = (uchar)ispReadFlash();
    } else {
      rval = (uchar)ispReadEEPROM();
    }
    *data++ =rval;
    inc_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;
  }

	uchar *data_i;
	data_i=data;

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

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

	ispWriteFlash( *data_i);

    } else {
      /* EEPROM */
      ispWriteEEPROM(*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();
      }
	  
	  retVal = 1; // Need to return 1 when no more data is to be received
    }
    data_i++;

   inc_prog_address();//prog_address ++;
  }

  return retVal;
}


int main(void)
{
	prog_state = PROG_STATE_IDLE;
//	prog_address_newmode = 0;
//	prog_nbytes = 0;



  PORTA = (1<<selectFAST)|(1<<PA1);/*ledRedOff() ledGreenOn() selectFAST pullup */
  DDRA = 0x03;          /* all inputs except PA0, PA1 */

  clockInit();          /* init timer */

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


⌨️ 快捷键说明

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