📄 avrisp.c
字号:
//ICC-AVR application builder : 2005-4-30 12:31:40
//Target : M16
//Crystal: 7.3728Mhz
#include "Include.H"
//static uint16 u16Addr;
void port_init(void)
{
DDRA = MASK(LEDBUSY) | MASK(LEDRDY) | MASK(LEDFAIL);
PORTA = 0x18;
DDRB = 0x00;
PORTB = MASK(MISO);
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
#ifdef HARDSPI
spi_init();
#endif
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
//all peripherals are now initialised
}
//释放所有外设
#ifndef REMOVE_AVRPROG_SUPPORT
void release_devices(void)
{
uart0_release();
PORTA = 0x00;
DDRB = 0x00;
PORTB = 0x00;
SPCR = 0x00;
}
#endif
void main(void)
{
uint16 u16BlockSize;
uint08 val;
union address_t unAddr;
uint08 device;
uint08 dev_flags = 0;
uint08 twd_flash;
uint08 twd_eprom;
sint08 i;
uint08 cmd1, cmd2, cmd3;
init_devices();
PORTA = MASK(LEDBUSY);
Delay1mS(500);
PORTA = MASK(LEDRDY);
Delay1mS(500);
PORTA = MASK(LEDFAIL);
Delay1mS(500);
PORTA = MASK(LEDRDY);
while (1)
{
while ((val = getchar()) == 0x1b);
//Return supported device codes.
if (val == 't')
{
SendDevCode();
}
//Set device type.
else if (val == 'T')
{
device = getchar();
dev_flags = GetDeviceFlag(device);
twd_flash = stDevTwd[(dev_flags & 0x07) - 1].TwdFlash;
twd_eprom = stDevTwd[(dev_flags & 0x07) - 1].TwdEprom;
putchar('\r');
}
//Check autoincrement address support.
else if (val == 'a')
{
putchar('Y'); //Yes, we do autoincrement.
}
//Get programmer type.
else if (val == 'p')
{
putchar('S'); //Answer 'SERIAL'.
}
//Return programmer identifier.
else if (val == 'S')
{
//Return 'AVR ISP'.Software identifier is always 7 characters.
putstr("AVR ISP");
}
//Return software version.
else if (val == 'V')
{
putchar(SW_MAJOR);
putchar(SW_MINOR);
}
//Return hardware version.
// else if (val == 'v')
// {
// putchar(HW_MAJOR);
// putchar(HW_MINOR);
// }
//Set LED
else if (val == 'x')
{
SetLed(getchar());
putchar('\r');
}
//Clear LED
else if (val == 'y')
{
ClrLed(getchar());
putchar('\r');
}
#ifndef REMOVE_BLOCK_SUPPORT
//Check block load support.
else if (val == 'b')
{
putchar('Y'); //Report block load supported.
putchar(BLOCKSIZE >> 8); //MSB first.
putchar(BLOCKSIZE); //Report BLOCKSIZE (bytes).
}
#endif
else if (dev_flags != 0)
{
#ifndef REMOVE_BLOCK_SUPPORT
//Start block write.
if (val == 'B')
{
uint08 u08Buf[BLOCKSIZE];
uint16 u16PageSize;
sint16 s16Counter;
u16PageSize = dev_flags & 0xf0;
PORTA ^= MASK(LEDBUSY); //黄色发光二极管闪
u16BlockSize = getchar(); //Get block size high byte.
u16BlockSize <<= 8;
u16BlockSize |= getchar(); //Get block size low byte.
val = getchar(); //Get memtype.
for (s16Counter = 0; s16Counter < u16BlockSize; )
{
u08Buf[s16Counter++] = getchar();
}
if (u16BlockSize <= BLOCKSIZE)
{
if (val == 'F')
{
for (s16Counter = 0; s16Counter < u16BlockSize; )
{
//支持页写的器件为加载程序存储器页低字节,不支持的为写FLASH低字节
SPIWrite(0x40);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(u08Buf[s16Counter++]);
if (u16PageSize == 0)
{
Delay1mS(twd_flash); //不支持页写
}
//支持页写的器件为加载程序存储器页高字节,不支持的为写FLASH高字节
SPIWrite(0x48);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(u08Buf[s16Counter++]);
if (u16PageSize == 0)
{
Delay1mS(twd_flash); //不支持页写
}
unAddr.word++;
//如果器件支持页写并且一页填充完或者块数据用完(通常发生在最后一块)则进行页写入
if ((u16PageSize != 0) && (((unAddr.word % u16PageSize) == 0) || (s16Counter == u16BlockSize)))
{
unAddr.word--; //切换到刚填充的那一页
SPIWrite(0x4c);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(0x00);
Delay1mS(twd_flash);
unAddr.word++; //切换到下一页起始地址
}
}
putchar('\r');
}
else if (val == 'E')
{
for (s16Counter = 0; s16Counter < u16BlockSize; )
{
SPIWrite(0xc0);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(u08Buf[s16Counter++]);
Delay1mS(twd_eprom);
unAddr.word++;
}
putchar('\r');
}
else
{
putchar('?');
}
}
else
{
putchar('?');
}
}
//Start block read.
else if (val == 'g')
{
PORTA ^= MASK(LEDBUSY); //黄色发光二极管闪
u16BlockSize = getchar(); //Get block size high byte.
u16BlockSize <<= 8;
u16BlockSize |= getchar(); //Get block size low byte.
val = getchar(); //Get memtype
if (val == 'F')
{
for (; u16BlockSize != 0; u16BlockSize -= 2)
{
SPIWrite(0x20);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
SPIWrite(0x28);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
unAddr.word++;
}
}
else
{
for (; u16BlockSize != 0; u16BlockSize--)
{
SPIWrite(0xA0);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
unAddr.word++;
}
}
}
#endif
#ifndef REMOVE_FLASH_BYTE_SUPPORT
//Write program memory, low byte.
//NOTE: Always use this command before sending high byte.
#ifndef REMOVE_BLOCK_SUPPORT
else
#endif
if (val == 'c')
{
val = getchar();
SPIWrite(0x40);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(val);
if (dev_flags < PAGE0X10)
{
Delay1mS(twd_flash);
}
putchar('\r');
}
//Write program memory, high byte.
else if (val == 'C')
{
val = getchar();
SPIWrite(0x48);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(val);
unAddr.word++;
if (dev_flags < PAGE0X10)
{
Delay1mS(twd_flash);
}
putchar('\r');
}
//Issue Page Write.
else if (val == 'm')
{
SPIWrite(0x4C);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(0x00);
Delay1mS(twd_flash);
putchar('\r');
}
//Read program memory.
else if (val == 'R')
{
//Send high byte, then low byte of flash word.
SPIWrite(0x28);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
SPIWrite(0x20);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
unAddr.word++;
}
#endif
#if 0
//'l'、'r'、'f'、'F'、'N'、'Q'命令已经被通用命令取代
//Write lockbits.
else if (val == 'l')
{
val = getchar();
SPIWrite(0xAC);
if (device == TN26)
{
SPIWrite(0xE0);
SPIWrite(0x00);
SPIWrite(0xFC | val);
}
else
{
SPIWrite(0xE0 | (val & 0x06));
SPIWrite(0x00);
//SPIWrite(val);
SPIWrite(0x00); //??
}
Delay1mS(10);
putchar('\r');
}
//Read lock bits.
else if (val == 'r')
{
SPIWrite(0x58);
SPIWrite(0x00);
SPIWrite(0x00);
putchar(SPIWrite(0x00));
putchar('\r');
}
//Write fuse bits
else if (val == 'f')
{
val = getchar();
SPIWrite(0xAC);
SPIWrite(0xA0 | (val & 0x1F));
SPIWrite(0x00);
SPIWrite(0x00);
Delay1mS(120);
putchar('\r');
}
//Read low fuse bits.
else if (val == 'F')
{
SPIWrite(0x50);
SPIWrite(0x00);
SPIWrite(0x00);
putchar(SPIWrite(0x00));
}
//Read high fuse bits.
else if (val == 'N')
{
SPIWrite(0x58);
SPIWrite(0x08);
SPIWrite(0x00);
putchar(SPIWrite(0x00));
}
//Read extended fuse bits.
else if (val == 'Q')
{
SPIWrite(0x50);
SPIWrite(0x08);
SPIWrite(0x00);
putchar(SPIWrite(0x00));
}
#endif
#ifndef REMOVE_EEPROM_BYTE_SUPPORT
//Write EEPROM memory.
else if (val == 'D')
{
val = getchar();
SPIWrite(0xC0);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
SPIWrite(val);
Delay1mS(twd_eprom);
unAddr.word++;
putchar('\r');
}
//Read EEPROM memory.
else if (val == 'd')
{
SPIWrite(0xA0);
SPIWrite(unAddr.byte[1]);
SPIWrite(unAddr.byte[0]);
putchar(SPIWrite(0x00));
unAddr.word++;
}
#endif
//Universial command
else if (val == ':')
{
cmd1 = getchar();
cmd2 = getchar();
cmd3 = getchar();
SPIWrite(cmd1);
SPIWrite(cmd2);
SPIWrite(cmd3);
putchar(SPIWrite(0x00));
Delay1mS(50);
putchar('\r');
}
//New universal command
else if (val == '.')
{
cmd1 = getchar();
cmd2 = getchar();
cmd3 = getchar();
val = getchar();
SPIWrite(cmd1);
SPIWrite(cmd2);
SPIWrite(cmd3);
putchar(SPIWrite(val));
Delay1mS(50);
putchar('\r');
}
//Enter programming mode.
else if (val == 'P')
{
EnterProgramMode(device);
putchar('\r');
}
//Leave programming mode.
else if (val == 'L')
{
DDRB = MASK(SSn);
SETB(PORTB, RST);
putchar('\r');
}
//Return signature bytes.
else if (val == 's')
{
for (i = 2; i >= 0; i--)
{
SPIWrite(0x30);
SPIWrite(0x00);
SPIWrite(i);
putchar(SPIWrite(0x00));
}
}
//Chip erase.
else if (val == 'e')
{
SPIWrite(0xAC);
SPIWrite(0x80);
SPIWrite(0x04);
SPIWrite(0x00);
Delay1mS(40);
putchar('\r');
}
//Set address.
//NOTE: Flash addresses are given in words, not bytes.
else if (val == 'A')
{
unAddr.byte[1] = getchar(); //Read address high byte.
unAddr.byte[0] = getchar(); //Read address low byte.
putchar('\r');
}
#ifndef REMOVE_AVRPROG_SUPPORT
//Exit bootloader.
else if (val == 'E')
{
UCSRA |= MASK(TXC);
putchar('\r');
while (!TSTB(UCSRA, TXC)); //等待发送完成
release_devices();
asm("JMP 0x0000");
}
#endif
//The last command to accept is ESC (synchronization).
else
{
putchar('?');
}
}
else
{
putchar('?');
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -