📄 eeprom_rw.asm
字号:
;***************************************************************
; company:cansum
;Assembling and debugging inplement by Kelvin Yuan, 2004-08-05
;passed at 2004-08-06,debugged by kelvin (for atmel 24c02n)
; for KB IC 83115
; function:read 24lc02 or 24c01,write 24lc02 or 24c01
;***************************************************************
;-----------------------------------------------???
;prtd equ pd ;???,(???Pd)
data_high equ 0b01000000 ;?????(????2?)
data_low equ 0b10111111 ;
clk_high equ 0b00100000 ;?????(????3?)
clk_low equ 0b11011111
write_opt_com equ 0b10100000 ;??(???A0A1A2=000,????0?.2401,2402?????)
read_opt_com equ 0b10100001 ;
c_eep_error equ #30
c_eep_wr_error equ #30
c_0x55_address equ #00
c_0xaa_address equ #01
c_access_code0_addr equ #02
c_access_code1_addr equ #03
c_access_code2_addr equ #04
c_sdata_in_ctrl = 01000000b
c_sdata_out_ctrl = 10111111b
;-----------------------------------------------?????
.area at24c02_var(data)
flg_eep_error:: .ds 1 ;1 state eeprom is mistake
cnt_eep_error:: .ds 1 ;happen error times when read eeprom
eep_data_tmp:: .ds 1 ;only be invoked by internal subroutie
eep_address:: .ds 1 ;address will be accessed
eep_data_writen:: .ds 1 ;data to be writen in memory or be read out from memory
cnt_eep_wr_error:: .ds 1 ;happen error when write eeprom
;*******************************************************************************
.area at24c02_code(code)
;-----------save result to memory------------------------------------------
;you should save data to memory after receive access code
eep_save_data::
lda #c_access_code0_addr
sta eep_address
lda access_code
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_access_code1_addr
sta eep_address
lda access_code+1
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_access_code2_addr
sta eep_address
lda access_code+2
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
ret
;------------------initial the eeprom---------------------------------------------
;it will be invoked when the program start from reset and it receive test command.
;if 00 01=0x55 0xaa,it will read out the memory data, otherwise it will initialization
;program will invoke the eep_init subroutie when it receive the eraser command
eep_init_check::
lda #c_0x55_address
sta eep_address
call read_eep_1byte
lda eep_data_tmp
cmpe #0x55
brnz eep_init
lda #c_0xaa_address
sta eep_address
call read_eep_1byte
lda eep_data_tmp
cmpe #0xaa
brnz eep_init
lda #c_access_code0_addr
sta eep_address
call read_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda eep_data_tmp
sta access_code ;save the first byte of access code
lda #c_access_code1_addr
sta eep_address
call read_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda eep_data_tmp
sta access_code+1 ;save the second byte of access code
lda #c_access_code2_addr
sta eep_address
call read_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda eep_data_tmp
sta access_code+2
ret
eep_init::
lda #c_0x55_address ;write 0x55 to address00
sta eep_address
lda #0x55
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_0xaa_address ;write 0xaa to address01
sta eep_address
lda #0xaa
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_access_code0_addr ;write first byte of access code 0 to address02
sta eep_address
lda #0x0
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_access_code1_addr ;write second byte of access code 0 to address03
sta eep_address
lda #0x0
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
lda #c_access_code2_addr
sta eep_address
lda #0x0
sta eep_data_writen
call write_eep_1byte
lda flg_eep_error
cmpe #1
brz eep_init_error
ret
eep_init_error:
ret
;-----------------------------------------------------------------------
;function: write a byte to eeprom
;entrance: eep_data_writen save the writen data,eep_address is to access address
;output: none
;status: flg_eep_error=1,wrong
write_eep_1byte:
lda #0h
sta cnt_eep_wr_error
write_eep_again:
lda cnt_eep_wr_error
inca
sta cnt_eep_wr_error
cmpe #c_eep_wr_error
brc write_eep_error
call byte_write
call h_delay60us
call read_eep_1byte
lda eep_data_tmp
cmpe eep_data_writen
brnz write_eep_again
lda #0 ;write 1 byte to eeprom OK
sta flg_eep_error
ret
write_eep_error:
lda #1
sta flg_eep_error
ret
;----------------------------------------------------------------------------
;*********************************************************************
;function: read a data from specific address
;entrance:eep_address is to read from this eeprom address
;result:eep_data_tmp
;status: flg_eep_error=0,OK. =1 is mistake
read_eep_1byte:
lda #0
sta cnt_eep_error
random_read_again:
call h_start
lda #write_opt_com ;dummy write
sta eep_data_tmp
call h_send_I2C ;??device address 000
call h_delay6us
call h_rec_ack
lda flg_eep_error
cmpe #1
brz random_read_error
call h_delay60us
lda eep_address
sta eep_data_tmp
call h_send_I2C ;??word address
call h_delay6us
call h_rec_ack
lda flg_eep_error
cmpe #1
brz random_read_error
call h_delay6us
lda plata
ora #data_high
sta plata
call h_start
lda #read_opt_com ;??device address
sta eep_data_tmp
call h_send_I2C
call h_delay6us
call h_rec_ack
lda flg_eep_error
cmpe #1
brz random_read_error
call h_receive_I2C ;????
call h_no_ack_to_ic
call h_stop
lda #0
sta flg_eep_error
ret
random_read_error:
call h_delay60us
lda cnt_eep_error
inca
sta cnt_eep_error
cmpe #c_eep_error
brnc random_read_again
lda #1
sta flg_eep_error
ret
;*********************************************************************
;function:write a data to specific address
;entry: eep_address (to access),eep_data_writen
;result:
;status: flg_eep_error=0,OK. =1 is mistake
byte_write:
; lda #0
; sta cnt_eep_error
byte_write_again:
call h_start
lda #write_opt_com
sta eep_data_tmp
call h_send_I2C ;??driver address
call h_rec_ack ;??IC???
lda flg_eep_error
cmpe #1
brz byte_write_error
lda eep_address
sta eep_data_tmp
call h_send_I2C ;??word address
call h_rec_ack ;??IC???
lda flg_eep_error
cmpe #1
brz byte_write_error
lda eep_data_writen
sta eep_data_tmp
call h_send_I2C ;????data
call h_rec_ack ;??IC???
lda flg_eep_error
cmpe #1
brz byte_write_error
call h_stop
lda #0
sta flg_eep_error ;?????
ret
byte_write_error:
call h_delay60us
lda cnt_eep_wr_error
inca
sta cnt_eep_wr_error
cmpe #c_eep_wr_error
brnc byte_write_again
ret
;-------------------------------------
h_start: ;????,???
lda plata
anda #clk_low
sta plata
call h_delay6us
lda #0
sta flg_eep_error
lda plata ;
ora #data_high
sta plata
call h_delay6us
lda plata
ora #clk_high
sta plata
call h_delay6us
lda plata ;?????
anda #data_low ;data=0
sta plata
call h_delay6us
call h_delay6us
lda plata
anda #clk_low ;clk=0
sta plata
call h_delay6us
call h_delay6us
ret
;---------------------------------------
h_stop:
lda plata
anda #data_low ;
sta plata
nop
call h_delay6us
lda plata
ora #clk_high ;clk=1
sta plata
call h_delay6us
call h_delay6us
lda plata
ora #data_high ;data=1
sta plata
call h_delay6us
call h_delay6us
ret
;---------------------------------------
h_rec_ack: ;?????
lda plata
ora #data_high
sta plata
lda plata
ora #clk_high ;clk=1
sta plata
call h_delay6us
lda plata
ora #data_high
sta plata ;ready for reading data port(only for KB)
call h_delay6us
lda pdira
ora #c_sdata_in_ctrl
sta pdira ;此处要改为输入以读引脚状态
lda porta
anda #data_high ;????
brz h_rec_ok
lda pdira
anda #c_sdata_out_ctrl
sta pdira ;此处改回输出以准备下一步处理
lda #1
sta flg_eep_error
call h_delay6us
ret
h_rec_ok:
lda pdira
anda #c_sdata_out_ctrl
sta pdira ;此处改回输出以准备下一步处理
call h_delay6us
call h_delay6us
lda plata
anda #clk_low ;clk=0
sta plata
lda #0
sta flg_eep_error
; lda prtd
; ora #data_high ;same the programmer tooling diagram
; sta prtd
ret
;---------------------------------------
h_ack_to_ic: ;??IC
lda plata
anda #data_low
sta plata
call h_delay6us
lda plata
ora #clk_high
sta plata
call h_delay6us
lda plata
anda #clk_low
sta plata
call h_delay6us
ret
;--------------------------------------
h_no_ack_to_ic: ;???IC
lda plata
ora #data_high
sta plata
call h_delay6us
lda plata
ora #clk_high
sta plata
call h_delay6us
call h_delay6us
lda plata
anda #clk_low
sta plata
call h_delay6us
ret
;--------------------------------------
h_send_I2C: ;??8?
lda #8
sta flg_eep_error
h_send_I2C_1:
adda #0
lda eep_data_tmp
rolc
sta eep_data_tmp
brc h_send_high
lda plata
anda #data_low
sta plata
br h_send_clk
h_send_high:
lda plata
ora #data_high
sta plata
nop
h_send_clk:
call h_delay6us
lda plata
ora #clk_high
sta plata
call h_delay6us
lda plata
anda #clk_low
sta plata
call h_delay6us
lda flg_eep_error
suba #1
sta flg_eep_error
brz h_send_over
br h_send_I2C_1
h_send_over:
ret
;-------------------------------------
h_receive_I2C: ;??8???
lda #8
sta flg_eep_error
h_receive_I2C_1:
lda plata
ora #data_high
sta plata
call h_delay6us
lda plata
ora #clk_high ;clk=1
sta plata
call h_delay6us
lda plata ;set to high before read for KB
ora #data_high
sta plata
nop
lda pdira
ora #c_sdata_in_ctrl
sta pdira ;此处改为输入以读引脚状态
lda porta
;lda plata
anda #data_high ;??data?
cmpe #data_high ;Acc>=data_high,cy=1
lda eep_data_tmp
rolc
sta eep_data_tmp
lda pdira
anda #c_sdata_out_ctrl
sta pdira ;此处改回输出
h_receive_clk:
lda plata
anda #clk_low ;clk=0
sta plata
lda flg_eep_error
suba #1
sta flg_eep_error
brz h_receive_over
br h_receive_I2C_1
h_receive_over:
ret
;--------------------------------------
h_delay60us:
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
call h_delay6us
ret
h_delay6us:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
;--------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -