i2c.c


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