amiro-blt / Target / Demo / ARMCM3_STM32F103_LightRing_GCC / Boot / lib / STM32F10x_StdPeriph_Driver / src / stm32f10x_i2c.c @ 69661903
History | View | Annotate | Download (44.7 KB)
1 |
/**
|
---|---|
2 |
******************************************************************************
|
3 |
* @file stm32f10x_i2c.c
|
4 |
* @author MCD Application Team
|
5 |
* @version V3.5.0
|
6 |
* @date 11-March-2011
|
7 |
* @brief This file provides all the I2C firmware functions.
|
8 |
******************************************************************************
|
9 |
* @attention
|
10 |
*
|
11 |
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
12 |
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
13 |
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
14 |
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
15 |
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
16 |
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
17 |
*
|
18 |
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
19 |
******************************************************************************
|
20 |
*/
|
21 |
|
22 |
/* Includes ------------------------------------------------------------------*/
|
23 |
#include "stm32f10x_i2c.h" |
24 |
#include "stm32f10x_rcc.h" |
25 |
|
26 |
|
27 |
/** @addtogroup STM32F10x_StdPeriph_Driver
|
28 |
* @{
|
29 |
*/
|
30 |
|
31 |
/** @defgroup I2C
|
32 |
* @brief I2C driver modules
|
33 |
* @{
|
34 |
*/
|
35 |
|
36 |
/** @defgroup I2C_Private_TypesDefinitions
|
37 |
* @{
|
38 |
*/
|
39 |
|
40 |
/**
|
41 |
* @}
|
42 |
*/
|
43 |
|
44 |
/** @defgroup I2C_Private_Defines
|
45 |
* @{
|
46 |
*/
|
47 |
|
48 |
/* I2C SPE mask */
|
49 |
#define CR1_PE_Set ((uint16_t)0x0001) |
50 |
#define CR1_PE_Reset ((uint16_t)0xFFFE) |
51 |
|
52 |
/* I2C START mask */
|
53 |
#define CR1_START_Set ((uint16_t)0x0100) |
54 |
#define CR1_START_Reset ((uint16_t)0xFEFF) |
55 |
|
56 |
/* I2C STOP mask */
|
57 |
#define CR1_STOP_Set ((uint16_t)0x0200) |
58 |
#define CR1_STOP_Reset ((uint16_t)0xFDFF) |
59 |
|
60 |
/* I2C ACK mask */
|
61 |
#define CR1_ACK_Set ((uint16_t)0x0400) |
62 |
#define CR1_ACK_Reset ((uint16_t)0xFBFF) |
63 |
|
64 |
/* I2C ENGC mask */
|
65 |
#define CR1_ENGC_Set ((uint16_t)0x0040) |
66 |
#define CR1_ENGC_Reset ((uint16_t)0xFFBF) |
67 |
|
68 |
/* I2C SWRST mask */
|
69 |
#define CR1_SWRST_Set ((uint16_t)0x8000) |
70 |
#define CR1_SWRST_Reset ((uint16_t)0x7FFF) |
71 |
|
72 |
/* I2C PEC mask */
|
73 |
#define CR1_PEC_Set ((uint16_t)0x1000) |
74 |
#define CR1_PEC_Reset ((uint16_t)0xEFFF) |
75 |
|
76 |
/* I2C ENPEC mask */
|
77 |
#define CR1_ENPEC_Set ((uint16_t)0x0020) |
78 |
#define CR1_ENPEC_Reset ((uint16_t)0xFFDF) |
79 |
|
80 |
/* I2C ENARP mask */
|
81 |
#define CR1_ENARP_Set ((uint16_t)0x0010) |
82 |
#define CR1_ENARP_Reset ((uint16_t)0xFFEF) |
83 |
|
84 |
/* I2C NOSTRETCH mask */
|
85 |
#define CR1_NOSTRETCH_Set ((uint16_t)0x0080) |
86 |
#define CR1_NOSTRETCH_Reset ((uint16_t)0xFF7F) |
87 |
|
88 |
/* I2C registers Masks */
|
89 |
#define CR1_CLEAR_Mask ((uint16_t)0xFBF5) |
90 |
|
91 |
/* I2C DMAEN mask */
|
92 |
#define CR2_DMAEN_Set ((uint16_t)0x0800) |
93 |
#define CR2_DMAEN_Reset ((uint16_t)0xF7FF) |
94 |
|
95 |
/* I2C LAST mask */
|
96 |
#define CR2_LAST_Set ((uint16_t)0x1000) |
97 |
#define CR2_LAST_Reset ((uint16_t)0xEFFF) |
98 |
|
99 |
/* I2C FREQ mask */
|
100 |
#define CR2_FREQ_Reset ((uint16_t)0xFFC0) |
101 |
|
102 |
/* I2C ADD0 mask */
|
103 |
#define OAR1_ADD0_Set ((uint16_t)0x0001) |
104 |
#define OAR1_ADD0_Reset ((uint16_t)0xFFFE) |
105 |
|
106 |
/* I2C ENDUAL mask */
|
107 |
#define OAR2_ENDUAL_Set ((uint16_t)0x0001) |
108 |
#define OAR2_ENDUAL_Reset ((uint16_t)0xFFFE) |
109 |
|
110 |
/* I2C ADD2 mask */
|
111 |
#define OAR2_ADD2_Reset ((uint16_t)0xFF01) |
112 |
|
113 |
/* I2C F/S mask */
|
114 |
#define CCR_FS_Set ((uint16_t)0x8000) |
115 |
|
116 |
/* I2C CCR mask */
|
117 |
#define CCR_CCR_Set ((uint16_t)0x0FFF) |
118 |
|
119 |
/* I2C FLAG mask */
|
120 |
#define FLAG_Mask ((uint32_t)0x00FFFFFF) |
121 |
|
122 |
/* I2C Interrupt Enable mask */
|
123 |
#define ITEN_Mask ((uint32_t)0x07000000) |
124 |
|
125 |
/**
|
126 |
* @}
|
127 |
*/
|
128 |
|
129 |
/** @defgroup I2C_Private_Macros
|
130 |
* @{
|
131 |
*/
|
132 |
|
133 |
/**
|
134 |
* @}
|
135 |
*/
|
136 |
|
137 |
/** @defgroup I2C_Private_Variables
|
138 |
* @{
|
139 |
*/
|
140 |
|
141 |
/**
|
142 |
* @}
|
143 |
*/
|
144 |
|
145 |
/** @defgroup I2C_Private_FunctionPrototypes
|
146 |
* @{
|
147 |
*/
|
148 |
|
149 |
/**
|
150 |
* @}
|
151 |
*/
|
152 |
|
153 |
/** @defgroup I2C_Private_Functions
|
154 |
* @{
|
155 |
*/
|
156 |
|
157 |
/**
|
158 |
* @brief Deinitializes the I2Cx peripheral registers to their default reset values.
|
159 |
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
160 |
* @retval None
|
161 |
*/
|
162 |
void I2C_DeInit(I2C_TypeDef* I2Cx)
|
163 |
{ |
164 |
/* Check the parameters */
|
165 |
assert_param(IS_I2C_ALL_PERIPH(I2Cx)); |
166 |
|
167 |
if (I2Cx == I2C1)
|
168 |
{ |
169 |
/* Enable I2C1 reset state */
|
170 |
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); |
171 |
/* Release I2C1 from reset state */
|
172 |
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); |
173 |
} |
174 |
else
|
175 |
{ |
176 |
/* Enable I2C2 reset state */
|
177 |
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); |
178 |
/* Release I2C2 from reset state */
|
179 |
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); |
180 |
} |
181 |
} |
182 |
|
183 |
/**
|
184 |
* @brief Initializes the I2Cx peripheral according to the specified
|
185 |
* parameters in the I2C_InitStruct.
|
186 |
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
187 |
* @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that
|
188 |
* contains the configuration information for the specified I2C peripheral.
|
189 |
* @retval None
|
190 |
*/
|
191 |
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
|
192 |
{ |
193 |
uint16_t tmpreg = 0, freqrange = 0; |
194 |
uint16_t result = 0x04;
|
195 |
uint32_t pclk1 = 8000000;
|
196 |
RCC_ClocksTypeDef rcc_clocks; |
197 |
/* Check the parameters */
|
198 |
assert_param(IS_I2C_ALL_PERIPH(I2Cx)); |
199 |
assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed)); |
200 |
assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode)); |
201 |
assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle)); |
202 |
assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1)); |
203 |
assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack)); |
204 |
assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress)); |
205 |
|
206 |
/*---------------------------- I2Cx CR2 Configuration ------------------------*/
|
207 |
/* Get the I2Cx CR2 value */
|
208 |
tmpreg = I2Cx->CR2; |
209 |
/* Clear frequency FREQ[5:0] bits */
|
210 |
tmpreg &= CR2_FREQ_Reset; |
211 |
/* Get pclk1 frequency value */
|
212 |
RCC_GetClocksFreq(&rcc_clocks); |
213 |
pclk1 = rcc_clocks.PCLK1_Frequency; |
214 |
/* Set frequency bits depending on pclk1 value */
|
215 |
freqrange = (uint16_t)(pclk1 / 1000000);
|
216 |
tmpreg |= freqrange; |
217 |
/* Write to I2Cx CR2 */
|
218 |
I2Cx->CR2 = tmpreg; |
219 |
|
220 |
/*---------------------------- I2Cx CCR Configuration ------------------------*/
|
221 |
/* Disable the selected I2C peripheral to configure TRISE */
|
222 |
I2Cx->CR1 &= CR1_PE_Reset; |
223 |
/* Reset tmpreg value */
|
224 |
/* Clear F/S, DUTY and CCR[11:0] bits */
|
225 |
tmpreg = 0;
|
226 |
|
227 |
/* Configure speed in standard mode */
|
228 |
if (I2C_InitStruct->I2C_ClockSpeed <= 100000) |
229 |
{ |
230 |
/* Standard mode speed calculate */
|
231 |
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
|
232 |
/* Test if CCR value is under 0x4*/
|
233 |
if (result < 0x04) |
234 |
{ |
235 |
/* Set minimum allowed value */
|
236 |
result = 0x04;
|
237 |
} |
238 |
/* Set speed value for standard mode */
|
239 |
tmpreg |= result; |
240 |
/* Set Maximum Rise Time for standard mode */
|
241 |
I2Cx->TRISE = freqrange + 1;
|
242 |
} |
243 |
/* Configure speed in fast mode */
|
244 |
else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/ |
245 |
{ |
246 |
if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
|
247 |
{ |
248 |
/* Fast mode speed calculate: Tlow/Thigh = 2 */
|
249 |
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
|
250 |
} |
251 |
else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/ |
252 |
{ |
253 |
/* Fast mode speed calculate: Tlow/Thigh = 16/9 */
|
254 |
result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
|
255 |
/* Set DUTY bit */
|
256 |
result |= I2C_DutyCycle_16_9; |
257 |
} |
258 |
|
259 |
/* Test if CCR value is under 0x1*/
|
260 |
if ((result & CCR_CCR_Set) == 0) |
261 |
{ |
262 |
/* Set minimum allowed value */
|
263 |
result |= (uint16_t)0x0001;
|
264 |
} |
265 |
/* Set speed value and set F/S bit for fast mode */
|
266 |
tmpreg |= (uint16_t)(result | CCR_FS_Set); |
267 |
/* Set Maximum Rise Time for fast mode */
|
268 |
I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1); |
269 |
} |
270 |
|
271 |
/* Write to I2Cx CCR */
|
272 |
I2Cx->CCR = tmpreg; |
273 |
/* Enable the selected I2C peripheral */
|
274 |
I2Cx->CR1 |= CR1_PE_Set; |
275 |
|
276 |
/*---------------------------- I2Cx CR1 Configuration ------------------------*/
|
277 |
/* Get the I2Cx CR1 value */
|
278 |
tmpreg = I2Cx->CR1; |
279 |
/* Clear ACK, SMBTYPE and SMBUS bits */
|
280 |
tmpreg &= CR1_CLEAR_Mask; |
281 |
/* Configure I2Cx: mode and acknowledgement */
|
282 |
/* Set SMBTYPE and SMBUS bits according to I2C_Mode value */
|
283 |
/* Set ACK bit according to I2C_Ack value */
|
284 |
tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack); |
285 |
/* Write to I2Cx CR1 */
|
286 |
I2Cx->CR1 = tmpreg; |
287 |
|
288 |
/*---------------------------- I2Cx OAR1 Configuration -----------------------*/
|
289 |
/* Set I2Cx Own Address1 and acknowledged address */
|
290 |
I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1); |
291 |
} |
292 |
|
293 |
/**
|
294 |
* @brief Fills each I2C_InitStruct member with its default value.
|
295 |
* @param I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.
|
296 |
* @retval None
|
297 |
*/
|
298 |
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
|
299 |
{ |
300 |
/*---------------- Reset I2C init structure parameters values ----------------*/
|
301 |
/* initialize the I2C_ClockSpeed member */
|
302 |
I2C_InitStruct->I2C_ClockSpeed = 5000;
|
303 |
/* Initialize the I2C_Mode member */
|
304 |
I2C_InitStruct->I2C_Mode = I2C_Mode_I2C; |
305 |
/* Initialize the I2C_DutyCycle member */
|
306 |
I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2; |
307 |
/* Initialize the I2C_OwnAddress1 member */
|
308 |
I2C_InitStruct->I2C_OwnAddress1 = 0;
|
309 |
/* Initialize the I2C_Ack member */
|
310 |
I2C_InitStruct->I2C_Ack = I2C_Ack_Disable; |
311 |
/* Initialize the I2C_AcknowledgedAddress member */
|
312 |
I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; |
313 |
} |
314 |
|
315 |
/**
|
316 |
* @brief Enables or disables the specified I2C peripheral.
|
317 |
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
318 |
* @param NewState: new state of the I2Cx peripheral.
|
319 |
* This parameter can be: ENABLE or DISABLE.
|
320 |
* @retval None
|
321 |
*/
|
322 |
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
|
323 |
{ |
324 |
/* Check the parameters */
|
325 |
assert_param(IS_I2C_ALL_PERIPH(I2Cx)); |
326 |
assert_param(IS_FUNCTIONAL_STATE(NewState)); |
327 |
if (NewState != DISABLE)
|
328 |
{ |
329 |
/* Enable the selected I2C peripheral */
|
330 |
I2Cx->CR1 |= CR1_PE_Set; |
331 |
} |
332 |
else
|
333 |
{ |
334 |
/* Disable the selected I2C peripheral */
|
335 |
I2Cx->CR1 &= CR1_PE_Reset; |
336 |
} |
337 |
} |
338 |
|
339 |
/**
|
340 |
* @brief Enables or disables the specified I2C DMA requests.
|
341 |
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
342 |
* @param NewState: new state of the I2C DMA transfer.
|
343 |
* This parameter can be: ENABLE or DISABLE.
|
344 |
* @retval None
|
345 |
*/
|
346 |
void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
|
347 |
{ |
348 |
/* Check the parameters */
|
349 |
assert_param(IS_I2C_ALL_PERIPH(I2Cx)); |
350 |
assert_param(IS_FUNCTIONAL_STATE(NewState)); |
351 |
if (NewState != DISABLE)
|
352 |
{ |
353 |
/* Enable the selected I2C DMA requests */
|
354 |
I2Cx->CR2 |= CR2_DMAEN_Set; |
355 |
} |
356 |
else
|
357 |
{ |
358 |
/* Disable the selected I2C DMA requests */
|
359 |
I2Cx->CR2 &= CR2_DMAEN_Reset; |
360 |
} |
361 |
} |
362 |
|
363 |
/**
|
364 |
* @brief Specifies if the next DMA transfer will be the last one.
|
365 |
* @param I2Cx: where x can be 1 or 2 to select the I2C peripheral.
|
366 |
* @param NewState: new state of the I2C DMA last transfer.
|
367 |
* This parameter can be: ENABLE or DISABLE.
|
368 |
* @retval None
|
369 |
*/
|
370 |
void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
|