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

📄 main.c

📁 我制作过的usbisp资料, 仅供参考
💻 C
📖 第 1 页 / 共 2 页
字号:
/**	\file
	<b>USBisp main</b><br>
	Autor: Matthias Wei遝r<br>
	Copyright 2005: Matthias Wei遝r<br>
	License: QPL (see license.txt)
	<hr>
*/
/*! \mainpage USBisp STK500 v2

	(c)2005 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 <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>

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

//Atmel Includes
#include "command.h"

#include "config.h"

//States used in the receive state machine
#define	ST_START		0xF000
#define	ST_GET_SEQ_NUM	0xF001
#define ST_MSG_SIZE_1	0xF002
#define ST_MSG_SIZE_2	0xF003
#define ST_GET_TOKEN	0xF004
#define ST_GET_DATA		0xF005
#define	ST_GET_CHECK	0xF006
#define	ST_PROCESS		0xF007

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

//Some global variables
unsigned char msg_buffer[300];
unsigned char clock_speed;
unsigned char reset_polarity;
unsigned char param_controller_init;
unsigned char prgmode;

unsigned long address;

int main(void)
{
	unsigned int i=0;

	unsigned char seq_num=0;
	unsigned int msg_size=0;
	unsigned char checksum=0;

	/// next state
	unsigned int state=ST_START;

	unsigned char t;
	signed int rec_data;

	chip_init();
	interface_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=interface_getc();
		//if a byte has been received -> process it
		if(rec_data!=-1)
		{
			t=rec_data&0xFF;

			if(state==ST_START)
			{
				if(t==MESSAGE_START)
				{
					state = ST_GET_SEQ_NUM;
					checksum = MESSAGE_START^0;
				}
			}
			else if(state==ST_GET_SEQ_NUM)
			{
				seq_num = t;
				state = ST_MSG_SIZE_1;
				checksum ^= t;
			}
			else if(state==ST_MSG_SIZE_1)
			{
				msg_size = t<<8;
				state = ST_MSG_SIZE_2;
				checksum ^= t;
			}
			else if(state==ST_MSG_SIZE_2)
			{
				msg_size |= t;
				state = ST_GET_TOKEN;
				checksum ^= t;
			}
			else if(state==ST_GET_TOKEN)
			{
				if(t==TOKEN)
				{
					state = ST_GET_DATA;
					checksum ^= t;
					i=0;
				}
				else state = ST_START;
			}
			else if(state==ST_GET_DATA)
			{
				msg_buffer[i++] = t;
				checksum ^= t;
				if(i==msg_size)
				{
					state = ST_GET_CHECK;
				}
			}
			else if(state==ST_GET_CHECK)
			{
				if(t==checksum)
				{
					process_command(seq_num);
				}

				state = ST_START;
			}

		}//if(rec_data!=-1)
	}//while(2)

	return 0;

}

/**
	Returns the value of the selected adc channel

	@param n Number of ADC channel

	@return  Value of ADC channel
*/
unsigned char adc_get(char n)
{
	ADMUX&=0xF0;
	ADMUX|=n&0x7;

	while(ADCSRA&0x40);
	ADCSRA|=(1<<ADSC);
	while(ADCSRA&0x40);

	return ADCH;
}

