📄 main.c
字号:
/** \file
<b>USBisp bootloader</b>
<hr>
*/
/*! \mainpage USBisp Bootloader
(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 <avr/io.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include "usb.h"
#include "tools.h"
#include "command.h"
#define READY 0x00
#define FILL_BUFFER 0xFF
void chip_init(void);
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
signed int rec_data;
unsigned int i,j=0,n_tmp=0;
unsigned int address=0;
unsigned char k,t;
unsigned char state=READY,n_state=READY; //N鋍hster und 黚ern鋍hster State
unsigned char n_add=0;
DDRB=0; //PORTB -> Eing鋘ge
PORTB=0x03; //Pull-Ups auf LED-Pins
for(k=0;k<250;k++) asm("nop");
if(!(PINB&0x03)) asm volatile("rjmp app_start");
DDRB=(1<<0)|(1<<1); //LED_RT, LED_GN
DDRC=(1<<1)|(1<<2); //USB_RD, USB_WR
LED_RT_ON;
for(k=0;k<128;k++) eeprom_write_byte((unsigned char *)((unsigned int)k),0xFF);
LED_GN_ON;
for(;;)
{
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_PARAMETER) {state = FILL_BUFFER; n_state=Cmnd_STK_GET_PARAMETER; n=1; j=0;}
if(t==Cmnd_STK_SET_DEVICE) {state = FILL_BUFFER; n_state=Cmnd_STK_GET_SYNC; n=20; j=0;}
if(t==Cmnd_STK_SET_DEVICE_EXT) {state = FILL_BUFFER; n_state=Cmnd_STK_GET_SYNC; 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_LOAD_ADDRESS) {state = FILL_BUFFER; n_state=Cmnd_STK_LOAD_ADDRESS; n=2; j=0;}
if(t==Cmnd_STK_CHIP_ERASE) {state = Cmnd_STK_GET_SYNC;}
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_READ_PAGE) {state = FILL_BUFFER; n_state=Cmnd_STK_READ_PAGE; n=3; j=0;}
if(t==Cmnd_STK_UNIVERSAL) {state = FILL_BUFFER; n_state=Cmnd_STK_UNIVERSAL; n=4; j=0;}
//Wenn mal was schief l鋟ft k鰊nen wir uns evtl. noch retten
if(t==Sync_CRC_EOP) {state = READY;}
}
//////////////////////////////////////
//Cmnd_STK_GET_SYNC
//////////////////////////////////////
else if(state==Cmnd_STK_GET_SYNC)
{
state = READY;
usb_putc(Resp_STK_INSYNC);
usb_putc(Resp_STK_OK);
}
//////////////////////////////////////
//Cmnd_STK_GET_PARAMETER
//////////////////////////////////////
else if(state==Cmnd_STK_GET_PARAMETER)
{
state = READY;
usb_putc(Resp_STK_INSYNC);
if(dat_buf[0]==Parm_STK_HW_VER) k=4;
else if(dat_buf[0]==Parm_STK_SW_MAJOR) k=1;
else if(dat_buf[0]==Parm_STK_SW_MINOR) k=28;
else k=0xAA;
usb_putc(k);
usb_putc(Resp_STK_OK);
}
//////////////////////////////////////
//Cmnd_STK_LOAD_ADDRESS
//////////////////////////////////////
else if(state==Cmnd_STK_LOAD_ADDRESS)
{
address=(dat_buf[0]+dat_buf[1]*256)*2;
state = READY;
usb_putc(Resp_STK_INSYNC);
usb_putc(Resp_STK_OK);
}
//////////////////////////////////////
//Cmnd_STK_PROG_PAGE
//////////////////////////////////////
else if(state==Cmnd_STK_PROG_PAGE)
{
LED_RT_TOG;
//Anzahl der Bytes im Puffer
n_tmp=dat_buf[0]*256+dat_buf[1];
//Pointer auf n鋍hste Daten
p=&dat_buf[3];
//Anzahl der Seiten im Datenpaket
k=(n_tmp/SPM_PAGESIZE); if(k<1) k=1;
//Alle Seiten im Datenpaket durchgehen
for(j=0;j<k;j++)
{
//Page l鰏chen
boot_page_erase((unsigned long)address);
while(boot_spm_busy());
//Page in AVR laden
for(i=0;i<SPM_PAGESIZE;i+= 2)
{
boot_page_fill(i,*p|(*(p+1)<<8));
p+=2;
}
//Page schreiben
boot_page_write((unsigned long)address);
while(boot_spm_busy());
address+=SPM_PAGESIZE;
}
boot_rww_enable();
for(i=0;i<300;i++) dat_buf[i]=0xFF;
state = READY;
usb_putc(Resp_STK_INSYNC);
usb_putc(Resp_STK_OK);
}
//////////////////////////////////////
//Cmnd_STK_READ_PAGE
//////////////////////////////////////
else if(state==Cmnd_STK_READ_PAGE)
{
LED_RT_OFF;
LED_GN_TOG;
n_tmp=dat_buf[0]*256+dat_buf[1];
for(i=0;i<n_tmp;i++)
{
dat_buf[i]=pgm_read_byte(address);
address++;
}
usb_putc(Resp_STK_INSYNC);
for(i=0;i<n_tmp;i++) usb_putc(dat_buf[i]);
usb_putc(Resp_STK_OK);
for(i=0;i<300;i++) dat_buf[i]=0xFF;
state = READY;
}
//////////////////////////////////////
//Cmnd_STK_UNIVERSAL
//////////////////////////////////////
else if(state==Cmnd_STK_UNIVERSAL)
{
state = READY;
usb_putc(Resp_STK_INSYNC);
usb_putc(0xAA);
usb_putc(Resp_STK_OK);
}
/////////////////////////////////////
//Cmnd_STK_ENTER_PROGMODE
//////////////////////////////////////
else if(state==Cmnd_STK_ENTER_PROGMODE)
{
LED_RT_OFF;
LED_GN_OFF;
state = READY;
usb_putc(Resp_STK_INSYNC);
usb_putc(Resp_STK_OK);
}
//////////////////////////////////////
//Cmnd_STK_LEAVE_PROGMODE
//////////////////////////////////////
else if(state==Cmnd_STK_LEAVE_PROGMODE)
{
usb_putc(Resp_STK_INSYNC);
usb_putc(Resp_STK_OK);
LED_RT_OFF;
LED_GN_OFF;
asm volatile("rjmp app_start");
}
//////////////////////////////////////
// Empfang von einem Byte-Block
// Eingabeparameter:
//
// Ist n positiv werden n Bytes gelesen und in dat_buf geschrieben. j mu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -