i2c.c


1
#include "main.h"
2
#include "i2c.h"
3
4
//-------------------------------------------
5
// Definition of local constants
6
//-------------------------------------------
7
#define I2C_TIMEOUT  (0x1000)
8
9
//-------------------------------------------
10
// Declaration of local functions
11
//-------------------------------------------
12
static int I2C_check_dev(uint8_t addr);
13
static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr);
14
static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr);
15
static int I2C_stop(I2C_TypeDef* I2Cx);
16
static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
17
static int I2C_read_ack(I2C_TypeDef* I2Cx);
18
static int I2C_read_nack(I2C_TypeDef* I2Cx);
19
static int I2C_timeout(char *msg);
20
21
/*******************************************************************************
22
* Function Name  : I2C_BusInit
23
* Description    : Configure I2C-Bus
24
* Input          : None
25
* Output         : None
26
* Return         : None
27
* Attention       : None
28
*******************************************************************************/
29
void I2C_BusInit(void)
30
{                         
31
  GPIO_InitTypeDef GPIO_InitStructure;
32
  I2C_InitTypeDef  I2C_InitStructure;
33
  //NVIC_InitTypeDef NVIC_InitStructure;
34
  //=========================================================================================
35
  // Enable GPIO clock
36
  //-----------------------------------------------------------------------------------------
37
  RCC_AHB1PeriphClockCmd(Open_I2C_SCL_GPIO_CLK, ENABLE);
38
39
  //=========================================================================================
40
  // Enable I2C clock
41
  //-----------------------------------------------------------------------------------------
42
  RCC_APB1PeriphClockCmd(Open_I2C_CLK, ENABLE);
43
44
  //=========================================================================================
45
  //GPIO Alternate functions configuration
46
  //-----------------------------------------------------------------------------------------
47
  GPIO_PinAFConfig(Open_I2C_SCL_GPIO_PORT, Open_I2C_SCL_SOURCE, Open_I2C_SCL_AF);
48
  GPIO_PinAFConfig(Open_I2C_SDA_GPIO_PORT, Open_I2C_SDA_SOURCE, Open_I2C_SDA_AF);
49
50
  //=========================================================================================
51
  // Configure I2C GPIO
52
  //-----------------------------------------------------------------------------------------
53
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
54
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
55
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
56
  GPIO_InitStructure.GPIO_Pin = Open_I2C_SCL_PIN | Open_I2C_SDA_PIN;
57
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
58
  GPIO_Init(GPIOB, &GPIO_InitStructure);
59
60
  //=========================================================================================
61
  // Configure I2C Controller
62
  //-----------------------------------------------------------------------------------------
63
  I2C_InitStructure.I2C_ClockSpeed = I2C_SCL_SPEED;
64
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
65
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
66
  I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDR;
67
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
68
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
69
70
  //=========================================================================================
71
  // Enable I2C
72
  //-----------------------------------------------------------------------------------------
73
  I2C_Cmd(Open_I2C, ENABLE);
74
  I2C_Init(Open_I2C, &I2C_InitStructure);
75
76
  //=========================================================================================
77
  // Configure the SPI interrupt priority
78
  //-----------------------------------------------------------------------------------------
79
  /*
80
  NVIC_InitStructure.NVIC_IRQChannel = Open_I2C_IRQn;
81
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
82
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
83
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
84
  NVIC_Init(&NVIC_InitStructure);
85
  */
86
}
87
88
//===============================================================================
89
// I2C_ReadTransfer - initiate a read transfer on the I2C bus
90
//
91
// Initiates a read transfer on the I2C bus.
92
// If a register address is specified (<addressLength> != 0) a write without a stop
93
// condition will be initiated to the device to write the address, before the
94
// read is initiated.
95
// If no address if required (sequential read) <addressLength> is set to 0.
96
//-------------------------------------------------------------------------------
97
// u08 dev_addr  I2C device address
98
// u08 *buffer   pointer to the buffer to store the read data.
99
//               The buffer must be at least 'cnt' bytes long
100
// int cnt       number of bytes to read
101
// u32 ptr       register address, if required by the I2C-device
102
// u08 ptrlen    length of the register address to be written.
103
//               Valid values are 0..4
104
//-------------------------------------------------------------------------------
105
int I2C_ReadTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen)
106
{
107
  int i, rc = OK;
108
  //-----------------------------------------------------------------------------
109
  // parameter check
110
  //-----------------------------------------------------------------------------
111
  if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0))