/**
	Processes a command packet received in main loop and located in the global buffer

	@param	seq_num	The sequence number of the command packet
*/
void process_command(unsigned char seq_num)
{
	unsigned char cmd;
	unsigned char tmp=0;
	unsigned char mode;
	unsigned int block_size;
	unsigned int i;
	unsigned int num_bytes=0;
	unsigned long polling_address=0;
	unsigned long start_address = address;

	cmd = msg_buffer[0];

	//////////////////////////////////////
	//CMD_SIGN_ON
	//////////////////////////////////////
	if(cmd==CMD_SIGN_ON)
	{
		num_bytes = 11;
		msg_buffer[0] = CMD_SIGN_ON;
		msg_buffer[1] = STATUS_CMD_OK;
		msg_buffer[2] = 8;
		memcpy(msg_buffer+3,"AVRISP_2",8);
	}
	//////////////////////////////////////
	//CMD_SET_PARAMETER
	//////////////////////////////////////
	else if(cmd==CMD_SET_PARAMETER)
	{
		switch(msg_buffer[1])
		{
			case PARAM_SCK_DURATION:
				clock_speed=SPI_SPEED_2MHZ;
				if((msg_buffer[2]) >= 1  ) clock_speed=SPI_SPEED_2MHZ;
				if((msg_buffer[2]) >= 2  ) clock_speed=SPI_SPEED_1MHZ;
				if((msg_buffer[2]) >= 4  ) clock_speed=SPI_SPEED_500KHZ;
				if((msg_buffer[2]) >= 8  ) clock_speed=SPI_SPEED_250KHZ;
				if((msg_buffer[2]) >= 16 ) clock_speed=SPI_SPEED_125KHZ;
				if((msg_buffer[2]) >= 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 PARAM_RESET_POLARITY:
				reset_polarity = msg_buffer[2];
				break;
			case PARAM_CONTROLLER_INIT:
				param_controller_init = msg_buffer[2];
				break;
		}
		
		num_bytes = 2;
		msg_buffer[0] = CMD_SET_PARAMETER;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	//////////////////////////////////////
	//CMD_GET_PARAMETER
	//////////////////////////////////////
	else if(cmd==CMD_GET_PARAMETER)
	{
		switch(msg_buffer[1])
		{
			case PARAM_BUILD_NUMBER_LOW:
				tmp = CONFIG_PARAM_BUILD_NUMBER_LOW;
				break;
			case PARAM_BUILD_NUMBER_HIGH:
				tmp = CONFIG_PARAM_BUILD_NUMBER_HIGH;
				break;
			case PARAM_HW_VER:
				tmp = CONFIG_PARAM_HW_VER;
				break;
			case PARAM_SW_MAJOR:
				tmp = CONFIG_PARAM_SW_MAJOR;
				break;
			case PARAM_SW_MINOR:
				tmp = CONFIG_PARAM_SW_MINOR;
				break;
			case PARAM_SCK_DURATION:
				tmp = clock_speed;
				break;
			case PARAM_RESET_POLARITY:
				tmp = reset_polarity;
				break;
			case PARAM_CONTROLLER_INIT:
				tmp = param_controller_init;
				break;
		}
		
		num_bytes = 3;
		msg_buffer[0] = CMD_GET_PARAMETER;
		msg_buffer[1] = STATUS_CMD_OK;
		msg_buffer[2] = tmp;
	}
	//////////////////////////////////////
	//CMD_LOAD_ADDRESS
	//////////////////////////////////////
	else if(cmd==CMD_LOAD_ADDRESS)
	{
		address =  ((unsigned long)msg_buffer[1])<<24;
		address |= ((unsigned long)msg_buffer[2])<<16;
		address |= ((unsigned long)msg_buffer[3])<<8;
		address |= ((unsigned long)msg_buffer[4]);
				
		num_bytes = 2;
		msg_buffer[0] = CMD_LOAD_ADDRESS;
		msg_buffer[1] = STATUS_CMD_OK;
	}
	//////////////////////////////////////
	//CMD_ENTER_PROGMODE_ISP
	//////////////////////////////////////
	else if(cmd==CMD_ENTER_PROGMODE_ISP)
	{
		//msg_buffer[1] //timeout		//Command time-out (in ms)
		//msg_buffer[2] //stabDelay		//Delay (in ms) used for pin stabilization
		//msg_buffer[3] //cmdexeDelay	//Delay (in ms) in connection with the EnterProgMode command execution
		//msg_buffer[4] //synchLoops	//Number of synchronization loops
		//msg_buffer[5] //byteDelay		//Delay (in ms) between each byte in the EnterProgMode command.
		//msg_buffer[6] //pollValue		//Poll value: 0x53 for AVR, 0x69 for AT89xx
		//msg_buffer[7] //pollIndex		//Start address, received byte: 0 = no polling, 3 = AVR, 4 = AT89xx
		//msg_buffer[8] //cmd1			//Command Byte # 1 to be transmitted
		//msg_buffer[9] //cmd2			//Command Byte # 2 to be transmitted
		//msg_buffer[10]//cmd3			//Command Byte # 3 to be transmitted
		//msg_buffer[11]//cmd4			//Command Byte # 4 to be transmitted
		
		prgmode=1;

		spi_enable();
												
		wait_ms(msg_buffer[2]);
		
		LED_GN_ON;
		LED_RT_ON;
		
		//Try to get connection with the target chip
		for(i=0;i<msg_buffer[4];i++)
		{
			//spi_transfer_16(0xAC53);
			spi_transfer_8(msg_buffer[8]);
			wait_ms(msg_buffer[5]);
			spi_transfer_8(msg_buffer[9]);
			wait_ms(msg_buffer[5]);
			
			if(msg_buffer[7]==3)
			{
				tmp=spi_transfer_8(msg_buffer[10]);
				wait_ms(msg_buffer[5]);
				spi_transfer_8(msg_buffer[11]);
				wait_ms(msg_buffer[5]);
			}
			else
			{
				spi_transfer_8(msg_buffer[10]);
				wait_ms(msg_buffer[5]);				
				tmp=spi_transfer_8(msg_buffer[11]);
				wait_ms(msg_buffer[5]);
			}				
					
			if((tmp==msg_buffer[6])||(msg_buffer[7]==0))
			{
				LED_GN_OFF;
				LED_RT_ON;
				i=0xFF;
				break;
			}
		
			spi_clock_pulse();
		}
		
		num_bytes = 2;
		msg_buffer[0] = CMD_ENTER_PROGMODE_ISP;
			
		if(i==0xFF)
		{			
			msg_buffer[1] = STATUS_CMD_OK;			
		}
		else
		{			
			msg_buffer[1] = STATUS_CMD_FAILED;
		}		
	}
	//////////////////////////////////////
	//CMD_LEAVE_PROGMODE_ISP
	//////////////////////////////////////
	else if(cmd==CMD_LEAVE_PROGMODE_ISP)
	{
		prgmode=0;

		spi_disable();
				
		LED_RT_OFF;
		LED_GN_ON;

		num_bytes = 2;
		msg_buffer[0] = CMD_LEAVE_PROGMODE_ISP;
		msg_buffer[1] = STATUS_CMD_OK;		
	}
	//////////////////////////////////////
	//CMD_CHIP_ERASE_ISP
	//////////////////////////////////////
	else if(cmd==CMD_CHIP_ERASE_ISP)
	{
		spi_transfer_8(msg_buffer[3]);
		spi_transfer_8(msg_buffer[4]);
		spi_transfer_8(msg_buffer[5]);
		spi_transfer_8(msg_buffer[6]);
		
		//Newer AVR's seems to have a busy bit
		//cant test this because I don't have any of these new chips
		if(msg_buffer[2]==0)
		{
			wait_ms(msg_buffer[1]);
		}
		else //if(msg_buffer[2]==1)
		{
			while(spi_transfer_32(0xF0000000)&1);
		}		
				
		num_bytes = 2;
		msg_buffer[0] = CMD_CHIP_ERASE_ISP;
		msg_buffer[1] = STATUS_CMD_OK;		
	}
	//////////////////////////////////////
	//CMD_PROGRAM_FLASH_ISP
	//////////////////////////////////////
	else if(cmd==CMD_PROGRAM_FLASH_ISP)
	{
		block_size = ((unsigned int)msg_buffer[1])<<8;
		block_size |= msg_buffer[2];
		mode = msg_buffer[3];
		
		//Word Mode
		if((mode&1) == 0)
		{		
			for(i=0;i<block_size;i++)
			{	
				//If we have an uneven byte programm the
				//high byte			
				if(i&1)
				{
					spi_transfer_8(msg_buffer[5]|(1<<3));
				}
				else
				{
					spi_transfer_8(msg_buffer[5]);
				}
				
				spi_transfer_16(address&0xFFFF);
				spi_transfer_8(msg_buffer[i+10]);
				
				//Check if we can do polling
				if(msg_buffer[8]!=msg_buffer[i+10])
				{
					polling_address = address&0xFFFF;
				}
				//If not switch the mode hard waiting
				else
				{
					mode = (mode&(~0x0E)) | 0x02;
				}
				
				//Different polling methods
				//Hard waiting
				if((mode&0x0E) == 0x02)
				{
					wait_ms(msg_buffer[4]);
				}
				//Data polling
				else if((mode&0x0E) == 0x04)
				{
					do{
						//If we have an uneven byte read the
						//high byte			

⌨️ 快捷键说明

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