Переход на C++
Очередная попытка реализовать чтение IMU как в рабочей прошивке оказалась провальной. Поэтому было принято решение перенести проект на C++ и писать его подобно рабочей прошивке. Реализован драйвер для I2C. Добавлены файлы интерфейса IMU и конкретного ICM20948.
This commit is contained in:
@@ -4,6 +4,11 @@
|
||||
static uint8_t i2c_buf[16];
|
||||
static uint8_t i2c_index = 0;*/
|
||||
|
||||
static I2C_Request* i2c_head = 0;
|
||||
static I2C_Request* i2c_current = 0;
|
||||
|
||||
static uint8_t imu_buffer[16];
|
||||
|
||||
void imu_pow_init()
|
||||
{
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;
|
||||
@@ -107,33 +112,23 @@ void i2c_read(uint8_t addr, uint8_t reg, uint8_t* buf, uint8_t len)
|
||||
I2C1->ICR |= I2C_ICR_STOPCF;
|
||||
}
|
||||
|
||||
/*void i2c_enqueue(I2C_Request* req)
|
||||
static void i2c_enqueue(I2C_Request* req)
|
||||
{
|
||||
req->next = 0;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
if (!i2c_head)
|
||||
{
|
||||
i2c_head = req;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_Request* cur = i2c_head;
|
||||
while (cur->next) cur = cur->next;
|
||||
cur->next = req;
|
||||
}
|
||||
req->Next = i2c_head;
|
||||
i2c_head = req;
|
||||
|
||||
__enable_irq();
|
||||
|
||||
// если I2C свободен — стартуем
|
||||
// если I2C свободен — запускаем
|
||||
if (!i2c_busy)
|
||||
{
|
||||
NVIC_SetPendingIRQ(I2C1_EV_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_start_next()
|
||||
static void i2c_start_next()
|
||||
{
|
||||
if (!i2c_head)
|
||||
{
|
||||
@@ -143,39 +138,37 @@ void i2c_start_next()
|
||||
|
||||
i2c_busy = 1;
|
||||
|
||||
current_req = i2c_head;
|
||||
i2c_head = i2c_head->next;
|
||||
i2c_current = i2c_head;
|
||||
i2c_head = i2c_head->Next;
|
||||
|
||||
I2C1->CR1 |= I2C_CR1_TXIE |
|
||||
I2C_CR1_RXIE |
|
||||
I2C_CR1_TCIE |
|
||||
I2C_CR1_STOPIE;
|
||||
|
||||
i2c_index = 0;
|
||||
NVIC_EnableIRQ(I2C1_EV_IRQn);
|
||||
|
||||
// сначала пишем регистр
|
||||
I2C1->CR2 = (current_req->addr << 1) |
|
||||
// старт записи регистра
|
||||
I2C1->CR2 = (i2c_current->Address << 1) |
|
||||
(1 << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_START;
|
||||
}*/
|
||||
}
|
||||
|
||||
void i2c_read_async(uint8_t addr, uint8_t reg, uint8_t len, void (*cb)(uint8_t*))
|
||||
void imu_get_async(void (*cb)(uint8_t* data, uint8_t size))
|
||||
{
|
||||
if (i2c_busy) return; // ❗ ВАЖНО
|
||||
static I2C_Request req;
|
||||
|
||||
i2c_busy = 1;
|
||||
req.Callback = cb;
|
||||
req.Buffer = imu_buffer;
|
||||
req.Size = sizeof(imu_buffer);
|
||||
|
||||
i2c_addr = addr;
|
||||
i2c_reg = reg;
|
||||
i2c_len = len;
|
||||
i2c_callback = cb;
|
||||
|
||||
I2C1->CR1 |= I2C_CR1_TXIE |
|
||||
I2C_CR1_RXIE |
|
||||
I2C_CR1_TCIE |
|
||||
I2C_CR1_STOPIE;
|
||||
req.Address = ICM_ADDR;
|
||||
req.Write = 1;
|
||||
req.Read = 12;
|
||||
|
||||
NVIC_EnableIRQ(I2C1_EV_IRQn);
|
||||
imu_buffer[0] = 0x2D; // регистр
|
||||
|
||||
// старт записи регистра
|
||||
I2C1->CR2 = (addr << 1) |
|
||||
(1 << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_START;
|
||||
i2c_enqueue(&req);
|
||||
}
|
||||
|
||||
void i2c_write(uint8_t addr, uint8_t reg, uint8_t data)
|
||||
@@ -197,51 +190,59 @@ void i2c_write(uint8_t addr, uint8_t reg, uint8_t data)
|
||||
|
||||
void I2C1_EV_IRQHandler()
|
||||
{
|
||||
uint32_t isr = I2C1->ISR;
|
||||
static int test_irq = 0;
|
||||
test_irq++;
|
||||
|
||||
|
||||
uint32_t isr = I2C1->ISR;
|
||||
|
||||
// TXIS — отправляем регистр
|
||||
if (isr & I2C_ISR_TXIS)
|
||||
{
|
||||
I2C1->TXDR = i2c_reg;
|
||||
}
|
||||
|
||||
// TC — запускаем чтение
|
||||
else if (isr & I2C_ISR_TC)
|
||||
{
|
||||
I2C1->CR2 = (i2c_addr << 1) |
|
||||
I2C_CR2_RD_WRN |
|
||||
(i2c_len << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_AUTOEND |
|
||||
I2C_CR2_START;
|
||||
}
|
||||
|
||||
// RXNE — читаем байты
|
||||
else if (isr & I2C_ISR_RXNE)
|
||||
{
|
||||
static uint8_t index = 0;
|
||||
i2c_buf[index++] = I2C1->RXDR;
|
||||
|
||||
if (index >= i2c_len)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
// STOP — завершение
|
||||
else if (isr & I2C_ISR_STOPF)
|
||||
{
|
||||
I2C1->ICR |= I2C_ICR_STOPCF;
|
||||
|
||||
i2c_busy = 0;
|
||||
if (!i2c_current)
|
||||
{
|
||||
i2c_start_next();
|
||||
return;
|
||||
}
|
||||
|
||||
I2C1->CR1 |= I2C_CR1_TXIE |
|
||||
I2C_CR1_RXIE |
|
||||
I2C_CR1_TCIE |
|
||||
I2C_CR1_STOPIE;
|
||||
static uint8_t index = 0;
|
||||
|
||||
NVIC_EnableIRQ(I2C1_EV_IRQn);
|
||||
// TXIS
|
||||
if (isr & I2C_ISR_TXIS)
|
||||
{
|
||||
I2C1->TXDR = i2c_current->Buffer[0];
|
||||
}
|
||||
|
||||
if (i2c_callback)
|
||||
i2c_callback(i2c_buf);
|
||||
}
|
||||
// TC → старт чтения
|
||||
else if (isr & I2C_ISR_TC)
|
||||
{
|
||||
I2C1->CR2 = (i2c_current->Address << 1) |
|
||||
I2C_CR2_RD_WRN |
|
||||
(i2c_current->Read << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_AUTOEND |
|
||||
I2C_CR2_START;
|
||||
}
|
||||
|
||||
// RXNE
|
||||
else if (isr & I2C_ISR_RXNE)
|
||||
{
|
||||
|
||||
|
||||
i2c_current->Buffer[index++] = I2C1->RXDR;
|
||||
|
||||
if (index >= i2c_current->Read)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
// STOP
|
||||
else if (isr & I2C_ISR_STOPF)
|
||||
{
|
||||
I2C1->ICR |= I2C_ICR_STOPCF;
|
||||
|
||||
if (i2c_current->Callback)
|
||||
i2c_current->Callback(i2c_current->Buffer, i2c_current->Read);
|
||||
|
||||
i2c_current = 0;
|
||||
|
||||
i2c_start_next();
|
||||
}
|
||||
}
|
||||
|
||||
void imu_read_raw(imu_raw_t* data)
|
||||
|
||||
Reference in New Issue
Block a user