AN-1367: I2C Interface Between the ADE7953 and the ADuCM360 (Rev. 0) PDF

AN-1367
APPLICATION NOTE
One Technology Way • P.O. Box 9106 • Norwood, MA 02062-9106, U.S.A. • Tel: 781.329.4700 • Fax: 781.461.3113 • www.analog.com
I2C Interface Between the ADE7953 and the ADuCM360
by Fermi Lim, Daniel Kim, and Hariharan Mani
INTRODUCTION
This application note demonstrates the implementation of an I2C
interface between the ADE7953 (the slave) and the ADuCM360
(the master), using C programming language. The ADE7953 is
a single-phase energy metering IC, and the ADuCM360 is an
ARM® Cortex®-M3-based microcontroller. The ADE7953
contains registers that are 8, 16, 24, or 32 bits long. While
writing the source code, it is important to make sure that the
data size for the read/write operation is identified based on the
address of the register. The register list in the ADE7953 data
sheet contains all the relevant information.
This application note introduces the ARM Cortex-M3 core and
the ADuCM360 microcontroller unit (MCU), followed by the
initialization steps that need to be completed within the
ADuCM360, and finally the implementation of the I2C interface
between the ADE7953 and the ADuCM360. The sample codes
described in this application note can also be used for other
Analog Devices, Inc., processors that are based on the ARM
Cortex-M core.
The complete source code for establishing the I2C interface is
available as a downloadable file, AN_1367_I2C_interface.zip, at
www.analog.com/ADE7953 or www.analogcom/ADuCM360.
I2C
To validate the source code, the following equipment and
software were used:





