1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-21 15:25:36 +03:00

Re-enabling i2c overclocking (lower CPU usage)

This commit is contained in:
blckmn 2016-06-25 21:22:10 +10:00
parent b953e1c0b4
commit 499d7522c2
3 changed files with 148 additions and 144 deletions

View file

@ -82,10 +82,10 @@ static void i2cUnstick(IO_t scl, IO_t sda);
#endif #endif
static i2cDevice_t i2cHardwareMap[] = { static i2cDevice_t i2cHardwareMap[] = {
{ .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = false, .ev_irq = I2C1_EV_IRQn, .er_irq = I2C1_ER_IRQn }, { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = I2C1_OVERCLOCK, .ev_irq = I2C1_EV_IRQn, .er_irq = I2C1_ER_IRQn },
{ .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = false, .ev_irq = I2C2_EV_IRQn, .er_irq = I2C2_ER_IRQn }, { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C2_EV_IRQn, .er_irq = I2C2_ER_IRQn },
#ifdef STM32F4 #ifdef STM32F4
{ .dev = I2C3, .scl = IO_TAG(I2C3_SCL), .sda = IO_TAG(I2C3_SDA), .rcc = RCC_APB1(I2C3), .overClock = false, .ev_irq = I2C3_EV_IRQn, .er_irq = I2C3_ER_IRQn } { .dev = I2C3, .scl = IO_TAG(I2C3_SCL), .sda = IO_TAG(I2C3_SDA), .rcc = RCC_APB1(I2C3), .overClock = I2C2_OVERCLOCK, .ev_irq = I2C3_EV_IRQn, .er_irq = I2C3_ER_IRQn }
#endif #endif
}; };
@ -396,7 +396,7 @@ void i2cInit(I2CDevice device)
i2cUnstick(scl, sda); i2cUnstick(scl, sda);
// Init pins // Init pins
#if defined(STM32F40_41xxx) || defined(STM32F411xE) #ifdef STM32F4
IOConfigGPIOAF(scl, IOCFG_I2C, GPIO_AF_I2C); IOConfigGPIOAF(scl, IOCFG_I2C, GPIO_AF_I2C);
IOConfigGPIOAF(sda, IOCFG_I2C, GPIO_AF_I2C); IOConfigGPIOAF(sda, IOCFG_I2C, GPIO_AF_I2C);
#else #else
@ -416,8 +416,7 @@ void i2cInit(I2CDevice device)
if (i2c->overClock) { if (i2c->overClock) {
i2cInit.I2C_ClockSpeed = 800000; // 800khz Maximum speed tested on various boards without issues i2cInit.I2C_ClockSpeed = 800000; // 800khz Maximum speed tested on various boards without issues
} } else {
else {
i2cInit.I2C_ClockSpeed = 400000; // 400khz Operation according specs i2cInit.I2C_ClockSpeed = 400000; // 400khz Operation according specs
} }

View file

