Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
i2c_arch.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (C) 2014 Freek van Tienen <freek.v.tienen@gmail.com>
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  */
23 
28 #include "mcu_periph/i2c.h"
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <sys/ioctl.h>
33 #include <linux/i2c.h>
34 #include <linux/i2c-dev.h>
35 #include <errno.h>
36 
37 void i2c_event(void)
38 {
39 }
40 
41 void i2c_setbitrate(struct i2c_periph *p __attribute__((unused)), int bitrate __attribute__((unused)))
42 {
43 }
44 
45 bool i2c_idle(struct i2c_periph *p __attribute__((unused)))
46 {
47  return true;
48 }
49 
50 #pragma GCC diagnostic push
51 #pragma GCC diagnostic ignored "-Wcast-qual"
52 bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
53 {
54  int file = (int)p->reg_addr;
55 
56  struct i2c_msg trx_msgs[2];
57  struct i2c_rdwr_ioctl_data trx_data = {
58  .msgs = trx_msgs,
59  .nmsgs = 2
60  };
61  // Switch the different transaction types
62  switch (t->type) {
63  // Just transmitting
64  case I2CTransTx:
65  // Set the slave address, converted to 7 bit
66  ioctl(file, I2C_SLAVE, t->slave_addr >> 1);
67  if (write(file, (uint8_t *)t->buf, t->len_w) < 0) {
68  /* if write failed, increment error counter queue_full_cnt */
69  p->errors->queue_full_cnt++;
70  t->status = I2CTransFailed;
71  return true;
72  }
73  break;
74  // Just reading
75  case I2CTransRx:
76  // Set the slave address, converted to 7 bit
77  ioctl(file, I2C_SLAVE, t->slave_addr >> 1);
78  if (read(file, (uint8_t *)t->buf, t->len_r) < 0) {
79  /* if read failed, increment error counter ack_fail_cnt */
80  p->errors->ack_fail_cnt++;
81  t->status = I2CTransFailed;
82  return true;
83  }
84  break;
85  // First Transmit and then read with repeated start
86  case I2CTransTxRx:
87  trx_msgs[0].addr = t->slave_addr >> 1;
88  trx_msgs[0].flags = 0; /* tx */
89  trx_msgs[0].len = t->len_w;
90  trx_msgs[0].buf = (void*) t->buf;
91  trx_msgs[1].addr = t->slave_addr >> 1;
92  trx_msgs[1].flags = I2C_M_RD;
93  trx_msgs[1].len = t->len_r;
94  trx_msgs[1].buf = (void*) t->buf;
95  if (ioctl(file, I2C_RDWR, &trx_data) < 0) {
96  /* if write/read failed, increment error counter miss_start_stop_cnt */
97  p->errors->miss_start_stop_cnt++;
98  t->status = I2CTransFailed;
99  return true;
100  }
101  break;
102  default:
103  break;
104  }
105 
106  // Successfull transfer
107  t->status = I2CTransSuccess;
108  return true;
109 }
110 #pragma GCC diagnostic pop
111 
112 
113 #if USE_I2C0
114 struct i2c_errors i2c0_errors;
115 
116 void i2c0_hw_init(void)
117 {
118  i2c0.reg_addr = (void *)open("/dev/i2c-0", O_RDWR);
119  i2c0.errors = &i2c0_errors;
120 
121  /* zeros error counter */
122  ZEROS_ERR_COUNTER(i2c0_errors);
123 }
124 #endif
125 
126 #if USE_I2C1
127 struct i2c_errors i2c1_errors;
128 
129 void i2c1_hw_init(void)
130 {
131  i2c1.reg_addr = (void *)open("/dev/i2c-1", O_RDWR);
132  i2c1.errors = &i2c1_errors;
133 
134  /* zeros error counter */
135  ZEROS_ERR_COUNTER(i2c1_errors);
136 }
137 #endif
138 
139 #if USE_I2C2
140 struct i2c_errors i2c2_errors;
141 
142 void i2c2_hw_init(void)
143 {
144  i2c2.reg_addr = (void *)open("/dev/i2c-2", O_RDWR);
145  i2c2.errors = &i2c2_errors;
146 
147  /* zeros error counter */
148  ZEROS_ERR_COUNTER(i2c2_errors);
149 }
150 #endif
151 
152 #if USE_I2C3
153 struct i2c_errors i2c3_errors;
154 
155 void i2c3_hw_init(void)
156 {
157  i2c3.reg_addr = (void *)open("/dev/i2c-3", O_RDWR);
158  i2c3.errors = &i2c3_errors;
159 
160  /* zeros error counter */
161  ZEROS_ERR_COUNTER(i2c3_errors);
162 }
163 #endif
I2C errors counter.
Definition: i2c.h:154
transaction successfully finished by I2C driver
Definition: i2c.h:57
transmit and receive transaction
Definition: i2c.h:49
bool i2c_idle(struct i2c_periph *p)
i2c_idle() function
Definition: i2c_arch.c:355
void i2c_setbitrate(struct i2c_periph *p, int bitrate)
i2c_setbitrate() function
Definition: i2c_arch.c:297
#define I2C_SLAVE
Definition: i2c_smbus.h:129
#define I2C_RDWR
Definition: i2c_smbus.h:138
void * reg_addr
Definition: i2c.h:146
#define I2C_M_RD
Definition: i2c_smbus.h:44
#define ZEROS_ERR_COUNTER(_i2c_err)
Definition: i2c.h:170
bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
i2c_submit() function
Definition: i2c_arch.c:316
transaction failed
Definition: i2c.h:58
I2C transaction structure.
Definition: i2c.h:93
I2C peripheral structure.
Definition: i2c.h:138
unsigned char uint8_t
Definition: types.h:14
transmit only transaction
Definition: i2c.h:47
static float p[2][2]
void i2c_event(void)
i2c_event() function
Definition: i2c_arch.c:289
receive only transaction
Definition: i2c.h:48
Architecture independent I2C (Inter-Integrated Circuit Bus) API.