ADE7953 and ADuCM360 evaluation module boards
(EVMs)
Software development environment: Keil MDK-ARM
Version 4.72
Terminal emulator: Tera Term Version 4.79
IDE: Visual C++ 2012
Laptop personal computer (PC)
The entire lab setup is shown in Figure 1. The two evaluation
boards are connected with the help of wires, as shown in
Figure 2. Because an isolation interface was not considered for
this setup, both boards are powered by a common supply
voltage and share a common ground. If isolating the I2C interface,
the propagation delay of the isolators must be taken into
account.
EVAL-ADuCM360
1, 2, 3, OR 4 BYTES
INTERNAL REGISTER ACCESS
USB TO UART
(Cortex-M3)
13338-001
EVAL-ADE7953
This application note describes how to implement the source
code in the Visual C++ 2012 integrated development
environment (IDE), and provides useful insight regarding the
I2C communication ports of the ADE7953 and the ADuCM360.
Figure 1. Lab Setup
Rev. 0 | Page 1 of 15
AN-1367
Application Note
TABLE OF CONTENTS
Introduction ...................................................................................... 1
Initializing the ADuCM360 for UART and I2C.............................8
Revision History ............................................................................... 2
I2C Interface: ADuCM360 and ADE7953 ................................... 10
Setup Description ............................................................................. 3
Simulating an Embedded C Code Using Visual C++ ........... 12
ARM Cortex-M3 Core and ADuCM360 MCU ........................... 5
Conclusion....................................................................................... 15
REVISION HISTORY
9/15—Revision 0: Initial Version
Rev. 0 | Page 2 of 15
Application Note
AN-1367
SETUP DESCRIPTION
The terminal emulator software, Tera Term Version 4.79, is
used to read from or write to any of the ADE7953 registers
through the ADuCM360. The universal asynchronous
receiver/transmitter (UART) communication interface is used
between the ADuCM360 and the PC to send and receive the
read/write commands and data. The Tera Term Version 4.79
software, including examples of complete source code for the
UART interface-based communication, is available for free
from various sources, including the OSDN Corporation.
Figure 3 shows the terminal window where the get and set
commands of the example code are used to access the ADE7953
registers. The syntax for the two commands are
•
Set REG_ADDR value
The set command writes the register located at
Address REG_ADDR with a specific value.
Get START_REG_ADDR REGISTER_NUMBER
The get command reads the contents of the registers
starting from Address START_REG_ADDR continuously
starting from REGISTER_NUMBER. The number of
register locations to be read is determined by
REGISTER_NUMBER.
•
The uniqueness of the source code is that it allows the PC to
communicate with the ADE7953 even without the knowledge of
the data size of each of the registers, because the register lookup
table is already implemented.
CONNECTOR OF ADuCM360 EVM
DIGITAL PORT PINS
SDA
SCL
RESET
CONNECTOR OF ADE7953 EVM
GND
Figure 2. Connection Between ADuCM360 EVM and ADE7953 EVM
Rev. 0 | Page 3 of 15
13338-002
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
VDD
ZX_ISO
MOSI_ISO
RESET_ISO
CS_ISO
SCLK_ISO
TX_ISO
SDA_ISO
MCU_VDD
SCLK_ISO
IRQ_ISO
RX_ISO
ZX_I_ISO
MISO_ISO
REVP_ISO
NC15
NC16
NC17
VDDOUT
5VUSB
J1-24
J1-23
J1-22
J1-21
J1-20
J1-19
J1-18
J1-17
J1-16
J1-15
J1-14
J1-13
J1-12
J1-11
J1-10
J1-9
J1-8
J1-7
J1-6
J1-5
J1-4
J1-3
J1-2
J1-1
P7
RESET
P2.2/BM
P2.1
P2.0
P1.7
P1.6
P1.5
P1.4
P1.3
P1.2
P1.1/IRQ4
P1.0
P0.7/SOUT
P0.6/SIN
P0.5
P0.4
P0.3/SS1
P0.2/MOSI
P0.1/SCLK1
P0.0/MISO1
DVDD
AN-1367
Application Note
ADDRESSES OF ADE7953
13338-003
REGISTER VALUES OF ADE7953
13338-104
Figure 3. Terminal Window Showing the Use of Get Command
Figure 4. Terminal Window Showing the Use of Get and Set Commands
Rev. 0 | Page 4 of 15
Application Note
AN-1367
ARM CORTEX-M3 CORE AND ADUCM360 MCU
The ARM Cortex-M3 core is based on the ARMv7-M
architecture. The Cortex-M family is used primarily in the
embedded market, in applications requiring a core clock
frequency of less than 300 MHz. Most of the embedded
applications such as ac motor control and other simple home
appliances do not need any sophisticated features such as a
memory management unit (MMU) and NEON™, thus making
the Cortex-M family a good choice. The architecture of the
Cortex-M core is simpler than other Cortex families.
Cortex-M family of cores include the following unique features:
A fixed memory map
A common nested vectored interrupt controller (NVIC)
Thumb®-2 instruction set support only
The code written for one Cortex-M family MCU can be easily
modified to use with another Cortex-M family MCU, even if it
is from another vendor. Furthermore, ARM provides useful
Cortex Microcontroller Software Interface Standard (CMSIS)
software for various applications, for free.
Figure 5 compares a fixed memory map of the Cortex-M family
core with that of the ADuCM360.
As shown in Figure 5, the ADuCM360 includes 8 kB SRAM and
128 kB Flash/EE memory based on a fixed memory map for the
Cortex-M family. All of the ADuCM360 peripherals are mapped
into the 0x40000000 to 0x4004FFFF address range. The address
range of 0xE000E000 to 0xE000EE000 is for the Cortex-M core
memory mapped registers (MMRs); the 0x40000000 to
0x4004FFFF address range is for the ADuCM360 MMRs.
511MB
VENDOR SPECIFIC
MEMORY
0xE000EF00
0xE000E100
1MB PRIVATE
PERIPHERAL BUS
NVIC
1GB


The Cortex-M family of cores has only one core interrupt,
whereas older ARM cores have a fast interrupt as well as a
normal interrupt.
Two sets of registers are available: interrupt set enable
registers (ISERs) and interrupt clear enable registers
(ICERs).
Usually, peripherals such as UART and I2C have their own registers
to enable/disable the interrupts. Only one of the interrupts
transferred by each peripheral can reach the core according to
the ISER/ICER values. The ISERs are located in the 0xE000E100
to 0xE000E13C address range, and ICERs are located in the
0xE000E180 to 0xE000E1BC address range. When a Cortex-M
family MCU is used, modify ISERs and ICERs as needed. Of all
available IDE tools, Keil MDK-ARM and IAR Embedded
Workbench® are the most popular. Both these tools can be used
when the executable image is within the specified size
limitations. The Keil MDK-ARM IDE was used in the lab setup
for this application note. To use the code with the IAR
Embedded Workbench IDE, the ADuCM360StartUp.s file,
from the downloadable file, AN_1367_I2C_interface.zip, must
be changed. When changing the IDE from Keil MDK-ARM to
IAR Embedded Workbench, or vice versa, only the assembler
directives have to be modified and not the instructions, because
the assembler directives depend on the assembler being used
and the instruction set depends on the MCU core.
0xFFFFFFFF
0xE0100000
0xE00FFFFF
0xE0000000
0xDFFFFFFF
ADuCM360
MEMORY MAP
MMRs
0xE000EE00
0xE000E000
EXTERNAL
DEVICE
0xA0000000
0x9FFFFFFF
1GB
EXTERNAL
RAM
0x34FFFFFF
0x42000000
BIT BAND ALIAS
32MB
0x400FFFFF
0x40000000
BIT BAND REGION
0x60000000
0x6FFFFFFF
0.5GB
0x23FFFFFF
0x22000000
0x40000000
0x3FFFFFFF
0.5GB
BIT BAND ALIAS
0x20000000
BIT BAND REGION
1MB
8kB SRAM
SRAM
32MB
0x200FFFFF
MMRs
PERIPHERALS
1MB
0x20000000
0x1FFFFFFF
0.5GB
CODE
0x00000000
KERNEL SPACE
128kB FLASH/
EE MEMORY
0x4004FFFF
0x40000000
0x20001FFF
0x20000000
0x000207FF
0x00020000
0x0001FFFF
0x0000E000
Figure 5. Memory Map Comparison Between Cortex-M and the ADuCM360
Rev. 0 | Page 5 of 15
13338-005