112
  {
113
    return I2C_check_dev(dev_addr); // may be used to check if device is responding
114
  }
115
  //-----------------------------------------------------------------------------
116
  // write the register address pointer to the device
117
  //-----------------------------------------------------------------------------
118
  if (ptrlen > 0)
119
  {
120
    rc = I2C_start(Open_I2C, dev_addr, I2C_Direction_Transmitter);
121
    if (rc == OK)
122
    {
123
      for (i=1; i<=ptrlen; i++)
124
      {
125
        rc |= I2C_write(Open_I2C,((ptr >>(8*(ptrlen-i))) & 0xff));
126
      }
127
    }
128
  }
129
  //-----------------------------------------------------------------------------
130
  // read data from device
131
  //-----------------------------------------------------------------------------
132
  if ((cnt > 0) && (rc == OK))
133
  {
134
    if (ptrlen > 0)
135
    {
136
      rc |= I2C_restart(Open_I2C, dev_addr, I2C_Direction_Receiver);
137
    }
138
    else
139
    {
140
      rc |= I2C_start(Open_I2C, dev_addr, I2C_Direction_Receiver);
141
    }
142
    if (rc == OK)
143
    {
144
      while (--cnt>0)                         // while more than one byte to read
145
      {
146
        *(buffer++) = I2C_read_ack(Open_I2C); // read next databyte from I2C device
147
      }
148
      *(buffer) = I2C_read_nack(Open_I2C);    // read last databyte from I2C device
149
    }
150
  }
151
  //-----------------------------------------------------------------------------
152
  I2C_stop(Open_I2C);                         // stop the transmission
153
  return rc;
154
}
155
156
157
//===============================================================================
158
// I2C_WriteTransfer r- initiate a write transfer on the I2C bus
159
//
160
// Initiates a write transfer on the I2C bus.
161
// If a register address is supplied it is inserted between the I2C device address
162
// and the data.
163
//-------------------------------------------------------------------------------
164
// u08 dev_addr  I2C device address
165
// u08 *buffer   pointer to the buffer to store the read data.
166
//               The buffer must be at least 'cnt' bytes long
167
// int cnt       number of bytes to read
168
// u32 ptr       register address, if required by the I2C-device
169
// u08 ptrlen    length of the register address to be written.
170
//               Valid values are 0..4
171
//-------------------------------------------------------------------------------
172
int  I2C_WriteTransferuint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen)
173
{
174
  int i, rc=OK;
175
  //-----------------------------------------------------------------------------
176
  // parameter check
177
  //-----------------------------------------------------------------------------
178
  if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0))
179
  {
180
    return I2C_check_dev(dev_addr); // may be used to check if device is responding
181
  }
182
  //-----------------------------------------------------------------------------
183
  rc = I2C_start(Open_I2C, dev_addr, I2C_Direction_Transmitter);
184
  if (rc == OK)
185
  {
186
    //---------------------------------------------------------------------------
187
    // write the register address pointer to the device
188
    //---------------------------------------------------------------------------
189
    if (ptrlen > 0)
190
    {
191
      for (i=1; i<=ptrlen; i++)
192
      {
193
        rc |= I2C_write(Open_I2C,((ptr >>(8*(ptrlen-i))) & 0xff));
194
      }
195
    }
196
    //---------------------------------------------------------------------------
197
    // write data to the device
198
    //---------------------------------------------------------------------------
199
    for (i=0; i<cnt; i++)
200
    {
201
      rc |= I2C_write(Open_I2C,*(buffer++));
202
    }
203
  }
