?? isp.c
字號(hào):
/* isp.c - part of USBasp Autor..........: Thomas Fischl <tfischl@gmx.de> Description....: Provides functions for communication/programming over ISP interface Licence........: GNU GPL v2 (see Readme.txt) Creation Date..: 2005-02-23 Last change....: 2007-07-23*//*-------------------------------------- Modify.........: avenbbs(8785116@qq.com) Date...........: 2008-9-28~2008-10-5----------------------------------------*/#include <avr/io.h>#include "isp.h"//#include "clock.h"#include <util/delay.h>#include <avr/eeprom.h>#include "usart.h"
#include "AT45.h"
#define ISP_OUT PORTB#define ISP_IN PINB#define ISP_DDR DDRB#define ISP_RST PB2#define ISP_MOSI PB3#define ISP_MISO PB4#define ISP_SCK PB5#define ISP_DELAY 1#define ISP_SCK_SLOW 0#define ISP_SCK_FAST 1
#define spiHWdisable() SPCR = 0extern unsigned char hex2ascii(unsigned char data);
extern volatile unsigned char error_flag;extern unsigned char buf[];#define avr_bin bufvoid spiHWenable(){ /* enable SPI, master, 375kHz SCK */ SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1); SPSR = (1 << SPI2X);}void ispSetSCKOption(uchar option){ if (option == 0) { /* use software spi */ //ispTransmit = ispTransmit_sw; // spiHWdisable(); } else { // use hardware spi ispTransmit = ispTransmit_hw; }}/*void ispDelay(){ uint8_t starttime = TIMERVALUE; while ((uint8_t)(TIMERVALUE - starttime) < 16) { } //_delay_us(64);}*/void ispConnect(){ /* all ISP pins are inputs before */ /* now set output pins */ ISP_DDR |= (1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI); /* reset device */ ISP_OUT &= ~(1 << ISP_RST); /* RST low */ ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */ /* positive reset pulse > 2 SCK (target) */ //ispDelay(); _delay_us(64); ISP_OUT |= (1 << ISP_RST); /* RST high */ //ispDelay(); _delay_us(64); ISP_OUT &= ~(1 << ISP_RST); /* RST low */ if (ispTransmit == ispTransmit_hw) { spiHWenable(); }}void ispDisconnect(){ /* set all ISP pins inputs */ ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); /* switch pullups off */ ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); /* disable hardware SPI */ spiHWdisable();}/*uchar ispTransmit_sw(uchar send_byte){ uchar rec_byte = 0; uchar i; for (i = 0; i < 8; i++) { // set MSB to MOSI-pin if ((send_byte & 0x80) != 0) { ISP_OUT |= (1 << ISP_MOSI); // MOSI high } else { ISP_OUT &= ~(1 << ISP_MOSI); // MOSI low } // shift to next bit send_byte = send_byte << 1; // receive data rec_byte = rec_byte << 1; if ((ISP_IN & (1 << ISP_MISO)) != 0) { rec_byte++; } // pulse SCK ISP_OUT |= (1 << ISP_SCK); // SCK high ispDelay(); ISP_OUT &= ~(1 << ISP_SCK); // SCK low ispDelay(); } return rec_byte;}*/uchar ispTransmit_hw(uchar send_byte){ SPDR = send_byte; //hex2send(send_byte); while (!(SPSR & (1 << SPIF))); return SPDR;}uchar ispEnterProgrammingMode(){ uchar check; uchar count = 32; while (count--) { ispTransmit(0xAC); ispTransmit(0x53); check = ispTransmit(0); ispTransmit(0); if (check == 0x53) { return 0; } spiHWdisable(); /* pulse SCK */ ISP_OUT |= (1 << ISP_SCK); /* SCK high */ //ispDelay(); _delay_us(64); ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */ //ispDelay(); _delay_us(64); if (ispTransmit == ispTransmit_hw) { spiHWenable(); } } return 1; /* error: device dosn't answer */}uchar ispReadFlash(uint32_t address){ //unsigned char tmp=0x55; //ispConnect(); //ispEnterProgrammingMode(); ispTransmit(0x20|((address & 1) << 3)); ispTransmit(address >> 9); ispTransmit(address >> 1); return(ispTransmit(0)); //ispDisconnect(); //return tmp;}/*uchar ispWriteFlash(unsigned long address, uchar data, uchar pollmode){// 0xFF is value after chip erase, so skip programming// if (data == 0xFF) {// return 0;// }// ispTransmit(0x40 | ((address & 1) << 3)); ispTransmit(address >> 9); ispTransmit(address >> 1); ispTransmit(data); if (pollmode == 0) return 0; if (data == 0x7F) { clockWait(15); // wait 4,8 ms return 0; } else { // polling flash uchar retries = 30; uint8_t starttime = TIMERVALUE; while (retries != 0) { if (ispReadFlash(address) != 0x7F) { return 0; }; if ((uint8_t)(TIMERVALUE - starttime) > CLOCK_T_320us) { starttime = TIMERVALUE; retries --; } } return 1; // error }}*//*uchar ispFlushPage(unsigned long address, uchar pollvalue){ ispTransmit(0x4C); ispTransmit(address >> 9); ispTransmit(address >> 1); ispTransmit(0); if (pollvalue == 0xFF) { clockWait(15); return 0; } else { // polling flash uchar retries = 30; uint8_t starttime = TIMERVALUE; while (retries != 0) { if (ispReadFlash(address) != 0xFF) { return 0; }; if ((uint8_t)(TIMERVALUE - starttime) > CLOCK_T_320us) { starttime = TIMERVALUE; retries --; } } return 1; // error }}*/uchar ispReadEEPROM(unsigned int address){ ispTransmit(0xA0); ispTransmit(address >> 8); ispTransmit(address); return ispTransmit(0);}uchar ispWriteEEPROM(unsigned int address, uchar data){ ispTransmit(0xC0); ispTransmit(address >> 8); ispTransmit(address); ispTransmit(data); _delay_ms(10); //clockWait(30); // wait 9,6 ms return 0; /* if (data == 0xFF) { clockWait(30); // wait 9,6 ms return 0; } else { // polling eeprom uchar retries = 30; // about 9,6 ms uint8_t starttime = TIMERVALUE; while (retries != 0) { if (ispReadEEPROM(address) != 0xFF) { return 0; }; if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) { starttime = TIMERVALUE; retries --; } } return 1; // error } */ }void isp_init(void){ //clockInit(); /* init timer */ ispSetSCKOption(ISP_SCK_FAST);}//---------------------------------------------------unsigned char fuse[3]={0};char fuse_ascii[9]={0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0};unsigned char read_fuse(void){ ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispTransmit_hw(0b01010000); ispTransmit_hw(0b00000000); ispTransmit_hw(0b00000000); fuse[0]=ispTransmit_hw(0b00000000); ispTransmit_hw(0b01011000); ispTransmit_hw(0b00001000); ispTransmit_hw(0b00000000); fuse[1]=ispTransmit_hw(0b00000000); ispTransmit_hw(0b01010000); ispTransmit_hw(0b00001000); ispTransmit_hw(0b00000000); fuse[2]=ispTransmit_hw(0b00000000); ispDisconnect(); fuse_ascii[0]=hex2ascii(fuse[0]>>4); fuse_ascii[1]=hex2ascii(fuse[0]&0x0f); fuse_ascii[3]=hex2ascii(fuse[1]>>4); fuse_ascii[4]=hex2ascii(fuse[1]&0x0f); fuse_ascii[6]=hex2ascii(fuse[2]>>4); fuse_ascii[7]=hex2ascii(fuse[2]&0x0f); return 0;}unsigned char erase_chip(void){ ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispTransmit_hw(0b10101100); ispTransmit_hw(0b10000000); ispTransmit_hw(0b00000000); ispTransmit_hw(0b00000000); _delay_ms(10); ispDisconnect(); return 0;}//讀取芯片IDunsigned char chip_id[3];char chip_id_ascii[9]={0x30,0x30,0x20,0x30,0x30,0x20,0x30,0x30,0};unsigned char read_id(void){ ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } //unsigned char tmp; //uart0_Printf("AVR ID:"); ispTransmit_hw(0x30); ispTransmit_hw(0x00); ispTransmit_hw(0x00); chip_id[0]=ispTransmit_hw(0x00); //uart0_Printf("%02X ",d); ispTransmit_hw(0x30); ispTransmit_hw(0x00); ispTransmit_hw(0x01); chip_id[1]=ispTransmit_hw(0x00); //uart0_Printf("%02X ",d); ispTransmit_hw(0x30); ispTransmit_hw(0x00); ispTransmit_hw(0x02); chip_id[2]=ispTransmit_hw(0x00); //uart0_Printf("%02X ",d); ispDisconnect(); chip_id_ascii[0]=hex2ascii(chip_id[0]>>4); chip_id_ascii[1]=hex2ascii(chip_id[0]&0x0f); chip_id_ascii[3]=hex2ascii(chip_id[1]>>4); chip_id_ascii[4]=hex2ascii(chip_id[1]&0x0f); chip_id_ascii[6]=hex2ascii(chip_id[2]>>4); chip_id_ascii[7]=hex2ascii(chip_id[2]&0x0f); return 0;}//寫頁緩沖數(shù)據(jù)void write_page_cache(unsigned char *pt,unsigned char chiptype){ unsigned char i; unsigned int one_page_size=1; for (unsigned char j=0;j<chiptype;j++) one_page_size*=2; for (i=0;i<0x20*one_page_size;i++) { ispTransmit_hw(0x40); ispTransmit_hw(0x00); ispTransmit_hw(i); ispTransmit_hw(*pt++); ispTransmit_hw(0x48); ispTransmit_hw(0x00); ispTransmit_hw(i); ispTransmit_hw(*pt++); }}//將頁緩沖數(shù)據(jù)寫入Flashvoid write_page_flash(uint32_t address){ address>>=1; //hex2send(address>>16); //hex2send(address>>8); //hex2send(address); ispTransmit_hw(0x4C); ispTransmit_hw(address/256); ispTransmit_hw(address&0xFF); ispTransmit_hw(0xFF); _delay_ms(5);}//逐頁編程void pro_page_1by1(unsigned char chiptype,uint32_t buf_cnt){ unsigned char *pt=avr_bin; //unsigned char *pt=buf; //unsigned int one_page_size=1; //while (pt<avr_bin+sizeof(avr_bin)) //for(unsigned char j=0;j<chiptype+6;j++) one_page_size*=2; unsigned int i; for (i=0;i<DF_BUFFER_SIZE;) //while (pt<buf+256) { write_page_cache(&pt[i],chiptype); //write_page_flash(((uint32_t)pt)-((uint32_t)avr_bin)+buf_cnt*256); write_page_flash(i+buf_cnt*DF_BUFFER_SIZE); //usart_tsmt((((unsigned long)pt)-((unsigned long)avr_bin)+buf_cnt*256)>>8); //write_page_flash(((unsigned long)pt)-((unsigned long)buf)); //hex2send(((uint16_t)pt)>>8); switch (chiptype) { case 0: //pt+=64; i+=64; break; case 1: //pt+=128; i+=128; case 2: //pt+=256; i+=256; break; } } //校驗(yàn) for (i=0;i<DF_BUFFER_SIZE;i++) { //unsigned char tmp; if (pt[i]!=ispReadFlash(i+buf_cnt*DF_BUFFER_SIZE)) { error_flag=1; return; } //else usart_tsmt(tmp); }}//寫熔絲unsigned char write_fuse(unsigned char low,unsigned char high,unsigned char ext){ ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispTransmit_hw(0xAC); ispTransmit_hw(0xA0); ispTransmit_hw(0xFF); ispTransmit_hw(low); _delay_ms(5); ispTransmit_hw(0xAC); ispTransmit_hw(0xA8); ispTransmit_hw(0xFF); ispTransmit_hw(high); _delay_ms(5); ispTransmit_hw(0xAC); ispTransmit_hw(0xA4); ispTransmit_hw(0xFF); ispTransmit_hw(ext); _delay_ms(5); ispDisconnect(); return 0;}//寫加密位unsigned char write_lockbit(unsigned char data){ data|=0xC0; ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispTransmit_hw(0xAC); ispTransmit_hw(0xFF); ispTransmit_hw(0xFF); ispTransmit_hw(data); _delay_ms(5); ispDisconnect(); return 0;}//讀加密位unsigned char read_lockbit(void){ unsigned char data=1; ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispTransmit_hw(0b01011000); ispTransmit_hw(0); ispTransmit_hw(0); data=ispTransmit_hw(0); ispDisconnect(); return(data);}//復(fù)位avrunsigned char reset_avr(void){ ispConnect(); if (ispEnterProgrammingMode()) { ispDisconnect(); return 1; } ispDisconnect(); return 0;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -