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 开始传输?
谢谢。
HI Jelphi phone: +8618605514330 Mail: [email protected]