204
  //-----------------------------------------------------------------------------
205
  I2C_stop(Open_I2C);                // stop the transmission
206
  return rc;
207
}
208
209
210
//===============================================================================
211
// Check if a device is responding with acknowledge on the given I2C-Bus address
212
//-------------------------------------------------------------------------------
213
static int I2C_check_dev(uint8_t addr)
214
{
215
  int timeout;
216
  //-----------------------------------------------------------------------------
217
  timeout = I2C_TIMEOUT;
218
  while(I2C_GetFlagStatus(Open_I2C, I2C_FLAG_BUSY))
219
  {
220
    if((timeout--)==0)   // wait until I2C-Bus is not busy anymore
221
    {
222
      return ERROR;
223
    }
224
  }
225
  //-----------------------------------------------------------------------------
226
  I2C_GenerateSTART(Open_I2C, ENABLE);
227
  timeout = I2C_TIMEOUT;
228
  while(!I2C_CheckEvent(Open_I2C, I2C_EVENT_MASTER_MODE_SELECT))
229
  {
230
    if((timeout--)==0)  // wait while sending I2C-Bus START condition
231
    {
232
      I2C_GenerateSTOP(Open_I2C, ENABLE);
233
      return ERROR;
234
    }
235
  }
236
  //-----------------------------------------------------------------------------
237
  I2C_Send7bitAddress(Open_I2C, addr, I2C_Direction_Transmitter);
238
  timeout = I2C_TIMEOUT;
239
  while(!I2C_CheckEvent(Open_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
240
  {
241
    if((timeout--)==0)   // wait while sending slave address for write
242
    {
243
      I2C_GenerateSTOP(Open_I2C, ENABLE);
244
      return ERROR;
245
    }
246
  }
247
  //-----------------------------------------------------------------------------
248
  I2C_GenerateSTOP(Open_I2C, ENABLE);
249
  return OK;
250
}
251
252
//------------------------------------------------------------------
253
// This function issues a start condition and
254
// transmits the slave address + R/W bit
255
//
256
// Parameters:
257
//  I2Cx  --> the I2C peripheral e.g. I2C1
258
//  addr  --> the 7 bit slave address
259
//  rdwr  --> the tranmission direction can be:
260
//              I2C_Direction_Tranmitter for Master transmitter mode
261
//              I2C_Direction_Receiver for Master receiver
262
//------------------------------------------------------------------
263
static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr)
264
{
265
  uint32_t timeout = (100 * I2C_TIMEOUT);
266
  // wait until I2C1 is not busy anymore
267
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))
268
  {
269
    if((timeout--)==0) return I2C_timeout("I2C_start(): bus busy");
270
  }
271
  // Send I2C1 RESTART condition
272
  return I2C_restart(I2Cx, addr, rdwr);
