;***************************************************************** ;* Command 'M': I2C EEPROM Communication * ;* Function: Reads or writes to the 24C08 I2C EEPROM * ;***************************************************************** CmdEepromI2C: ; Check to see if we're reading the EEPROM or writing to it LCALL SI2CRES JC CEIerror MOV R0,#CmdBuffer + 1 ;Point to second character of command buffer MOV A,@R0 JZ CEIDumpZ ;no argument given, dump all EEPROM locations MOV R1,#Scratch ;buffer for decoding 16-bit address LCALL GetHexValue JC CEInoaddress MOV R4,Scratch+1 ;save LSB of address to write MOV R5,Scratch ;save MSB address to write CJNE A,#'=',CEIRead ;go to read subroutine LCALL GetHexValue ;decode 8-bit data @R0 to @R1+1 JC CEInodata ;end if no data MOV A,Scratch+1 MOV Scratch,A MOV DPH,R5 MOV DPL,R4 LCALL I2C_EEPROM_WRITE LJMP SBCMain ;Go back to main menu CEIerror: LCALL SendSerial DB "I2C bus reset error",13,0 LJMP SBCMain CEInoaddress: LCALL SendSerial DB "invalid address",13,0 LJMP SBCMain CEInodata: LCALL SendSerial DB "invalid data",13,0 LJMP SBCMain CEIDumpZ: LJMP CEIDump CEIRead: ;This means we're reading data from the I2C EEPROM MOV DPH,R5 ;get address MSB MOV DPL,R4 ACALL I2C_EEPROM_READ MOV A,Scratch LCALL SendSerialHexByte ;show EEPROM content CEIReadEnd: MOV A,#CR LCALL SendSerialByte LJMP SBCMain ;Go back to main menu ;R/W I2C EEPROM <= 16 Kb I2C_EEPROM_READ: ;read from eeprom at DPTR to Scratch LCALL SI2CSTA ;start I2C bus MOV A,DPH ANL A,#07h ;3 address MSB CLR C ;R/W=0 RLC A ;address MSB at bits 3,2,1 ORL A,#10100000b ;device address MOV B,A LCALL SI2COUT JNC IER2 ;quit if no ACK RET IER2: MOV A,DPL LCALL SI2COUT ;address LSB JNC IER3 ;quit if no ACK RET IER3: LCALL SI2CSTA ;restart MOV A,B ;resend device address and MSB SETB ACC.0 ;with R/W=1 LCALL SI2COUT JNC IER4 ;quit if no ACK RET IER4: SETB C ;receive byte with NAK LCALL SI2CIN MOV Scratch,A LCALL SI2CSTO ;stop I2C bus RET I2C_EEPROM_WRITE: ;write Scratch to eeprom at DPTR LCALL SI2CSTA ;start I2C bus MOV A,DPH ANL A,#07h ;3 address MSB CLR C ;R/W=0 RLC A ;address MSB at bits 3,2,1 ORL A,#10100000b ;device address LCALL SI2COUT JNC IEW2 ;quit if no ACK RET IEW2: MOV A,DPL ;address LSB LCALL SI2COUT JNC IEW3 ;quit if no ACK RET IEW3: MOV A,Scratch LCALL SI2COUT JNC IEW4 ;quit if no ACK RET IEW4: LCALL SI2CSTO RET CEIDump: MOV R5,#4 MOV DPH,#0 CEIDumpLoop: LCALL CEIDumpBlock INC DPH DJNZ R5,CEIDumpLoop LJMP CEIReadEnd ;print CR and return to SBCMain CEIDumpBlock: ;Read 256 EEPROM locations at block DPH LCALL SI2CSTA ;start I2C bus MOV A,DPH ANL A,#07h CLR C RLC A ORL A,#10100000b ;device address and MSB MOV B,A LCALL SI2COUT JNC IED2 ;quit if no ACK RET IED2: CLR A LCALL SI2COUT ;address LSB JNC IED3 ;quit if no ACK RET IED3: LCALL SI2CSTA ;restart MOV A,B ;resend device address and MSB SETB ACC.0 ;with R/W=1 LCALL SI2COUT JNC IED4 ;quit if no ACK RET IED4: MOV R4,#255 IED5: CLR C ;receive bytes with AK LCALL SI2CIN JC IEDX LCALL SendSerialHexByte DJNZ R4,IED5 SETB C ;read last byte and end with NAK LCALL SI2CIN LCALL SendSerialHexByte IEDX: LCALL SI2CSTO ;stop I2C bus RET