Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with i2c code for lpc2138

Status
Not open for further replies.

adamarul

Junior Member level 3
Joined
Mar 26, 2009
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Chennai,India
Activity points
1,542
Hi All,
I am using lpc2138 as i2c master to read eight ADCs(AD7400) using a mux(PCA9548a).
After sending the slave address, i see only level high(NACK) in the SDA line instead of level 0(ACK).
Attached the code and simulator screenshot(image location: https://obrazki.elektroda.pl/3144481400_1406226026.png ) for your reference.the control remains in the statement "while(!(I2C1STAT == Status));" in the function "I2C_Send_Byte" as NACK is received(I2C1STAT = 0x20) instead of ACK(I2C1STAT = 0x18). Could you please suggest me if there any modification required.
Thanks in advance


Code C - [expand]
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// Header:    I2C interface
// File Name: I2c_Interface
// Date:     
 
 
 /*
   Device address
----------------
 
 |----SLAVE Address -----------|
 
 |0 | 1 | 0 | 0 | A2 | A1 | A0 | R/W-bar |
 
 |-Fixed--------|--Programmable-|
 
*/
 
 
 
#include<lpc213x.h>
  /* Master */
#define START                   0x08
#define REP_START               0x10
 
/* Master Transmitter */
#define MT_SLA_ACK              0x18
#define MT_SLA_NACK             0x20
#define MT_DATA_ACK             0x28
#define MT_DATA_NACK            0x30
#define MT_ARB_LOST             0x38
 
/* Master Receiver */
#define MR_ARB_LOST             0x38
#define MR_SLA_ACK              0x40
#define MR_SLA_NACK             0x48
#define MR_DATA_ACK             0x50
#define MR_DATA_NACK            0x58
 
/* Slave Transmitter */
#define ST_SLA_ACK              0xA8
#define ST_ARB_LOST_SLA_ACK     0xB0
#define ST_DATA_ACK             0xB8
#define ST_DATA_NACK            0xC0
#define ST_LAST_DATA            0xC8
 
/* Slave Receiver */
#define SR_SLA_ACK              0x60
#define SR_ARB_LOST_SLA_ACK     0x68
#define SR_GCALL_ACK            0x70
#define SR_ARB_LOST_GCALL_ACK   0x78
#define SR_DATA_ACK             0x80
#define SR_DATA_NACK            0x88
#define SR_GCALL_DATA_ACK       0x90
#define SR_GCALL_DATA_NACK      0x98
#define SR_STOP                 0xA0
 
/* Misc */
#define NO_INFO                 0xF8
#define BUS_ERROR               0x00
 
// bit defines
#define I2CON_AA            2
#define I2CON_SI            3
#define I2CON_STO           4
#define I2CON_STA           5
#define I2CON_I2EN          6
 
// defines and constants
#define TWCR_CMD_MASK       0x0F
#define TWSR_STATUS_MASK    0xF8
 
// return values
#define I2C_OK              0x00
#define I2C_ERROR           0x01
 
 
 
typedef enum
{
    I2C_IDLE = 0, I2C_BUSY = 1,
    I2C_MASTER_TX = 2, I2C_MASTER_RX = 3,
    I2C_SLAVE_TX = 4, I2C_SLAVE_RX = 5
} eI2CStateType;
 
// functions
//u32 init_i2c(void) ;
// Initialize I2C (TWI) interface
char I2C_Init(char bitrateKHz);
// Deinitialize I2C (TWI) interface
char I2C_DeInit(void);
 
// Set the I2C transaction bitrate (in KHz)
char I2CSetBitrate(char bitrateKHz);
 
// Set an I2C start condition 
char I2C_Start_Condition(void);
// Set an I2C stop condition 
char  I2C_Stop_Condition(void);
 
char I2C_Send_Byte(char , char );
char I2C_Receive_Byte(void);
 
char I2C_Master_Write(char *,char * );
char I2C_Master_Read(char *);
 
char I2C_Slave_Write(char *);
char I2C_Slave_Read(char *);
 
 
 
char bitrate_KHz=100;
  char Send_Cmd[2]={0xA0,0x00};
   char Send_Data[2]={1,'a'};
 
 
 
void Delay_Ms(unsigned int i)  
{
    i*=2728; 
    while(i--); 
}    
     
char I2C_Init(char bitrateKHz)
{
    //PINSEL0 |= 0X00000050;
    
    PINSEL0 |= 0X30C00000;
    IODIR0 = 0x4800;
//  PCONP |= 0x80000;
    I2C1CONCLR |= 0X6c;
    I2C1CONSET = 0X40; 
    I2CSetBitrate(bitrateKHz);
    return 0;   
}
 
char I2CSetBitrate(char bitrateKHz)
{
    unsigned int b;
    b=(20000/(bitrateKHz *2));
    //I2C0SCLL = b;
    //I2C0SCLH = b;
    I2C1SCLL = 50; // PCLK = 10MHz, I2C Speed = 100KHz
    I2C1SCLH = 50;
    return 0;
}
 
 
char  I2C_Start_Condition(void)
{
    I2C1CONSET = 0X60;//enable start condition in master tx mode
    while(!((I2C1CONSET & 0x08)==0x08));//checking for SI to go high 
    while(!(I2C1STAT == START));
    I2C1CONCLR = 0x00000028;//clearing SI and START 
    return 0;
}
 
char I2C_Stop_Condition(void)
{
    I2C1CONSET = 0X50;              // sending stop bit by making STO high
    while(!((I2C1CONSET & 0x10)==0x10));
    I2C1CONCLR = 0X08;
    return 0;
}
 
 
char I2C_Send_Byte(char data, char Status)
{
    I2C1DAT = data;//slave address and W bit loaded
    //Delay_Ms(1000);
    while(!(I2C1STAT == Status));//waiting for slave addr to be send 
    I2C1CONCLR = 0x28;//clearing SI
    return 0;
}
char I2C_Receive_Byte(void)
{
    char Rec_Data;
    while(!(I2C1STAT == MR_DATA_ACK));
    Rec_Data=I2C1DAT;
    I2C1CONCLR = 0X28;//clearing SI*/
    return Rec_Data;    
}
 
 
/*
    buffer  - Send device address, memory addr, length and data 
*/
char I2C_Master_Write(char* buffer,char* buffer2)
{
    unsigned char length,dat1=0xE0,dat2=0x06;
    I2C1CONSET = 0X40; 
    if((I2C_Start_Condition())!=0)
    return 1;
    
 
    if((I2C_Send_Byte(dat1,MT_SLA_ACK))!=0)
        return 1;
    //Delay_Ms (1000000);
    if((I2C_Send_Byte(dat2,MT_DATA_ACK))!=0)
    return 1;  
/*  length=*buffer++;
    do{
    if((I2C_Send_Byte(*buffer2++,MT_DATA_ACK))!=0)
    return 1;
    }while(--length);  */
    if((I2C_Stop_Condition())!=0)
    return 1;
    return 0;
}
 
 
char I2C_Master_Read(char *buffer)
{
    char *dat,length,i,a[100];
    char dat1 = 0xE1, dat2 = 0x03;
    I2C1CONSET = 0X60;//enable start bit in Master mode
    if((I2C_Start_Condition())!=0)
    return 1;
    if((I2C_Send_Byte(dat1,MT_SLA_ACK))!=0)
    return 1;
    if((I2C_Send_Byte(dat2,MT_DATA_ACK))!=0)
    return 1;
    if((I2C_Stop_Condition())!=0)
    return 1;
/* 
    length=  *buffer--;
    buffer--;
 
    I2C1CONSET = 0X44;//enable start bit in Master mode      
 
    if((I2C_Start_Condition())!=0)
    return 1;       
    if((I2C_Send_Byte((*buffer |0x01),MR_SLA_ACK))!=0)               //(*buffer |0x01)
    return 1;   
    for(i=0;i<length;i++)
    {
        if((a[i] =I2C_Receive_Byte())==0)
        return 1;
    }
    a[i]='\0';
 
    if((I2C_Stop_Condition())!=0)
    return 1;
    dat=a;
//return dat;*/
 return 0;
 
}
/*******************************************************
        EEPROM Write 
        Send_CMD send Slave address,Memory loc (i.e) 0xA0,0x00
        Send_Dat send Length and data (i.e) 1,'a'
 
        
 
*******************************************************/
  int main()
  {
   char  Send_Cmd = 0xe1,send = 0x01 ;
   I2C_Init(bitrate_KHz);
   I2C_Master_Write(&Send_Cmd,&send);
   I2C_Master_Read (&Send_Cmd);
   while(1)
   {
 
   }
  }

 
Last edited by a moderator:

Also, why is that the value set in the register I2CCONSET gets cleared during runtime., SI bit in particular ? Is this a hardware driven register ? that is., does this register value change based on any hardware event ?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top