Демонстрационная прошивка отладочного комплекта МТС NB-IoT
i2c_api.c
См. документацию.
1 #include "i2c_api.h"
2 
9 uint8_t __wait_SR1_bit(I2C_TypeDef* i2c_inst,uint16_t mask)
10 {
11  volatile uint32_t safety_counter;
12 
13  safety_counter=0;
14  while ((!(i2c_inst->SR1 & mask)) && (safety_counter<I2C_SAFETY_TIMEOUT))
15  {
16  safety_counter++;
17  }
18 
19  if (safety_counter<I2C_SAFETY_TIMEOUT)
20  {
21  return 1;
22  }
23  else
24  {
25  return 0;
26  }
27 }
28 
29 inline uint8_t __generate_START(I2C_TypeDef* i2c_inst)
30 {
31  i2c_inst->CR1 |= I2C_CR1_START;
32 
33  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_SB))
34  {
35  return 0;
36  }
37  else
38  {
39  return 1;
40  }
41 }
42 
43 inline uint8_t __read_single_byte(I2C_TypeDef* i2c_inst,uint8_t i2c_addr,uint8_t* byte_out)
44 {
45  i2c_inst->DR = (i2c_addr<<1) | 1;
46 
47  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_ADDR))
48  {
49  return 0;
50  }
51 
52  //Now set NACK
53  i2c_inst->CR1 &= ~I2C_CR1_ACK;
54 
55  if (!(i2c_inst->SR2 & I2C_SR2_MSL))
56  {
57  return 0;
58  }
59 
60  //Now the byte reception is in progress, program STOP
61  i2c_inst->CR1 |= I2C_CR1_STOP;
62 
63  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_RXNE))
64  {
65  return 0;
66  }
67 
68  (*byte_out) = i2c_inst->DR;
69 
70  return 1;
71 }
72 
73 inline uint8_t __read_two_bytes(I2C_TypeDef* i2c_inst,uint8_t i2c_addr,uint8_t* bytes_out)
74 {
75  i2c_inst->DR = (i2c_addr<<1) | 1;
76 
77  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_ADDR))
78  {
79  return 0;
80  }
81 
82  i2c_inst->CR1 &= ~I2C_CR1_ACK;
83  i2c_inst->CR1 |= I2C_CR1_POS; //Magic bit
84 
85  if (!(i2c_inst->SR2 & I2C_SR2_MSL))
86  {
87  return 0;
88  }
89 
90  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_BTF))
91  {
92  return 0;
93  }
94 
95  i2c_inst->CR1 |= I2C_CR1_STOP;
96 
97  bytes_out[0] = i2c_inst->DR;
98  bytes_out[1] = i2c_inst->DR;
99 
100  i2c_inst->CR1 &= ~I2C_CR1_POS;
101 
102  return 1;
103 }
104 
105 inline uint8_t __read_multiple_bytes(I2C_TypeDef* i2c_inst,uint8_t i2c_addr,uint8_t* bytes_out,uint16_t read_length)
106 {
107  uint16_t k;
108 
109  if (read_length<3)
110  {
111  return 0; //Wrong usage!
112  }
113 
114  i2c_inst->DR = (i2c_addr<<1) | 1;
115 
116  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_ADDR))
117  {
118  return 0;
119  }
120 
121  if (!(i2c_inst->SR2 & I2C_SR2_MSL))
122  {
123  return 0;
124  }
125 
126  i2c_inst->CR1 |= I2C_CR1_ACK;
127 
128  for (k=0; k<read_length; k++)
129  {
130  if (k<(read_length-3))
131  {
132  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_RXNE))
133  {
134  return 0;
135  }
136 
137  bytes_out[k] = i2c_inst->DR;
138  }
139  else
140  {
141  if (k==(read_length-3))
142  {
143  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_BTF))
144  {
145  return 0;
146  }
147  i2c_inst->CR1 &= ~I2C_CR1_ACK;
148  bytes_out[k] = i2c_inst->DR;
149  }
150 
151  if (k==(read_length-2))
152  {
153  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_BTF))
154  {
155  return 0;
156  }
157  i2c_inst->CR1 |= I2C_CR1_STOP;
158  bytes_out[k] = i2c_inst->DR;
159  }
160 
161  if (k==(read_length-1))
162  {
163  bytes_out[k] = i2c_inst->DR;
164  }
165  }
166  }
167 
168  return 1;
169 }
170 
171 i2c_error_t i2c_read_with_pointer(I2C_TypeDef* i2c_inst,uint8_t i2c_addr,uint8_t pointer_byte,uint8_t read_length,uint8_t* read_buffer)
172 {
173  volatile uint32_t safety_counter;
174 
175  if (read_length==0)
176  {
177  return I2C_ERROR_READ_FAIL;
178  }
179 
180  if (read_buffer==NULL)
181  {
182  return I2C_ERROR_READ_FAIL;
183  }
184 
185  //Step 1: generate START condition
186  if (!__generate_START(i2c_inst))
187  {
188  return I2C_ERROR_START_FAIL;
189  }
190 
191  //Step 2: transmit slave address with LSB reset, master transmitter mode
192  i2c_inst->DR = i2c_addr<<1;
193 
194  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_ADDR))
195  {
196  return I2C_ERROR_ADDR_FAIL;
197  }
198 
199  if (!(i2c_inst->SR2 & I2C_SR2_MSL))
200  {
201  return I2C_ERROR_ADDR_FAIL;
202  }
203 
204  i2c_inst->DR = pointer_byte; //Send pointer byte, as required by i2c devices protocol
205 
206  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_TXE))
207  {
208  //For some reason, byte could not be transmitted
209  return I2C_ERROR_READ_FAIL;
210  }
211 
212  //Send repeated start
213  if (!__generate_START(i2c_inst))
214  {
215  return I2C_ERROR_START_FAIL;
216  }
217 
218  if (read_length==1)
219  {
220  if (!__read_single_byte(i2c_inst,i2c_addr,read_buffer))
221  {
222  return I2C_ERROR_READ_FAIL;
223  }
224  }
225 
226  if (read_length==2)
227  {
228  if (!__read_two_bytes(i2c_inst,i2c_addr,read_buffer))
229  {
230  return I2C_ERROR_READ_FAIL;
231  }
232  }
233 
234  if (read_length>2)
235  {
236  if (!__read_multiple_bytes(i2c_inst,i2c_addr,read_buffer,read_length))
237  {
238  return I2C_ERROR_READ_FAIL;
239  }
240  }
241 
242  safety_counter=0;
243  while ((i2c_inst->SR2 & I2C_SR2_MSL) && (safety_counter<I2C_SAFETY_TIMEOUT))
244  {
245  safety_counter++;
246  }
247 
248  return I2C_ERROR_NONE;
249 }
250 
251 i2c_error_t i2c_write_with_pointer(I2C_TypeDef* i2c_inst,uint8_t i2c_addr,uint8_t pointer_byte,uint16_t write_length,uint8_t* write_buffer)
252 {
253  uint16_t k;
254  volatile uint32_t safety_counter;
255 
256  if (!__generate_START(i2c_inst))
257  {
258  return I2C_ERROR_START_FAIL;
259  }
260 
261  i2c_inst->DR = i2c_addr<<1; //Send I2C address with LSB reset, master transmitter mode
262 
263  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_ADDR))
264  {
265  return I2C_ERROR_ADDR_FAIL;
266  }
267 
268  if (!(i2c_inst->SR2 & I2C_SR2_MSL))
269  {
270  return I2C_ERROR_ADDR_FAIL;
271  }
272 
273  i2c_inst->DR = pointer_byte;
274 
275  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_TXE))
276  {
277  return I2C_ERROR_WRITE_FAIL;
278  }
279 
280  if (write_buffer!=NULL)
281  {
282  for (k=0; k<write_length; k++)
283  {
284  i2c_inst->DR = write_buffer[k];
285 
286  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_TXE))
287  {
288  return I2C_ERROR_WRITE_FAIL;
289  }
290  }
291  }
292 
293  if (!__wait_SR1_bit(i2c_inst,I2C_SR1_BTF))
294  {
295  return I2C_ERROR_WRITE_FAIL;
296  }
297 
298  i2c_inst->CR1 |= I2C_CR1_STOP;
299 
300  //When all bus master activity is over, the interface will return to default slave mode
301  safety_counter=0;
302  while ((i2c_inst->SR2 & I2C_SR2_MSL) && (safety_counter<I2C_SAFETY_TIMEOUT))
303  {
304  safety_counter++;
305  }
306 
307  return I2C_ERROR_NONE;
308 }
309 
310 void init_i2c(I2C_TypeDef* i2c_inst,uint32_t sys_clk)
311 {
312  i2c_inst->CR2 = sys_clk / 1000000UL;
313  i2c_inst->CCR = sys_clk / 200000UL; //T_bus_high = T_bus_low = CCR periods of sys_clk = 0.5*(period of 100 kHz clock)
314  i2c_inst->TRISE = (sys_clk / 1000000UL) + 1; //T_rise_max = 1 us for standard mode
315  i2c_inst->CR1 = I2C_CR1_PE;
316 }
init_i2c
void init_i2c(I2C_TypeDef *i2c_inst, uint32_t sys_clk)
Выполняет настройку модуля I2C для работы на стандартной частоте SDA, равной 100 кГц.
Definition: i2c_api.c:310
i2c_write_with_pointer
i2c_error_t i2c_write_with_pointer(I2C_TypeDef *i2c_inst, uint8_t i2c_addr, uint8_t pointer_byte, uint16_t write_length, uint8_t *write_buffer)
Функция выполняет запись регистра устройства I2C по правилам, общим для многих I2C-устройств.
Definition: i2c_api.c:251
i2c_read_with_pointer
i2c_error_t i2c_read_with_pointer(I2C_TypeDef *i2c_inst, uint8_t i2c_addr, uint8_t pointer_byte, uint8_t read_length, uint8_t *read_buffer)
Функция выполняет чтение регистра устройства I2C по правилам, общим для многих I2C-устройств.
Definition: i2c_api.c:171
I2C_SAFETY_TIMEOUT
#define I2C_SAFETY_TIMEOUT
Definition: i2c_api.h:20
i2c_api.h