I2C使用DMA传输

HI, Dialog
我想使用DMA来做 I2C的高速数据传输,DA14586为主机模式。
已经阅读你们提供的 sdk/platform/driver/dma/dma.c提供的驱动和sdk/platform/driver/pdm/pdm_mic.c 对PDM的使用,同时看到你们相关的帖子 https://support.dialog-semiconductor.com/forums/post/dialog-smartbond-bl...,我已经配置了I2C和DMA的相关驱动,但不知道怎么启用I2C开始通过DMA进行读与写的操作。我的DA14586作为主机模式。请问能否提供相关的驱动代码,或者是相关的寄存器的配置与读写流程?

下面是我实现的 I2C DMA的代码

1、DMA初始化部分:

138 static void DMA_init(uint32_t *buffer, uint16_t length)
139 {
140 DMA_Setup_for_PDM_to_buffer.channel_number = DMA_CHANNEL_0;
141 DMA_Setup_for_PDM_to_buffer.src_address = (uint32_t)I2C_DATA_CMD_REG;
142
143 DMA_Setup_for_PDM_to_buffer.a_inc = DMA_AINC_FALSE;
144 DMA_Setup_for_PDM_to_buffer.b_inc = DMA_BINC_TRUE;
145 DMA_Setup_for_PDM_to_buffer.bus_width = DMA_BW_HALFWORD;
146 DMA_Setup_for_PDM_to_buffer.callback = DMA_callback;
147 DMA_Setup_for_PDM_to_buffer.dma_idle = DMA_IDLE_INTERRUPTING_MODE;
148 DMA_Setup_for_PDM_to_buffer.dma_init = DMA_INIT_AX_BX_AY_BY;
149 DMA_Setup_for_PDM_to_buffer.dma_prio = DMA_PRIO_3;
150 DMA_Setup_for_PDM_to_buffer.dma_req_mux = DMA_TRIG_I2C_RXTX;
151 //DMA_Setup_for_PDM_to_buffer.dreq_mode = DMA_DREQ_START;
152 DMA_Setup_for_PDM_to_buffer.dreq_mode = DMA_DREQ_TRIGGERED;
153 DMA_Setup_for_PDM_to_buffer.irq_enable = DMA_IRQ_STATE_ENABLED;
154 DMA_Setup_for_PDM_to_buffer.user_data = NULL;
155 DMA_Setup_for_PDM_to_buffer.dma_sense = DMA_SENSE_LEVEL_SENSITIVE;
156
157 DMA_Setup_for_PDM_to_buffer.circular = (mic_circular == true) ? DMA_MODE_CIRCULAR : DMA_MODE_NORMAL;
158 DMA_Setup_for_PDM_to_buffer.length = length;
159 DMA_Setup_for_PDM_to_buffer.dest_address = (uint32_t)buffer;
160 DMA_Setup_for_PDM_to_buffer.irq_nr_of_trans = mic_int_threshold;
161
162 dma_channel_initialization(&DMA_Setup_for_PDM_to_buffer);
163 }

2、DMA中断回调部分

120 void DMA_callback(void *user_data, uint16_t len)
121 {
123 pr_bug("\n%s: start\n", __func__);
136 }

3、I2C 和DMA 初始化

175 void i2c_dma_master_init(uint16_t dev_address, uint8_t speed, uint8_t address_mode, uint8_t address_size)
176 {
177 DMA_init((uint32_t*)press_buff, 16);
178 dma_channel_enable(DMA_Setup_for_PDM_to_buffer.channel_number, DMA_STATE_ENABLED);
179
180 SetBits16(CLK_PER_REG, I2C_ENABLE, 1); // enable clock for I2C
181 SetWord16(I2C_ENABLE_REG, 0x0); // Disable the I2C controller
182
183 SetWord16(I2C_CON_REG, I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN); // Slave is disabled
184 SetBits16(I2C_CON_REG, I2C_SPEED, speed); // Set speed
185 #ifdef I2C_SS_FREQ_TRIM
186 SetWord16(I2C_SS_SCL_HCNT_REG, I2C_SS_SCL_HCNT_VAL); // Set the SCL clock high-period count for standard speed
187 SetWord16(I2C_SS_SCL_LCNT_REG, I2C_SS_SCL_LCNT_VAL); // Set the SCL clock low-period count for standard speed
188 #endif // I2C_SS_FREQ_TRIM
189 #ifdef I2C_FS_FREQ_TRIM
190 SetWord16(I2C_FS_SCL_HCNT_REG, I2C_FS_SCL_HCNT_VAL); // Set the SCL clock high-period count for fast speed
191 SetWord16(I2C_FS_SCL_LCNT_REG, I2C_FS_SCL_LCNT_VAL); // Set the SCL clock low-period count for fast speed
192 #endif // I2C_HS_FREQ_TRIM
193 SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, address_mode); // Set addressing mode
194 SetWord16(I2C_TAR_REG, dev_address & 0x3FF); // Set Slave device address
195 SetWord16(I2C_RX_TL_REG, RX_TL);
196 i2c_dev_address = dev_address;
197
198 SetWord16(I2C_DMA_CR_REG, RDMAE | TDMAE);
199 SetWord16(I2C_DMA_TDLR_REG, DMATDL);
200 SetWord16(I2C_DMA_RDLR_REG, DMARDL);
201
202 SetWord16(I2C_ENABLE_REG, 0x1); // Enable the I2C controller
203
204 #if 0
205 SetWord16(I2C_ENABLE_REG, 0x1); // Enable the I2C controller
206 WAIT_UNTIL_NO_MASTER_ACTIVITY(); // Wait for I2C master FSM to become IDLE
207 #endif
208
209
210 #if 1
211 if (WAIT_UNTIL_NO_MASTER_ACTIVITY() != 0) {
212 pr_err("%s: Wait no master activity error\n", __func__);
213 }
214
215 if (i2c_send_command(START_PRESS_SCNNE_CMD) != 0) {
216 pr_err("%s: i2c send command\n", __func__);
217 }
218
219 uint32_t tmp_size = I2C_FIFO_SIZE;
220 uint32_t tmp_cmd = READ_PRESS_FRAME_CMD;
221 uint8_t *tmp_buf = press_buff;
222 int ret = read_data_single(&tmp_buf, tmp_cmd, tmp_size);
223 pr_bug("press scann retval (%d)\n", ret);
224 #endif
225 }

上面的 I2C代码使用轮讯的方式可以使用,但是通信速率太低。

以上代码可以 初始完后,我不知道怎么 I2C DMA开始工作? 而且 DMA中断函数也没有调用?
请问我改怎么启动 DMA I2C 开始传输?

谢谢。

Parents Reply Children
No Data