29
Communication - Using PSoC Internal Resistors for I2C Communications August 29, 2003 Document No. 001-35979 Rev. ** 1 AN2121 Author: Jason A. Goldstein Associated Project: No Associated Part Family: CY8C25xxx, CY8C26xxx GET FREE SAMPLES HERE Software Version: NA Associated Application Notes: None Application Note Abstract This Application Note describes how to use the internal pull-up resistors present on the PSoC® I/O pins when communicating as an I 2 C™ Bus Master. Introduction All devices that drive an I 2 C bus must use an open collector. A high value is driven on the bus by resistors tied to V CC . For a lightly loaded bus, it is possible to use the pull-up resistors built into each PSoC I/O pin instead of external resistors. This Application Note describes how to modify the I 2 C Bus Master Software User Module supplied with PSoC Designer™ to provide a choice of using either internal or external resistors. Pull-Up Resistors and I 2 C Figure 1 shows a block diagram of a typical I 2 C system. The pull-up resistors (R P ) are determined by the supply voltage, clock speed and bus capacitance. The minimum sink current for any device (master or slave) should be no less than 3 mA at V OLmax = 0.4 V for the output stage. This limits the minimum pull-up resistor value for a 5V system to about 1.5 kΩ. The maximum value for R P is dependent on the bus capacitance and clock speed. For a 5 V system with a bus capacitance of 150 pF, the pull-up resistors should be no larger than 6 kΩ. Each I/O pin on the PSoC has the option of driving the signal with a strong low signal and a weak high signal. The weak high voltage signal is provided with a pull-up resistor of at least 4 kΩ and no more than 8 kΩ (see section 13.2 of the PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors, the total bus capacitance is limited to 100 pF when using the internal pull-up resistors. To avoid destroying the output driver of any of the parts, never use both external and internal resistors – use one or the other. Also, one and only one PSoC should use the internal resistors when connecting multiple PSoC devices in a system. For more information on “The I 2 C-Bus Specification,” see the Philips web site at: http://www.semiconductors.philips.com/buses/i2c. Driving the Bus The I 2 C Bus Master User Module provided with PSoC Designer operates by toggling the I/O pins in software. A logic zero is provided by driving a strong 0 (Data 0, Drive Mode 11), and a logic one is provided by changing the pin to be high impedance (Data 0, Drive Mode 10). Thus, only Drive Mode Bit 0 must be toggled to change states. However, a bank mode switch is required to change any of the drive mode bits. The bank must be switched back after the modification is made. When using the internal pull-up resistors, a logic low is provided as before but a resistive high is provided (Data 1, Drive Mode 11) instead of high impedance. The bank switches are avoided because the Drive Mode bits remain unchanged resulting in a slight performance increase. Modifying the Code All of the files for the I 2 C Bus Master User Module can be found in the following directory: C:\Program Files\Cypress MicroSystems\PSoC Designer\Data\StdUM\I2Cm_SW (If you did not install to the default directory, you can locate the files at …\PSoC Designer\Data\StdUM\I2Cm_SW.) [+] Feedback [+] Feedback

Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

Communication - Using PSoC Internal Resistors for I2C Communications

August 29, 2003 Document No. 001-35979 Rev. ** 1

AN2121Author: Jason A. Goldstein

Associated Project: No Associated Part Family: CY8C25xxx, CY8C26xxx

GET FREE SAMPLES HERE

Software Version: NAAssociated Application Notes: None

Application Note Abstract This Application Note describes how to use the internal pull-up resistors present on the PSoC® I/O pins when communicating as an I2C™ Bus Master.

Introduction All devices that drive an I2C bus must use an open collector. A high value is driven on the bus by resistors tied to VCC. For a lightly loaded bus, it is possible to use the pull-up resistors built into each PSoC I/O pin instead of external resistors. This Application Note describes how to modify the I2C Bus Master Software User Module supplied with PSoC Designer™ to provide a choice of using either internal or external resistors.

Pull-Up Resistors and I2C Figure 1 shows a block diagram of a typical I2C system.

The pull-up resistors (RP) are determined by the supply voltage, clock speed and bus capacitance. The minimum sink current for any device (master or slave) should be no

less than 3 mA at VOLmax = 0.4 V for the output stage. This limits the minimum pull-up resistor value for a 5V

system to about 1.5 kΩ. The maximum value for RP is dependent on the bus capacitance and clock speed. For a 5 V system with a bus capacitance of 150 pF, the pull-up resistors should be no larger than 6 kΩ.

Each I/O pin on the PSoC has the option of driving the signal with a strong low signal and a weak high signal. The weak high voltage signal is provided with a pull-up resistor of at least 4 kΩ and no more than 8 kΩ (see section 13.2 of the PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors, the total bus capacitance is limited to 100 pF when using the internal pull-up resistors.

To avoid destroying the output driver of any of the parts, never use both external and internal resistors – use one or the other. Also, one and only one PSoC should use the internal resistors when connecting multiple PSoC devices in a system.

For more information on “The I2C-Bus Specification,” see the Philips web site at:

http://www.semiconductors.philips.com/buses/i2c.

Driving the Bus The I2C Bus Master User Module provided with PSoC Designer operates by toggling the I/O pins in software. A logic zero is provided by driving a strong 0 (Data 0, Drive Mode 11), and a logic one is provided by changing the pin to be high impedance (Data 0, Drive Mode 10). Thus, only Drive Mode Bit 0 must be toggled to change states. However, a bank mode switch is required to change any of the drive mode bits. The bank must be switched back after the modification is made.

When using the internal pull-up resistors, a logic low is provided as before but a resistive high is provided (Data 1, Drive Mode 11) instead of high impedance. The bank switches are avoided because the Drive Mode bits remain unchanged resulting in a slight performance increase.

Modifying the Code All of the files for the I2C Bus Master User Module can be found in the following directory:

C:\Program Files\Cypress MicroSystems\PSoC Designer\Data\StdUM\I2Cm_SW

(If you did not install to the default directory, you can locate the files at …\PSoC Designer\Data\StdUM\I2Cm_SW.)

[+] Feedback [+] Feedback

Page 2: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

The first step in modifying the User Module is to add an entry into the properties list so that the user can choose internal or external resistors from within PSoC Designer. Do this by modifying the I2Cm_SW.xml file. Cypress warns against doing this and provides no support for those who do. As such, it is highly recommended that you backup the entire directory before proceeding.

Figure 1. Typical I2C System

The I2C Bus Master User Module already has three parameters; I2C_Port, SDA_Pin and SCL_Pin, that together define which pins are used for the data and clock signals. A fourth parameter called Pullup must be added as shown in Listing 1. PSoC Designer will replace the string `@Pullup` in the source code files with 0 for external and 1 for internal resistors. Figure 2 shows the resulting change in the Device Editor.

Figure 2. Resulting User Module Parameters

Simple modifications of the assembly language source file I2Cm_SW.asm (shown in Listing 2) using the IF-ELSE-ENDIF assembler directives are used to toggle the I/O pins as necessary.

To facilitate this process, some of the bank switches were re-arranged. When external resistors are chosen, this code behaves exactly the same as that originally provided by Cypress.

PSoC Designer should be restarted to pick up the changes, but otherwise the module works exactly as expected. Add the module in the Device Editor and build the project as usual.

Testing the Module This software has been tested using the PSoC as the I2C Bus Master and a Cypress Semiconductor CY22393 Triple PLL Clock Generator as the only slave. The output frequencies are easily changed by loading the proper registers inside the CY22393 from a lookup table stored in the PSoC Flash memory.

Summary For lightly loaded I2C busses, the internal pull-up resistors on the I/O pins of the PSoC can be used instead of external resistors. Modification of the I2C Bus Master User Module provided with the PSoC Designer software permits internal or external resistor usage to be easily chosen from within the Device Editor.

August 29, 2003 Document No. 001-35979 Rev. ** 2

[+] Feedback [+] Feedback

Page 3: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

Listing 1 <!--***********************************************************************-->

<!-- Filename: I2Cm_SW.XML -->

<!-- Rev A, 2002 Oct 20 -->

<!-- Description: Library routines to control the software I2C Master. -->

<!-- Copyright (c) Cypress MicroSystems 2001-2002. All rights reserved. -->

<!--***********************************************************************-->

<PSOC_DEVICE_DB>

<USER_MODULE_LIST>

<USER_MODULE NAME="I2Cm_SW" TYPE="PSOC_DIG_COMM" HTML="I2Cm_SW.HTM"

ICON="I2Cm_SW.ico" METAFILE="I2Cm_SW.emf"

API_PATH_TYPE="CUSTOM"

RAM="4" ROM="585" VERSION="Rev A, 2002 Oct 20">

<SHAPE SHAPE_TYPE="NONE"/>

<PARAMETER_LIST>

<PARAMETER NAME="I2C_Port" TYPE="PORT" SOURCE="None" VALUE_TYPE="ENUM" MASK="0x00" VALUE="None" ORDER="0">

<PARAMETER_VALUE_LIST>

<PARAMETER_VALUE NAME="None" ORDER="0" VALUE="0" />

</PARAMETER_VALUE_LIST>

<SHADOW_REG_LIST>

<SHADOW_REG NAME="DriveMode_0" />

<SHADOW_REG NAME="DriveMode_1" />

<SHADOW_REG NAME="Data" />

</SHADOW_REG_LIST>

</PARAMETER>

<PARAMETER NAME="SDA_Pin" TYPE="PIN" SOURCE="I2C_Port" VALUE_TYPE="ENUM" VALUE="None"

PIN_SELECT="StdCPU" PIN_DRIVE="High Z" ORDER="1">

<PARAMETER_VALUE_LIST>

<PARAMETER_VALUE NAME="None" ORDER="0" VALUE="0" />

</PARAMETER_VALUE_LIST>

</PARAMETER>

<PARAMETER NAME="SCL_Pin" TYPE="PIN" SOURCE="I2C_Port" VALUE_TYPE="ENUM" VALUE="None"

PIN_SELECT="StdCPU" PIN_DRIVE="High Z" ORDER="2">

<PARAMETER_VALUE_LIST>

<PARAMETER_VALUE NAME="None" ORDER="0" VALUE="0" />

</PARAMETER_VALUE_LIST>

</PARAMETER>

August 29, 2003 Document No. 001-35979 Rev. ** 3

[+] Feedback [+] Feedback

Page 4: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

<PARAMETER NAME="Pullup" TYPE="API" SOURCE="None" VALUE_TYPE="ENUM" VALUE="External" MASK="0x00" ORDER="3">

<PARAMETER_VALUE_LIST>

<PARAMETER_VALUE NAME="External" ORDER="0" VALUE="00" />

<PARAMETER_VALUE NAME="Internal" ORDER="1" VALUE="01" />

</PARAMETER_VALUE_LIST>

</PARAMETER>

</PARAMETER_LIST>

<API_REGISTER_ALIAS_LIST/>

</USER_MODULE>

</USER_MODULE_LIST>

</PSOC_DEVICE_DB>

August 29, 2003 Document No. 001-35979 Rev. ** 4

[+] Feedback [+] Feedback

Page 5: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

Listing 2 ;------------------------------------------------------------------------------

; FILENAME: `@INSTANCE_NAME`.asm

; VERSION: REV A, 2002 Oct 20

;------------------------------------------------------------------------------

; DESCRIPTION:

; I2C Master User Module API.

;

; The original I2C Master module drives strong 0 to indicate a logic low level

; and high-Z to indicate a logic high level. This assumes external pull-ups

; on the SCL and SDA pins. For lightly load I2C busses the internal pull-ups

; of the PSoC should be fine.

;

; This module has been modified to drive strong 0 to indicate a logic low level

; and resistive 1 (ie. pull-up) to indicate a logic high level. Care is taken

; to make sure the pull-up is active when receiving.

;

; The modifications are easily identified as being surrounded by an

; IF `@Pullup`-ELSE-ENDIF construct. The orginal code is the ELSE portion.

; Some of the bank switch statements have been moved to minimize the number of

; IF-ELSE-ENDIF constructs.

;

;------------------------------------------------------------------------------

; Copyright (c) Cypress MicroSystems 2000-2002. All Rights Reserved.

;------------------------------------------------------------------------------

;

;-----------------------------------------------

; include instance specific register definitions

;-----------------------------------------------

include "m8c.inc"

include "`@INSTANCE_NAME`.inc"

;-------------------------------------------------------------------

; Declare the functions global for both assembler and C compiler.

;

; Note that there are two names for each API. First name is

; assembler reference. Name with underscore is name refence for

; C compiler. Calling function in C source code does not require

; the underscore.

;-------------------------------------------------------------------

August 29, 2003 Document No. 001-35979 Rev. ** 5

[+] Feedback [+] Feedback

Page 6: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

export `@INSTANCE_NAME`_Start

export _`@INSTANCE_NAME`_Start

export `@INSTANCE_NAME`_Stop

export _`@INSTANCE_NAME`_Stop

export `@INSTANCE_NAME`_fSendRepeatStart

export _`@INSTANCE_NAME`_fSendRepeatStart

export `@INSTANCE_NAME`_fSendStart

export _`@INSTANCE_NAME`_fSendStart

export `@INSTANCE_NAME`_SendStop

export _`@INSTANCE_NAME`_SendStop

export `@INSTANCE_NAME`_fReadBytes

export _`@INSTANCE_NAME`_fReadBytes

export `@INSTANCE_NAME`_bWriteBytes

export _`@INSTANCE_NAME`_bWriteBytes

export `@INSTANCE_NAME`_bWriteCBytes

export _`@INSTANCE_NAME`_bWriteCBytes

export `@INSTANCE_NAME`_fWrite

export _`@INSTANCE_NAME`_fWrite

export `@INSTANCE_NAME`_bRead

export _`@INSTANCE_NAME`_bRead

;-------------------------------------------------------------------

; Declare the varables for both the assembler and C compiler.

;

;-------------------------------------------------------------------

export `@INSTANCE_NAME`_bStatus

export _`@INSTANCE_NAME`_bStatus

export `@INSTANCE_NAME`_bData

export _`@INSTANCE_NAME`_bData

export `@INSTANCE_NAME`_bAddr

export _`@INSTANCE_NAME`_bAddr

area bss(RAM)

_`@INSTANCE_NAME`_bStatus:

`@INSTANCE_NAME`_bStatus: `@CTAB40`blk 1 ; Status during transfers

_`@INSTANCE_NAME`_bData:

`@INSTANCE_NAME`_bData: `@CTAB40`blk 1 ; Data transfered

_`@INSTANCE_NAME`_bXferCnt:

August 29, 2003 Document No. 001-35979 Rev. ** 6

[+] Feedback [+] Feedback

Page 7: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

`@INSTANCE_NAME`_bXferCnt: `@CTAB50`; Reused variable for counting transfered

_`@INSTANCE_NAME`_bAddr: `@CTAB50`; Bytes

`@INSTANCE_NAME`_bAddr: `@CTAB40`blk 1 ; Slave Address

_`@INSTANCE_NAME`_bit_count:

`@INSTANCE_NAME`_bit_count: `@CTAB40`blk 1 ; Bit counter

area text(ROM,REL)

`@INSTANCE_NAME`_SLAVE_ACKed: `@CTAB40`equ 0x01 ; This bit set if Slave ACKed Master

`@INSTANCE_NAME`_SEND_ACK: `@CTAB40`equ 0x10 ; If this flag set, Master should send ACK

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_Start

;

; DESCRIPTION: Call this function once to initialize the `@INSTANCE_NAME` bus.

; Sets up pins for `@INSTANCE_NAME` bus

;

; ARGUMENTS: none

;

; RETURNS: none

; SIDE EFFECTS: Resets all pins on the I2C master port to the pulldown drive

; mode.

;

; THEORY of OPERATION:

; none.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_Start:

_`@INSTANCE_NAME`_Start:

IF `@Pullup`

; set pins to drive resistive high

or [`@I2C_Port_DriveMode_1_SHADE`],`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin

ELSE

; Set pins to drive mode high Z

or [`@I2C_Port_DriveMode_1_SHADE`],`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin

and [`@I2C_Port_DriveMode_0_SHADE`],~(`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin)

ENDIF

August 29, 2003 Document No. 001-35979 Rev. ** 7

[+] Feedback [+] Feedback

Page 8: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

M8C_SetBank1 ; Setup port for normal operation

mov A,[`@I2C_Port_DriveMode_1_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM1],A

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

IF `@Pullup`

; set both pins high to apply the pull-ups

; only the data port needs to be changed from strong zero to a resistive 1

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin

ELSE

; Set both pins, low so that only the port

; mode has to be changed from a 0 to a 1

and [`@I2C_Port_Data_SHADE`],~(`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin)

ENDIF

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_Stop

;

; DESCRIPTION: This function performs no operation and is used for future

; module compatibility.

;

; ARGUMENTS: none

;

; RETURNS: none

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_Stop:

_`@INSTANCE_NAME`_Stop:

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_ReadBytes

;

August 29, 2003 Document No. 001-35979 Rev. ** 8

[+] Feedback [+] Feedback

Page 9: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

; DESCRIPTION: Read multiple data bytes from slave device.

;

; ARGUMENTS: A => Address of slave

; X => Pointer to other arguments.

; [x] => LSB of Array address to put data in.

; [X-1] => MSB of Array address to put data in (ignorned)

; [X-2] => Count of bytes to read.

; [X-3] => Mode flags that allow the programmer to set flags

; to determine if:

; 0x01 => Use RepeatStart instead of Start

; 0x02 => Don't send Stop

;

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION:

;

;-----------------------------------------------------------------------------

RxArray: equ 0

RxByteCount: equ -2

RxMode: equ -3

`@INSTANCE_NAME`_fReadBytes:

_`@INSTANCE_NAME`_fReadBytes:

asl A ; Shift address to the left to make

; a complete byte with the R/W bit.

or A,0x01 ; OR the address with the Read bit.

mov [`@INSTANCE_NAME`_bStatus],0x00 `@CTAB60`; Clear all flags

tst [x+RxMode],`@INSTANCE_NAME`_RepStart

jnz DoRestartRx

call I2C_DoStart ; Send a start and address.

jmp CheckRxAck

DoRestartRx:

call I2C_DoRepeatStart ; Send a repeat start and address.

CheckRxAck: ; Test to see if Slave ACKed

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed

jz End_RD_Loop

; Send ACK until last byte

August 29, 2003 Document No. 001-35979 Rev. ** 9

[+] Feedback [+] Feedback

Page 10: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

or [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SEND_ACK `@CTAB60`; Send ACK until last byte

RD_Loop: ; Loop through bytes

push x ; Save X for later

dec [x+RxByteCount] ; Decrement data counter

jnz I2C_READ

and [`@INSTANCE_NAME`_bStatus],~`@INSTANCE_NAME`_SEND_ACK `@CTAB60`; If last Byte, don't ACK

I2C_READ:

call `@INSTANCE_NAME`_read `@CTAB60`; Read a byte

pop x ; Restore x

push x ; Store x

mov x,[x+RxArray] ; Get pointer to data and put it in X

mov a,[`@INSTANCE_NAME`_bData] `@CTAB60`; Save data in data array

mov [x+RxArray],a ; Put read data in array

pop x ; Restore the original pointer

inc [x+RxArray] ; Advance data pointer

tst [x+RxByteCount],FFh ; Decrement data counter

jnz RD_Loop ; Not finished, do another byte.

End_RD_Loop: ; Endloop

tst [x+RxMode],`@INSTANCE_NAME`_NoStop

jnz SkipRxStop

call `@INSTANCE_NAME`_SendStop

SkipRxStop:

mov a,`@INSTANCE_NAME`_XFER_ERROR `@CTAB60`; Clear return value until we test if slave ACKed

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed `@CTAB60`; Test to see if Slave ACKed

jz End_ReadBytes

mov a,`@INSTANCE_NAME`_XFER_COMPLETE `@CTAB60`; Return ACKed True

End_ReadBytes:

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_bWriteBytes

;

; DESCRIPTION: Write multiple data bits to slave device.

;

; ARGUMENTS: A => Address of slave

; X => Pointer to other arguments.

; [x] => LSB of Array address to put data in.

; [X-1] => MSB of Array address to put data in (ignorned)

August 29, 2003 Document No. 001-35979 Rev. ** 10

[+] Feedback [+] Feedback

Page 11: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

; [X-2] => Count of bytes to write.

; [X-3] => Mode flags that allow the programmer to set flags

; to determine if:

; 0x01 => Use RePeatStart instead of Start

; 0x02 => Don't send Stop

;

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION:

;

;-----------------------------------------------------------------------------

TxArray: equ 0

TxByteCount: equ -2

TxMode: equ -3

`@INSTANCE_NAME`_bWriteBytes:

_`@INSTANCE_NAME`_bWriteBytes:

asl A ; Shift address to the left to make

; a complete byte with the R/W bit.

; The ASL takes care of clearing bit 0.

mov [`@INSTANCE_NAME`_bStatus],0x00 `@CTAB55`; Clear all flags

tst [x+TxMode],`@INSTANCE_NAME`_RepStart

jnz DoRestartTx

call I2C_DoStart ; Send a start and address.

jmp DoTxAck

DoRestartTx:

call I2C_DoRepeatStart ; Send a repeat start and address.

DoTxAck:

mov [`@INSTANCE_NAME`_bXferCnt],0x00 `@CTAB55`; Zero out byte count first

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed `@CTAB55`; Test to see if Slave ACKed

jz End_WR_Loop

WR_Loop: ; Loop through bytes

push x ; Save X for later

mov x,[x+TxArray] ; Get pointer to data and put it in X

mov a,[x] ; Get data pointer to by X

August 29, 2003 Document No. 001-35979 Rev. ** 11

[+] Feedback [+] Feedback

Page 12: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

mov [`@INSTANCE_NAME`_bData],a `@CTAB55`; Save data in temp location

call `@INSTANCE_NAME`_write `@CTAB55`; Write the data

pop x

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed

jz DoWBstop ; Stop transfer if NAKed

inc [`@INSTANCE_NAME`_bXferCnt] `@CTAB55`; Increment transfer byte count

inc [x+TxArray] ; Advance pointer

dec [x+TxByteCount] ; Decrement byte counter

jnz WR_Loop ; Not finished, do another byte.

End_WR_Loop: ; Endloop

tst [x+TxMode],`@INSTANCE_NAME`_NoStop

jnz SkipTxStop

DoWBstop:

call `@INSTANCE_NAME`_SendStop

SkipTxStop:

mov a,[`@INSTANCE_NAME`_bXferCnt] `@CTAB55`; Return bytes transfered

End_WriteBytes:

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_bWriteCBytes

;

; DESCRIPTION: Write multiple data bits to slave device from ROM

;

; ARGUMENTS: A => Address of slave

; X => Pointer to other arguments.

; [x] => LSB of ROM Array address to put data in.

; [X-1] => MSB of ROM Array address to put data in (ignorned)

; [X-2] => Count of bytes to write.

; [X-3] => Mode flags that allow the programmer to set flags

; to determine if:

; 0x01 => Use RepeatStart instead of Start

; 0x02 => Don't send Stop

;

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

August 29, 2003 Document No. 001-35979 Rev. ** 12

[+] Feedback [+] Feedback

Page 13: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

;

; THEORY of OPERATION:

;

;-----------------------------------------------------------------------------

TxCArrayLSB: equ 0

TxCArrayMSB: equ -1

TxCByteCount: equ -2

TxCMode: equ -3

`@INSTANCE_NAME`_bWriteCBytes:

_`@INSTANCE_NAME`_bWriteCBytes:

asl A ; Shift address to the left to make

; a complete byte with the R/W bit.

; The ASL takes care of clearing bit 0.

mov [`@INSTANCE_NAME`_bStatus],0x00 `@CTAB55`; Clear all flags

tst [x+TxMode],`@INSTANCE_NAME`_RepStart `@CTAB55`; Check if a Start or RepeatStart

jnz DoCRestartTx ; should executed.

call I2C_DoStart ; Send a start and address.

jmp DoCTxAck

DoCRestartTx:

call I2C_DoRepeatStart ; Send a repeat start and address.

DoCTxAck: ; Test to see if Slave is ACKed

mov [`@INSTANCE_NAME`_bXferCnt],0x00 ; Zero out byte count first

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed

jz End_WRC_Loop

WRC_Loop: ; Loop through bytes

push x ; Save X for later

mov a,[x+TxCArrayMSB] ; Get data pointer to by X

mov x,[x+TxCArrayLSB] ; Get pointer to data and put it in X

romx ; Put ROM Data in a

mov [`@INSTANCE_NAME`_bData],a `@CTAB55`; Save data in temp location

call `@INSTANCE_NAME`_write `@CTAB55`; Write the data

pop x

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed

jz DoWCBstop ; Stop transfer if NAKed

inc [`@INSTANCE_NAME`_bXferCnt] `@CTAB55`; Increment transfer byte count

inc [x+TxCArrayLSB] ; Advance LSB of pointer

jnc DecBCnt

August 29, 2003 Document No. 001-35979 Rev. ** 13

[+] Feedback [+] Feedback

Page 14: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

inc [x+TxCArrayMSB] ; Advance MSB of pointer

DecBCnt:

dec [x+TxCByteCount] ; Decrement byte counter

jnz WRC_Loop ; Not finished, do another byte.

End_WRC_Loop: ; Endloop

tst [x+TxCMode],`@INSTANCE_NAME`_NoStop

jnz SkipTxCStop

DoWCBstop:

call `@INSTANCE_NAME`_SendStop

SkipTxCStop:

mov a,[`@INSTANCE_NAME`_bXferCnt] `@CTAB55`; Return bytes transfered

End_WriteCBytes:

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_fSendRepeatStart

;

; DESCRIPTION: Send repeated start condition and send slave address.

;

; ARGUMENTS: `@INSTANCE_NAME`_bAddr - Contains the slave address and transfer direction.

;

; RETURNS: `@INSTANCE_NAME`_bSTatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: prepare to send start by setting SCl and SDA high.

; must be followed directly by `@INSTANCE_NAME`_start.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_fSendRepeatStart:

_`@INSTANCE_NAME`_fSendRepeatStart:

asl a ; Shift address to the left

dec x ; If zero, C flag will be set

jc I2C_DoRepeatStart ; Do a write if zero

or a,0x01 ; Set Read flag

I2C_DoRepeatStart:

August 29, 2003 Document No. 001-35979 Rev. ** 14

[+] Feedback [+] Feedback

Page 15: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

push a

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

; Delay 3/4 period

mov A,`@INSTANCE_NAME`_delay3qtr

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch1: ; Wait for SCL high in case of wait

; states adde by slave

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch1

mov A,`@INSTANCE_NAME`_delay3qtr `@CTAB60`; Delay 1/2 period

call `@INSTANCE_NAME`_delay

pop a

jmp I2C_DoStart ; Jump through to I2C_DoStart

August 29, 2003 Document No. 001-35979 Rev. ** 15

[+] Feedback [+] Feedback

Page 16: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_fSendStart

;

; DESCRIPTION: Generates start condition and sends slave address.

;

; ARGUMENTS: A => Contains the slave address.

;

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: Send start by setting SDA low while SCL is high. Set

; SCL low in preparation to send address. Must be followed

; by `@INSTANCE_NAME`_write.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_fSendStart:

_`@INSTANCE_NAME`_fSendStart:

asl a ; Shift address to the left

dec x ; If zero, C flag will be set

jc I2C_DoStart ; Do a write if zero

or a,0x01 ; Set Read flag

I2C_DoStart:

push A ; Save the slave address

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Assert SDA low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB65`; Assert SDA low

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

mov A,`@INSTANCE_NAME`_delayhalf `@CTAB65`; Delay 1/2 period

call `@INSTANCE_NAME`_delay

August 29, 2003 Document No. 001-35979 Rev. ** 16

[+] Feedback [+] Feedback

Page 17: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

pop A ; Restore slave address to A

mov [`@INSTANCE_NAME`_bData],A

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB65`; Set SCL low

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

mov A,`@INSTANCE_NAME`_delayqtr `@CTAB65`; Delay 1/4 period

call `@INSTANCE_NAME`_delay

jmp `@INSTANCE_NAME`_write `@CTAB65`; Write the byte.

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_fWrite

;

; DESCRIPTION: Writes a byte to the I2C master bus.

;

; ARGUMENTS: Reg A contains Data

;

; RETURNS: 1 If ACKed, else 0

;

; SIDE EFFECTS: none.

;

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

;

; FUNCTION NAME: `@INSTANCE_NAME`_write

;

; DESCRIPTION: Writes a byte to the I2C master bus. Also used for sending the address.

;

; ARGUMENTS: Reg A contains slave address.

; `@INSTANCE_NAME`_bData - Contains data to be transmitted.

;

; RETURNS: `@INSTANCE_NAME`_bStatus - Cleared if a slave responds to a request. Set otherwise

;

; SIDE EFFECTS: none.

August 29, 2003 Document No. 001-35979 Rev. ** 17

[+] Feedback [+] Feedback

Page 18: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

;

; THEORY of OPERATION: Send data byte to slave. Must be followed by `@INSTANCE_NAME`_get_ack.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_fWrite:

_`@INSTANCE_NAME`_fWrite:

mov [`@INSTANCE_NAME`_bData],A `@CTAB60`; Put data in bData

`@INSTANCE_NAME`_write:

_`@INSTANCE_NAME`_write:

mov [`@INSTANCE_NAME`_bit_count],8 `@CTAB60` ; Set up count to xmit 8 bits

writenextbit:

dec [`@INSTANCE_NAME`_bit_count]

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1

; Assert SCL low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

rlc [`@INSTANCE_NAME`_bData]

jc write_bit ; Assert SDA low for data 0

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Assert SDA low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

jmp writestartclock

August 29, 2003 Document No. 001-35979 Rev. ** 18

[+] Feedback [+] Feedback

Page 19: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

write_bit: ; Release SDA high for data 1

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin `

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

writestartclock:

mov A,`@INSTANCE_NAME`_delayhalf `@CTAB60`; Delay 1/2 period

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL High

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch2: ; Wait for SCL high in case of wait states

; are added by slave.

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch2

IF `@Pullup`

ELSE

M8C_SetBank1

ENDIF

; Delay for 1/2 period

mov A,`@INSTANCE_NAME`_delayhalf

call `@INSTANCE_NAME`_delay

cmp [`@INSTANCE_NAME`_bit_count],0

August 29, 2003 Document No. 001-35979 Rev. ** 19

[+] Feedback [+] Feedback

Page 20: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

jnz writenextbit

; jmp `@INSTANCE_NAME`_get_ack `@CTAB60`; This jump is not required since it falls

; through to `@INSTANCE_NAME`_get_ack

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_get_ack

;

; DESCRIPTION: Get slave acknowledge response. Used only by `@INSTANCE_NAME`_write.

;

; ARGUMENTS: `@INSTANCE_NAME`_bData - Contains data to be transmitted.

;

; RETURNS: Sets flag in `@INSTANCE_NAME`_bStatus if ACKed by Slave.

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: Do the ack clock and check for Slave ACK

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_get_ack:

_`@INSTANCE_NAME`_get_ack:

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

; Release SDA high so slave may ACK

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Assert SCL low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

; Release SDA high so slave may ACK

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

August 29, 2003 Document No. 001-35979 Rev. ** 20

[+] Feedback [+] Feedback

Page 21: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

; Delay 3/4 period

mov A,`@INSTANCE_NAME`_delay3qtr

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch3: ; Wait for SCL to go high in case wait states

; are added my slave.

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch3

; Clear ACK bit

and [`@INSTANCE_NAME`_bStatus],~`@INSTANCE_NAME`_SLAVE_ACKed

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SDA_pin

jnz getack2 ; If ACKed, set flag

or [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SLAVE_ACKed

getack2:

mov A,`@INSTANCE_NAME`_delayhalf `@CTAB60`; Delay 1/2 period

call `@INSTANCE_NAME`_delay

mov A,[`@INSTANCE_NAME`_bStatus] `@CTAB60`; Get result and put it in A

and A,`@INSTANCE_NAME`_SLAVE_ACKed `@CTAB60`; Mask off just the ACK flag.

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_read

;

; DESCRIPTION: Reads 1 data byte from the I2C master bus.

;

August 29, 2003 Document No. 001-35979 Rev. ** 21

[+] Feedback [+] Feedback

Page 22: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

; ARGUMENTS: Reg A Contains the Slave Address.

; `@INSTANCE_NAME`_bStatus - Set for no ack to be followed by stop.

; Clear for ack to indicate more data to follow.

;

; RETURNS: `@INSTANCE_NAME`_bData - Contains received data.

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: Must be followed by `@INSTANCE_NAME`_put_ack.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_bRead:

_`@INSTANCE_NAME`_bRead:

mov [`@INSTANCE_NAME`_bStatus],0x00 `@CTAB60`; Clear ACK flag

and A,0xFF ; Is Ack flag set"

jz `@INSTANCE_NAME`_read `@CTAB60`; Don't ACK

or [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SEND_ACK `@CTAB60`; Set ACK flag

`@INSTANCE_NAME`_read:

_`@INSTANCE_NAME`_read:

mov [`@INSTANCE_NAME`_bit_count],8 `@CTAB60`; Count and prepare bits to read

readnextbit:

dec [`@INSTANCE_NAME`_bit_count]

rlc [`@INSTANCE_NAME`_bData]

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1 ; Asser SCL low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

; Delay 1/2 period

mov A,`@INSTANCE_NAME`_delayhalf

call `@INSTANCE_NAME`_delay

IF `@Pullup`

August 29, 2003 Document No. 001-35979 Rev. ** 22

[+] Feedback [+] Feedback

Page 23: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch4: ; Wait for SCL to go high in case slave

; addes wait states.

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch4

; Delay 1/4 period

mov A,`@INSTANCE_NAME`_delayqtr

call `@INSTANCE_NAME`_delay

and [`@INSTANCE_NAME`_bData],~01h `@CTAB60`; Record bit received

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SDA_pin

jz readnobit

or [`@INSTANCE_NAME`_bData],01h

readnobit:

cmp [`@INSTANCE_NAME`_bit_count],0

jnz readnextbit ; Check for byte complete

; jmp `@INSTANCE_NAME`_put_ack `@CTAB60`; This jump is not required since it falls

; through to `@INSTANCE_NAME`_put_ack.

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_put_ack

;

; DESCRIPTION: Send acknowledge to slave. Used only by `@INSTANCE_NAME`_read

;

; ARGUMENTS: `@INSTANCE_NAME`_bStatus - Set for no ack to be followed by stop. Clear for ack

; to indicate more data to follow.

August 29, 2003 Document No. 001-35979 Rev. ** 23

[+] Feedback [+] Feedback

Page 24: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

;

; RETURNS: `@INSTANCE_NAME`_bData - Contains received data.

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: Send ack if more data will follow.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_put_ack:

_`@INSTANCE_NAME`_put_ack:

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1 ; Assert SCL low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

; Check if ack is to be transmitted

tst [`@INSTANCE_NAME`_bStatus],`@INSTANCE_NAME`_SEND_ACK

jz noputack

; Assert SDA low

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Assert SDA low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

jmp putack1

noputack: ; Release SDA high

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

August 29, 2003 Document No. 001-35979 Rev. ** 24

[+] Feedback [+] Feedback

Page 25: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

ELSE

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

ENDIF

putack1:

mov A,`@INSTANCE_NAME`_delayqtr `@CTAB60`; Delay 1/4 period

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch5: ; Wait for SCL high in case slave

; adds wait states.

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch5

; delay for the high half of the clock.

mov A,`@INSTANCE_NAME`_delayhalf `@CTAB60`; Delay 1/2 period

call `@INSTANCE_NAME`_delay

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Assert SCL low

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

; If there is another read pending

; must release SDA for slave

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

August 29, 2003 Document No. 001-35979 Rev. ** 25

[+] Feedback [+] Feedback

Page 26: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

ELSE

M8C_SetBank1 ; Assert SCL low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

; If there is another read pending

; must release SDA for slave

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

mov A, [`@INSTANCE_NAME`_bData]

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_SendStop

;

; DESCRIPTION: Assert stop condition.

;

; ARGUMENTS: none

;

; RETURNS: none

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: Send stop by releasing SDA high while SCL high.ASA21CR1

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_SendStop:

_`@INSTANCE_NAME`_SendStop:

IF `@Pullup`

and [`@I2C_Port_Data_SHADE`],~(`@INSTANCE_NAME`_SDA_pin|`@INSTANCE_NAME`_SCL_pin)

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1 ; Assert ACK and SDA low

or [`@I2C_Port_DriveMode_0_SHADE`],`@INSTANCE_NAME`_SCL_pin|`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

August 29, 2003 Document No. 001-35979 Rev. ** 26

[+] Feedback [+] Feedback

Page 27: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

ENDIF

mov A,`@INSTANCE_NAME`_delay3qtr `@CTAB60`; Delay 3/4 period

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SCL_pin `@CTAB60`; Release SCL high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

; Release SCL high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SCL_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

clockstretch6: ; Wait for SCL to go high in case slave

; has added wait states.

tst reg[`@INSTANCE_NAME`_I2CPRTDR],`@INSTANCE_NAME`_SCL_pin

jz clockstretch6

mov A,`@INSTANCE_NAME`_delay3qtr `@CTAB60`; Delay 3/4 period

call `@INSTANCE_NAME`_delay

IF `@Pullup`

or [`@I2C_Port_Data_SHADE`],`@INSTANCE_NAME`_SDA_pin `@CTAB60`; Release SDA high

mov A,[`@I2C_Port_Data_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDR],A

ELSE

M8C_SetBank1

; Release SDA high

and [`@I2C_Port_DriveMode_0_SHADE`],~`@INSTANCE_NAME`_SDA_pin

mov A,[`@I2C_Port_DriveMode_0_SHADE`]

mov reg[`@INSTANCE_NAME`_I2CPRTDM0],A

M8C_SetBank0

ENDIF

mov A,`@INSTANCE_NAME`_delayhalf `@CTAB60`; Delay 1/2 period

August 29, 2003 Document No. 001-35979 Rev. ** 27

[+] Feedback [+] Feedback

Page 28: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

call `@INSTANCE_NAME`_delay

ret

;-----------------------------------------------------------------------------

; FUNCTION NAME: `@INSTANCE_NAME`_delay

;

; DESCRIPTION: create delays for `@INSTANCE_NAME` routines.

;

; ARGUMENTS: none

;

; RETURNS: none

;

; SIDE EFFECTS: none.

;

; THEORY of OPERATION: none.

;

;-----------------------------------------------------------------------------

`@INSTANCE_NAME`_delay: `@CTAB50`; 11 cycles for call. 32 total.

`@INSTANCE_NAME`delay1: `@CTAB50`; Delay 1/4 period at 100 kHz

dec A ; 4 cycles

jnz `@INSTANCE_NAME`delay1 `@CTAB50`; 5 cycles for jump, 4 no jump.

ret ; 8 cycles

;end of file

August 29, 2003 Document No. 001-35979 Rev. ** 28

[+] Feedback [+] Feedback

Page 29: Communication - Using PSoC Internal Resistors for I2C ...application-notes.digchip.com/011/11-14135.pdf · PSoC Device Family Data Sheet). For a 5 V system with 8 kΩ pull-up resistors,

0BAN2121

August 29, 2003 Document No. 001-35979 Rev. ** 29

About the Author Name: Jason A. Goldstein

Title: Proprietor Background: Jason has a B.S. in Physics from Carnegie

Mellon University and an M.S. in Electrical Engineering from Northeastern University. He is the founder of Agitation Engines, a company based in Brookline Massachusetts. Agitation Engines provides critical thinking, design services and intellectual property at all stages of product development.

Contact: [email protected] www.agitationengines.com Agitation Engines 76 Parkman St. #1 Brookline, MA 02446 USA 617.278.9914

In March of 2007, Cypress recataloged all of its Application Notes using a new documentation number and revision code. This new documentation number and revision code (001-xxxxx, beginning with rev. **), located in the footer of the document, will be used in all subsequent revisions.

PSoC is a registered trademark of Cypress Semiconductor Corp. "Programmable System-on-Chip," PSoC Designer, and PSoC Express are trademarks of Cypress Semiconductor Corp. All other trademarks or registered trademarks referenced herein are the property of their respective owners.

Purchase of I2C components from Cypress or one of its sublicensed Associated Companies conveys a license under the Philips I2C Patent Rights to use these components in an I2C system, provided that the system conforms to the I2C Standard Specification as defined by Philips.

Cypress Semiconductor 198 Champion Court

San Jose, CA 95134-1709 Phone: 408-943-2600

Fax: 408-943-4730 http://www.cypress.com/

© Cypress Semiconductor Corporation, 2003-2007. The information contained herein is subject to change without notice. Cypress Semiconductor Corporation assumes no responsibility for the use of any circuitry other than circuitry embodied in a Cypress product. Nor does it convey or imply any license under patent or other rights. Cypress products are not warranted nor intended to be used for medical, life support, life saving, critical control or safety applications, unless pursuant to an express written agreement with Cypress. Furthermore, Cypress does not authorize its products for use as critical components in life-support systems where a malfunction or failure may reasonably be expected to result in significant injury to the user. The inclusion of Cypress products in life-support systems application implies that the manufacturer assumes all risk of such use and in doing so indemnifies Cypress against all charges.

This Source Code (software and/or firmware) is owned by Cypress Semiconductor Corporation (Cypress) and is protected by and subject to worldwide patent protection (United States and foreign), United States copyright laws and international treaty provisions. Cypress hereby grants to licensee a personal, non-exclusive, non-transferable license to copy, use, modify, create derivative works of, and compile the Cypress Source Code and derivative works for the sole purpose of creating custom software and or firmware in support of licensee product to be used only in conjunction with a Cypress integrated circuit as specified in the applicable agreement. Any reproduction, modification, translation, compilation, or representation of this Source Code except as specified above is prohibited without the express written permission of Cypress.

Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes without further notice to the materials described herein. Cypress does not assume any liability arising out of the application or use of any product or circuit described herein. Cypress does not authorize its products for use as critical components in life-support systems where a malfunction or failure may reasonably be expected to result in significant injury to the user. The inclusion of Cypress’ product in a life-support systems application implies that the manufacturer assumes all risk of such use and in doing so indemnifies Cypress against all charges.

Use may be limited by and subject to the applicable Cypress software license agreement.

[+] Feedback [+] Feedback