📄 main.c
字号:
/** \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 + -