GadgetSeed  0.9.6
i2c.c
[詳解]
1 /** @file
2  @brief STM32F4 I2Cドライバ
3 
4  @date 2015.08.10
5  @author Takashi SHUDO
6 
7  PB8 - I2C1_SCL
8  PB9 - I2C1_SDA
9 */
10 
11 #include "sysconfig.h"
12 #include "device.h"
13 #include "interrupt.h"
14 #include "tkprintf.h"
15 #include "device/i2c_ioctl.h"
16 #include "task/event.h"
17 #include "task/mutex.h"
18 #include "task/syscall.h"
19 
20 #include "stm32f4xx_hal.h"
21 
22 //#define DEBUGKBITS 0x03
23 #include "dkprintf.h"
24 
25 
26 typedef struct st_i2c_data {
27  struct st_i2c_config config;
28 
29  I2C_HandleTypeDef hi2c;
30 
31  unsigned short seek_addr;
32 } st_i2c_data;
33 
34 static st_i2c_data i2c_prv_data[1];
35 static struct st_mutex i2c_mutex[1];
36 
37 void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
38 {
39 
40  GPIO_InitTypeDef GPIO_InitStruct;
41  if(hi2c->Instance==I2C1) {
42  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
43  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
44  GPIO_InitStruct.Pull = GPIO_PULLUP;
45  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
46  GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
47  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
48  __HAL_RCC_I2C1_CLK_ENABLE();
49  }
50 }
51 
52 
53 /*
54  *
55  */
56 extern const struct st_device i2c_device;
57 
58 static void init_i2c(struct st_device *dev)
59 {
60  st_i2c_data *i2c_data = (dev->private_data);
61  I2C_HandleTypeDef *hi2c = &(i2c_data->hi2c);
62 
63  __HAL_RCC_GPIOB_CLK_ENABLE();
64  __HAL_RCC_GPIOD_CLK_ENABLE();
65 
66  if(dev == &i2c_device) {
67  hi2c->Instance = I2C1;
68  }
69 
70  hi2c->Init.ClockSpeed = 100000;
71  hi2c->Init.DutyCycle = I2C_DUTYCYCLE_2;
72  hi2c->Init.OwnAddress1 = 0;
73  hi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
74  hi2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
75  hi2c->Init.OwnAddress2 = 0;
76  hi2c->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
77  hi2c->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
78  if(HAL_I2C_Init(hi2c) != HAL_OK) {
79  SYSERR_PRINT("I2C Initialize error(%s)\n", dev->name);
80  }
81 }
82 
83 static int i2c_register(struct st_device *dev, char *param)
84 {
85  st_i2c_data *i2c_data = (dev->private_data);
86 
87  i2c_data->config.speed = 100;
88  i2c_data->config.address_mode = I2C_ADDR_MODE_7BIT;
89  i2c_data->config.slave_addr = 0x00;
90  i2c_data->config.mem_addr_size = I2C_MEMADD_SIZE_8BIT;
91  i2c_data->seek_addr = 0;
92 
93  init_i2c(dev);
94 
95  return 0;
96 }
97 
98 static int i2c_open(struct st_device *dev)
99 {
100  return 0;
101 }
102 
103 static int i2c_close(struct st_device *dev)
104 {
105  return 0;
106 }
107 
108 static int i2c_read(struct st_device *dev, void *data, unsigned int size)
109 {
110  st_i2c_data *i2c_data = (dev->private_data);
111  I2C_HandleTypeDef *hi2c = &(i2c_data->hi2c);
112  unsigned short slave_addr = i2c_data->config.slave_addr;
113  unsigned short i2c_memadd_size = I2C_MEMADD_SIZE_8BIT;
114  HAL_StatusTypeDef rtn = 0;
115 
116  DKFPRINTF(0x01, "size = %d\n", size);
117 
118  switch(i2c_data->config.mem_addr_size) {
120  i2c_memadd_size = I2C_MEMADD_SIZE_8BIT;
121  break;
123  i2c_memadd_size = I2C_MEMADD_SIZE_16BIT;
124  break;
125  default:
126  break;
127  }
128 
129  DKPRINTF(0x01, "I2C READ ADDRESS %08X\n", (unsigned int)i2c_data->seek_addr);
130 
131  rtn = HAL_I2C_Mem_Read(hi2c,
132  (slave_addr << 1),
133  i2c_data->seek_addr,
134  i2c_memadd_size,
135  data, size,
136  10/* tick */);
137 
138  if(rtn == HAL_OK) {
139  i2c_data->seek_addr += size;
140  return size;
141  } else {
142  return -1;
143  }
144 }
145 
146 static int i2c_write(struct st_device *dev, const void *data, unsigned int size)
147 {
148  st_i2c_data *i2c_data = (dev->private_data);
149  I2C_HandleTypeDef *hi2c = &(i2c_data->hi2c);
150  unsigned short slave_addr = i2c_data->config.slave_addr;
151  unsigned short i2c_memadd_size = I2C_MEMADD_SIZE_8BIT;
152  HAL_StatusTypeDef rtn = 0;
153 
154  DKFPRINTF(0x01, "size = %d\n", size);
155 
156  switch(i2c_data->config.mem_addr_size) {
158  i2c_memadd_size = I2C_MEMADD_SIZE_8BIT;
159  break;
161  i2c_memadd_size = I2C_MEMADD_SIZE_16BIT;
162  break;
163  default:
164  break;
165  }
166 
167  DKPRINTF(0x01, "I2C WRITE ADDRESS %08X\n", (unsigned int)i2c_data->seek_addr);
168 
169  rtn = HAL_I2C_Mem_Write(hi2c,
170  (slave_addr << 1),
171  i2c_data->seek_addr,
172  i2c_memadd_size,
173  (unsigned char *)data, size,
174  10/* tick */);
175 
176  if(rtn == HAL_OK) {
177  i2c_data->seek_addr += size;
178  return size;
179  } else {
180  return -1;
181  }
182 }
183 
184 static int i2c_set_speed(I2C_TypeDef *i2cx, int speed)
185 {
186  return 0;
187 }
188 
189 static int i2c_ioctl(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
190 {
191  st_i2c_data *i2c_data = (dev->private_data);
192  I2C_TypeDef *i2cx = i2c_data->hi2c.Instance;
193  int rtn = 0;
194 
195  switch(com) {
196  case IOCMD_I2C_SPEED:
197  i2c_data->config.speed = arg;
198  rtn = i2c_set_speed(i2cx, arg);
199  break;
200 
202  {
203  i2c_data->config.slave_addr = arg;
204  }
205  break;
206 
208  {
209  DKPRINTF(0x01, "I2C IOCTL Memory Address Size %dbit\n",
210  (arg == I2C_MEM_ADDR_SIZE_16BIT) ? 16 : 8);
211  i2c_data->config.mem_addr_size = arg;
212  }
213  break;
214 
215  case IOCMD_I2C_SETCONFIG:
216  {
217  struct st_i2c_config *conf = (struct st_i2c_config *)arg;
218 
219  i2c_data->config.speed = conf->speed;
220  i2c_data->config.address_mode = conf->address_mode;
221  i2c_data->config.slave_addr = conf->slave_addr;
222  i2c_data->config.mem_addr_size = conf->mem_addr_size;
223  }
224  break;
225 
226  default:
227  SYSERR_PRINT("Unknown ioctl(%08lX)\n", com);
228  rtn = -1;
229  break;
230  }
231 
232  return rtn;
233 }
234 
235 static int i2c_seek(struct st_device *dev, int offset, int whence)
236 {
237  st_i2c_data *i2c_data = (dev->private_data);
238 
239  switch(whence) {
240  case SEEK_SET:
241  DKPRINTF(0x01, "I2C SEEK_SET Address %08X\n", offset);
242  i2c_data->seek_addr = offset;
243  break;
244 
245  case SEEK_CUR:
246  DKPRINTF(0x01, "I2C SEEK_CUR Address %08X\n", offset);
247  i2c_data->seek_addr += offset;
248  break;
249 
250  case SEEK_END:
251  default:
252  SYSERR_PRINT("Unknown seek whence(%08lX)\n", whence);
253  return -1;
254  }
255 
256  return i2c_data->seek_addr;
257 }
258 
259 static int i2c_suspend(struct st_device *dev)
260 {
261  return 0;
262 }
263 
264 static int i2c_resume(struct st_device *dev)
265 {
266  init_i2c(dev);
267 
268  return 0;
269 }
270 
271 const struct st_device i2c_device = {
273  .explan = "STM32F4 I2C1 Master",
274  .private_data = (void *)&i2c_prv_data[0],
275  .register_dev = i2c_register,
276  .mutex = &i2c_mutex[0],
277  .open = i2c_open,
278  .close = i2c_close,
279  .read = i2c_read,
280  .write = i2c_write,
281  .ioctl = i2c_ioctl,
282  .seek = i2c_seek,
283  .suspend = i2c_suspend,
284  .resume = i2c_resume,
285 };
I2Cコンフィグデータ
Definition: i2c_ioctl.h:17
#define IOCMD_I2C_MEMADDRSIZE
Memory Address Size 8bit or 16bit etc
Definition: i2c_ioctl.h:36
struct st_mutex * mutex
デバイス排他アクセス用MUTEX
Definition: device.h:30
void * private_data
ドライバ固有データポインタ
Definition: device.h:29
#define IOCMD_I2C_SPEED
com : 通信速度を設定する, arg : 通信速度(bps)
Definition: i2c_ioctl.h:32
#define I2C_ADDR_MODE_7BIT
I2C 7ビットアドレスモード
Definition: i2c_ioctl.h:20
#define IOCMD_I2C_SETCONFIG
Device Access configration
Definition: i2c_ioctl.h:37
#define I2C_MEM_ADDR_SIZE_16BIT
I2Cスレーブデバイスメモリアドレスサイズは16ビット
Definition: i2c_ioctl.h:27
int suspend(void)
全デバイスを休止状態にする
Definition: device.c:634
#define I2C_MEM_ADDR_SIZE_8BIT
I2Cスレーブデバイスメモリアドレスサイズは8ビット
Definition: i2c_ioctl.h:26
カーネル用機能限定printf
int speed
ビットレート(Kbps)
Definition: i2c_ioctl.h:18
MUTEX
Definition: mutex.h:13
#define IOCMD_I2C_SLAVE_ADDR7
Set Save 7bit Address
Definition: i2c_ioctl.h:33
システムコール
割り込みハンドラ
MUTEX制御
#define DEF_DEV_NAME_I2C
標準I2Cコントローラデバイス名
Definition: i2c_ioctl.h:15
#define SEEK_SET
設定
Definition: device.h:21
int mem_addr_size
I2Cスレーブデバイスメモリアドレスサイズ
Definition: i2c_ioctl.h:28
イベント待ちタスクキューの操作
int resume(void)
全デバイスを活性化する
Definition: device.c:655
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
I2Cドライバ ioctl 用マクロ定義
カーネル、ドライバ(非タスク)デバッグ用マクロ
int address_mode
未使用(予約)
Definition: i2c_ioctl.h:22
#define SEEK_END
ファイルサイズに加算
Definition: device.h:23
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26
unsigned int slave_addr
I2Cスレーブデバイスアドレス
Definition: i2c_ioctl.h:24
#define SEEK_CUR
現在値に加算
Definition: device.h:22