@ -54,8 +54,8 @@ static volatile uint16_t i2cErrorCount = 0;
//static volatile uint16_t i2c2ErrorCount = 0; //static volatile uint16_t i2c2ErrorCount = 0;
static i2cDevice_t i2cHardwareMap[] = { static i2cDevice_t i2cHardwareMap[] = {
{ .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = false }, { .dev = I2C1, .scl = IO_TAG(I2C1_SCL), .sda = IO_TAG(I2C1_SDA), .rcc = RCC_APB1(I2C1), .overClock = I2C1_OVERCLOCK },
{ .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = false } { .dev = I2C2, .scl = IO_TAG(I2C2_SCL), .sda = IO_TAG(I2C2_SDA), .rcc = RCC_APB1(I2C2), .overClock = I2C2_OVERCLOCK }
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -64,190 +64,189 @@ static i2cDevice_t i2cHardwareMap[] = {
uint32_t i2cTimeoutUserCallback(void) uint32_t i2cTimeoutUserCallback(void)
{ {
i2cErrorCount++; i2cErrorCount++;
return false; return false;
} }
void i2cInit(I2CDevice device) void i2cInit(I2CDevice device)
{ {
i2cDevice_t *i2c; i2cDevice_t *i2c;
i2c = &(i2cHardwareMap[device]); i2c = &(i2cHardwareMap[device]);
I2C_TypeDef *I2Cx; I2C_TypeDef *I2Cx;
I2Cx = i2c->dev; I2Cx = i2c->dev;
IO_t scl = IOGetByTag(i2c->scl); IO_t scl = IOGetByTag(i2c->scl);
IO_t sda = IOGetByTag(i2c->sda); IO_t sda = IOGetByTag(i2c->sda);
RCC_ClockCmd(i2c->rcc, ENABLE); RCC_ClockCmd(i2c->rcc, ENABLE);
RCC_I2CCLKConfig(I2Cx == I2C2 ? RCC_I2C2CLK_SYSCLK : RCC_I2C1CLK_SYSCLK); RCC_I2CCLKConfig(I2Cx == I2C2 ? RCC_I2C2CLK_SYSCLK : RCC_I2C1CLK_SYSCLK);
IOConfigGPIOAF(scl, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4); IOConfigGPIOAF(scl, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4);
IOConfigGPIOAF(sda, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4); IOConfigGPIOAF(sda, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL), GPIO_AF_4);
I2C_InitTypeDef i2cInit = { I2C_InitTypeDef i2cInit = {
.I2C_Mode = I2C_Mode_I2C, .I2C_Mode = I2C_Mode_I2C,
.I2C_AnalogFilter = I2C_AnalogFilter_Enable, .I2C_AnalogFilter = I2C_AnalogFilter_Enable,
.I2C_DigitalFilter = 0x00, .I2C_DigitalFilter = 0x00,
.I2C_OwnAddress1 = 0x00, .I2C_OwnAddress1 = 0x00,
.I2C_Ack = I2C_Ack_Enable, .I2C_Ack = I2C_Ack_Enable,
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit, .I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
.I2C_Timing = 0x00E0257A, // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10. .I2C_Timing = i2c->overClock ?
//.I2C_Timing = 0x8000050B; 0x00500E30 : // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
}; 0x00E0257A, // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
//.I2C_Timing = 0x8000050B;
};
if (i2c->overClock) { I2C_Init(I2Cx, &i2cInit);
i2cInit.I2C_Timing = 0x00500E30; // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
}
I2C_Init(I2Cx, &i2cInit);
I2C_Cmd(I2Cx, ENABLE); I2C_Cmd(I2Cx, ENABLE);
} }
uint16_t i2cGetErrorCounter(void) uint16_t i2cGetErrorCounter(void)
{ {
return i2cErrorCount; return i2cErrorCount;
} }
bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data) bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
{ {
addr_ <<= 1; addr_ <<= 1;
I2C_TypeDef *I2Cx; I2C_TypeDef *I2Cx;
I2Cx = i2cHardwareMap[device].dev; I2Cx = i2cHardwareMap[device].dev;
/* Test on BUSY Flag */ /* Test on BUSY Flag */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Configure slave address, nbytes, reload, end mode and start or stop generation */ /* Configure slave address, nbytes, reload, end mode and start or stop generation */
I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
/* Wait until TXIS flag is set */ /* Wait until TXIS flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Send Register address */ /* Send Register address */
I2C_SendData(I2Cx, (uint8_t) reg); I2C_SendData(I2Cx, (uint8_t) reg);
/* Wait until TCR flag is set */ /* Wait until TCR flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET) while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET)
{ {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Configure slave address, nbytes, reload, end mode and start or stop generation */ /* Configure slave address, nbytes, reload, end mode and start or stop generation */
I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
/* Wait until TXIS flag is set */ /* Wait until TXIS flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Write data to TXDR */ /* Write data to TXDR */
I2C_SendData(I2Cx, data); I2C_SendData(I2Cx, data);
/* Wait until STOPF flag is set */ /* Wait until STOPF flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Clear STOPF flag */ /* Clear STOPF flag */
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF); I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
return true; return true;
} }
bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf) bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t* buf)
{ {
addr_ <<= 1; addr_ <<= 1;
I2C_TypeDef *I2Cx; I2C_TypeDef *I2Cx;
I2Cx = i2cHardwareMap[device].dev; I2Cx = i2cHardwareMap[device].dev;
/* Test on BUSY Flag */ /* Test on BUSY Flag */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Configure slave address, nbytes, reload, end mode and start or stop generation */ /* Configure slave address, nbytes, reload, end mode and start or stop generation */
I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* Wait until TXIS flag is set */ /* Wait until TXIS flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Send Register address */ /* Send Register address */
I2C_SendData(I2Cx, (uint8_t) reg); I2C_SendData(I2Cx, (uint8_t) reg);
/* Wait until TC flag is set */ /* Wait until TC flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Configure slave address, nbytes, reload, end mode and start or stop generation */ /* Configure slave address, nbytes, reload, end mode and start or stop generation */
I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); I2C_TransferHandling(I2Cx, addr_, len, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
/* Wait until all data are received */ /* Wait until all data are received */
while (len) { while (len) {
/* Wait until RXNE flag is set */ /* Wait until RXNE flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Read data from RXDR */ /* Read data from RXDR */
*buf = I2C_ReceiveData(I2Cx); *buf = I2C_ReceiveData(I2Cx);
/* Point to the next location where the byte read will be saved */ /* Point to the next location where the byte read will be saved */
buf++; buf++;
/* Decrement the read bytes counter */ /* Decrement the read bytes counter */
len--; len--;
} }
/* Wait until STOPF flag is set */ /* Wait until STOPF flag is set */
i2cTimeout = I2C_LONG_TIMEOUT; i2cTimeout = I2C_LONG_TIMEOUT;
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) { while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
if ((i2cTimeout--) == 0) { if ((i2cTimeout--) == 0) {
return i2cTimeoutUserCallback(); return i2cTimeoutUserCallback();
} }
} }
/* Clear STOPF flag */ /* Clear STOPF flag */
I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF); I2C_ClearFlag(I2Cx, I2C_ICR_STOPCF);
/* If all operations OK */ /* If all operations OK */
return true; return true;
} }
#endif #endif

View file

@ -17,13 +17,19 @@
#pragma once #pragma once
#define I2C1_OVERCLOCK true
#define I2C2_OVERCLOCK true
/* STM32F4 specific settings that apply to all F4 targets */
#ifdef STM32F4 #ifdef STM32F4
#define TASK_GYROPID_DESIRED_PERIOD 125 #define TASK_GYROPID_DESIRED_PERIOD 125
#define SCHEDULER_DELAY_LIMIT 10 #define SCHEDULER_DELAY_LIMIT 10
#define USE_SLOW_SERIAL_CLI #define USE_SLOW_SERIAL_CLI
#define I2C3_OVERCLOCK true
#else #else /* when not an F4 */
#define TASK_GYROPID_DESIRED_PERIOD 1000 #define TASK_GYROPID_DESIRED_PERIOD 1000
#define SCHEDULER_DELAY_LIMIT 100 #define SCHEDULER_DELAY_LIMIT 100