📄 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 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 + -