Skip to content

Commit 60e94f2

Browse files
committed
fw/drviers/i2c: add dma support for i2c4 on sifli
Signed-off-by: Qingsong Gou <gouqs@hotmail.com>
1 parent 00bdcb2 commit 60e94f2

3 files changed

Lines changed: 96 additions & 12 deletions

File tree

src/fw/board/boards/board_obelix.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static const I2CSlavePort s_i2c_aw86225 = {
282282
.bus = &s_i2c_bus_1,
283283
.address = 0x58,
284284
};
285-
285+
286286
I2CSlavePort *const I2C_AW86225 = &s_i2c_aw86225;
287287

288288
static const AW86225Config s_aw86225_config = {
@@ -488,6 +488,24 @@ static I2CBusHalState s_i2c_bus_hal_state_4 = {
488488
.Mode = HAL_I2C_MODE_MASTER,
489489
.core = CORE_ID_HCPU,
490490
},
491+
.dma_tx = {
492+
.Instance = DMA1_Channel6,
493+
.dma_irq = DMAC1_CH6_IRQn,
494+
.request = DMA_REQUEST_3,
495+
.dma_irq_prio = 5,
496+
},
497+
.dma_rx = {
498+
.Instance = DMA1_Channel7,
499+
.dma_irq = DMAC1_CH7_IRQn,
500+
.request = DMA_REQUEST_3,
501+
.dma_irq_prio = 5,
502+
},
503+
.hdma_tx = {
504+
.Instance = DMA1_Channel6,
505+
},
506+
.hdma_rx = {
507+
.Instance = DMA1_Channel7,
508+
},
491509
};
492510

