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

📄 main.c

📁 我制作过的usbisp资料, 仅供参考
💻 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 version history version history
	<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)
{
	
	/// Send/Receive buffer
	unsigned char dat_buf[300];
	
	/// Multi-Use pointer
	unsigned char *p;
	
	/// Number of chars to be received into dat_buf If n is negative the first abs(n) bytes are used as the length of the data field
	signed int n=0;
	
	unsigned int i,j=0,k,n_tmp=0;
	
	/// next and over next state
	unsigned int state=READY,n_state=READY;
	
	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;
	
	//wait a bit
	for(i=0;i<100;i++) for(j=0;j<6750;j++) asm("nop");

	chip_init();
	spi_disable();
	
	//read the SPI clock speed from EEPROM
	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();
		//if a byte has been received -> process it
		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

				//If something went wrong we can mybe come get back to work
				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;	//Hardware version 4
					case Parm_STK_SW_MAJOR: 		usb_putc(1); 			break;	//Software version 0x01.0x12 (AVRStudio 4.10)
					case Parm_STK_SW_MINOR:			usb_putc(0x12);			break;	//Software version 0x01.0x12 (AVRStudio 4.10)
					case Parm_STK_LEDS:				usb_putc(0);			break;	//LED's off
					case Parm_STK_VTARGET:			usb_putc(50);			break;	//5V target voltage
					case Parm_STK_VADJUST:			usb_putc(50);			break;	//5V adjustable voltage
					case Parm_STK_OSC_PSCALE:		usb_putc(1);			break;	//Prescaler to /1
					case Parm_STK_OSC_CMATCH:		usb_putc(0xFF);			break;	//Match to 255
					case Parm_STK_RESET_DURATION:	usb_putc(1);			break;	//reset duration (is not documented in the protocol)
					case Parm_STK_SCK_DURATION:		usb_putc(clock_speed);	break;	//length of one SPI clock pulse
					case Parm_STK_BUFSIZEL:			usb_putc(0x2C);			break;	//buffer size that I can handle (300 Byte)
					case Parm_STK_BUFSIZEH:			usb_putc(1);			break;	//buffer size that I can handle (300 Byte)
					case Parm_STK_DEVICE:			usb_putc(1);			break;	//???
					case Parm_STK_PROGMODE:			usb_putc('S');			break;	//Maybe programming mode S=seriall
					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;	//No card on STK500 detected (I am not a 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;
				
				//special handling of AT90S1200
				if(avr_dev.devicecode==AT90S1200)
				{
					spi_transfer_32(0xAC800000);
					wait_ms(25);
					spi_reset();
					wait_ms(25);
					spi_transfer_32(0xAC530000);
				}
				//all other 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 with page flash
					{
						p=&dat_buf[3];
						
						//number of pages in data packet
						k=(n_tmp/avr_dev.pagesize);
						if(k<1) k=1;

						//process all pages in data packet
						for(j=0;j<k;)
						{
							tmp=0;
							tmp3=avr_dev.flashpollval1;

							//load page into AVR
							for(i=0;i<(avr_dev.pagesize/2);i++)
							{
								tmp1=*p;p++;
								tmp2=*p;p++;

								//store one address for polling of 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);
							}

							//write page
							spi_transfer_8(0x4C);
							spi_transfer_16(address);
							spi_transfer_8(0x00);

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

							//befor waiting send finish message
							if(j==k)
							{
								usb_putc(Resp_STK_INSYNC);
								usb_putc(Resp_STK_OK);
							}

							
							if(avr_dev.devicecode==ATMEGA162)
							{
								wait_ms(5);
							}
							else
							{
								//polling or hard waiting
								if(tmp)
								{
									do{
										if(tmp==1) spi_transfer_8(0x20);	//Low-Byte in address
										else spi_transfer_8(0x28);			//High-Byte in address
	
										spi_transfer_16(address_tmp);
										tmp1=spi_transfer_8(0x00);
									}while(tmp1==tmp3);
								}
								else wait_ms(5);
							}
						}
					}
					else	//AVR's without page flash
					{
						//process all bytes within packet
						for(i=0;i<n_tmp;i+=2)
						{
							tmp1=avr_dev.flashpollval1;
							tmp2=avr_dev.flashpollval2;

							//high and low byte
							for(j=0;j<0x09;j+=0x08)
							{
								tmp=dat_buf[i+3+(j>>3)];

								spi_transfer_8(0x40|j);
								spi_transfer_16(address);
								spi_transfer_8(tmp);
								
								if(avr_dev.devicecode==AT90S1200)
								{
									wait_ms(20);									
								}
								else	
								{
									//polling or hard waiting
									if((tmp!=tmp1)&&(tmp!=tmp2))
									{
										do{
											spi_transfer_8(0x20|j);
											spi_transfer_16(address);
											tmp=spi_transfer_8(0x00);

⌨️ 快捷键说明

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