|
|

楼主 |
发表于 2012-10-26 19:36:23
|
显示全部楼层
/**
* Atmega644p parallel promgram by using Aruino 2560
* version 0.1
* Author by Sahlite.hu
* Data by 2012/10/25
*/
/*
* the progammer(Arduino 2560) is called master.
* the slave is the Atmega644p to be programmed.
*/
/*
* data 0~7 I/O pins, read from or write to slave
*/
#define DATA0 47
#define DATA1 45
#define DATA2 43
#define DATA3 41
#define DATA4 39
#define DATA5 37
#define DATA6 35
#define DATA7 33
/*
* positive plus XTAL1 pin issue slave to excute the given command
* work with command(DATA0~7), XA0, XA1
*/
#define XTAL1 23
// RDYBSY is low as slave in working
#define RDYBSY 21
/*
* pull down OE to read from slave
* work witch data pins
*/
#define OE 20
/*
* pull down WR to write to slave
* work with data pins
*/
#define WR 19
/*
* BS2 | BS1 | flash/eeprom address | flash data reading/loading | fuse programing | read fuse and lock bits
* 0 | 0 | low byte | low byte | low byte | fuse low byte
* 0 | 1 | high byte | high byte | high byte | lock bits
* 1 | 0 | externed high byte | reserved | externed byte | externed fuse byte
* 1 | 1 | reseved | reserved | reserved | fuse high byte
*/
#define BS1 18
#define BS2 46
/*
* XA1 | XA0 | action when XTAL1 is plused
* 0 | 0 | load flash and eeprom addres
* 0 | 1 | load data
* 1 | 0 | load command
* 1 | 1 | no action, idle
*/
#define XA0 17
#define XA1 16
// program memory and eeprom data page load
#define PAGEL 15
//reserved for pcb
#define RESET12V
// switch the slave status for master to write or read.
#define SWITCH_WRITE_MODE \
digitalWrite(WR, LOW);\
digitalWrite(OE, HIGH)
#define SWITCH_READ_MODE \
digitalWrite(WR, HIGH);\
digitalWrite(OE, LOW)
// switch data pins status for master to write or read
#define SET_DATA_OUT \
pinMode(DATA0, OUTPUT); \
pinMode(DATA1, OUTPUT); \
pinMode(DATA2, OUTPUT); \
pinMode(DATA3, OUTPUT); \
pinMode(DATA4, OUTPUT); \
pinMode(DATA5, OUTPUT); \
pinMode(DATA6, OUTPUT); \
pinMode(DATA7, OUTPUT)
#define SET_DATA_IN \
pinMode(DATA0, INPUT); \
pinMode(DATA1, INPUT); \
pinMode(DATA2, INPUT); \
pinMode(DATA3, INPUT); \
pinMode(DATA4, INPUT); \
pinMode(DATA5, INPUT); \
pinMode(DATA6, INPUT); \
pinMode(DATA7, INPUT)
// check the slave is busy or not
#define IS_SLV_BUSY (LOW == digitalRead(RDYBSY))
#define IS_SLV_READY (HIGH == digitalRead(RDYBSY))
//send positive pluse to the given pin
#define SEND_POSITIVE_PLUSE(pin) \
digitalWrite(pin, LOW); \
delay(1); \
digitalWrite(pin, HIGH); \
delay(1); \
digitalWrite(pin, LOW)
// send negative pluse to the given pin
#define SEND_NEGATIVE_PLUSE(pin) \
digitalWrite(pin, HIGH); \
delay(1); \
digitalWrite(pin, LOW); \
delay(1); \
digitalWrite(pin, HIGH)
// positive pluse the XTAL1 to excute the current command
#define COMMAND_EXCUTION \
SEND_POSITIVE_PLUSE(XTAL1)
// negative pluse to WR to write data
#define WRITE_DATA \
SEND_NEGATIVE_PLUSE(WR)
// negative pluse to OE to read data
#define READ_DATA \
SEND_NEGATIVE_PLUSE(OE)
/*
* command byte | command excuted
* 1000 0000 | chip erase
* 0100 0000 | write fuse bits
* 0010 0000 | write lock bits
* 0001 0000 | write flash
* 0001 0001 | write eeprom
* 0000 1000 | read signature byte and calibration byte
* 0000 0100 | read fuse and lock bits
* 0000 0010 | read flash
* 0000 0011 | read eeprom
*/
#define CMD_ERASE 0x80
#define CMD_WRITE_FUSE_BITS 0x40
#define CMD_WRITE_LOCK_BITS 0x20
#define CMD_WRITE_FLASH 0x10
#define CMD_WRITE_EEPROM 0x11
#define CMD_READ_SIGN_CALI 0x08
#define CMD_READ_FUSE_LOCK 0x04
#define CMD_READ_FLASH 0x02
#define CMD_READ_EEPROM 0x03
// set XA pins
#define SET_XA(data) \
digitalWrite(XA1, (data>>1)&1); \
digitalWrite(XA0, data&1)
#define SET_XA_00 \
digitalWrite(XA1, 0x00);\
digitalWrite(XA0, 0x00)
#define SET_XA_01 \
digitalWrite(XA1, 0x00);\
digitalWrite(XA0, 0x01)
#define SET_XA_10 \
digitalWrite(XA1, 0x01);\
digitalWrite(XA0, 0x00)
#define SET_XA_11 \
digitalWrite(XA1, 0x01);\
digitalWrite(XA0, 0x01)
#define SET_XA_IDLE SET_XA_11
//set byte select pins
#define SET_BS(data) \
digitalWrite(BS2, (data>>1)&1); \
digitalWrite(BS1, data&1)
#define SET_BS_00 \
digitalWrite(BS2, 0x00); \
digitalWrite(BS1, 0x00)
#define SET_BS_01 \
digitalWrite(BS2, 0x00); \
digitalWrite(BS1, 0x01)
#define SET_BS_10 \
digitalWrite(BS2, 0x01); \
digitalWrite(BS1, 0x00)
#define SET_BS_11 \
digitalWrite(BS2, 0x01); \
digitalWrite(BS1, 0x01)
// command or send data to slave
#define SET_DATA(data) \
digitalWrite(DATA7, (data&0x80)>>7); \
digitalWrite(DATA6, (data&0x40)>>6); \
digitalWrite(DATA5, (data&0x20)>>5); \
digitalWrite(DATA4, (data&0x10)>>4); \
digitalWrite(DATA3, (data&0x08)>>3); \
digitalWrite(DATA2, (data&0x04)>>2); \
digitalWrite(DATA1, (data&0x02)>>1); \
digitalWrite(DATA0, data&1)
#define SET_DATA_CHECK(data, data7, data6, data5, data4, data3, data2, data1, data0) \
data7 = (data&0x80)>>7); \
data6 = (data&0x40)>>6); \
data5 = (data&0x20)>>5); \
data4 = (data&0x10)>>4); \
data3 = (data&0x08)>>3); \
data2 = (data&0x04)>>2); \
data1 = (data&0x02)>>1); \
data0 = data&0x01
// get data from slave
#define GET_DATA(data) \
data = (digitalRead(DATA7)<<7) \
||(digitalRead(DATA6)<<6) \
||(digitalRead(DATA5)<<5) \
||(digitalRead(DATA4)<<4) \
||(digitalRead(DATA3)<<3) \
||(digitalRead(DATA2)<<2) \
||(digitalRead(DATA1)<<1) \
||(digitalRead(DATA0))
#define GET_DATA_CHECK(data, data7, data6, data5, data4, data3, data2, data1, data0) \
data = ((data7<<7)&0x80)|((data6<<6)&0x40)|((data5<<5)&0x20)|((data4<<4)&0x10)|((data3<<3)&0x08)|((data2<<2)&0x04)|((data1<<1)&0x02)|((data0&0x01)
//set page load pin
#define SET_PAGEL(state) digitalWrite(PAGEL, state)
void setup()
{
Serial.begin(19200);
pinMode(XTAL1, OUTPUT);
pinMode(RDYBSY, INPUT);
pinMode(OE, OUTPUT);
pinMode(WR, OUTPUT);
pinMode(BS1, OUTPUT);
pinMode(BS2, OUTPUT);
pinMode(XA0, OUTPUT);
pinMode(XA1, OUTPUT);
pinMode(PAGEL, OUTPUT);
//pinMode(RESET12V, OUTPUT);
digitalWrite(WR, HIGH);
digitalWrite(OE, HIGH);
SET_DATA_OUT;
SET_XA_IDLE;
}
int op_ch;
int num_ch;
int high_wch;
int low_wch;
int data = 0x00;
int data0 = 0x00;
int data1 = 0x01;
int data2 = 0x01;
int data3 = 0x00;
int data4 = 0x01;
int data5 = 0x00;
int data6 = 0x00;
int data7 = 0x01;
void loop()
{
//int op_ch;
//int num_ch;
if(Serial.available())
{
op_ch = Serial.read();
Serial.print(op_ch);
//if (80 == op_ch)
//{
//num_ch = Serial.read();
//Serial.print(op_ch);
//Serial.print(num_ch);
Serial.print("\n");
switch(op_ch)
{
case '0': // enter parallel program mode
enter_parallel_program();
Serial.print("Welcom!\n");
Serial.print("You have enter the parallel world!\n");
Serial.print("Enjoy youself!\n");
break;
case '1': // erase chip
erase_chip();
Serial.print("Chip erased done!\n");
break;
case '2': // write flash
Serial.print("/n");
Serial.print("Sorry!Under construction\n");
break;
case '3': // write eeprom
Serial.print("Sorry!Under construction\n");
break;
case '4': // read flash
Serial.print("Sorry!Under construction\n");
break;
case '5': // read eeprom
Serial.print("Sorry!Under construction\n");
break;
case '6': // write fuse
write_fuse();
Serial.print("Write fuse done\n");
break;
case '7': // read fuse and lock bits
read_fuse();
Serial.print("Read fuse done\n");
Serial.print(high_wch);
Serial.print("\n");
Serial.print(low_wch);
Serial.print("\n");
break;
case '8': // write lock bits
Serial.print("Sorry!Under construction\n");
break;
case '9': // read the signature and calibration
Serial.print("Sorry!Under construction\n");
break;
default:
Serial.print("No such operation number\n");
}
//}
}
}
/*
* first of all, give vcc,avcc 5+ voltage, and gnd and reset to ground.
* after this function, give reset pin 12+ voltage.
* caution: any change on [PAGEL, XA1, XA0, BS1] in 100ns after the 12+ apply to reset, will casuse failing to enter parallel program.
*/
void enter_parallel_program()
{
int i;
// send at least 6 pluse on XTAL1
for(i=0;i<6;i++)
{
//COMMAND_EXCUTION;
digitalWrite(XTAL1, HIGH);
delay(1);
digitalWrite(XTAL1, LOW);
delay(1);
}
// set PAGEL, XA1, XA0, BS1 to 0x00
SET_PAGEL(LOW);
SET_XA(0x00);
SET_BS(0x00);
delay(1);
}
/*
* 'A'
* load command to slave
*/
void load_command(int command)
{
// set XA1,XA0 to 10 to enable command loading
SET_XA_10;
// set BS1 to 0
SET_BS_00;
// set command
SET_DATA(command);
// excute
COMMAND_EXCUTION;
// wait for slave to excute
while(IS_SLV_BUSY);
}
/*
* 'B'
* load low byte of address
*/
void load_address_low_byte(int address)
{
}
/*
* 'C'
* load low byte of data
*/
void load_data_low_byte(int data)
{
// set XA1, XA0 to 01 to enable data loading
SET_XA_01;
// set BS2, BS1 to 00 to select low byte
SET_BS_00;
// set DATA[0:7] to data
SET_DATA(data);
// give positive pluse on XTAL1 to load data
COMMAND_EXCUTION;
}
/*
* 'D'
* load high byte of data
*/
void load_data_hight_byte(int data)
{
// set XA1, XA0 to 01 to enable data loading
SET_XA_01;
// set BS2, BS1 to 01 to select low byte
SET_BS_01;
// set DATA[0:7] to data
SET_DATA(data);
// give positive pluse on XTAL1 to load data
COMMAND_EXCUTION;
}
void erase_chip()
{
load_command(CMD_ERASE);
}
void write_fuse()
{
int data = 0;
// programing fuse low bits
// load command
load_command(CMD_WRITE_FUSE_BITS);
// load data low byte
data = 0xff;
load_data_low_byte(data);
// send pluse to write
WRITE_DATA;
// wait for slave to write data
while(IS_SLV_BUSY);
// programing fuse high bits
// load command
load_command(CMD_WRITE_FUSE_BITS);
// load data low byte
data = 0xff;
load_data_low_byte(data);
// set BS2, BS1 to 01, select high bits
SET_BS_01;
// send pluse to write
WRITE_DATA;
// wait for slave to write data
while(IS_SLV_BUSY);
// set BS2, BS1 to 00
SET_BS_00;
// programing fuse externed bits
// load command
load_command(CMD_WRITE_FUSE_BITS);
// load data low byte
data = 0xff;
load_data_low_byte(data);
// set BS2, BS1 to 10, select externed bits
SET_BS_10;
// send pluse to write
WRITE_DATA;
// wait for slave to write data
while(IS_SLV_BUSY);
// set BS2, BS1 to 00
SET_BS_00;
}
void read_fuse()
{
int data = 0;
// load command
load_command(CMD_READ_FUSE_LOCK);
// reading fuse low byte
// set OE to 0
digitalWrite(OE, LOW);
// set BS2, BS1 to 00 to read low byte fuse
SET_BS_00;
// get data
GET_DATA(data);
Serial.print(data);
low_wch |= (data&0x00ff);
// reading fuse high byte
// set OE to 0
digitalWrite(OE, LOW);
// set BS2, BS1 to 11 to read high byte fuse
SET_BS_11;
// get data
GET_DATA(data);
Serial.print(data);
low_wch |= (data&0x00ff)<<8;
// reading externed fuse byte
// set OE to 0
digitalWrite(OE, LOW);
// set BS2, BS1 to 10 to read externed byte fuse
SET_BS_10;
// get data
GET_DATA(data);
Serial.print(data);
high_wch |= (data&0x00ff);
// reading lock bits
// set OE to 0
digitalWrite(OE, LOW);
// set BS2, BS1 to 01 to read lock bits
SET_BS_01;
// get data
GET_DATA(data);
Serial.print(data);
high_wch |= (data&0x00ff)<<8;
digitalWrite(OE, HIGH);
}
|
|