Note the following regarding the NVIC:
AN-1367
Application Note
Figure 8 shows the architecture of the ADuCM360. Among the
peripherals of the ADuCM360, only the I2C, UART, and GPIOs
are used to communicate with the ADE7953 and the PC.
Figure 6 and Figure 7 shows the tool chains of the Keil MDKARM and IAR Embedded Workbench IDE, respectively. In
Figure 6, armcc, armasm, and armlink are displayed in shaded
gray to indicate that they form the C/C++ compiler, assembler,
and linker, respectively. Similarly, in Figure 7, iccarm, iasmarm,
and ilinkarm are indicated in shaded gray to denote that they
are the compiler, assembler, and linker, respectively.
First, configure UART to communicate with PC, and then
configure the I2C to interface with the ADE7953.
Though the focus of this application note is the I2C interface,
the sample codes provided in the downloadable file,
AN_1367_I2C_interface.zip, have modules for UART interface
as well as GPIO usage.
LINEAR
ASSEMBLY
(*.s/*.asm)
C SOURCE FILES
(*.c)
LINKER SCRIPT
(*.sct)
C COMPILER
(armcc)
ASSEMBLER
(armasm)
LIBRARY BUILD
UTILITY
OBJECT FILES
(*.o)
OBJECT FILES
(*.o)
RUN-TIME SUPPORT
LIBRARY
(*.lib)
--scatter
CROSSREFERENCE
LISTER
(*.lst)
--list
IMAGE MAP FILE
(*.map)
--map
LINKER
(armlink)
EXECUTABLE IMAGE FILE
(*.axf/*.elf)
TARGET
BOARD
HEX CONVERSION UTILITY
(fromelf)
HEX FILES
(*.hex)
13338-006
DISASSEMBLED FILE --asm
(*.s)
Figure 6. Keil MDK-ARM Tool Chain
C SOURCE FILES
(*.c)
LINKER SCRIPT
(*.icf)
CROSSREFERENCE
LISTER
(*.lst)
IMAGE MAP FILE
(*.map)
C COMPILER
(iccarm)
ASSEMBLER
(iasmarm)
LIBRARY BUILD
UTILITY
OBJECT FILES
(*.o)
OBJECT FILES
(*.o)
RUN-TIME SUPPORT
LIBRARY
(*.a)
LINKER
(ilinkarm)
EXECUTABLE IMAGE FILE
(*.out)
TARGET
BOARD
HEX CONVERSION UTILITY
(ielftool)
HEX FILES
(*.hex)
Figure 7. IAR Embedded Workbench Tool Chain
Rev. 0 | Page 6 of 15
13338-107
DISASSEMBLED FILE
(*.s)
LINEAR
ASSEMBLY
(*.s/*.asm)
Application Note
DAC
AVDD
AGND
AN-1367
ON-CHIP
1.8V ANALOG
LDO
12-BIT
DAC
BUFFER
AMP
BUF
MOD2
GAIN
VREF
24-BIT
Σ-Δ ADC
Σ-Δ
MODULATOR
SINC3/
SINC4
FILTER
AIN6/IEXC
AIN8/EXTREF2IN–
AIN9/DACBUFF+
AIN10
AIN11/VBIAS1
POWER-ON
RESET
RESET
VBIAS
GENERATOR
AIN0
AIN1
AIN2
AIN3
AIN4/IEXC
AIN5/IEXC
AIN7/VBIAS0/IEXC/
EXTREF2IN+
ON-CHIP
1.8V DIGITAL
LDO
SINC2
FILTER
MUX
VREF
AMP
BUF
MOD2
GAIN
24-BIT
Σ-Δ ADC
SINC3/
SINC4
FILTER
Σ-Δ
MODULATOR
ON-CHIP
OSCILLATOR
(1% TYP)
16MHz
ARM
CORTEX-M3
PROCESSOR
16MHz
GPIO PORTS
UART PORTS
2 × SPI PORTS
I2C PORTS
MEMORY
128kB FLASH
8kB SRAM
TIMER0
TIMER1
WATCHDOG
WAKE-UP TIMER
PWM
DMA AND
INTERRUPT
CONTROLLER
SERIAL WIRE
DEBUG,
PROGRAMMING
AND DEBUG
SELECTABLE
VREF
SOURCES
DAC, TEMP,
IOVDD/4,
AVDD/4
XTALO
XTALI
19 GENERALPURPOSE
I/O PORTS
SWDIO
SWCLK
PRECISION
REFERENCE
ADuCM360
DVDD_REG
BUFFER
CURRENT
SOURCES
AVDD_REG
BUFFER
GND_SW
VREF– VREF+
INT_REF
Figure 8. ADuCM360 Block Diagram
Rev. 0 | Page 7 of 15
IOVDD
IOVDD
13338-007
IREF
AN-1367
Application Note
INITIALIZING THE ADUCM360 FOR UART AND I2C
I2CCLK. This is true for all peripherals whose clock can be
divided by CLKCON1. If the peripheral clock is slower, the
clock to the peripheral is gated and the peripheral does not
work. For more information, refer to the ADuCM360/
ADuCM361 Hardware User Guide.
When developing any embedded C code, first disable the
watchdog timer, and then configure the clock for the core and
peripherals as needed.
After any reset operation, the watchdog timer is enabled
automatically. To disable the watchdog timer of the
ADuCM360, write 0’b0 to T3CON[5], the watchdog timer
enable bit.
As shown in Figure 9, the UART interface with the PC is set up
with a baud rate of 115,200 bps. Therefore, configure the Tera
Term tool accordingly as well. Refer to the project file of Tera
Term named ‘MyTera_Setup2014.INI’, which is available from
the downloadable file, AN_1367_I2C_interface.zip.
// Step 1. Disable the watchdog timer.
*pT3CON=0x0;
Next, configure the clocks for the UART, I2C, and the Cortex-M3
core. Figure 9 and Figure 10 show how to configure the clocks
for the UART and I2C. Configure the core clock as 16 MHz, and
then set the control registers of the UART and the I2C interface
accordingly. When selecting the I2C system clock divide ratio
via CLKCON1, ensure that the core clock frequency is less than
or equal to that of the I2C system clock, that is, HCLK ≤
16MHz
CLKSYSDIV[0]
UCLK
16MHz
115200bps
CLKCON1[11:9]
16MHz
DISUARTCLK = 0
DIV2EN = 0
HOST
PC
CLKDIS[3]
UCLK/1 = 000
BAUDRATE =
UCLK/DIV/(2 × 16 × COMDIV)/(M + N/2048)
COMDIV = 2
UARTCLK = 16MHz
UCLK/DIV = UARTCLK
M = 2, N = 348
COMLCR = 0x0003
13338-008
HFOSC
To use the Tera Term project file, select the Restore setup
option from the Setup menu, as shown in Figure 11. Next,
select the MyTera_Setup2014.INI project file from the location
saved on the PC.
COMFBR = 0x915C
Figure 9. Clock Configuration for UART
16MHz
CLKSYSDIV[0]
UCLK
16MHz
DIV2EN = 0
100kHz
400kHz
SCL
CLKCON1[8:6] = 0
16MHz
DISI2CCLK = 0
UCLK/1 = 000
BAUDRATE =
UCLK/DIV/(2 × 16 × COMDIV)/(M + N/2048)
100kHz → I2CDIV = 0x4E4F
400kHz → I2CDIV = 0x1213
I2CCLK = 16MHz
UCLK/DIV = I2CCLK
Figure 10. Clock Configuration for I2C
13338-010
I2C
SLAVE
CLKDIS[2] = 0
Figure 11. Tera Term Configuration
Rev. 0 | Page 8 of 15
13338-009
HFOSC
Application Note
AN-1367
The following C code instructions, which are extracted from the
ADuCM360_I2C_AppNote.c file (from the downloadable file,
AN_1367_I2C_interface.zip), show how to configure the UART
interface. All the variables in the code denote MMRs related to
the clock, GPIOs, and UART.
// Step 2. Configure clocks.
// UART speed rate is 115,200 bps:
UCLK/DIV = 16 MHz.
Next, initialize the I2C peripheral of the ADuCM360. The
ADE7953 is always the slave and, therefore, the ADuCM360
must be configured as the master.
As a master, the I2C modes available in the ADuCM360 include
•
•
*pCLKDIS=0x03F7;
*pCLKSYSDIV=0x00;
*pCLKCON0=0x0000;
The generation method of SCL in standard mode is shown in
Figure 12.
*pCLKCON1=0x0000;
fI2CCLK = 16MHz
// Step 3. Set up the behavior of the
chosen UART.
*pCOMCON=0x00;
enabling.
Standard mode: 100 kHz
First set CLKSYSDIV[0] = 0, CLKCON1[8:6] = 000 and
then then set I2CDIV[15:8] = 0x4E, I2CDIV[7:0] = 0x4F
Fast mode: 400 kHz
First set CLKSYSDIV[0] = 0, CLKCON1[8:6] = 000 and
then set I2CDIV[15:8] = 0x12, I2CDIV[7:0] = 0x13
NEED_HIGH_TIME/fI2CCLK – 2
1
// UART peripheral is
15
I2CDIV
NEED_LOW_TIME/fI2CCLK – 1
8 7
0
HIGH
(0x4E)
LOW
(0x4F)
5µs
5µs
2
// P0.2 is UART Tx; P0.1 is UART Rx.
*pGP0CON=0x003C;
// COMDIV = 2;
*pCOMFBR=0x915C;
// Set to 115,200 bps
SCL
10µs = 100kHz
// WordLength = 8 bits, stop bit = 1 bit,
no parity check.
*pCOMLCR=0x0003;
// COMTX and COMRX are enabled; COMIEN[1]
= COMIEN[0] = 1
Figure 12. Generation Method of Standard 100 kHz SCL
As shown in Figure 10 and Figure 12, fI2CCLK is 16 MHz, and if
CLKSYSDIV[0] = 0 and CLKCON1[8:6] = 0 are initialized, the
SCL bit rate, fSCL, is calculated using the following formula:
f SCL =
*pCOMIEN=0x0003;
The interrupt enable register for the UART, COMIEN, is for UART
peripheral interrupts only (see the ADuCM360/ADuCM361
Hardware User Guide for more information). For the UART
transmitter (Tx)/receiver (Rx) interrupts to be transferred to
Cortex-M3 core, set the corresponding ISER, as follows:
// ISER = 0xE000E100; enabling UART
interrupt.
write_reg(0xE000E100,0x00020000);
It is important to differentiate between an interrupt and an
exception. An exception can be classified as synchronous or
asynchronous. Any system fault can generally be called a
synchronous exception, whereas an interrupt is an
asynchronous exception. The UART is located in the 17th
position in the interrupt vector table of the ADuCM360.
Therefore, to enable the UART interrupt, set the 0xE000E100
address location of the ISER as 0x00020000. Similarly, to enable
the I2C interrupts, set the ISER as follows:
OldRegVal=read_reg(0xE000E100);
RegVal = OldRegVal | 0x00200000; // for
I2C
write_reg(0xE000E100,RegVal);
0xE000E100;
//ISER =
13338-011
*pCOMDIV=0x0002;
f I 2CCLK
[Hz]
(Low + High + 3)
where:
Low is the low period of SCL, which is set by I2CDIV[7:0].
High is the high period of SCL, which is set by I2CDIV[15:8].
In standard mode, I2CDIV[7:0] is set as 0x4F (0d'78) and
I2CDIV[15:8] is set as 0x4E (0d’79). Using these values,
100 kHz is obtained as the SCL clock rate.
To use this code with Visual C++, the following piece of
instructions was added:
#ifdef FermiEmulation_Mode
//to initialize all of the ADuCM360
register set.
ADuCM360_RegsInit();
#endif
For more information about this sample code, see the I2C
Interface: ADuCM360 and ADE7953 section. This sample code
is based on the super loop architecture. Therefore, this code
style cannot handle multiple tasks. The use of menus via the
Tera Term tool allows any graphic user interface (GUI)
component to be implemented easily with Visual C++ or Visual
Basic. Most of factory automation systems use this approach.
Rev. 0 | Page 9 of 15
AN-1367
Application Note
I2C INTERFACE: ADUCM360 AND ADE7953
An I2C interface is implemented using two pins, SCL and SDA.
(Note that, throughout this section, multifunction pins, such as
P2.0/SCL/UARTCLK, are referred to by a single function, for
example, SCL, when only that function is relevant.)
•
The I2C interface of the ADuCM360 has a 2-byte Tx and Rx
FIFO scheme, as shown in Figure 13.
2
SCL: serial clock pin. Only the master can generate the I C
clock; SCL can be used in either standard mode or fast
mode.
SDA: serial data pin.
The core clock and peripheral clock are usually different. If data
in one clock domain is transferred into the other clock domain,
metastability can occur leading to error in communication. To
avoid metastability, it is common to use a FIFO or dual-port
RAM. Metastability cannot be resolved by the use of
combinational logic.
Both SCL and SDA are bidirectional and must be connected to
a positive supply voltage using a pull-up resistor. Although, SCL
is generated by the ADuCM360 in this case, in theory, it can be
bidirectional because the I2C interface of the ADuCM360 can
be set as a slave. The I2C interface of the ADE7953 can only be
used as a slave.
TXFSTA (I2CMSTA[1:0])
TXREQ (I2CMSTA[2])
I2CMTX
Note that the ADE7953 requires a minimum delay of 0.1 µs
between the SCL and SDA edges; see the tHD;DAT specification in
the data sheet. The ADE7953 data sheet also lists other timing
specifications that must be maintained.
FIFO
FIFO
8 BITS
8 BITS
FIFO
FIFO
IENTX (I2CMCON[5])
TSR
IENTX (I2CSCON[10])
I2CSTX
TXREQ (I2CSSTA[2])
TXFSEREQ (I2CSSTA[0])
Figure 14 shows a typical I2C transfer sequence.
I2C TRANSMIT PATH
The ADuCM360 has two I2C interfaces: one via the P0.1/
SCLK1/SCL/SIN and P0.2/MOSI1/SDA/SOUT pins and the
other via the P2.0/SCL/UARTCLK and P2.1/SDA/UARTDCD
pins. For this example, the P2.0/SCL/UARTCLK and
P2.1/SDA/UARTDCD pins are used.
RXREQ (I2CMSTA[3])
I2CMRX
FIFO
FIFO
8 BITS
8 BITS
FIFO
// P2.0/SCL/UARTCLK is used for SCL,
P2.1/SDA/UARTDCD is used for SDA.
IENRX (I2CMCON[4])
RSR
IENRX (I1CSCON[9])
FIFO
I2CSRX
RXREQ (I2CSSTA[3])
*pGP2CON |= 0x05;
// Master Enable, Tx/Rx Request Interrupt
Enable.
I2C RECEIVE PATH
13338-013
•
The I2C addressing type can be either 7-bit or 10-bit. Due to the
addressing type of the ADE7953, 7-bit addressing is used in this
case.
Figure 13. Datapath of I2C Tx/Rx
*pI2CMCON = 0x131;
Every slave has an address for I2C operation and a master can
identify a slave using this address, which is set by the vendor.
For example, the ADE7953 address is 0x38.
MSB
LSB
SLAVE ADDRESS
SCL
MSB
LSB
R/W
DATA
3 TO 6
1
START
BIT
2
2 TO 7
7
8
9
ACK
BIT
Figure 14. Typical I2C Transfer Sequence
Rev. 0 | Page 10 of 15
1
8
9
ACK
BIT
STOP
BIT
13338-012
SDA
Application Note
AN-1367
15
8 7
0
VALUE
(SLAVE ADDRESS R/W
RESERVED
MSB
I2CADR0
LSB
SDA
SLAVE ADDRESS
SCL
R/W
3 TO 6
2
7
8
9
START
BIT
13338-014
1
ACK
BIT
15
8
7
0
23
16
15
8
7
0
7
STOP
START
Figure 15. 7-Bit Addressing Mode
0
SLAVE ADDRESS
P
A
C
K
MSB OF REGISTER ADDRESS
A
C
K
A
C
K
LSB OF REGISTER ADDRESS
BYTE 3 (MSB) OF REGISTER
A
C
K
BYTE 2 OF REGISTER
A
C
K
BYTE 1 OF REGISTER
A
C
K
BYTE 0 (LSB) OF REGISTER
A
C
K
13338-015
READ/WRITE
S 0 1 1 1 0 0 0 0
ACK GENERATED BY
ADE7953
START
Figure 16. I2C Write Sequence of the ADE7953
15
0
1
1
1
0
0
0
SLAVE ADDRESS
8
7
0
0
A
A
A
C MSB OF REGISTER ADDRESS C LSB OF REGISTER ADDRESS C
K
K
K
READ/WRITE
S
ACK GENERATED BY
ADE7953
1
1
1
0
0
SLAVE ADDRESS
0
16
A
C 15
K
8
A
C
K
7
0
A
C
K
7
0
1
P
A
C
K
BYTE 3 (MSB)
OF REGISTER
BYTE 2 OF REGISTER
BYTE 1 OF REGISTER
BYTE 0 (LSB)
OF REGISTER
13338-016
0
READ/WRITE
S
23
STOP
START
ACK GENERATED BY
MASTER
ACK GENERATED BY
ADE7953
Figure 17. I2C Read Sequence of the ADE7953
Figure 15 shows how the master sends the 7-bit address
(Bits[7:1]) and the directional (read or write) bit (Bit 0) to the
slave.
The I2CADR0 register stores the slave address and the
directional bit.
The I2C interface of the ADE7953 operates at a maximum serial
clock frequency of 400 kHz.
The I2C write and read operations of the ADE7953 are shown in
Figure 16 and Figure 17, respectively.
The ADE7953 I2C address is 0b'0111000x, where x is a
directional bit. A 0 indicates a write, and a 1 indicates a read.
A write operation on the ADE7953 is initiated when the master
issues a 7-bit device address and the directional bit is set to 0
(that is, 0x70). It is then followed by the 16-bit address of an
internal register. Whenever each byte is received, the ADE7953
issues an acknowledge to the master. Following that, the master
sends the register data, MSB first. The length of this data can be
8, 16, 24, or 32 bits long, depending on the register. When
transmission of the final byte is complete, the master issues a
stop condition, and the bus returns to the idle condition.
Rev. 0 | Page 11 of 15
AN-1367
Application Note
When writing source code, it is essential to understand how the
I2C is implemented in the target device.
The following piece of code represents the ADE7953 I2C write
operation:
void I2C_Write_ADE7953(void)
{
int i=0;
assigned by the MMU of the operating system (OS). The virtual
addresses may change when the program is run. The Cortex-M
family microcontrollers do not include a MMU; therefore, a
MCU based on the Cortex-M core cannot be ported to, for
example, Windows® CE or Linux® OS, easily. To learn how to
use Visual C++ with embedded C code, refer to the Simulating
an Embedded C Code Using Visual C++ section.
SIMULATING AN EMBEDDED C CODE USING
VISUAL C++
if (((I2CMasterTxDat[0] >4) &&
(I2CMasterTxDat[0] <=
6))||((I2CMasterTxDat[0] >9))) {
After completing the entire C code in Visual C++, to make an
executable image for the ADuCM360, perform a rebuild in the
Keil MDK-ARM or IAR Embedded Workbench IDE. This
rebuild is possible because of the following C/C++ precompiler
directive in the sample code:
printf("The specified ADE7953
register address is out of range\n");
} else {
ReadFlag=0;
#ifdef FermiEmulation_Mode
uiMasterTxIndex = 0;
// to initialize all of the ADuCM360
register set.
// Master case : send 1st data.
*pI2CMTX =
I2CMasterTxDat[uiMasterTxIndex++];
ADuCM360_RegsInit();
#endif
I2cMWrCfg(0x70);
The following step by step procedure is useful to understand the
debugging process when using the Visual C++ 2012 debugger
tool. Note that the following method can be used with any
Visual Studio version.
while (!ucComplete){}
ucComplete = 0;
}
1.
}
Create a new project as shown in Figure 18.
The if condition in the preceding code is based on the ADE7953
address range. The MSB of the register address determines
whether the address is out of range. Refer the ADE7953 data
sheet and the ADE7953 Evaluation Board User Guide for more
information.
Whenever each byte is received, the ADE7953 issues an
acknowledgement to the master and the ADuCM360 generates
an I2C interrupt to invoke the I2C0_Master_Int_Handler
function found in the ADuCM360_Test_Lib.h file, which
changes the value of ucComplete in the preceding code. If the
ucComplete value is changed, I2C_Write_ADE7953() exits
from the while loop and continues to send a byte to the
ADE7953.
13338-017
The I2cMWrCfg(0x70) routine sends 0x01110000 (0x70) to the
ADE7953, as shown in Figure 15 and Figure 16.
Figure 18. Create New Project
2.
Select Empty Project as shown in Figure 19.
Use Visual C++ debugger to help with debugging when there
are bugs in the code, particularly while working on initial
projects or with new ICs. Using the Visual C++ debugger may
also help the user understand how a piece of code works.
Generally, the embedded code involves physical addresses but
Visual C++ can only interpret virtual addresses, which are
Rev. 0 | Page 12 of 15
13338-018
When writing to any of the ADE7953 registers, it is essential to
make sure that the length of the data matches the description of
the register. The same concept applies while reading back data
from the ADE7953 IC. The I2C0_Master_Int_Handler function
considers the register data length during both write and read
operations.
Figure 19. Select Empty Project
Application Note
Add all the sample files and existing items into the project, as
shown in Figure 20 and Figure 21.
5.
Select the folder that contains the sample codes under
C/C++. Click Additional Include Directories. Refer to
Figure 23 and Figure 24.
13338-022
3.
AN-1367
13338-019
Figure 23. Search for Sample Codes
13338-023
Figure 20. Add Sample Files
Figure 24. Select Folder with Visual Studio Sample Code
13338-020
6.
Figure 21. Add Existing Items
13338-024
Modify certain properties as shown in Figure 22 to Figure 25.
Figure 25. Define the Code
Compile and link all the sample codes under Visual C++,
as shown in Figure 26.
13338-025
7.
13338-021
4.
For Visual C++ compiler only, define
FermiEmulation_Mode, as shown in Figure 25.
This step predefines FermiEmulation_Mode based on
which Visual C++ code can be programmed to work with
the embedded C code.
When using other Visual Studio versions, the
corresponding options shown in Figure 22 to Figure 25
need to be searched in the menu options, but the
procedure is the same. Add _CRT_SECURE_NO_
WARNINGS only for .NET (see Figure 25).
Figure 22. Select Properties
Figure 26. Compile and Link all Sample Codes
As shown in Figure 26, there are no errors and warnings in the
code.
Rev. 0 | Page 13 of 15
AN-1367
Application Note
debugger is that the I2C0_Master_Int_Handler function and
the set/get commands can be analyzed easily.
Figure 27 shows how to simulate the embedded code using
Visual C++.
The following code of the I2C0_Master_Int_Handler function
is for synchronization:
#ifndef FermiEmulation_Mode
__asm{ nop}
__asm{ nop}
__asm{ nop}
__asm{ DSB}
__asm{ nop}
13338-026
__asm{ nop}
Figure 27. Simulate Embedded Code
To understand how Visual C++ works, analyze both
ADuCM360_Regs.c and ADuCM360_Regs.h carefully. These
files define real addresses related to the ADuCM360 and enable
the MMU to assign virtual addresses corresponding to the real
addresses so that Visual C++ can debug the files. Note that the
files can also be debugged by Keil MDK-ARM or IAR
Embedded Workbench. If debugging is done using Keil MDKARM or IAR Embedded Workbench, FermiEmulation_Mode
does not need to be used.
#endif
The printf function in the downloaded sample code is specially
developed to reduce code size when using Visual C++;
therefore, if the Keil MDK-ARM or IAR Embedded Workbench
runtime library is used, the code size may be larger. The
compact printf function can be found in the JongSuLib_V2.c
library file, which includes many other useful functions, such as
register read/write functions. One useful library file, named
ADuCM360_Test_Lib.c, includes functions to support
ADuCM360 peripherals such as I2C, SPI, UART, and
ADCs/DACs. These two general-purpose libraries can be
ported to other projects as well, as needed.
This debugging method is very simple and can be used on all
types of processors. The advantage of using Visual C++
Rev. 0 | Page 14 of 15
Application Note
AN-1367
CONCLUSION
This application note demonstrates how to implement I2C
C code to monitor and modify the registers of the ADE7953
using the ADuCM360. To develop any embedded code, it is
recommended that Visual C++ be used because coding and
debugging are very simple using this tool. Then use Keil MDKARM or IAR Embedded Workbench to compile and link the C
code to make an executable image without additional
modification.
I2C refers to a communications protocol originally developed by Philips Semiconductors (now NXP Semiconductors).
©2015 Analog Devices, Inc. All rights reserved. Trademarks and
registered trademarks are the property of their respective owners.
AN13338-0-9/15(0)
Rev. 0 | Page 15 of 15