273
}
274
275
//------------------------------------------------------------------
276
// This function issues a restart condition and
277
// transmits the slave address + R/W bit
278
//
279
// Parameters:
280
//  I2Cx  --> the I2C peripheral e.g. I2C1
281
//  addr  --> the 7 bit slave address
282
//  rdwr  --> the tranmission direction can be:
283
//              I2C_Direction_Tranmitter for Master transmitter mode
284
//              I2C_Direction_Receiver for Master receiver
285
//------------------------------------------------------------------
286
static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr)
287
{
288
  uint32_t timeout = I2C_TIMEOUT;
289
  // Send I2C1 START condition
290
  I2C_GenerateSTART(I2Cx, ENABLE);
291
  // wait for I2C1 EV5 --> Slave has acknowledged start condition
292
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
293
  {
294
    if((timeout--)==0) return I2C_timeout("I2C_start(): start failed");
295
  }
296
  // Send slave Address for read or write
297
  I2C_Send7bitAddress(I2Cx, addr, rdwr);
298
  //------------------------------------------------------------------------
299
  // wait for I2C1 EV6, check if Slave has acknowledged Master transmitter
300
  // or Master receiver mode, depending on the transmission direction
301
  //------------------------------------------------------------------------
302
  timeout = I2C_TIMEOUT;
303
  if (rdwr==I2C_Direction_Transmitter)
304
  {
305
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
306
    {
307
      if((timeout--)==0) return I2C_timeout("I2C_start(): no acknowledge");
308
    }
309
  }
310
  else if(rdwr==I2C_Direction_Receiver)
311
  {
312
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
313
    {
314
      if((timeout--)==0) return I2C_timeout("I2C_start(): no acknowledge");
315
    }
316
  }
317
  return 0;
318
}
319
320
//------------------------------------------------------------------
321
// This function transmits one byte to the slave device
322
// Parameters:
323
//    I2Cx --> the I2C peripheral e.g. I2C1
324
//    data --> the data byte to be transmitted
325
//------------------------------------------------------------------
326
static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
327
{
328
  uint32_t timeout = I2C_TIMEOUT;
329
  I2C_SendData(I2Cx, data);
330
  // wait for I2C1 EV8_2 --> byte has been transmitted
331
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
332
  {
333
    if((timeout--)==0) return I2C_timeout("I2C_write(): write byte failed");
334
  }
335
  return 0;
336
}
337
338
//------------------------------------------------------------------
339
// This function reads one byte from the slave device
340
// and acknowledges the byte (requests another byte)
341
//------------------------------------------------------------------
342
static int I2C_read_ack(I2C_TypeDef* I2Cx)
343
{
344
  uint32_t timeout = I2C_TIMEOUT;
345
  // enable acknowledge of recieved data
346
  I2C_AcknowledgeConfig(I2Cx, ENABLE);
347
  // wait until one byte has been received
348
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
349
  {
350
    if((timeout--)==0) return I2C_timeout("I2C_read_ack(): read byte failed");
351
  }
352
  // read data from I2C data register and return data byte
353
  return I2C_ReceiveData(I2Cx);
354
}
355
356
//------------------------------------------------------------------
357
// This function reads one byte from the slave device
358
// and doesn't acknowledge the recieved data
359
//------------------------------------------------------------------
360
static int I2C_read_nack(I2C_TypeDef* I2Cx)
361
{
362
  uint32_t timeout = I2C_TIMEOUT;
363
  // disabe acknowledge of received data
364
  I2C_AcknowledgeConfig(I2Cx, DISABLE);
365
  // wait until one byte has been received
366
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
367
  {
368
    if((timeout--)==0) return I2C_timeout("I2C_read_nack(): read byte failed");
369
  }
370
  // read data from I2C data register and return data byte
371
  return I2C_ReceiveData(I2Cx);
372
}
373
374
//------------------------------------------------------------------
375
// This funtion issues a stop condition and therefore
376
// releases the bus
377
//------------------------------------------------------------------
378
static int I2C_stop(I2C_TypeDef* I2Cx)
379
{
380
  // Send I2C1 STOP Condition
381
  I2C_GenerateSTOP(I2Cx, ENABLE);
382
  return 0;
383
}
384
385
static int I2C_timeout(char *msg)
386
{
387
  printf("TIMEOUT: %s\n",msg);
388
  return -1;
389
}
390
391
void I2C1_EV_IRQHandler(void)
392
{
393
  u32 event;
394
  event = I2C_GetLastEvent(I2C2);
395
  printf("I2C1_EV_IRQHandler(): Event=0x%08X\n",event);
396
  //---------------------------------------------------
397
  // todo, if I2C1 ISR mode shall be used
398
  //---------------------------------------------------
399
}
400
401
void I2C2_EV_IRQHandler(void)
402
{
403
  u32 event;
404
  event = I2C_GetLastEvent(I2C2);
405
  printf("I2C2_EV_IRQHandler(): Event=0x%08X\n",event);
406
  //---------------------------------------------------
407
  // todo, if I2C2 ISR mode shall be used
408
  //---------------------------------------------------
409
}