📄 samsungflashv11.asm
字号:
//======================================================
// 文件名称: SamsungflashV11.asm
// 功能描述: K9F1208的读写、擦除
// 使用方法:
// 建议使用以下顺序
// 初始化过程:
// InitSamsungFlash()
// 写过程:
// InitWriteSamsungFlash() -> FillSamsungFlash(Data) -> ... -> StopWriteSamsungFlash()
// 读过程:
// InitReadSamsungFlash() -> ExtractSamsungFlash() -> ...-> StopReadSamsungFlash()
// 流控制:
// GetColAddr()
// GetPage()
// GetBlock()
//
// Note:
// 1. 注意每次读/写操作都要调用初始化和结束函数
// 2. 为了避免错误,请不要交迭使用读/写操作
// 3. 当program/erase错误发生的时候, 用户必须根据自己的文件系统自行处理
// 请参考_SP_FillSamsungFlash和_SamsungEraseBlock,这里假定没有错误产生
// 4、本例子只用到低位地址Addr0~Addr24。Addr25设为1即可使用全部高位地址。
// 完成日期: 2004-4-12
//========================================================================================
.INCLUDE hardware.inc;
.PUBLIC _SP_InitSamsungFlash
.PUBLIC _SP_FillSamsungFlash
.PUBLIC _SP_ExtractSamsungFlash
.PUBLIC _SP_InitReadSamsungFlash
.PUBLIC _SP_InitWriteSamsungFlash
.PUBLIC _SP_StopWriteSamsungFlash
.PUBLIC _SP_StopReadSamsungFlash
.PUBLIC _SP_SamsungEraseBlock
.PUBLIC _SP_SamsungMassErase
.PUBLIC _SP_GetColAddr
.PUBLIC _SP_GetPage
.PUBLIC _SP_GetBlock
.PUBLIC _SP_SamsungReadByte
.PUBLIC _SP_SamsungWriteByte
.PUBLIC _SP_SamsungReadPageW
.PUBLIC _SP_SamsungWritePageW
// Flash 控制信号
.DEFINE RE_BIT 0x01
.DEFINE WE_BIT 0x02
.DEFINE CE_BIT 0x04
.DEFINE ALE_BIT 0x08
.DEFINE CLE_BIT 0x10
.DEFINE BASE_CONF 0x001F
// K9F1208的地址边界
.DEFINE C_PageBin 0x0000
.DEFINE C_PageEnd 0x1FFFF
.DEFINE C_BlockBin 0x0000
.DEFINE C_MaxBlock 0x0FFF // 4096 block
.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
.DEFINE Port_Watchdog_Clear P_Watchdog_Clear
.DEFINE Port_SystemClock P_SystemClock
// 数据Buffer
.DEFINE C_PageSize 0x200 // 512 bytes
.DEFINE C_MaxPageBufferBytes 0x80 // 128 bytes 2*C_MaxPageBuffer
.DEFINE C_MaxPageBuffer 0x40 // 64 words
.IRAM
.VAR R_CurrAddr = 0
.VAR R_CurrPage = C_PageBin
.VAR R_WriteIndex = 0
.VAR R_ReadIndex = C_MaxPageBuffer
.RAM
T_PageBuffer: .DW C_MaxPageBuffer dup(0)
.TEXT
.public _InitSignalLine
_InitSignalLine: .proc
r1 = CE_BIT|RE_BIT|WE_BIT;
[Port_IOB_Buffer]=r1;
.endp
//--------------------------------------------------------------------
//-- 宏名: M_SaveIoSetting
//-- 参数: 无
//-- 把IO设置保存到堆栈
//--------------------------------------------------------------------
M_SaveIoSetting: .MACRO
R5 = [Port_IOB_Buffer];
R5 &= 0xFFD0
push R5 to [SP]
R5 = [Port_IOA_Buffer];
R5 &= 0xFF00
push R5 to [SP]
.ENDM
//--------------------------------------------------------------------
//-- 宏名: M_RetrieveIoSetting
//-- 参数: 无
//-- 从堆栈恢复IO设置
//--------------------------------------------------------------------
M_RetrieveIoSetting: .MACRO
pop R5 from [SP]
[Port_IOA_Data] = R5
pop R5 from [SP]
R5 |= CE_BIT
[Port_IOB_Data] = R5
.ENDM
//--------------------------------------------------------------------
//-- 宏名: M_InitIOAOut
//-- 参数: 无
//--------------------------------------------------------------------
M_InitIOAOut: .MACRO
R5 = [Port_IOA_Attrib]
R5 |= 0x00FF
[Port_IOA_Attrib] = R5
R5 = [Port_IOA_Dir]
R5 |= 0x00FF
[Port_IOA_Dir] = R5
.ENDM
//--------------------------------------------------------------------
//-- 宏名: _M_InitIOAIn
//-- 参数: 无
//--------------------------------------------------------------------
M_InitIOAIn: .MACRO
R5 = [P_IOA_Attrib]
R5 &= 0xFF00
[P_IOA_Attrib] = R5
R5 = [P_IOA_Dir]
R5 &= 0xFF00
[P_IOA_Dir] = R5
.ENDM
//--------------------------------------------------------------------
//-- 宏名: M_SendReadCmd
//-- 参数: column,page,portA,portB
//-- 发送 0x00, 0x01 or 0x50
//--------------------------------------------------------------------
M_SendReadCmd: .MACRO column,page,portA,portB
R5 = SP
portA = [R5+1]
portB = [R5+2]
R5 = (CLE_BIT|RE_BIT)
R5 |= portB
[Port_IOB_Data] = R5
R5 = 0x0000 //read0 命令
cmp column, 256
jb ?NotChArea
column -= 256
R5 = 0x0001 //read1 命令
cmp column, 256
jb ?NotChArea
column -= 256
R5 = 0x0050 //read2 命令
?NotChArea:
R5 |= portA
[Port_IOA_Data] = R5
R5 = (CLE_BIT|RE_BIT|WE_BIT)
R5 |= portB
[Port_IOB_Data] = R5 //WE高电平
R5 = (WE_BIT|ALE_BIT|RE_BIT) //CLE低电平 , WE高电平 , ALE高电平 , RE高电平
R5 |= portB
[Port_IOB_Data] = R5
//.....写地址.....................
portB |= (ALE_BIT|RE_BIT)
[Port_IOB_Data] = portB //WE低电平
column |= portA
[Port_IOA_Data] = column //Address0 - 7
[Port_IOB_Data] = R5 //WE, ALE, RE高电平
[Port_IOB_Data] = portB //WE低电平
column = page & 0x00FF
column |= portA
[Port_IOA_Data] = column //Address9 - 16
[Port_IOB_Data] = R5 //WE, ALE高电平
[Port_IOB_Data] = portB //WE低电平
page = page LSR 4
page = page LSR 4
page |= portA
[Port_IOA_Data] = page //Address17 - 22
[Port_IOB_Data] = R5 //WE, ALE高电平
[Port_IOB_Data] = R4 //WE低电平
push r1 to [sp]
r1 = 0
[Port_IOA_Data] = r1 //Address25
pop r1 from [sp]
[Port_IOB_Data] = R5 //WE, ALE高电平
R5 = SP
portB = [R5+2]
R5 = (WE_BIT|RE_BIT)
R5 |= portB
[Port_IOB_Data] = R5 //WE高电平 , RE高电平 , ALE低电平
.ENDM
//--------------------------------------------------------------------
//-- 宏名: M_SendWriteCmd
//-- 参数: column,page,portA,portB
//-- 发送 0x80
//--------------------------------------------------------------------
M_SendWriteCmd: .MACRO column,page,portA,portB
R5 = SP
portA = [R5+1]
portB = [R5+2]
R5 = (CLE_BIT|RE_BIT)
R5 |= portB
[Port_IOB_Data] = R5
R5 = 0x0000
cmp column, 256
jb ?NotChArea
column -= 256
R5 = 0x0001
cmp column, 256
jb ?NotChArea
column -= 256
R5 = 0x0050
?NotChArea:
R5 |= portA
[Port_IOA_Data] = R5
R5 = (CLE_BIT|RE_BIT|WE_BIT)
R5 |= portB
[Port_IOB_Data] = R5
R5 = (CLE_BIT|RE_BIT)
R5 |= portB
[Port_IOB_Data] = R5
R5 = 0x0080 // 连续数据输入命令
R5 |= portA
[Port_IOA_Data] = R5
R5 = (CLE_BIT|RE_BIT|WE_BIT)
R5 |= portB
[Port_IOB_Data] = R5 //WE高电平
R5 = (WE_BIT|ALE_BIT|RE_BIT) //CLE低电平 , WE高电平 , ALE高电平 , RE高电平
R5 |= portB
[Port_IOB_Data] = R5
//.....写地址.....................
portB |= (ALE_BIT|RE_BIT)
[Port_IOB_Data] = portB //WE低电平
column |= portA
[Port_IOA_Data] = column //Address0 - 7
[Port_IOB_Data] = R5 //WE, ALE, RE高电平
[Port_IOB_Data] = portB //WE低电平
column = page & 0x00FF
column |= portA
[Port_IOA_Data] = column //Address9 - 16
[Port_IOB_Data] = R5 //WE, ALE高电平
[Port_IOB_Data] = portB //WE低电平
page = page LSR 4
page = page LSR 4
page |= portA
[Port_IOA_Data] = page //Address17 - 22
[Port_IOB_Data] = R5 //WE, ALE高电平
//for debug,no a25
[Port_IOB_Data] = R4 //WE低电平
push r1 to [sp]
r1 = 0
[Port_IOA_Data] = r1 //Address25
pop r1 from [sp]
[Port_IOB_Data] = R5 //WE, ALE高电平
//
R5 = SP
portB = [R5+2]
.ENDM
//--------------------------------------------------------------------
//-- 宏名: M_StartProgram
//-- 参数: portA,portB
//-- Send 0x10
//--------------------------------------------------------------------
M_StartProgram: .MACRO portA,portB
R5 = (CLE_BIT|RE_BIT)
R5 |= portB
[Port_IOB_Data] = R5 //WE低电平 , RE高电平 , CLE高电平
R5 = 0x0010 //program 命令
R5 |= portA
[Port_IOA_Data] = R5 //WE低电平 , RE高电平 , CLE高电平
R5 = (CLE_BIT|RE_BIT|WE_BIT)
R5 |= portB
[Port_IOB_Data] = R5
.ENDM
//--------------------------------------------------------------------
//-- 函数名: _SP_InitSamsungFlash
//-- 参数: 无
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_InitSamsungFlash: .proc
_InitSamsungFlash:
push R1 to [SP]
R1 = 0
[Port_TimeBaseSetup] = R1
[Port_SystemClock] = R1
// R1 = 0x01
// [Port_Watchdog_Clear] = R1
R1 = [Port_IOA_Attrib]
R1 &= 0xFF00
[Port_IOA_Attrib] = R1
R1 = [Port_IOA_Dir]
R1 &= 0xFF00
[Port_IOA_Dir] = R1
R1 = [Port_IOB_Attrib]
R1 &= 0xFFD0
R1 |= BASE_CONF
[Port_IOB_Attrib] = R1
R1 = [Port_IOB_Dir]
R1 &= 0xFFD0
R1 |= BASE_CONF
[Port_IOB_Dir] = R1
R1 = [Port_IOB_Buffer]
R1 |= CE_BIT
[Port_IOB_Data] = R1
pop R1 from [SP]
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_InitWriteSamsungFlash
//-- 语法: InitWriteSamsungFlash()
//-- 参数: 无
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_InitWriteSamsungFlash: .proc
PUSH R1,R1 TO [SP];
R1 = 0;
[R_WriteIndex]=R1;
[R_CurrAddr]=R1;
R1 = C_PageBin;
[R_CurrPage]=R1;
POP R1,R1 FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_StopWriteSamsungFlash
//-- 语法: SP_StopWriteSamsungFlash()
//-- 参数: 无
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_StopWriteSamsungFlash: .proc
PUSH R1,R4 TO [SP];
R2=0;
R5=[R_CurrAddr];
cmp R5, C_MaxPageBufferBytes;
jb ?L_LowerPage;
R2=C_MaxPageBufferBytes;
?L_LowerPage:
R1 = R2;
R2 = [R_CurrPage];
R3 = T_PageBuffer;
R4 = [R_WriteIndex];
R4 = R4 lsl 1
call F_SamsungWritePageW;
R1 = 0;
[R_WriteIndex]=R1;
[R_CurrAddr]=R1;
R1 = C_PageBin;
[R_CurrPage]=R1;
POP R1,R4 FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_InitReadSamsungFlash
//-- 语法: SP_InitReadSamsungFlash()
//-- 参数: 无
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_InitReadSamsungFlash: .proc
PUSH R1,R1 TO [SP];
R1=C_MaxPageBuffer;
[R_ReadIndex]=R1;
R1=C_PageBin;
[R_CurrPage]=R1;
R1=0;
[R_CurrAddr]=R1;
POP R1,R1 FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_StopReadSamsungFlash
//-- 语法: SP_StopReadSamsungFlash()
//-- 参数: 无
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_StopReadSamsungFlash: .proc
PUSH R1,R1 TO [SP];
R1 = C_PageBin;
[R_CurrPage] = R1;
R1=0;
[R_ReadIndex] = R1;
[R_CurrAddr]=R1;
POP R1,R1 FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_GetColAddr
//-- 语法: SP_GetColAddr()
//-- 参数: 无
//-- 返回值: R1=Column Addr
//--------------------------------------------------------------------
_SP_GetColAddr: .proc
PUSH BP,BP TO [SP];
R1=[R_CurrAddr];
POP BP,BP FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_GetPage
//-- 语法: SP_GetPage()
//-- 参数: 无
//-- 返回值: R1=Page
//--------------------------------------------------------------------
_SP_GetPage: .proc
PUSH BP,BP TO [SP];
R1=[R_CurrPage];
POP BP,BP FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_GetBlock
//-- 语法: SP_GetBlock()
//-- 参数: 无
//-- 返回值: R1=Block
//--------------------------------------------------------------------
_SP_GetBlock: .proc
PUSH BP,BP TO [SP];
R1=[R_CurrPage];
R1= R1 LSR 4;
POP BP,BP FROM [SP];
retf
.endp
//--------------------------------------------------------------------
//-- 函数名: _SP_FillSamsungFlash
//-- 语法: SP_FillSamsungFlash(Data)
//-- 参数: R1=Data
//-- 返回值: 无
//--------------------------------------------------------------------
_SP_FillSamsungFlash: .proc
PUSH BP,BP TO [SP];
BP = SP + 1
R1=[BP+3]
call F_FillSamsungFlash
POP BP,BP FROM [SP];
retf
.endp
F_FillSamsungFlash:
push R2,R5 to [SP];
// Fill the data to buffer
R2=[R_WriteIndex];
R3=T_PageBuffer;
R3+=R2;
[R3]=R1;
//..... Update Buffer used and Addr
R2=R2+1;
[R_WriteIndex]=R2;
R2 =[R_CurrAddr];
R2+=2;
[R_CurrAddr]=R2;
//..... Check buffer full
R2=[R_WriteIndex]
cmp R2,C_MaxPageBuffer;
jb ?L_Done
// ..... Get Status
?L_WaitForProgramFlash:
call _SamsungGetStatus;
R2=R1&0x40; // ..... Check busy/ready
jz ?L_WaitForProgramFlash
//R2=R1&0x0001; // Check success/failure
//jz ?L_ProgramFlash
//
//
// ... Handle Program Error here according to you file system ...
//
//
// ..... Program Flash
?L_ProgramFlash:
R1=[R_CurrAddr];
R1-=C_MaxPageBufferBytes;
R2=[R_CurrPage];
R3= T_PageBuffer;
R4= C_MaxPageBufferBytes;
call F_SamsungWritePageW;
R2=[R_CurrAddr];
cmp R2, C_PageSize;
jb ?L_LowerPage
R1=0;
[R_CurrAddr]=R1;
R2=[R_CurrPage];
R2+=1;
[R_CurrPage]=R2;
?L_LowerPage:
R1=0;
[R_WriteIndex]=R1;
?L_Done:
pop R2,R5 from [SP]
retf
//--------------------------------------------------------------------
//-- 函数名: _SP_ExtractSamsungFlash
//-- 语法: SP_ExtractSamsungFlash()
//-- 参数: 无
//-- 返回值: R1=Data
//--------------------------------------------------------------------
_SP_ExtractSamsungFlash: .proc
PUSH BP,BP TO [SP];
BP = SP + 1
call F_ExtractSamsungFlash
POP BP,BP FROM [SP];
retf
.endp
F_ExtractSamsungFlash:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -