📄 i2c.asm
字号:
;+---------------------------------------------------------------------------+;| |;| Copyright (C) 2002, Tom De Rybel |;| on1dcd@hotmail.com |;| |;| This program is free software; you can redistribute it and/or |;| modify it under the terms of the GNU General Public License |;| as published by the Free Software Foundation; either version 2 |;| of the License, or any later version. |;| |;| This program is distributed in the hope that it will be useful, |;| but WITHOUT ANY WARRANTY; without even the implied warranty of |;| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |;| GNU General Public License for more details. |;| |;| You should have received a copy of the GNU General Public License |;| along with this program; if not, write to the Free Software |;| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |;| |;| |;+---------------------------------------------------------------------------+; I2C EEProm test on the Cypress EZ-USB; The object is to write a self-loading program;; The external EEProm is a 24C64 device;; This program has all the elegance of a mortally wounded warthog,; so whatever you do, don't show this to anyone who knows how to code if you ; decide to actually use it in the first place ;-). It works though.; ;+-------------------------------------+;| Declaration of the EZ-USB registers |;+-------------------------------------+;.equ DPL1, 0x84.equ DPH1, 0x85.equ DPS, 0x86 .equ CKCON, 0x8E.equ SPC_FNC, 0x8F.equ EXIF, 0x91.equ MPAGE, 0x92.equ SCON1, 0xC0.equ SBUF1, 0xC1.equ EICON, 0xD8.equ EIE, 0xE8.equ EIP, 0xF8 .equ CPUCS, 0x7F92 .equ PORTACFG, 0x7F93.equ PORTBCFG, 0x7F94.equ PORTCCFG, 0x7F95.equ OUTA, 0x7F96 .equ OUTB, 0x7F97.equ OUTC, 0x7F98.equ PINSA, 0x7F99.equ PINSB, 0x7F9A.equ PINSC, 0x7F9B.equ OEA, 0x7F9C.equ OEB, 0x7F9D.equ OEC, 0x7F9E.equ I2CS, 0x7FA5.equ I2DAT, 0x7FA6.equ USBCS, 0x7FD6 ;+--------------------+;| Some LCD constants |;+--------------------+; .equ LINE1, 0x00.equ LINE2, 0x40.equ LINE3, 0x10.equ LINE4, 0x50;+-------------------+;| Interrupt vectors |;+-------------------+;;Reset Vector.org 0x0000lcall SelfLoader ljmp Main.org 0x0100;+--------------+;| Main program |;+--------------+; Main: lcall Init ; Call the initialisation sequence mov r0, #LINE1 mov dptr, #0x1000 lcall write_string mov r0, #LINE2 mov dptr, #0x1011 lcall write_string mov r0, #LINE3 mov dptr, #0x1022 lcall write_string mov r0, #LINE4 mov dptr, #0x1033 lcall write_string blink: mov dptr, #OUTB mov a, #00010000b movx @dptr, a lcall Wait100msec lcall Wait100msec lcall Wait100msec mov dptr, #OUTB mov a, #00000000b movx @dptr, a lcall Wait100msec lcall Wait100msec lcall Wait100msec ljmp blink;+-------------------------+;| Initialisation sequence |;+-------------------------+; Init: ;;mov 0x92, #0x7F ; tc, allows movx Ri to access ez-usb memory mov dptr, #PORTBCFG ; All pins are standard PB pins mov a, #00000000b movx @dptr, a mov dptr, #OEB ; Pin PB4 is an output pin mov a, #00010000b movx @dptr, a mov dptr, #PORTCCFG ; All pins are standard PC pins mov a, #00000000b movx @dptr, a mov dptr, #OEC ; Port PC is output mov a, #0xFF movx @dptr, a mov dptr, #PORTACFG ; All pins are standard PA pins mov a, #00000000b movx @dptr, a mov dptr, #OEA ; Pins PA4 and PA5 are output mov a, #00110000b movx @dptr, a lcall init_LCD ; Initialize LCD module ret ;+----------------+;| Device ID data |;+----------------+;.equ VIDL, 0x47 ; Cypress Semiconductor (0547h).equ VIDH, 0x05.equ PIDL, 0x31 ; EZ-USB (2131h).equ PIDH, 0x21.equ DIDL, 0x21 ; Device Release Number (YY21h).equ DIDH, 0x00 ; I don't really know this one.... ;+----------------------------------------------------+;| High-level SelfLoader routines |;| |;| A, dptr, dptr1, R0-R2, R5-R7 are used and modified | ;+----------------------------------------------------+; These routines serve to copy the (almost) entire RAM contents of the; EZ-USB chip into the external EEPROM, making it a "B2" device. The data; is written in the proper bootloader format. The routines disable; themselves in the process by replacing the calling lcall with nops.; This means that they become "dead code" after their function has been; fulfilled. Thus they don't interfere with the normal functioning of the; normal firmware. It is vitally important that the lcall is at 0x00 (the reset; vector) followed by the jump to the main program. These routines are very ; dumb and assume that the proper hardware is there and functioning.; It is possible to start the user program without a reset after the ; programming sequence has been completed.; Consult the EZ-USB datasheet P. 5-10 and surrounding for more details.;; I write the various USB id data into the EEPROM, because my program runs; with ReNum=0. For now, just the Cypress defaults declared above.;SelfLoader: inc DPS mov dptr, #0x0000 ; Inititalise the EEProm datapointer inc DPS mov R0, #0xB2 ; Write 0xB2 in the EEProm lcall Inc_dptr1Write_EEProm mov R0, #VIDL ; Write the VID L lcall Inc_dptr1Write_EEProm mov R0, #VIDH ; Write the VID H lcall Inc_dptr1Write_EEProm mov R0, #PIDL ; Write the PID L lcall Inc_dptr1Write_EEProm mov R0, #PIDH ; Write the PID H lcall Inc_dptr1Write_EEProm mov R0, #DIDL ; Write the DID L lcall Inc_dptr1Write_EEProm mov R0, #DIDH ; Write the DID H lcall Inc_dptr1Write_EEProm ; Now we write the RAM into the EEPROM, 512 bytes per block. The first block; needs special attention, as we are going to replace the call to this routine; by the proper number of nops. The others are automatic. BEWARE of the last ; one. Due to the overhead caused by the bootloader protocol, the last XXX ; bytes of the EZ-USB memory WILL NOT be programmed, as the used EEPROM is ; precisely 8K in size, thus just a bit too small!!!! ;; We start reading the code memory from 0000h. mov dptr, #0x0000 ;; All addresses are being kept by the dptr and dptr1. mov R7, #0x0F ; We will loop through this section 15 timesbulk_write_loop: mov R0, #0x02 ; Write Length H lcall Inc_dptr1Write_EEProm mov R0, #0x00 ; Write Length L lcall Inc_dptr1Write_EEProm mov R0, DPH ; Write StartAddr H lcall Inc_dptr1Write_EEProm mov R0, DPL ; Write StartAddr L lcall Inc_dptr1Write_EEProm ;; Now the header for the block has been compiled. ;; Let's write the contents.... mov R6, #0x04 ; 4X128=512write_loop_A: mov R5, #0x80 ; Do the inner loop 128 times inner_write_loop_A: mov a, #0x00 ; Read the byte from the code memory movc a, @a+dptr inc dptr ; And increment the dptr mov R0, a ; Write the byte to the EEProm lcall Inc_dptr1Write_EEProm djnz R5, inner_write_loop_A djnz R6, write_loop_A ;; Ok, 512 bytes written now. Time for some automation. djnz R7, bulk_write_loop ;; 7.68K have been written. The one but last block is special again ;; due to space restrictions. We can only program 436 bytes instead ;; of 512 due to the space restrictions explained above. mov R0, #0x01 ; Write Length H lcall Inc_dptr1Write_EEProm mov R0, #0xB4 ; Write Length L (436 in total left tb written) lcall Inc_dptr1Write_EEProm mov R0, DPH ; Write StartAddr H, from the regular dptr lcall Inc_dptr1Write_EEProm mov R0, DPL ; Write StartAddr L lcall Inc_dptr1Write_EEProm ;; Now the header for the last block has been compiled. ;; Let's write the contents.... mov R6, #0x02 ; 2X218=436 (must have 436, or a little less)write_loop_B: mov R5, #218d ; Do the inner loop 218 times inner_write_loop_B: mov a, #0x00 ; Read the byte from the code memory movc a, @a+dptr inc dptr ; And increment the dptr mov R0, a ; Write the byte to the EEProm lcall Inc_dptr1Write_EEProm djnz R5, inner_write_loop_B djnz R6, write_loop_B ;; And now we modify the first datablock itself. ;; Note: the first code 3 bytes (the call to these routines in the ;; reset vector) is replaced by 3 nops to skip the SelfLoader ;; on the next run. This is the first ljmp call. mov R0, #0x00 ; Write nop mov R1, #0x00 mov R2, #0x0B lcall EEProm_write mov R0, #0x00 ; Write nop mov R1, #0x00 mov R2, #0x0C lcall EEProm_write mov R0, #0x00 ; Write nop mov R1, #0x00 mov R2, #0x0D lcall EEProm_write ;; Finally the last data block. ;; The last available address in the EEProm is 1FFFh, starting ;; from 0000h. (Thus 8192 addresses.) mov R0, #0x80 ; Write 80h (MSB set to 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -