📄 otp.c.bak
字号:
#include "define.h"
#include "otp.h"
#include "mainloop.h"
#include "isr.h"
bdata k_flag=0x0;
bdata s_flag=0x0;
sbit _50ms = s_flag^0;
//k_flag(_kdown, _lkey1, _lkey0, _key1, _key0), lkey_num, key_buf
uchar key_buf=0;
uchar lkey_num=0;
sbit _kdown=k_flag^7;
sbit _lkey1=k_flag^6;
sbit _lkey0=k_flag^5;
sbit _key1=k_flag^4;
sbit _key0=k_flag^3;
unsigned char otp_type=0x00;
unsigned char code mcu_size[]={0x04,0x04,0x04,0x08,0x02}; //get muc_size from type
unsigned int code blank_config[]={0x2fff, 0x3fff, 0x3fff, 0x3fff, 0x27ff};
void timer0_50ms(void) interrupt 1 using 1
{
TH0=(65536-50000)/256; /*每隔50MS扫描一次*/
TL0=(65536-50000)%256;
_50ms=1;
}
void init_sub(void)
{
P0=0XFF; P1=0XFF;
P2=0XFF; P3=0XFF;
LED=0; //LED ON
CE_FLS=1; //SELECT USB
CE_DET=1;
VPP_CTRL=1;
VCC_CTRL=1;
NRST=1;
SCLK=1;
SDAT=1;
BZ_IO=1;
INH=1;
CE_FLS=0; //SELECT FLASH
// 如果FLASH内没有CONFIG值,或者没有A标志,就默认型号为0X00
//0X8000-0X8001:CONFIG, 0X8002:A5, 0X8003:otp_type
if( (XWORD[0X4000]>0X3FFF)||(XBYTE[0X8002]!=0XA5) )
otp_type=0x00;
else
otp_type=XBYTE[0X8003];
}
void DelayNms(uchar count) //Nms
{
uchar i,j;
for(i=0; i<count; i++)
{
for(j=0; j<250; j++)
{
nop; nop; nop; nop;
}
}
}
void DelayXus(void) //5.4us
{
/* nop;
nop;
nop;
nop;
nop; */
}
/*******************************************************/
void I2cReset(void)
{
VCC_CTRL=1;
VPP_CTRL=1;
SDAT=0;
SCLK=1;
DelayXus();
}
void pulse_read(void) //???
{
VCC_CTRL=0; //可以改善挑片的毛病
DelayNms(1);
VCC_CTRL=1;
DelayNms(10); //???
}
void start(void)
{
VCC_CTRL=0; //vcc high
NRST=0; //pe40 and pa80 reset
DelayXus();
NRST=1;
SDAT=1;
DelayXus();
SCLK=0;
DelayXus();
SDAT=0;
DelayXus();
SCLK=1;
}
void send_1bit(bit si)
{
SCLK=1;
SDAT=si; //SDAT在时钟间断中不跳零
DelayXus();
SCLK=0;
DelayXus();
SCLK=1;
}
//10,AAAAA,rw,1,AAAAAAAA,0,if x=0, showing read, else showing write
void main_command(bit rw, uchar command_adrh, uchar command_adrl)
{
uchar count;
send_1bit(1); //show main mode
send_1bit(0);
for(count=0;count<5;count++) /*要传送的数据长度为5位*/
{
if((command_adrh<<count)&0x10)
send_1bit(1);
else
send_1bit(0);
}
if(rw==0) //根据RW选择读写模式
send_1bit(0);
else
send_1bit(1);
send_1bit(1); //high dummy clock
for(count=0; count<8; count++)
{
if((command_adrl<<count)&0x80) /*要传送的数据长度为8位*/
send_1bit(1);
else
send_1bit(0);
}
send_1bit(0); //low dummy clock
}
bit rev_1bit(void) //接收一个位
{
bit i;
SCLK=1; //???
DelayXus();
//set SDAT as input mode
SCLK=0;
SDAT=1;
i=SDAT; //READ???
nop;
if(SDAT)
i=1;
else
i=0;
DelayXus();
SCLK=1;
return i;
}
void whole_write(void)
{
uint adr;
uchar i, iw;
if(!PIN_TEST())
return;
CE_FLS =0;
for(iw=0; iw<mcu_size[otp_type]*16; iw++)
{
adr=128*iw; //start address
for(i=0; i<128; i++)
{
EpBuf[i]=XBYTE[adr];
adr++;
}
otp_write(iw);
P1=P1^0x01;
}
EpBuf[0]=XBYTE[0x8000];
EpBuf[1]=XBYTE[0x8001];
nop; nop;
write_configue();
LED=0;
}
void read_data(uchar *p) //读出两个字节放在p指定的地址
{
uchar temp=0x00;
uchar count;
for(count=0;count<8;count++)
{
temp=temp<<1;
if(rev_1bit()) //???
temp=temp|0x01;
}
*p=temp;
send_1bit(1); //write high dummy clock
temp=0x00;
for(count=0;count<8;count++)
{
temp=temp<<1;
if(rev_1bit())
temp=temp|0x01;
}
p++;
*p=temp;
send_1bit(0); //write low dummy clock
}
void stop(void)
{
SDAT=0;
SCLK=1;
DelayXus();
SCLK=0;
DelayXus();
SDAT=1;
DelayXus();
NRST=1;
DelayXus();
VCC_CTRL=1;
DelayXus();
SDAT=0;
SCLK=1;
}
void write_data(uchar *p_read, uchar wt_num)
{
uchar idata iw;
uchar idata tempw;
VPP_CTRL=0; //send 12.5v to vpp
DelayXus();
DelayXus();
while(wt_num)
{
wt_num--;
tempw=*p_read;
for(iw=0; iw<8; iw++)
{
if(tempw&0x80)
send_1bit(1);
else
send_1bit(0);
tempw=tempw<<1;
}
send_1bit(1); //send high dummy clock
p_read++;
tempw=*p_read;
for(iw=0; iw<8; iw++)
{
if(tempw&0x80)
send_1bit(1);
else
send_1bit(0);
tempw=tempw<<1;
}
send_1bit(0); //send low dummy clock
p_read++;
}
/*******write 0xffff at last unit as end*************/
for(iw=0; iw<18; iw++)
{
if(iw==17)
send_1bit(0);
else
send_1bit(1);
}
VPP_CTRL=1;
DelayXus(); //???
DelayXus();
}
void otp_write(uchar page)
{
I2cReset();
start();
//void main_command(bit rw, uchar command_adrh, uchar command_adrl)
main_command(1, 64*page/256, 64*page%256);
write_data(&EpBuf[0], 64);
stop();
}
void write_configue()
{
I2cReset();
start();
smart_command(1, 0x3f, 0xff);
EpBuf[0]=0x20|EpBuf[0]; //加密位先不写
write_data(&EpBuf[0], 1);
stop();
}
void read_configue()
{
I2cReset();
start();
smart_command(0, 0x3f, 0Xff);
read_data(&EpBuf[0]);
stop();
}
void otp_read_usb(uchar page) //母片读取
{
uchar io;
I2cReset();
start();
main_command(0, 32*page/256, 32*page%256);
for(io=0; io<64; io=io+2)
{
read_data(&EpBuf[io]);
}
stop();
}
void otp_read(uchar page) //母片读取
{
uchar io;
I2cReset();
start();
main_command(0, 64*page/256, 64*page%256);
for(io=0; io<128; io=io+2)
{
read_data(&EpBuf[io]);
}
stop();
}
//1,AAAAAA,rw,1,AAAAAAAA,0,if x=0, showing read, else showing write
void smart_command(bit rw, uchar command_adrh, uchar command_adrl)
{
uchar count;
send_1bit(1); //show main mode
for(count=0;count<6;count++) /*要传送的数据长度为6位*/
{
if((command_adrh<<count)&0x20)
send_1bit(1);
else
send_1bit(0);
}
if(rw==0) //根据RW选择读写模式
send_1bit(0);
else
send_1bit(1);
send_1bit(1); //high dummy clock
for(count=0; count<8; count++)
{
if((command_adrl<<count)&0x80) /*要传送的数据长度为8位*/
send_1bit(1);
else
send_1bit(0);
}
send_1bit(0); //low dummy clock
}
void buzzer_3(void)
{
bit i=EA;
EA=0;
BZ_IO=0;
DelayNms(125);
BZ_IO=1;
DelayNms(125);
BZ_IO=0;
DelayNms(125);
BZ_IO=1;
DelayNms(125);
BZ_IO=0;
DelayNms(125);
BZ_IO=1;
DelayNms(125);
LED=1; //LED_OFF
EA=i;
}
void buzzer_1(void)
{
bit i=EA;
EA=0;
BZ_IO=0;
DelayNms(250);
BZ_IO=1;
LED=0; //LED_ON
EA=i;
}
void buzzer_2(void)
{
bit i=EA;
EA=0;
BZ_IO=0;
DelayNms(125);
BZ_IO=1;
DelayNms(125);
BZ_IO=0;
DelayNms(125);
BZ_IO=1;
LED=1; //LED_OFF
EA=i;
}
void write_page(uint page, uchar *p_buf)
{
uchar i;
uint adr;
CE_FLS =0;
adr=128*page; //start address
XBYTE[0x5555]=0xaa;
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0xa0;
for(i=0; i<128; i++)
{ XBYTE[adr]=*p_buf;
adr++;
p_buf++;
}
DelayNms(15); //???
}
void download_otp(void)
{
uchar ib, temp1, temp2;
uint adr;
if(!PIN_TEST())
{
buzzer_3();
buzzer_3();
return;
}
for(ib=0; ib<mcu_size[otp_type]*16; ib++)
{
otp_read(ib);
P1=P1^0x01;
write_page(ib, &EpBuf[0]);
}
read_configue(); //read config and save them start at 0x8000
CE_FLS = 0;
temp1=XBYTE[0X8002]; //get mcu_type
temp2=XBYTE[0X8003];
adr=0x8000;
XBYTE[0x5555]=0xaa;
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0xa0;
XBYTE[adr++]=EpBuf[0];
XBYTE[adr++]=EpBuf[1];
XBYTE[adr++]=temp1;
XBYTE[adr++]=temp2;
for(ib=0; ib<124; ib++)
{
XBYTE[adr++]=0xff;
}
DelayNms(15);
verify_otp(); //校验
}
unsigned int cal_checksum() //
{
unsigned int i, chksum;
chksum=0x0000;
CE_FLS = 0;
for(i=0; i<mcu_size[otp_type]*1024; i++)
{
chksum=XWORD[i]+chksum;
nop; nop;
}
return chksum;
}
unsigned char blank_check(void)
{
uchar ib, jb;
if(!PIN_TEST())
{
buzzer_3();
buzzer_3();
return 2;
}
pulse_read();
for(ib=0; ib<mcu_size[otp_type]*16; ib++)
{
otp_read(ib);
for(jb=0; jb<128; jb=jb+2)
{
if(EpBuf[jb]!=0x3f||EpBuf[jb+1]!=0xff)
{
buzzer_3();
return 0;
}
}
P1=P1^0x01;
}
pulse_read();
read_configue(); //read config
if(EpBuf[0]!=blank_config[otp_type]/0x100||EpBuf[1]!=blank_config[otp_type]%0x100)
{
buzzer_2();
return 0;
}
buzzer_1();
return 1;
}
void verify_otp(void)
{
uchar iv, jv, temp;
uint adr;
if(!PIN_TEST())
{
buzzer_3();
buzzer_3();
return;
}
pulse_read(); //???改善挑片的毛病
for(iv=0; iv<mcu_size[otp_type]*16; iv++)
{
otp_read(iv);
P1=P1^0x01;
adr=128*iv;
for(jv=0; jv<128; jv++)
{
CE_FLS = 0;
temp=XBYTE[adr++];
if(temp!=EpBuf[jv])
{
buzzer_3();
return;
}
}
}
EpBuf[1]=EpBuf[0]=0xaa;
read_configue(); //read config and save them start at 0x8000
CE_FLS =0;
iv=XBYTE[0x8000];
jv=XBYTE[0X8001];
read_configue(); //read config
nop; nop;
if((iv!=EpBuf[0])|(jv!=EpBuf[1]))
{
buzzer_3();
return;
}
buzzer_1();
}
void scan_popkey(void)
{
uchar temp_key=0x0;
if(_50ms!=1)
return;
_50ms=0;
KEY1=1; KEY0=1;
nop;
if(KEY0==0)
temp_key=temp_key|0x01;
if(KEY1==0)
temp_key=temp_key|0x02;
//==============================
if(temp_key!=0)
{ //handle with key push_down
_kdown=1;
if(temp_key!=key_buf) //如果按键中途改变, 就重新计算新的长按键
{
key_buf=temp_key;
lkey_num=0;
return;
}
else
{
if(lkey_num<250)
lkey_num++;
if(lkey_num==150)
{
if(key_buf==0x01)
_lkey0=1;
if(key_buf==0x02)
_lkey1=1;
return;
}
}
}
else
{
if(_kdown!=1)
{
k_flag=0;
return;
}
if(lkey_num<150)
{
k_flag=0;
if(key_buf==0x01)
_key0=1;
if(key_buf==0x02)
_key1=1;
}
key_buf=0x0;
lkey_num=0x0;
return;
}
}
void write_protect(void)
{
I2cReset();
start();
smart_command(1, 0x3f, 0xff);
EpBuf[0]=0x1f; EpBuf[1]=0xff;
write_data(&EpBuf[0], 1);
stop();
}
void initial_timer0(void)
{
TMOD=0XF0&TMOD|0X01; //定时方式0
TH0=(65536-50000)/256; /*每隔50MS扫描一次*/
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
}
bit PIN_TEST(void)
{
pulse_read();
read_configue();
if( EpBuf[0]>0x3f )
return 0;
else if( (EpBuf[0]|EpBuf[1])==0x00 )
return 0;
else
return 1;
}
/*
bit pin_test_by_type(unsigned char mcu_type)
{
uchar i;
if(mcu_type<2)
{
OE=0; //VC_DOWN=1;
INH=0;
nop;
for(i=0; i<3; i++)
{
nop;
P2=(P2&0xf0)+i+3; //只测试了3个脚
DelayXus();
VDET=1;
nop; nop; nop;
if(VDET==0)
{
OE=1;
return 1; //????
}
}
OE=1;
return 1;
}
else
{
pulse_read();
read_configue(); //10p20(8pin) read config
if( EpBuf[0]>0x3f )
return 0;
else
return 1;
}
} */
void check_buttton()
{
scan_popkey();
EA=0;
if(_lkey1==1)
{
_lkey1=0;
verify_otp();//校验PM10P40
}
if(_key1==1)
{
_key1=0;
whole_write();//把W29EE512的程序写入PM10P40中 //red long key
verify_otp();
}
if(_key0==1)
{
_key0=0;
blank_check();//检查PM10P40是否为空
}
if(_lkey0==1)
{
_lkey0=0;
download_otp();///把PM10P40的程序读到W29EE512中
}
EA=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -