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

📄 main.c

📁 AVR USB 下载线, 全套的开发资料,想做板子的可以参考下/
💻 C
📖 第 1 页 / 共 2 页
字号:
/**	\file 
	<b>USBisp main</b><br>
	Autor: Matthias Wei遝r<br>
	Copyright 2004: Matthias Wei遝r<br>
	License: QPL (see license.txt)
	<hr>
*/
/*! \mainpage USBisp

	(c)2004 by Matthias Weisser
	
	This software is distributed under the QPL
	see license.txt for more information

 	\section Compiler
 	latest WINAVR

	\section Versionshistory Versionshistory
	<b>v1.0</b>
	<ul>
		<li>First Release</li>
	</ul>
*/

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>

#include "usb.h"
#include "spi.h"
#include "tools.h"
#include "extern_vars.h"

//Atmel Includes
#include "command.h"
#include "devices.h"

#define	READY		0x00
#define	FILL_BUFFER	0xFFFF

void chip_init(void);
unsigned char adc_get(char n);

int main(void)
{
	unsigned char dat_buf[300];		//Sende/Empfangspuffer
	unsigned char *p;				//Multi-Use Pointer
	signed int n=0;					//Anzahl der zu empfangenden Zeichen in dat_buf, Wenn n negativ ist werden die ersten abs(n) Bytes als L鋘ge verwendet
	unsigned int i,j=0,k,n_tmp=0;
	unsigned int state=READY,n_state=READY;	//N鋍hster und 黚ern鋍hster State
	unsigned int address=0,address_tmp=0;
	unsigned char prgmode=0,tmp,tmp1,tmp2,tmp3,n_add=0;
	unsigned char t,clock_speed;
	signed int rec_data;
	avr_device avr_dev;

	for(i=0;i<100;i++) for(j=0;j<6750;j++) asm("nop");

	chip_init();
	spi_disable();
	
	clock_speed=eeprom_read_byte(&eeprom_sck_period);
	if(clock_speed==0xFF) clock_speed=SPI_SPEED_125KHZ;
	spi_set_speed(clock_speed);
	
	sei();

	LED_GN_ON;
	LED_RT_OFF;

	while(2)
	{
		rec_data=usb_getc();
		//Wenn Byte empfangen -> Verarbeitung
		if(rec_data!=-1)
		{
			t=rec_data&0xFF;
			if(state==READY)
			{
				if(t==Cmnd_STK_GET_SYNC) 		{state = Cmnd_STK_GET_SYNC;}
				if(t==Cmnd_STK_GET_SIGN_ON)		{state = Cmnd_STK_GET_SIGN_ON;}
				if(t==Cmnd_STK_GET_PARAMETER)	{state = FILL_BUFFER; n_state=Cmnd_STK_GET_PARAMETER; n=1; j=0;}
				if(t==Cmnd_STK_SET_PARAMETER)	{state = FILL_BUFFER; n_state=Cmnd_STK_SET_PARAMETER; n=2; j=0;}
				if(t==Cmnd_STK_SET_DEVICE)		{state = FILL_BUFFER; n_state=Cmnd_STK_SET_DEVICE; n=20; j=0;}
				if(t==Cmnd_STK_SET_DEVICE_EXT)	{state = FILL_BUFFER; n_state=Cmnd_STK_SET_DEVICE_EXT; n=5; j=0;}
				if(t==Cmnd_STK_ENTER_PROGMODE)	{state = Cmnd_STK_ENTER_PROGMODE;}
				if(t==Cmnd_STK_LEAVE_PROGMODE)	{state = Cmnd_STK_LEAVE_PROGMODE;}
                
				if(t==Cmnd_STK_CHECK_AUTOINC)	{state = Cmnd_STK_CHECK_AUTOINC;}
				if(t==Cmnd_STK_LOAD_ADDRESS)	{state = FILL_BUFFER; n_state=Cmnd_STK_LOAD_ADDRESS; n=2; j=0;}
				if(t==Cmnd_STK_CHIP_ERASE)		{state = Cmnd_STK_CHIP_ERASE;}
                
				if(t==Cmnd_STK_PROG_PAGE)		{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_PAGE; n=-2; n_add=1; n_tmp=0; j=0;}	//Parameter variabler L鋘ge
				if(t==Cmnd_STK_PROG_FLASH)		{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_FLASH; n=2; j=0;}
				if(t==Cmnd_STK_PROG_DATA)		{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_DATA; n=1; j=0;}
				if(t==Cmnd_STK_PROG_FUSE)		{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_FUSE; n=2; j=0;}
				if(t==Cmnd_STK_PROG_LOCK)		{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_LOCK; n=1; j=0;}
				if(t==Cmnd_STK_PROG_FUSE_EXT)	{state = FILL_BUFFER; n_state=Cmnd_STK_PROG_FUSE_EXT; n=3; j=0;}
                
				if(t==Cmnd_STK_READ_SIGN)		{state = Cmnd_STK_READ_SIGN;}
				if(t==Cmnd_STK_READ_PAGE)		{state = FILL_BUFFER; n_state=Cmnd_STK_READ_PAGE; n=3; j=0;}
				if(t==Cmnd_STK_READ_FLASH)		{state = Cmnd_STK_READ_FLASH;}
				if(t==Cmnd_STK_READ_DATA)		{state = Cmnd_STK_READ_DATA;}
				if(t==Cmnd_STK_READ_FUSE)		{state = Cmnd_STK_READ_FUSE;}
				if(t==Cmnd_STK_READ_LOCK)		{state = Cmnd_STK_READ_LOCK;}
				if(t==Cmnd_STK_READ_OSCCAL)		{state = Cmnd_STK_READ_OSCCAL;}
				if(t==Cmnd_STK_READ_FUSE_EXT)	{state = Cmnd_STK_READ_FUSE_EXT;}
				if(t==Cmnd_STK_READ_OSCCAL_EXT)	{state = FILL_BUFFER; n_state=Cmnd_STK_READ_OSCCAL_EXT; n=1; j=0;}
                
				if(t==Cmnd_STK_UNIVERSAL)		{state = FILL_BUFFER; n_state=Cmnd_STK_UNIVERSAL; n=4; j=0;}
				if(t==Cmnd_STK_UNIVERSAL_MULTI)	{state = FILL_BUFFER; n_state=Cmnd_STK_UNIVERSAL_MULTI; n=-1; n_add=1; n_tmp=0; j=0;}	//Parameter variabler L鋘ge

				//Wenn mal was schief l鋟ft k鰊nen wir uns evtl. noch retten
				if(t==Sync_CRC_EOP)				{state = READY;}
				
				if(state==READY) 				usb_putc(Resp_STK_NOSYNC);
			}
			//////////////////////////////////////
			//Cmnd_STK_GET_SYNC
			//////////////////////////////////////
			else if(state==Cmnd_STK_GET_SYNC)
			{
				if(t==Sync_CRC_EOP) state = READY;

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}
			//////////////////////////////////////
			//Cmnd_STK_GET_SIGN_ON
			//////////////////////////////////////
			else if(state==Cmnd_STK_GET_SIGN_ON)
			{
				if(t==Sync_CRC_EOP) state = READY;

				usb_putc(Resp_STK_INSYNC);
				usb_print("AVR STK");
				usb_putc(Resp_STK_OK);
			}
			//////////////////////////////////////
			//Cmnd_STK_GET_PARAMETER
			//////////////////////////////////////
			else if(state==Cmnd_STK_GET_PARAMETER)
			{
				if(t==Sync_CRC_EOP) state = READY;

				usb_putc(Resp_STK_INSYNC);

				switch(dat_buf[0])
				{
					case Parm_STK_HW_VER:			usb_putc(4);			break;	//Hardwareversion 4
					case Parm_STK_SW_MAJOR: 		usb_putc(1); 			break;	//Softwareversion 1.15
					case Parm_STK_SW_MINOR:			usb_putc(15);			break;	//Softwareversion 1.15
					case Parm_STK_LEDS:				usb_putc(0);			break;	//LED's aus
					case Parm_STK_VTARGET:			usb_putc(50);			break;	//5V Targetspannung
					case Parm_STK_VADJUST:			usb_putc(50);			break;	//5V Einstellbare Spannung
					case Parm_STK_OSC_PSCALE:		usb_putc(1);			break;	//Prescaler auf /1
					case Parm_STK_OSC_CMATCH:		usb_putc(0xFF);			break;	//Match auf 255
					case Parm_STK_RESET_DURATION:	usb_putc(1);			break;	//Resetdauer (ist im Protokoll nicht beschrieben)
					case Parm_STK_SCK_DURATION:		usb_putc(clock_speed);	break;	//L鋘ge einer Taktperiode f黵 das SPI-Interface
					case Parm_STK_BUFSIZEL:			usb_putc(0x2C);			break;	//Puffergr鲞e die ich verwalten kann (300 Byte)
					case Parm_STK_BUFSIZEH:			usb_putc(1);			break;	//Puffergr鲞e die ich verwalten kann (300 Byte)
					case Parm_STK_DEVICE:			usb_putc(1);			break;	//???
					case Parm_STK_PROGMODE:			usb_putc('S');			break;	//Wohl Programmiermodus S=seriell
					case Parm_STK_PARAMODE:			//usb_putc(1);			break;	//???
					case Parm_STK_POLLING:			//usb_putc(1);			break;	//???
					case Parm_STK_SELFTIMED:		usb_putc(1);			break;	//???
					case Param_STK500_TOPCARD_DETECT: usb_putc(3);			break;	//Keine Aufgesteckte Karte auf dem STK500
				}
				usb_putc(Resp_STK_OK);
			}
			//////////////////////////////////////
			//Cmnd_STK_SET_PARAMETER
			//////////////////////////////////////
			else if(state==Cmnd_STK_SET_PARAMETER)
			{
				if(t==Sync_CRC_EOP) state = READY;

				usb_putc(Resp_STK_INSYNC);

				switch(dat_buf[0])
				{
					case Parm_STK_HW_VER:						//break;	//Hardwareversion 4
					case Parm_STK_SW_MAJOR: 					//break;	//Softwareversion 1.15
					case Parm_STK_SW_MINOR:						//break;	//Softwareversion 1.15
						break;
					case Parm_STK_LEDS:							//LED's setzen
						if((dat_buf[1])==0){LED_RT_OFF; LED_GN_OFF;}
						if((dat_buf[1])==1){LED_RT_OFF; LED_GN_ON; }
						if((dat_buf[1])==2){LED_RT_ON;  LED_GN_OFF;}
						if((dat_buf[1])==3){LED_RT_ON;  LED_GN_ON; }						
						break;
					case Parm_STK_VTARGET:						//break;	//5V Targetspannung
					case Parm_STK_VADJUST:						//break;	//5V Einstellbare Spannung
					case Parm_STK_OSC_PSCALE:					//break;	//Prescaler auf /1
					case Parm_STK_OSC_CMATCH:					//break;	//Match auf 255
					case Parm_STK_RESET_DURATION:				//break;	//Resetdauer (ist im Protokoll nicht beschrieben)
						break;
					case Parm_STK_SCK_DURATION:					//L鋘ge einer halben Taktperiode f黵 das SPI-Interface in 祍
						clock_speed=SPI_SPEED_2MHZ;
						if((dat_buf[1]) >= 1  ) clock_speed=SPI_SPEED_2MHZ;
						if((dat_buf[1]) >= 2  ) clock_speed=SPI_SPEED_1MHZ;
						if((dat_buf[1]) >= 4  ) clock_speed=SPI_SPEED_500KHZ;
						if((dat_buf[1]) >= 8  ) clock_speed=SPI_SPEED_250KHZ;
						if((dat_buf[1]) >= 16 ) clock_speed=SPI_SPEED_125KHZ;
						if((dat_buf[1]) >= 32 ) clock_speed=SPI_SPEED_62KHZ;
						if(eeprom_read_byte(&eeprom_sck_period)!=clock_speed) eeprom_write_byte(&eeprom_sck_period,clock_speed);
						spi_set_speed(clock_speed);
						break;
					case Parm_STK_BUFSIZEL:						//break;	//Puffergr鲞e die ich verwalten kann (300 Byte)
					case Parm_STK_BUFSIZEH:						//break;	//Puffergr鲞e die ich verwalten kann (300 Byte)
					case Parm_STK_DEVICE:						//break;	//???
					case Parm_STK_PROGMODE:						//break;	//???
					case Parm_STK_PARAMODE:						//break;	//???
					case Parm_STK_POLLING:						//break;	//???
					case Parm_STK_SELFTIMED:					//break;	//???
					case Param_STK500_TOPCARD_DETECT:						//Keine Aufgesteckte Karte auf dem STK500
					default:
						break;
				}
				usb_putc(Resp_STK_OK);
			}
			//////////////////////////////////////
			//Cmnd_STK_SET_DEVICE
			//////////////////////////////////////
			else if(state==Cmnd_STK_SET_DEVICE)
			{
				if(t==Sync_CRC_EOP) state = READY;

				avr_dev.devicecode=dat_buf[0];
				avr_dev.revision=dat_buf[1];
				avr_dev.progtype=dat_buf[2];
				avr_dev.parmode=dat_buf[3];
				avr_dev.polling=dat_buf[4];
				avr_dev.selftimed=dat_buf[5];
				avr_dev.lockbytes=dat_buf[6];
				avr_dev.fusebytes=dat_buf[7];
				avr_dev.flashpollval1=dat_buf[8];
				avr_dev.flashpollval2=dat_buf[9];
				avr_dev.eeprompollval1=dat_buf[10];
				avr_dev.eeprompollval2=dat_buf[11];
				avr_dev.pagesize=(dat_buf[12]<<8)|dat_buf[13];
				avr_dev.eepromsize=(dat_buf[14]<<8)|dat_buf[15];;
				avr_dev.flashsize=((unsigned long)dat_buf[16]<<24)|((unsigned long)dat_buf[17]<<16)|(dat_buf[18]<<8)|dat_buf[19];

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}
			//////////////////////////////////////
			//Cmnd_STK_SET_DEVICE_EXT
			//////////////////////////////////////
			else if(state==Cmnd_STK_SET_DEVICE_EXT)
			{
				if(t==Sync_CRC_EOP) state = READY;

				avr_dev.commandsize=dat_buf[0];
				avr_dev.eeprompagesize=dat_buf[0];
				avr_dev.signalpagel=dat_buf[0];
				avr_dev.signalbs2=dat_buf[0];
				avr_dev.resetdisable=dat_buf[0];

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}

			//////////////////////////////////////
			//Cmnd_STK_CHECK_AUTOINC
			//////////////////////////////////////
			else if(state==Cmnd_STK_CHECK_AUTOINC)
			{
				if(t==Sync_CRC_EOP) state = READY;

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}

			//////////////////////////////////////
			//Cmnd_STK_LOAD_ADDRESS
			//////////////////////////////////////
			else if(state==Cmnd_STK_LOAD_ADDRESS)
			{
				if(t==Sync_CRC_EOP) state = READY;

				address=dat_buf[0]+dat_buf[1]*256;

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}

			//////////////////////////////////////
			//Cmnd_STK_CHIP_ERASE
			//////////////////////////////////////
			else if(state==Cmnd_STK_CHIP_ERASE)
			{
				if(t==Sync_CRC_EOP) state = READY;
				
				//Spezialbehandlung AT90S1200
				if(avr_dev.devicecode==AT90S1200)
				{
					spi_transfer_32(0xAC800000);
					wait_ms(25);
					spi_reset();
					wait_ms(25);
					spi_transfer_32(0xAC530000);
				}
				//alle anderen AVR's
				else
				{
					spi_transfer_32(0xAC800000);
					wait_ms(20);
				}

				usb_putc(Resp_STK_INSYNC);
				usb_putc(Resp_STK_OK);
			}

			//////////////////////////////////////
			//Cmnd_STK_PROG_PAGE
			//////////////////////////////////////
			else if(state==Cmnd_STK_PROG_PAGE)
			{
				if(t==Sync_CRC_EOP) state = READY;

				n_tmp=dat_buf[0]*256+dat_buf[1];

				//Flash
				if(dat_buf[2]=='F')
				{
					if(avr_dev.pagesize>0)	//AVR's mit Pageflash
					{
						p=&dat_buf[3];
						
						//Anzahl Seiten im Datenpakte
						k=(n_tmp/avr_dev.pagesize);
						if(k<1) k=1;

						//Alle Seiten im Datenpaket durchgehen
						for(j=0;j<k;)
						{
							tmp=0;
							tmp3=avr_dev.flashpollval1;

							//Page in AVR laden
							for(i=0;i<(avr_dev.pagesize/2);i++)
							{
								tmp1=*p;p++;
								tmp2=*p;p++;

								//Speichern einer Addresse f黵 Polling im Flash
								if(!tmp)
								{
									if(tmp1!=tmp3){address_tmp=address+i; tmp=1;}
									else if(tmp2!=tmp3){address_tmp=address+i; tmp=2;}
								}
								
								spi_transfer_16(0x4000);
								spi_transfer_8(i);
								spi_transfer_8(tmp1);
								
								spi_transfer_16(0x4800);
								spi_transfer_8(i);
								spi_transfer_8(tmp2);
							}

							//Page schreiben
							spi_transfer_8(0x4C);
							spi_transfer_16(address);
							spi_transfer_8(0x00);

							address+=avr_dev.pagesize/2;
							j++;

							//Vor dem warten schonmal Fertigmeldung rausschicken
							if(j==k)
							{
								usb_putc(Resp_STK_INSYNC);
								usb_putc(Resp_STK_OK);
							}

							//Polling oder hartes warten
							if(tmp)
							{
								do{
									if(tmp==1) spi_transfer_8(0x20);	//Low-Byte in Addresse
									else spi_transfer_8(0x28);		//High-Byte in Addresse

									spi_transfer_16(address_tmp);
									tmp1=spi_transfer_8(0x00);
								}while(tmp1==tmp3);
							}
							else wait_ms(5);
						}
					}
					else	//AVR's ohne Pageflash
					{
						//alle Bytes im Paket bearbeiten
						for(i=0;i<n_tmp;i+=2)

⌨️ 快捷键说明

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