2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "drivers/io.h"
24 #include "drivers/time.h"
26 #include "drivers/bus_i2c.h"
27 #include "drivers/nvic.h"
28 #include "drivers/i2c_application.h"
31 #if !defined(SOFT_I2C) && defined(USE_I2C)
33 #define CLOCKSPEED 800000 // i2c clockspeed 400kHz default (conform specs), 800kHz and 1200kHz (Betaflight default)
35 #define I2Cx_ADDRESS 0x00
36 // Clock period in us during unstick transfer
37 #define UNSTICK_CLK_US 10
38 // Allow 500us for clock strech to complete during unstick
39 #define UNSTICK_CLK_STRETCH (500/UNSTICK_CLK_US)
41 static void i2cUnstick(IO_t scl
, IO_t sda
);
43 #if defined(USE_I2C_PULLUP)
44 #define IOCFG_I2C IOCFG_AF_OD_UP
46 #define IOCFG_I2C IOCFG_AF_OD
71 //Define thi I2C hardware map
72 static i2cDevice_t i2cHardwareMap
[I2CDEV_COUNT
] = {
73 { .dev
= I2C1
, .scl
= IO_TAG(I2C1_SCL
), .sda
= IO_TAG(I2C1_SDA
), .rcc
= RCC_APB1(I2C1
), .speed
= I2C_SPEED_400KHZ
, .ev_irq
= I2C1_EVT_IRQn
, .er_irq
= I2C1_ERR_IRQn
, .af
= GPIO_MUX_4
},
74 { .dev
= I2C2
, .scl
= IO_TAG(I2C2_SCL
), .sda
= IO_TAG(I2C2_SDA
), .rcc
= RCC_APB1(I2C2
), .speed
= I2C_SPEED_400KHZ
, .ev_irq
= I2C2_EVT_IRQn
, .er_irq
= I2C2_ERR_IRQn
, .af
= GPIO_MUX_4
},
75 { .dev
= I2C3
, .scl
= IO_TAG(I2C3_SCL
), .sda
= IO_TAG(I2C3_SDA
), .rcc
= RCC_APB1(I2C3
), .speed
= I2C_SPEED_400KHZ
, .ev_irq
= I2C3_EVT_IRQn
, .er_irq
= I2C3_ERR_IRQn
, .af
= GPIO_MUX_4
},
78 static volatile uint16_t i2cErrorCount
= 0;
80 // Note that I2C_TIMEOUT is in us, while the HAL
81 // functions expect the timeout to be in ticks.
82 // Since we're setting up the ticks a 1khz, each
84 // AT32F4 i2c TIMEOUT USING loop times
85 #define I2C_DEFAULT_TIMEOUT (I2C_TIMEOUT*288 / 1000 )
86 //#define I2C_DEFAULT_TIMEOUT (0xD80)
90 i2c_handle_type handle
;
93 static i2cState_t i2cState
[I2CDEV_COUNT
];
95 void i2cSetSpeed(uint8_t speed
)
97 for (unsigned int i
= 0; i
< ARRAYLEN(i2cHardwareMap
); i
++) {
98 i2cHardwareMap
[i
].speed
= speed
;
102 //I2C1_ERR_IRQHandler
103 void I2C1_ERR_IRQHandler(void)
105 i2c_err_irq_handler(&i2cState
[I2CDEV_1
].handle
);
108 void I2C1_EVT_IRQHandler(void)
110 i2c_evt_irq_handler(&i2cState
[I2CDEV_1
].handle
);
113 void I2C2_ERR_IRQHandler(void)
115 i2c_err_irq_handler(&i2cState
[I2CDEV_2
].handle
);
118 void I2C2_EVT_IRQHandler(void)
120 i2c_evt_irq_handler(&i2cState
[I2CDEV_2
].handle
);
123 void I2C3_ERR_IRQHandler(void)
125 i2c_err_irq_handler(&i2cState
[I2CDEV_3
].handle
);
128 void I2C3_EVT_IRQHandler(void)
130 i2c_evt_irq_handler(&i2cState
[I2CDEV_3
].handle
);
133 static bool i2cHandleHardwareFailure(I2CDevice device
)
141 bool i2cWriteBuffer(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t len_
, const uint8_t *data
, bool allowRawAccess
)
143 if (device
== I2CINVALID
)
146 i2cState_t
* state
= &(i2cState
[device
]);
148 if (!state
->initialised
)
151 i2c_status_type status
;
153 if ((reg_
== 0xFF || len_
== 0) && allowRawAccess
) {
154 status
= i2c_master_transmit(&state
->handle
, addr_
<< 1, CONST_CAST(uint8_t*, data
), len_
, I2C_DEFAULT_TIMEOUT
);
157 /* wait for the stop flag to be set */
158 i2c_wait_flag(&state
->handle
, I2C_STOPF_FLAG
, I2C_EVENT_CHECK_NONE
, I2C_DEFAULT_TIMEOUT
);
160 /* clear stop flag */
161 i2c_flag_clear(state
->handle
.i2cx
, I2C_STOPF_FLAG
);
165 status
= i2c_memory_write(&state
->handle
,I2C_MEM_ADDR_WIDIH_8
, addr_
<< 1, reg_
, CONST_CAST(uint8_t*, data
), len_
, I2C_DEFAULT_TIMEOUT
);
166 //status = i2c_memory_write_int(&state->handle,I2C_MEM_ADDR_WIDIH_8, addr_ << 1, reg_, data, len_, I2C_DEFAULT_TIMEOUT);
170 /* wait for the stop flag to be set */
171 i2c_wait_flag(&state
->handle
, I2C_STOPF_FLAG
, I2C_EVENT_CHECK_NONE
, I2C_DEFAULT_TIMEOUT
);
173 /* clear stop flag */
174 i2c_flag_clear(state
->handle
.i2cx
, I2C_STOPF_FLAG
);
178 if (status
== I2C_ERR_STEP_1
) {//BUSY
182 if (status
!= I2C_OK
)
183 return i2cHandleHardwareFailure(device
);
188 bool i2cWrite(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t data
, bool allowRawAccess
)
190 return i2cWriteBuffer(device
, addr_
, reg_
, 1, &data
, allowRawAccess
);
193 bool i2cRead(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t len
, uint8_t* buf
, bool allowRawAccess
)
195 if (device
== I2CINVALID
)
198 i2cState_t
* state
= &(i2cState
[device
]);
200 if (!state
->initialised
)
203 //HAL_StatusTypeDef status;
204 i2c_status_type status
;
205 if (reg_
== 0xFF && allowRawAccess
) {
206 status
= i2c_master_receive(&state
->handle
, addr_
<< 1,buf
, len
, I2C_DEFAULT_TIMEOUT
);
209 /* wait for the stop flag to be set */
210 i2c_wait_flag(&state
->handle
, I2C_STOPF_FLAG
, I2C_EVENT_CHECK_NONE
, I2C_DEFAULT_TIMEOUT
);
212 /* clear stop flag */
213 i2c_flag_clear(state
->handle
.i2cx
, I2C_STOPF_FLAG
);
218 status
= i2c_memory_read(&state
->handle
, I2C_MEM_ADDR_WIDIH_8
,addr_
<< 1, reg_
, buf
, len
, I2C_DEFAULT_TIMEOUT
);
222 /* wait for the stop flag to be set */
223 i2c_wait_flag(&state
->handle
, I2C_STOPF_FLAG
, I2C_EVENT_CHECK_NONE
, I2C_DEFAULT_TIMEOUT
);
225 /* clear stop flag */
226 i2c_flag_clear(state
->handle
.i2cx
, I2C_STOPF_FLAG
);
231 if (status
!= I2C_OK
)
232 return i2cHandleHardwareFailure(device
);
238 * Compute SCLDEL, SDADEL, SCLH and SCLL for TIMINGR register according to reference manuals.
240 static void i2cClockComputeRaw(uint32_t pclkFreq
, int i2cFreqKhz
, int presc
, int dfcoeff
,
241 uint8_t *scldel
, uint8_t *sdadel
, uint16_t *sclh
, uint16_t *scll
)
243 // Values from I2C-SMBus specification
244 uint16_t trmax
; // Rise time (max)
245 uint16_t tfmax
; // Fall time (max)
246 uint8_t tsuDATmin
; // SDA setup time (min)
247 uint8_t thdDATmin
; // SDA hold time (min)
248 uint16_t tHIGHmin
; // High period of SCL clock (min)
249 uint16_t tLOWmin
; // Low period of SCL clock (min)
251 // Silicon specific values, from datasheet
252 uint8_t tAFmin
= 50; // Analog filter delay (min)
254 // Actual (estimated) values
255 uint8_t tr
= 100; // Rise time
256 uint8_t tf
= 10; // Fall time
258 if (i2cFreqKhz
> 400) {
259 // Fm+ (Fast mode plus)
276 // Convert pclkFreq into nsec
277 float tI2cclk
= 1000000000.0f
/ pclkFreq
;
279 // Convert target i2cFreq into cycle time (nsec)
280 float tSCL
= 1000000.0f
/ i2cFreqKhz
;
282 uint32_t SCLDELmin
= (trmax
+ tsuDATmin
) / ((presc
+ 1) * tI2cclk
) - 1;
283 uint32_t SDADELmin
= (tfmax
+ thdDATmin
- tAFmin
- ((dfcoeff
+ 3) * tI2cclk
)) / ((presc
+ 1) * tI2cclk
);
285 float tsync1
= tf
+ tAFmin
+ dfcoeff
* tI2cclk
+ 2 * tI2cclk
;
286 float tsync2
= tr
+ tAFmin
+ dfcoeff
* tI2cclk
+ 2 * tI2cclk
;
288 float tSCLH
= tHIGHmin
* tSCL
/ (tHIGHmin
+ tLOWmin
) - tsync2
;
289 float tSCLL
= tSCL
- tSCLH
- tsync1
- tsync2
;
291 uint32_t SCLH
= tSCLH
/ ((presc
+ 1) * tI2cclk
) - 1;
292 uint32_t SCLL
= tSCLL
/ ((presc
+ 1) * tI2cclk
) - 1;
294 while (tsync1
+ tsync2
+ ((SCLH
+ 1) + (SCLL
+ 1)) * ((presc
+ 1) * tI2cclk
) < tSCL
) {
304 static uint32_t i2cClockTIMINGR(uint32_t pclkFreq
, int i2cFreqKhz
, int dfcoeff
)
306 #define TIMINGR(presc, scldel, sdadel, sclh, scll) \
307 ((presc << 28)|(scldel << 20)|(sdadel << 16)|(sclh << 8)|(scll << 0))
314 for (int presc
= 1; presc
< 15; presc
++) {
315 i2cClockComputeRaw(pclkFreq
, i2cFreqKhz
, presc
, dfcoeff
, &scldel
, &sdadel
, &sclh
, &scll
);
317 // If all fields are not overflowing, return TIMINGR.
318 // Otherwise, increase prescaler and try again.
319 if ((scldel
< 16) && (sdadel
< 16) && (sclh
< 256) && (scll
< 256)) {
320 return TIMINGR(presc
, scldel
, sdadel
, sclh
, scll
);
323 return 0; // Shouldn't reach here
326 void i2cInit(I2CDevice device
)
328 i2cDevice_t
* hardware
= &(i2cHardwareMap
[device
]);
329 i2cState_t
* state
= &(i2cState
[device
]);
331 //I2C_HandleTypeDef * pHandle = &state->handle;
332 i2c_handle_type
* pHandle
= &state
->handle
;
334 if (hardware
->dev
== NULL
)
337 IO_t scl
= IOGetByTag(hardware
->scl
);
338 IO_t sda
= IOGetByTag(hardware
->sda
);
340 IOInit(scl
, OWNER_I2C
, RESOURCE_I2C_SCL
, RESOURCE_INDEX(device
));
341 IOInit(sda
, OWNER_I2C
, RESOURCE_I2C_SDA
, RESOURCE_INDEX(device
));
343 RCC_ClockCmd(hardware
->rcc
, ENABLE
);
345 i2cUnstick(scl
, sda
);
348 IOConfigGPIOAF(scl
, IOCFG_I2C
, hardware
->af
);
349 IOConfigGPIOAF(sda
, IOCFG_I2C
, hardware
->af
);
351 // Init I2C peripheral
352 pHandle
->i2cx
= hardware
->dev
;
353 i2c_reset(pHandle
->i2cx
);
354 // Compute TIMINGR value based on peripheral clock for this device instance
357 #if defined(AT32F43x)
358 crm_clocks_freq_type clocks_struct
;
359 crm_clocks_freq_get(&clocks_struct
);
360 i2cPclk
= clocks_struct
.apb1_freq
;
363 #error Unknown MCU type
367 // switch (hardware->speed) {
368 // case I2C_SPEED_400KHZ:
370 // i2c_init(pHandle->i2cx, 15, 0x10F03863); // 400kHz, Rise 100ns, Fall 10ns 0x10C03863
373 // case I2C_SPEED_800KHZ:
374 // i2c_init(pHandle->i2cx, 15, 0x00E03259); // 800khz, Rise 40, Fall 4
377 // case I2C_SPEED_100KHZ:
378 // i2c_init(pHandle->i2cx, 15, 0x30E0AEAE); // 100kHz, Rise 100ns, Fall 10ns 0x30607EE0 0x30607DDE
381 // case I2C_SPEED_200KHZ:
382 // i2c_init(pHandle->i2cx, 15, 0x10F078D6); // 200kHz, Rise 100ns, Fall 10ns 0x10C078D6
387 switch (hardware
->speed
) {
388 case I2C_SPEED_400KHZ
:
390 i2c_init(pHandle
->i2cx
, 0x0f, i2cClockTIMINGR(i2cPclk
, 400, 0));
393 case I2C_SPEED_800KHZ
:
394 i2c_init(pHandle
->i2cx
, 0x0f, i2cClockTIMINGR(i2cPclk
, 800, 0));
397 case I2C_SPEED_100KHZ
:
398 i2c_init(pHandle
->i2cx
, 0x0f, i2cClockTIMINGR(i2cPclk
, 100, 0));
401 case I2C_SPEED_200KHZ
:
402 i2c_init(pHandle
->i2cx
, 0x0f, i2cClockTIMINGR(i2cPclk
, 200, 0));
406 i2c_own_address1_set(pHandle
->i2cx
, I2C_ADDRESS_MODE_7BIT
, 0x0);
407 //i2c_own_address2_enable(pHandle->i2cx, false); // enable or disable own address 2
408 //i2c_own_address2_set(pHandle->i2cx, I2C_ADDRESS_MODE_7BIT, 0x0);
409 //i2c_general_call_enable(pHandle->i2cx, false); // enable or disable general call mode
410 //i2c_clock_stretch_enable(pHandle->i2cx, true); // enable or disable clock stretch
412 nvic_irq_enable(hardware
->er_irq
,NVIC_PRIO_I2C_ER
, 0);
413 nvic_irq_enable(hardware
->ev_irq
, NVIC_PRIO_I2C_EV
,0);
415 i2c_enable(pHandle
->i2cx
, TRUE
);
417 state
->initialised
= true;
420 uint16_t i2cGetErrorCounter(void)
422 return i2cErrorCount
;
425 static void i2cUnstick(IO_t scl
, IO_t sda
)
432 IOConfigGPIO(scl
, IOCFG_OUT_OD
);
433 IOConfigGPIO(sda
, IOCFG_OUT_OD
);
435 // Analog Devices AN-686
436 // We need 9 clock pulses + STOP condition
437 for (i
= 0; i
< 9; i
++) {
438 // Wait for any clock stretching to finish
439 int timeout
= UNSTICK_CLK_STRETCH
;
440 while (!IORead(scl
) && timeout
) {
441 delayMicroseconds(UNSTICK_CLK_US
);
446 IOLo(scl
); // Set bus low
447 delayMicroseconds(UNSTICK_CLK_US
/2);
448 IOHi(scl
); // Set bus high
449 delayMicroseconds(UNSTICK_CLK_US
/2);
452 // Generate a stop condition in case there was none
454 delayMicroseconds(UNSTICK_CLK_US
/2);
456 delayMicroseconds(UNSTICK_CLK_US
/2);
458 IOHi(scl
); // Set bus scl high
459 delayMicroseconds(UNSTICK_CLK_US
/2);
460 IOHi(sda
); // Set bus sda high
463 bool i2cBusy(I2CDevice device
, bool *error
)
465 if (device
== I2CINVALID
)
468 i2cState_t
* state
= &(i2cState
[device
]);
471 *error
= state
->handle
.error_code
==I2C_OK
?false:true;
474 if(state
->handle
.error_code
==I2C_OK
){
476 if (i2c_flag_get(state
->handle
.i2cx
, I2C_BUSYF_FLAG
) == SET
)