#include "c:\miniIDE\hcs12.inc" EE_ID equ 5 ; stack offset for EE_ID EE_addr equ 4 ; stack offset for EE_addr EE_dat equ 3 ; stack offset for EE_data org $1000 inbuf ds.b 16 ; buffer to hold 16 bytes of data bytecnt ds.b 1 org $1500 lds #$1500 movb #$FF,DDRB ; configure Port B for output bset DDRJ,$02 ; enable LEDs bclr PTJ,$02 ; " jsr openI2C ; initialize I2C module ; test EEbyteWrite and EErandomRead movb #$A0,1,-sp ; pass EEPROM ID in stack movb #0,1,-sp ; pass EEPROM address to be written movb #$3D,1,-sp ; pass data to be written jsr EEbyteWrite ; write the value at location 0 leas 3,sp ldaa #$A0 jsr EEAckPoll ldaa #$A0 ; read back the contents of location 0 ldab #0 ; " jsr EErandomRead ; " staa PTB ; display the contents in LEDs ldy #5 ; display the value on LEDs for 0.4 seconds jsr delayby100ms ; " ; test page write and current address read ldx #testDat ldaa #$A0 ldab #0 ldy #16 jsr EEpageWrite ldaa #$A0 ; wait for page write internal operation jsr EEAckpoll ; wait for internal write operation to complete ; test block read again ldaa #16 ; initialize buffer to all zeroes ldx #inbuf init_lp movb #0,1,x+ dbne a,init_lp ldaa #$A0 ; perform a block read ldab #0 ; " ldx #inbuf ; " ldy #16 ; " jsr EEblockRead ; " ldx #inbuf ldab #16 chk_lp movb 1,x+,PTB ldy #4 ; display data for 0.4 seconds jsr delayby100ms dbne b,chk_lp ldaa #$A0 ldab #0 jsr EErandomRead staa PTB ldy #5 jsr delayby100ms movb #15,bytecnt rdloop ldaa #$A0 ; read 15 bytes from EEPROM jsr EEcurrentRead staa PTB ldy #4 jsr delayby100ms dec bytecnt bne rdloop swi testDat dc.b 1,2,3,4,5,6,7,8,9,$A,$B,$C,$D,$E,$F,$10 ; ******************************************************************************************** ; The following function configures the I2C module. ; ******************************************************************************************** openI2C bset IBCR,IBEN ; enable I2C module movb #$1F,IBFD ; establish I2C baud rate (100 Kbps) movb #$FE,IBAD ; establish I2C module slave address bclr IBCR,IBIE ; disable I2C interrupt bset IBCR,IBSWAI ; disable I2C in wait mode rts ; ******************************************************************************************** ; The following function sends the slave ID contained in accumulator A. ; ******************************************************************************************** sendSlaveID brset IBSR,IBB,* ; wait until I2C bus is free bset IBCR,TXRX+MSSL ; generate a start condition staa IBDR ; send out slave ID brclr IBSR,IBIF,* ; wait for ID to be shifted out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,sendIDok ldab #$FF rts sendIDok ldab #0 rts ; ******************************************************************************************** ; The following function reads a location specified by accumulator B. Device ID is specified ; in A. Data is returned in A. The I2C module sends NACK to the EEPROM after the read. ;********************************************************************************************* EErandomRead jsr sendSlaveID ; send out 24LC08B ID and block address brclr IBSR,RXAK,ranRdok0 ; does EEPROM acknowledge? ldab #$FF ; return -1, if EEprom does not ack rts ranRdok0 stab IBDR ; send out EEPROM memory address brclr IBSR,IBIF,* ; wait until the address is shifted out movb #IBIF,IBSR ; clear IBIF flag brclr IBSR,RXAK,ranRdok1 ; does EEPROM acknowledge? ldab #$FF ; return -1, if EEprom does not ack rts ranRdok1 bset IBCR,RSTA ; generate restart condition oraa #$01 ; set R/W bit for read staa IBDR ; resend the device ID brclr IBSR,IBIF,* ; wait until the EEPROM ID is sent out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,ranRdok2 ; does EEPROM acknowledge? ldab #$FF ; return -1, if EEprom does not ack rts ranRdok2 bset IBCR,TXAK ; prepare sent NACK bclr IBCR,TXRX ; perform reception ldaa IBDR ; dummy read to initiate reception brclr IBSR,IBIF,* ; wait for a byte to shift in movb #IBIF,IBSR ; clear the IBIF flag bclr IBCR,MSSL ; generate a stop condition ldaa IBDR ; get the data byte ldab #0 ; normal read status rts ; ********************************************************************************************* ; The following function reads the contents of the memory location specified by the current ; address counter and returns its contents in A. Error code is returned in B. ; ********************************************************************************************* EEcurrentRead oraa #$01 ; make sure to set R/W bit jsr sendSlaveID ; sends slave ID with R/W bit set to 1 brclr IBSR,RXAK,normal1 ; does EEPROM acknowledge? ldab #$FF ; return -1 as error code rts normal1 bset IBCR,TXAK ; prepare to send NACK bclr IBCR,TXRX ; perform reception ldaa IBDR ; a dummy read to trigger 9 clock pulses brclr IBSR,IBIF,* ; wait for data byte to shift in movb #IBIF,IBSR ; clear the IBIF flag bclr IBCR,MSSL ; generate a stop condition ldaa IBDR ; place the byte in A ldab #0 ; return error code 0 rts ; ********************************************************************************************* ; The following function reads a block of memory and store the contents to a buffer pointed by ; index register X. The EEPROM ID and starting address to be read are passed in A and B. The ; number of bytes to be read in passed in Y. If EEPROM did no acknowledge, returns an error ; code of -1 in B. ; ********************************************************************************************* EEblockRead jsr sendSlaveID ; sends out slave ID with R/W bit set to 0 brclr IBSR,RXAK,normal2 ; does EEPROM acknowledge? ldab #$FF ; return -1 as error code rts normal2 stab IBDR ; send out EEPROM memory address brclr IBSR,IBIF,* ; wait until the address is shifted out movb #IBIF,IBSR ; clear IBIF flag bset IBCR,RSTA ; generate restart condition oraa #$01 ; set R/W bit to 1 for read operation staa IBDR ; resend the device ID brclr IBSR,IBIF,* ; wait until the EEPROM ID is sent out movb #IBIF,IBSR ; clear the IBIF flag bclr IBCR,TXAK+TXRX ; perform reception and prepare sent ACK movb IBDR,0,x ; dummy read to trigger 9 clock pulses rd_loop brclr IBSR,IBIF,* ; wait until a data byte is shifted in and also acknowledge movb #IBIF,IBSR ; clear IBIF flag movb IBDR,1,x+ ; store the data byte in buffer and trigger 9 clock pulses dey cpy #2 ; fall thru when there are only 2 more bytes to shift in bhi rd_loop brclr IBSR,IBIF,* ; wait for the second-to-last-byte to shift in movb #IBIF,IBSR ; clear the IBIF flag bset IBCR,TXAK ; prepare to NACK the last byte movb IBDR,1,x+ ; save second to last byte and read the last byte brclr IBSR,IBIF,* ; wait for last byte to shift in movb #IBIF,IBSR bclr IBCR,MSSL ; generate a stop condition movb IBDR,1,x+ ; save the last byte clr 0,x ; terminate the data buffer with a NULL ldab #0 ; return 0 as the error code rts ; *********************************************************************************************** ; The following function writes a byte to the EEPROM. The device ID, address to be accessed, and ; the data byte to be written into EEPROM are pushed into the stack in that order. If EEPROM does ; not respond to its ID, then return the error code of -1. ; *********************************************************************************************** EEbyteWrite psha ldaa EE_ID,sp ; get the EEPROM ID from stack jsr sendSlaveID ; generate start condition, send EEPROM ID brclr IBSR,RXAK,bywriteok1 ; does EEPROM acknowledge? ldab #$FF ; return -1 as the error code pula rts bywriteok1 ldaa EE_addr,sp ; get the address to be accessed from the stack staa IBDR ; send address to I2C bus brclr IBSR,IBIF,* ; wait until address is shifted out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,bywriteok2 ; does EEPROM acknowledge? ldab #$FF ; return -1 as the error code pula rts bywriteok2 ldaa EE_dat,sp ; get the data byte to be written from stack staa IBDR ; send out the data byte brclr IBSR,IBIF,* ; wait until data byte is shifted out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,bywriteok3 ; does EEPROM acknowledge? ldab #$FF ; return -1 as the error code pula rts bywriteok3 bclr IBCR,MSSL ; generate stop condition ldab #0 ; return error code 0 pula rts ; ********************************************************************************* ; The following function performs a page write operation. ; Block data to be output is pointed to by X. Device ID is passed in A. ; Start address of block is in B. The number of bytes to be output is passed in Y. ; If any error occured, error code -1 is returned in B. ; ********************************************************************************* EEpageWrite jsr sendSlaveID ; generate start condition and send out slave ID brclr IBSR,RXAK,pwriteok1 ; does the EEPROM acknowledge? ldab #$FF ; return error code -1 rts pwriteok1 stab IBDR ; send out the starting address to be written brclr IBSR,IBIF,* ; wait until the byte is shifted out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,w_loop ; does the EEPROM acknowledge? ldab #$FF ; return error code -1 rts w_loop cpy #0 beq done_EEwrite ; byte count is 0, done movb 1,x+,IBDR ; send out one byte brclr IBSR,IBIF,* ; wait until the byte is shifted out movb #IBIF,IBSR ; clear the IBIF flag brclr IBSR,RXAK,okNxt ; receive ACK? ldab #$FF rts okNxt dey ; decrement byte count bra w_loop done_EEwrite bclr IBCR,MSSL ; generate a stop condition ldab #0 ; return error code 0 rts ; ************************************************************************************************* ; The following function polls the EEPROM until it acknowledge, which indicates that its internal ; write operation is complete. ; ************************************************************************************************* EEAckPoll jsr sendSlaveID ; generate start condition and send out EEPROM ID pollloop brclr IBSR,RXAK,done_Write ; EEPROM acknowledges, so internal write operation is done bset IBCR,RSTA ; restart staa IBDR ; send out ID brclr IBSR,IBIF,* ; wait until is shifted out movb #IBIF,IBSR ; clear IBIF bra pollloop done_Write bclr IBCR,MSSL ; generate a stop condition rts ; return immediately when EEPROM acknowledges #include "c:\miniide\delay.asm" end