嗨,对话框
我想使用DMA来做I2C的高速数据传输,DA14586为主机模式。
已经阅读你们提供的sdk /平台/司机/ dma / dma.c提供的驱动和sdk /平台/司机/ 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。回调= 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 =零;
155 DMA_Setup_for_PDM_to_buffer。dma_sense = DMA_SENSE_LEVEL_SENSITIVE;
156
157 DMA_Setup_for_PDM_to_buffer。(mic_circular == true) ?DMA_MODE_CIRCULAR: DMA_MODE_NORMAL;
158 DMA_Setup_for_PDM_to_buffer。长度=长度;
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初始化
(uint16_t dev_address, uint8_t speed, uint8_t address_mode, uint8_t address_size, 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);//启动I2C时钟
181 SetWord16 (I2C_ENABLE_REG 0 x0);//关闭I2C控制器
182
183 SetWord16(I2C_CON_REG, I2C_MASTER_MODE | I2C_SLAVE_DISABLE | I2C_RESTART_EN);//禁用Slave
184 SetBits16(I2C_CON_REG, I2C_SPEED, speed);/ /设置速度
185 # ifdef I2C_SS_FREQ_TRIM
186 SetWord16 (I2C_SS_SCL_HCNT_REG I2C_SS_SCL_HCNT_VAL);//设置SCL时钟高周期计数为标准速度
187 SetWord16 (I2C_SS_SCL_LCNT_REG I2C_SS_SCL_LCNT_VAL);//设置SCL时钟低周期计数为标准速度
188 #endif // I2C_SS_FREQ_TRIM . //
189 # ifdef I2C_FS_FREQ_TRIM
190 SetWord16 (I2C_FS_SCL_HCNT_REG I2C_FS_SCL_HCNT_VAL);//设置SCL时钟高周期计数为快速
191 SetWord16 (I2C_FS_SCL_LCNT_REG I2C_FS_SCL_LCNT_VAL);//设置SCL时钟低周期计数为快速
#endif // I2C_HS_FREQ_TRIM . //
193 SetBits16(I2C_CON_REG, I2C_10BITADDR_MASTER, address_mode);//设置寻址模式
194 SetWord16(I2C_TAR_REG, dev_address & 0x3FF);//设置从设备地址
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);//启用I2C控制器
203
204 #如果0
205 SetWord16 (I2C_ENABLE_REG 0 x1);//启用I2C控制器
206年WAIT_UNTIL_NO_MASTER_ACTIVITY ();//等待I2C主FSM空闲
207 # endif
208
209
210 # 1
211 if (WAIT_UNTIL_NO_MASTER_ACTIVITY() != 0) {
212 pr_err("%s:等待没有主活动错误\n", __func__);
213}
214
215 if (i2c_send_command(START_PRESS_SCNNE_CMD) != 0) {
216 pr_err("%s: i2c发送命令\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;
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开始传输吗?
谢谢。
你好先生,
能告诉我你的电话和邮箱地址吗?
嗨Jelphi
电话:+ 8618605514330
邮件:582883253 @qq.com