493511
static I2CBusHal s_i2c_bus_hal_4 = {
@@ -507,6 +525,9 @@ static I2CBusHal s_i2c_bus_hal_4 = {
507525
.module = RCC_MOD_I2C4,
508526
.irqn = I2C4_IRQn,
509527
.irq_priority = 5,
528+
.dma_tx_irqn = DMAC1_CH6_IRQn,
529+
.dma_rx_irqn = DMAC1_CH7_IRQn,
530+
.dma_irq_priority = 5,
510531
};
511532

512533
static I2CBusState s_i2c_bus_state_4;
@@ -521,6 +542,8 @@ static I2CBus s_i2c_bus_4 = {
521542
I2CBus *const I2C4_BUS = &s_i2c_bus_4;
522543

523544
IRQ_MAP(I2C4, i2c_irq_handler, I2C4_BUS);
545+
IRQ_MAP(DMAC1_CH6, i2c_dma_tx_irq_handler, I2C4_BUS);
546+
IRQ_MAP(DMAC1_CH7, i2c_dma_rx_irq_handler, I2C4_BUS);
524547

525548
static const I2CSlavePort s_i2c_gh3x2x = {
526549
.bus = &s_i2c_bus_4,
@@ -563,7 +586,7 @@ static const I2CSlavePort s_i2c_w1160 = {
563586
.bus = &s_i2c_bus_1,
564587
.address = 0x48,
565588
};
566-
589+
567590
I2CSlavePort *const I2C_W1160 = &s_i2c_w1160;
568591

569592
const BoardConfigPower BOARD_CONFIG_POWER = {
@@ -610,7 +633,7 @@ static const MicDevice mic_device = {
610633
.clk_gpio = {
611634
.pad = PAD_PA22,
612635
.func = PDM1_CLK,
613-
.flags = PIN_NOPULL,
636+
.flags = PIN_NOPULL,
614637
},
615638
.data_gpio = {
616639
.pad = PAD_PA23,
@@ -619,7 +642,7 @@ static const MicDevice mic_device = {
619642
},
620643
.pdm_dma_irq = DMAC1_CH5_IRQn,
621644
.pdm_irq = PDM1_IRQn,
622-
.pdm_irq_priority = 5,
645+
.pdm_irq_priority = 5,
623646
.channels = 1,
624647
.sample_rate = 16000,
625648
.channel_depth = 16,

src/fw/drivers/i2c/sf32lb.c

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ void i2c_irq_handler(I2CBus *bus) {
3434
portEND_SWITCHING_ISR(woken);
3535
}
3636

37+
void i2c_dma_tx_irq_handler(I2CBus *bus) {
38+
I2CBusHal *hal = bus->hal;
39+
I2C_HandleTypeDef *hdl = &hal->state->hdl;
40+
41+
if (hdl->State == HAL_I2C_STATE_BUSY_TX) {
42+
HAL_DMA_IRQHandler(&hal->state->hdma_tx);
43+
} else if (hal->state->hdma_tx.State == HAL_DMA_STATE_BUSY) {
44+
HAL_DMA_IRQHandler(&hal->state->hdma_tx);
45+
}
46+
}
47+
48+
void i2c_dma_rx_irq_handler(I2CBus *bus) {
49+
I2CBusHal *hal = bus->hal;
50+
I2C_HandleTypeDef *hdl = &hal->state->hdl;
51+
52+
if (hdl->State == HAL_I2C_STATE_BUSY_RX) {
53+
HAL_DMA_IRQHandler(&hal->state->hdma_rx);
54+
} else if (hal->state->hdma_rx.State == HAL_DMA_STATE_BUSY) {
55+
HAL_DMA_IRQHandler(&hal->state->hdma_rx);
56+
}
57+
}
58+
3759
void i2c_hal_init_transfer(I2CBus *bus) {}
3860

3961
void i2c_hal_abort_transfer(I2CBus *bus) {
@@ -51,19 +73,35 @@ void i2c_hal_start_transfer(I2CBus *bus) {
5173

5274
if (transfer->type == I2CTransferType_SendRegisterAddress) {
5375
if (transfer->direction == I2CTransferDirection_Read) {
54-
ret = HAL_I2C_Mem_Read_IT(hdl, transfer->device_address, transfer->register_address,
55-
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
76+
if (hal->state->hdma_rx.Instance != NULL) {
77+
ret = HAL_I2C_Mem_Read_DMA(hdl, transfer->device_address, transfer->register_address,
78+
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
79+
} else {
80+
ret = HAL_I2C_Mem_Read_IT(hdl, transfer->device_address, transfer->register_address,
81+
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
82+
}
5683
} else {
57-
ret = HAL_I2C_Mem_Write_IT(hdl, transfer->device_address, transfer->register_address,
58-
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
84+
if (hal->state->hdma_tx.Instance != NULL) {
85+
ret = HAL_I2C_Mem_Write_DMA(hdl, transfer->device_address, transfer->register_address,
86+
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
87+
} else {
88+
ret = HAL_I2C_Mem_Write_IT(hdl, transfer->device_address, transfer->register_address,
89+
I2C_MEMADD_SIZE_8BIT, transfer->data, transfer->size);
90+
}
5991
}
6092
} else {
6193
if (transfer->direction == I2CTransferDirection_Read) {
62-
ret =
63-
HAL_I2C_Master_Receive_IT(hdl, transfer->device_address, transfer->data, transfer->size);
94+
if (hal->state->hdma_rx.Instance != NULL) {
95+
ret = HAL_I2C_Master_Receive_DMA(hdl, transfer->device_address, transfer->data, transfer->size);
96+
} else {
97+
ret = HAL_I2C_Master_Receive_IT(hdl, transfer->device_address, transfer->data, transfer->size);
98+
}
6499
} else {
65-
ret =
66-
HAL_I2C_Master_Transmit_IT(hdl, transfer->device_address, transfer->data, transfer->size);
100+
if (hal->state->hdma_tx.Instance != NULL) {
101+
ret = HAL_I2C_Master_Transmit_DMA(hdl, transfer->device_address, transfer->data, transfer->size);
102+
} else {
103+
ret = HAL_I2C_Master_Transmit_IT(hdl, transfer->device_address, transfer->data, transfer->size);
104+
}
67105
}
68106
}
69107

@@ -106,9 +144,23 @@ void i2c_hal_init(I2CBus *bus) {
106144
HAL_PIN_Set(hal->sda.pad, hal->sda.func, hal->sda.flags, 1);
107145

108146
HAL_RCC_EnableModule(hal->module);
147+
109148
ret = HAL_I2C_Init(hdl);
110149
PBL_ASSERTN(ret == HAL_OK);
111150

151+
if (hal->state->hdma_tx.Instance != NULL && hal->state->hdma_rx.Instance != NULL ) {
152+
__HAL_LINKDMA(hdl, hdmatx, hal->state->hdma_tx);
153+
__HAL_LINKDMA(hdl, hdmarx, hal->state->hdma_rx);
154+
155+
HAL_I2C_DMA_Init(hdl, &hal->state->dma_rx, &hal->state->dma_tx);
156+
157+
HAL_NVIC_SetPriority(hal->dma_tx_irqn, hal->dma_irq_priority, 0);
158+
NVIC_EnableIRQ(hal->dma_tx_irqn);
159+
160+
HAL_NVIC_SetPriority(hal->dma_rx_irqn, hal->dma_irq_priority, 0);
161+
NVIC_EnableIRQ(hal->dma_rx_irqn);
162+
}
163+
112164
HAL_NVIC_SetPriority(hal->irqn, hal->irq_priority, 0);
113165
NVIC_EnableIRQ(hal->irqn);
114166
}

src/fw/drivers/i2c/sf32lb.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
typedef struct I2CBusHalState {
1313
I2C_HandleTypeDef hdl;
14+
DMA_HandleTypeDef hdma_tx;
15+
DMA_HandleTypeDef hdma_rx;
16+
struct dma_config dma_tx;
17+
struct dma_config dma_rx;
1418
} I2CBusHalState;
1519

1620
typedef const struct I2CBusHal {
@@ -20,6 +24,11 @@ typedef const struct I2CBusHal {
2024
RCC_MODULE_TYPE module;
2125
IRQn_Type irqn;
2226
uint8_t irq_priority;
27+
IRQn_Type dma_tx_irqn;
28+
IRQn_Type dma_rx_irqn;
29+
uint8_t dma_irq_priority;
2330
} I2CBusHal;
2431

2532
void i2c_irq_handler(I2CBus *bus);
33+
void i2c_dma_tx_irq_handler(I2CBus *bus);
34+
void i2c_dma_rx_irq_handler(I2CBus *bus);

0 commit comments

Comments
 (0)