diff options
-rw-r--r-- | chip/stm32/dma.c | 28 | ||||
-rw-r--r-- | chip/stm32/dma.h | 8 | ||||
-rw-r--r-- | chip/stm32/i2c.c | 48 |
3 files changed, 54 insertions, 30 deletions
diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c index ab8e8f2d58..c5d1c5e493 100644 --- a/chip/stm32/dma.c +++ b/chip/stm32/dma.c @@ -278,16 +278,32 @@ struct dma_ctlr *dma_get_ctlr(int channel) static void dma_event_interrupt_channel_4(void) { - dma_clear_isr(DMAC_I2C_TX); - if (id[DMAC_I2C_TX] != TASK_ID_INVALID) - task_wake(id[DMAC_I2C_TX]); + dma_clear_isr(DMAC_I2C2_TX); + if (id[DMAC_I2C2_TX] != TASK_ID_INVALID) + task_wake(id[DMAC_I2C2_TX]); } DECLARE_IRQ(STM32_IRQ_DMA_CHANNEL_4, dma_event_interrupt_channel_4, 3); static void dma_event_interrupt_channel_5(void) { - dma_clear_isr(DMAC_I2C_RX); - if (id[DMAC_I2C_RX] != TASK_ID_INVALID) - task_wake(id[DMAC_I2C_RX]); + dma_clear_isr(DMAC_I2C2_RX); + if (id[DMAC_I2C2_RX] != TASK_ID_INVALID) + task_wake(id[DMAC_I2C2_RX]); } DECLARE_IRQ(STM32_IRQ_DMA_CHANNEL_5, dma_event_interrupt_channel_5, 3); + +static void dma_event_interrupt_channel_6(void) +{ + dma_clear_isr(DMAC_I2C1_TX); + if (id[DMAC_I2C1_TX] != TASK_ID_INVALID) + task_wake(id[DMAC_I2C1_TX]); +} +DECLARE_IRQ(STM32_IRQ_DMA_CHANNEL_6, dma_event_interrupt_channel_6, 3); + +static void dma_event_interrupt_channel_7(void) +{ + dma_clear_isr(DMAC_I2C1_RX); + if (id[DMAC_I2C1_RX] != TASK_ID_INVALID) + task_wake(id[DMAC_I2C1_RX]); +} +DECLARE_IRQ(STM32_IRQ_DMA_CHANNEL_7, dma_event_interrupt_channel_7, 3); diff --git a/chip/stm32/dma.h b/chip/stm32/dma.h index 76380de6f7..c9832fcfe3 100644 --- a/chip/stm32/dma.h +++ b/chip/stm32/dma.h @@ -26,11 +26,13 @@ enum { DMAC_SPI2_TX, /* - * The same channels are used for i2c and spi, you can't use them at + * The same channels are used for i2c2 and spi, you can't use them at * the same time or it will cause dma to not work */ - DMAC_I2C_RX = 4, - DMAC_I2C_TX = 3, + DMAC_I2C2_TX = 3, + DMAC_I2C2_RX = 4, + DMAC_I2C1_TX = 5, + DMAC_I2C1_RX = 6, /* DMA1 has 7 channels, DMA2 has 5 */ DMA1_NUM_CHANNELS = 7, diff --git a/chip/stm32/i2c.c b/chip/stm32/i2c.c index 6a4da26158..5acd5c40f9 100644 --- a/chip/stm32/i2c.c +++ b/chip/stm32/i2c.c @@ -59,6 +59,12 @@ #define I2C1 STM32_I2C1_PORT #define I2C2 STM32_I2C2_PORT +/* select the DMA channels matching the board configuration */ +#define DMAC_SLAVE_TX ((I2C_PORT_SLAVE) ? DMAC_I2C2_TX : DMAC_I2C1_TX) +#define DMAC_SLAVE_RX ((I2C_PORT_SLAVE) ? DMAC_I2C2_RX : DMAC_I2C1_RX) +#define DMAC_HOST_TX ((I2C_PORT_HOST) ? DMAC_I2C2_TX : DMAC_I2C1_TX) +#define DMAC_HOST_RX ((I2C_PORT_HOST) ? DMAC_I2C2_RX : DMAC_I2C1_RX) + enum { /* * A stop condition should take 2 clocks, but the process may need more @@ -73,16 +79,16 @@ enum { }; static const struct dma_option dma_tx_option[NUM_PORTS] = { - {DMAC_I2C_TX, (void *)&STM32_I2C_DR(I2C1), + {DMAC_I2C1_TX, (void *)&STM32_I2C_DR(I2C1), DMA_MSIZE_BYTE | DMA_PSIZE_HALF_WORD}, - {DMAC_I2C_TX, (void *)&STM32_I2C_DR(I2C2), + {DMAC_I2C2_TX, (void *)&STM32_I2C_DR(I2C2), DMA_MSIZE_BYTE | DMA_PSIZE_HALF_WORD}, }; static const struct dma_option dma_rx_option[NUM_PORTS] = { - {DMAC_I2C_RX, (void *)&STM32_I2C_DR(I2C1), + {DMAC_I2C1_RX, (void *)&STM32_I2C_DR(I2C1), DMA_MSIZE_BYTE | DMA_PSIZE_HALF_WORD}, - {DMAC_I2C_RX, (void *)&STM32_I2C_DR(I2C2), + {DMAC_I2C2_RX, (void *)&STM32_I2C_DR(I2C2), DMA_MSIZE_BYTE | DMA_PSIZE_HALF_WORD}, }; @@ -142,26 +148,26 @@ static int i2c_write_raw_slave(int port, void *buf, int len) /* we don't want to race with TxE interrupt event */ disable_i2c_interrupt(port); - /* Configuring DMA1 channel DMAC_I2X_TX */ + /* Configuring DMA1 channel DMAC_SLAVE_TX */ enable_ack(port); - chan = dma_get_channel(DMAC_I2C_TX); + chan = dma_get_channel(DMAC_SLAVE_TX); dma_prepare_tx(dma_tx_option + port, len, buf); /* Start the DMA */ dma_go(chan); - /* Configuring i2c2 to use DMA */ + /* Configuring i2c to use DMA */ STM32_I2C_CR2(port) |= (1 << 11); if (in_interrupt_context()) { /* Poll for the transmission complete flag */ - dma_wait(DMAC_I2C_TX); - dma_clear_isr(DMAC_I2C_TX); + dma_wait(DMAC_SLAVE_TX); + dma_clear_isr(DMAC_SLAVE_TX); } else { /* Wait for the transmission complete Interrupt */ - dma_enable_tc_interrupt(DMAC_I2C_TX); + dma_enable_tc_interrupt(DMAC_SLAVE_TX); rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - dma_disable_tc_interrupt(DMAC_I2C_TX); + dma_disable_tc_interrupt(DMAC_SLAVE_TX); if (!(rv & TASK_EVENT_WAKE)) { CPRINTF("[%T Slave timeout, resetting i2c]\n"); @@ -169,7 +175,7 @@ static int i2c_write_raw_slave(int port, void *buf, int len) } } - dma_disable(DMAC_I2C_TX); + dma_disable(DMAC_SLAVE_TX); STM32_I2C_CR2(port) &= ~(1 << 11); enable_i2c_interrupt(port); @@ -273,8 +279,8 @@ static void i2c_event_handler(int port) /* If it's a receiver slave */ if (!(STM32_I2C_SR2(port) & (1 << 2))) { /* Disable, and clear the DMA transfer complete flag */ - dma_disable(DMAC_I2C_RX); - dma_clear_isr(DMAC_I2C_RX); + dma_disable(DMAC_SLAVE_RX); + dma_clear_isr(DMAC_SLAVE_RX); /* Turn off i2c's DMA flag */ STM32_I2C_CR2(port) &= ~(1 << 11); @@ -741,10 +747,10 @@ static int i2c_master_transmit(int port, int slave_addr, uint8_t *data, /* Configuring DMA1 channel DMAC_I2X_TX */ dma_prepare_tx(dma_tx_option + port, size, data); - dma_enable_tc_interrupt(DMAC_I2C_TX); + dma_enable_tc_interrupt(DMAC_HOST_TX); /* Start the DMA */ - dma_go(dma_get_channel(DMAC_I2C_TX)); + dma_go(dma_get_channel(DMAC_HOST_TX)); /* Configuring i2c2 to use DMA */ STM32_I2C_CR2(port) |= CR2_DMAEN; @@ -756,8 +762,8 @@ static int i2c_master_transmit(int port, int slave_addr, uint8_t *data, if (!rv_start) rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - dma_disable(DMAC_I2C_TX); - dma_disable_tc_interrupt(DMAC_I2C_TX); + dma_disable(DMAC_HOST_TX); + dma_disable_tc_interrupt(DMAC_HOST_TX); STM32_I2C_CR2(port) &= ~CR2_DMAEN; if (rv_start) @@ -790,7 +796,7 @@ static int i2c_master_receive(int port, int slave_addr, uint8_t *data, enable_ack(port); dma_start_rx(dma_rx_option + port, size, data); - dma_enable_tc_interrupt(DMAC_I2C_RX); + dma_enable_tc_interrupt(DMAC_HOST_RX); STM32_I2C_CR2(port) |= CR2_DMAEN; STM32_I2C_CR2(port) |= CR2_LAST; @@ -799,8 +805,8 @@ static int i2c_master_receive(int port, int slave_addr, uint8_t *data, if (!rv_start) rv = task_wait_event(DMA_TRANSFER_TIMEOUT_US); - dma_disable(DMAC_I2C_RX); - dma_disable_tc_interrupt(DMAC_I2C_RX); + dma_disable(DMAC_HOST_RX); + dma_disable_tc_interrupt(DMAC_HOST_RX); STM32_I2C_CR2(port) &= ~CR2_DMAEN; disable_ack(port); |