📄 w29c040.asm
字号:
//========================================================================================
// Progarm: W29C040.asm
// By: xiangyan zhang
// Last modified date:
// 2002/12/28: first version
//
// PB0-PB15 ==> Addr0-Addr15 PA5-PA7 ==> Addr16-Addr18
// PA2-PA4 ==> CE+OE+WE
// PA8-PA15 ==> DB0-DB7
// PA0-PA1 no use
//========================================================================================
.INCLUDE hardware.inc;
.DEFINE RE_BIT_DIS 0x08
.DEFINE WE_BIT_DIS 0x10
.DEFINE CE_BIT_DIS 0x04
// For Cyberon
.DEFINE Port_IOA_Attrib P_IOA_Attrib
.DEFINE Port_IOA_Dir P_IOA_Dir
.DEFINE Port_IOA_Data P_IOA_Data
.DEFINE Port_IOA_Buffer P_IOA_Buffer
.DEFINE Port_IOB_Attrib P_IOB_Attrib
.DEFINE Port_IOB_Dir P_IOB_Dir
.DEFINE Port_IOB_Data P_IOB_Data
.DEFINE Port_IOB_Buffer P_IOB_Buffer
.DEFINE Port_TimeBaseSetup P_TimeBase_Setup //time base configuration
.DEFINE Port_Watchdog_Clear P_Watchdog_Clear //clear watchdog ??
.DEFINE Port_SystemClock P_SystemClock //system clock generator setup
.define P_INT_Ctrl_New 0x702d
//////////////////////////////////////////////
//W29C040 command
/////////////////////////////////////////////
.data
Software_Data_Protection_Dis_addr: .dw 0x5555,0x2aaa,0x5555,0x5555,0x2aaa,0x5555
Software_Data_Protection_Dis_data: .dw 0xaa00,0x5500,0x8000,0xaa00,0x5500,0x2000
Software_data_Protection_en_data: .dw 0xaa00,0x5500,0xa000
Software_chip_erase_data: .dw 0xaa00,0x5500,0x8000,0xaa00,0x5500,0x1000
.IRAM
.VAR Read_W29C040_Byte=0//
.VAR _M_AddrL=0;
.VAR _M_AddrH=0;
.VAR _write_data=0;
.TEXT
//----------------------------------------------------------------------
//_SP_InitW29C040Flash
//Argument: None
//return: none
//--------------------------------------------------------------------
.PUBLIC _SP_InitW29C040Flash_Assembly
_SP_InitW29C040Flash_Assembly: .PROC
PUSH R5 TO [SP]
//M_InitIO;
R1=0xFFFF
[Port_IOB_Attrib] = R1 //Set port B to output
[Port_IOB_Dir] = R1 //Set port B to output
R1 = 0x0000
[Port_IOB_Data] = R1
R1=0xFFFF
[Port_IOA_Attrib] = R1 //Set port A to output
[Port_IOA_Dir] = R1
R1 = 0x0000
[Port_IOA_Data] = R1
// M_SP_Software_Data_Protection_Dis; //Protection_Dis
R5 = 0x0000
Prot_Dis_L:
R1 = R5 + Software_Data_Protection_Dis_addr
R3 = R5 + Software_Data_Protection_Dis_data
R1 = [R1] //get address
R3 = [R3] //get data
R2 = 0x0000
//r1:low addr , r2:high addr ,r3:data
call F_SP_Write_W29C040_One_Word
R5 = R5 + 1
CMP R5,6
JNE Prot_Dis_L;
CALL F_Delay11ms //delay 10ms
// CALL F_SP_Software_chip_MassErase //chip_MassErase
R5 = 0x0000
Chip_MassErase_L:
R1 = R5 + Software_Data_Protection_Dis_addr
R3 = R5 + Software_chip_erase_data
R1 = [R1] //get address
R3 = [R3] //get data
// R4 = [Port_IOA_Buffer]
R2 = 0x0000
call F_SP_Write_W29C040_One_Word;
R5 = R5 + 1
CMP R5,6
JNE Chip_MassErase_L
CALL F_Delay11ms //delay 10ms
POP R5 FROM [SP]
RETF
.ENDP
//----------------------------------------------------------------------
//--_SP_InitReadW29C040Flash
//--Argument: None
//--------------------------------------------------------------------
.public _SP_InitReadW29C040Flash
F_SP_InitReadW29C040Flash:
_SP_InitReadW29C040Flash: .proc
push bp to [sp]
//M_InitIOA_8bitH_In;
R5 = [P_IOA_Dir]
R5 &= 0x00FF
[P_IOA_Dir] = R5
R5 = [P_IOA_Attrib]
R5 &= 0x00FF
[P_IOA_Attrib] = R5
pop bp from [sp]
retf
.endp
RETF
//----------------------------------------------------------------------
//--_SP_InitWriteW29C040Flash
//--Argument: None
//--------------------------------------------------------------------
.public _SP_InitWriteW29C040Flash
_SP_InitWriteW29C040Flash: .proc
push bp to [sp]
//M_InitIOA_8bitH_Out;
R5 = [Port_IOA_Attrib]
R5 |= 0xFF00
[Port_IOA_Attrib] = R5
R5 = [Port_IOA_Dir]
R5 |= 0xFF00
[Port_IOA_Dir] = R5
//CALL F_SP_page_write_Com;
pop bp from [sp]
retf
.endp
//----------------------------------------------------------------------
//_Write_Addr_Data to W29C040
//-- Argument: None
//--------------------------------------------------------------------
.PUBLIC _SP_Write_W29C040_One_Word
.public F_SP_Write_W29C040_One_Word
F_SP_Write_W29C040_One_Word:
_SP_Write_W29C040_One_Word: .PROC
PUSH R1,R5 TO [SP]
R5 = SP
R1 = [R5 + 8] //get AddrL
R2 = [R5 + 9] //get AddrH
R3 = [R5 + 10] //get Data
r4 = [R5 + 10]
r3 =r3 LSL 4;
r3 =r3 LSL 4;
CALL F_SP_Write_W29C040_One_Byte;
CMP R1,0xFFFF;
JNE Inc_WriteAddr;
r1=0;
r2+=1;
jmp WriteNextByte;
Inc_WriteAddr:
r1+=1;
WriteNextByte:
R3=R4&0xff00;
CALL F_SP_Write_W29C040_One_Byte;
// call F_Delay11ms;
POP R1,R5 FROM [SP]
RETF
.ENDP
//----------------------------------------------------------------------
//SP_Read_Data from W29C040
//Argument:Addr ( unsigned long int)
//writer: abin
//--------------------------------------------------------------------
.PUBLIC _SP_Read_W29C040_One_Word;
F_SP_Read_W29C040_One_Wordr:
_SP_Read_W29C040_One_Word: .PROC
PUSH R2,R5 TO [SP]
R5 = SP
R1 = [R5 + 7] // [AddrL] = R1
R2 = [R5 + 8] // [AddrH] = R2
CALL F_SP_Read_W29C040_One_Byte;
R3 = [Read_W29C040_Byte]; //read Data
CMP R1,0xFFFF;
JNE INC_Addr;
R1=0x0000;
R2+=1;
jmp GetNextByte;
INC_Addr:
R1+=1;
GetNextByte:
CALL F_SP_Read_W29C040_One_Byte;
R1=[Read_W29C040_Byte];
R1=R1 LSL 4;
R1=R1 LSL 4;
R1+=R3;
POP R2,R5 FROM [SP]
RETF
.ENDP
//----------------------------------------------------------------------
//SP_Write_W29C040_One_Byte
//Argument:r1:low addr, r2: high addr ,r3: data
//return:none
//--------------------------------------------------------------------
.PUBLIC _SP_Write_W29C040_One_Byte
.public F_SP_Write_W29C040_One_Byte
F_SP_Write_W29C040_One_Byte:
_SP_Write_W29C040_One_Byte: .PROC
PUSH R1,R5 TO [SP];
//R5 = SP
//R1 = [R5 + 8] // [AddrL] = R1
//R2 = [R5 + 9] // [AddrH] = R2
//R3 = [R5 + 10]// R3=DATA;
[Port_IOB_Data] = R1 //write AddrL
R4 = [Port_IOA_Buffer];
R4 &= 0xFFE3;
R4 |= (RE_BIT_DIS|WE_BIT_DIS|CE_BIT_DIS) //CE=1,WE=1,OE=1
[Port_IOA_Data] = R4
//---------------------------------------------------------------------
//换芯片的时候,需要改变这断代码
//---------------------------------------------------------------------
R4 &= 0xFF1F
R2 = R2 LSL 4
R2 = R2 LSL 1
R4 |= R2
[Port_IOA_Data] = R4 //wirte AddrH
// R4 = [Port_IOA_Buffer];
R4 &= 0xFFE3;
R4 &=0x00ff;
R4 |=R3;
[Port_IOA_Data] = R4
R4 |= RE_BIT_DIS
[Port_IOA_Data] = R4 //CE=0,WE=0,OE=1
r4|=(WE_BIT_DIS|CE_BIT_DIS)
[Port_IOA_Data] = R4 //CE=1,WE=1,OE=1
POP R1,R5 FROM [SP];
RETF
.ENDP
//----------------------------------------------------------------------
//SP_Read_Data from W29C040
//Argument: r1:low addr,r2:high addr
//return:[Read_W29C040_Byte]
//--------------------------------------------------------------------
.PUBLIC _SP_Read_W29C040_One_Byte; //_SP_Read_Data;
F_SP_Read_Data_Addr:
F_SP_Read_W29C040_One_Byte:
_SP_Read_W29C040_One_Byte: .PROC
PUSH R1,R5 TO [SP]
//R5 = SP
//R1 = [R5 + 8] // [AddrL] = R1
//R2 = [R5 + 9] // [AddrH] = R2
[Port_IOB_Data] = R1 //write AddrL
R4 = [Port_IOA_Buffer];
R4 &= 0xFFE3;
R4 |= (RE_BIT_DIS|WE_BIT_DIS|CE_BIT_DIS) //CE=1,WE=1,OE=1
[Port_IOA_Data] = R4
//---------------------------------------------------------------------
//换芯片的时候,需要改变这断代码
//---------------------------------------------------------------------
R4 &= 0xFF1F
R2 = R2 LSL 4
R2 = R2 LSL 1
R4 |= R2
[Port_IOA_Data] = R4 //wirte AddrH
R4 &= 0xFFE3;
R4 |= WE_BIT_DIS
[Port_IOA_Data] = R4 //write control bit LOW
R1 = [Port_IOA_Data] //get data
R1 &= 0xFF00
R1 = R1 LSR 4;
R1 = R1 LSR 4;
[Read_W29C040_Byte] = R1;
R4 |= (RE_BIT_DIS|WE_BIT_DIS|CE_BIT_DIS)//CE=1,WE=1,OE=1
[Port_IOA_Data] = R4
POP R1,R5 FROM [SP]
// R1 = [Read_W29C040_Byte]; //read Data
RETF
.ENDP
///////////////////////////////////////////////////////////////
//Function : 100us Dealy for S_Flash programming time (base on CPUCLK= 24MHz)
// Syntax: Delay100uS()
// Used register: r1,r2
///////////////////////////////////////////////////////////////
.public _Delay11ms
_Delay11ms:
F_Delay11ms:
push r1,r1 to [sp];
//r1=17*10;
r1=20*10; // delay
L_LoopDelay11:
call F_Delay100uS;
r1-=1;
jne L_LoopDelay11
pop r1,r1 from [sp];
retf;
///////////////////////////////////////////////////////////////
//Function : 100us Dealy for S_Flash programming time (base on CPUCLK= 24MHz)
// Syntax: Delay100uS()
// Used register: r1,r2
///////////////////////////////////////////////////////////////
.public _Delay100uS;
_Delay100uS: .PROC
F_Delay100uS: //13
push r1,r1 to [sp]; //7
r1=294; //6
L_DelayLoop:
r1-=1; //3 26+19+8*294 =2400
jne L_DelayLoop; //5
pop r1,r1 from [sp]; //7
retf; //12
.ENDP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -