问题GD32F330CBT6 I2C DMA仅在第一次工作

[复制链接]
 楼主| fleepv7 发表于 2020-12-12 11:04 | 显示全部楼层 |阅读模式
本帖最后由 fleepv7 于 2020-12-12 11:05 编辑

你好,我试图将I2C总线与GD32F330CBT6中的DMA一起使用,但没有成功。 仅在将其固定在DMA的FTF标志之后的等待BTC标志的底线上之后,它才第一次工作。 下面是源代码:


初始化代码
  1. void i2cbus_ll_init(void)
  2. {
  3.   dma_parameter_struct dma_init_struct;
  4.   
  5.   // RCU Part
  6.   rcu_periph_clock_enable(I2C_PERIPH_RCU);
  7.   rcu_periph_clock_enable(I2C_PORT_RCU);
  8.   rcu_periph_clock_enable(RCU_DMA);
  9.   
  10.   // GPIO Part
  11.   gpio_af_set(I2C_PORT, GPIO_AF_1, I2C_CLOCK_PIN);
  12.   gpio_af_set(I2C_PORT, GPIO_AF_1, I2C_DATA_PIN);
  13.   
  14.   gpio_mode_set(I2C_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_CLOCK_PIN);
  15.   gpio_output_options_set(I2C_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_CLOCK_PIN);
  16.   
  17.   gpio_mode_set(I2C_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_DATA_PIN);
  18.   gpio_output_options_set(I2C_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_DATA_PIN);
  19.   
  20.   // DMA Part
  21.   // -> RX
  22.   dma_deinit(DMA_CH4);
  23.   dma_struct_para_init(&dma_init_struct);
  24.   dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  25.   dma_init_struct.memory_addr = (uint32_t)i2c_rxbuffer;
  26.   dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  27.   dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  28.   dma_init_struct.number = 24;
  29.   dma_init_struct.periph_addr = I2C1_DATA_ADDRESS;
  30.   dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  31.   dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  32.   dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  33.   dma_init(DMA_CH4, &dma_init_struct);
  34.   
  35.   // -> TX
  36.   dma_deinit(DMA_CH3);
  37.   dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
  38.   dma_init_struct.memory_addr = (uint32_t)i2c_txbuffer;
  39.   dma_init_struct.periph_addr = I2C1_DATA_ADDRESS;
  40.   dma_init_struct.priority = DMA_PRIORITY_HIGH;
  41.   dma_init(DMA_CH3, &dma_init_struct);
  42.   
  43.   dma_circulation_disable(DMA_CH4);
  44.   dma_circulation_disable(DMA_CH3);
  45.   dma_memory_to_memory_disable(DMA_CH4);
  46.   dma_memory_to_memory_disable(DMA_CH3);
  47.   
  48.   dma_interrupt_enable(DMA_CH3, DMA_INT_FTF);
  49.   dma_interrupt_enable(DMA_CH4, DMA_INT_FTF);
  50.   
  51.   // I2C Part
  52.   i2c_clock_config(I2C_PERIPH, 400000U, I2C_DTCY_2);  
  53.   i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0x70);  
  54.   i2c_enable(I2C_PERIPH);
  55.   
  56.   // NVIC Part
  57.   //nvic_irq_enable(I2C_NVIC_EVENT_IRQ, 1, 1);
  58.   nvic_irq_enable(I2C_NVIC_ERROR_IRQ, 1, 2);  
  59.   //nvic_irq_enable(DMA_Channel3_4_IRQn, 0, 0);
  60. }


编写功能代码

  1. i2cbus_error_t i2cbus_write_data(uint8_t addr, uint8_t *data, uint8_t count)
  2. {
  3.   i2cbus_error_t err = I2C_OperationTimedOutError;
  4.   dma_parameter_struct dma_init_struct;
  5.   
  6.   // Copying data to static buffer
  7.   for (int i = 0; i < count; i++)
  8.     i2c_txbuffer[i] = *data++;
  9.   
  10.   // DMA Transfer configuration according to GD32F3x0 User Manual - Page 158/159.
  11.   dma_channel_disable(DMA_CH3);                                         // 1
  12.   dma_memory_to_memory_disable(DMA_CH3);                                // 2
  13.   dma_transfer_direction_config(DMA_CH3, DMA_MEMORY_TO_PERIPHERAL);     // 2  
  14.   dma_circulation_disable(DMA_CH3);                                     // 3
  15.   dma_priority_config(DMA_CH3, DMA_PRIORITY_HIGH);                      // 4  
  16.   dma_periph_increase_disable(DMA_CH3);                                 // 5
  17.   dma_periph_width_config(DMA_CH3, DMA_PERIPHERAL_WIDTH_8BIT);          // 5  
  18.   dma_memory_increase_enable(DMA_CH3);                                  // 5
  19.   dma_memory_width_config(DMA_CH3, DMA_MEMORY_WIDTH_8BIT);              // 5  
  20.   dma_interrupt_enable(DMA_CH3, DMA_INT_FTF);                           // 6
  21.   dma_interrupt_enable(DMA_CH3, DMA_INT_ERR);                           // 6  
  22.   dma_periph_address_config(DMA_CH3, I2C1_DATA_ADDRESS);                // 7
  23.   dma_memory_address_config(DMA_CH3, (uint32_t)i2c_txbuffer);           // 8  
  24.   dma_transfer_number_config(DMA_CH3, count);                           // 9  
  25.   dma_channel_enable(DMA_CH3);                                          // 10
  26.   
  27.   // Wait for bus to be available
  28.   while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));
  29.   // Start
  30.   i2c_start_on_bus(I2C1);  
  31.   while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));
  32.   
  33.   // Address
  34.   i2c_master_addressing(I2C1, addr, I2C_TRANSMITTER);
  35.   while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));  
  36.   i2c_flag_clear(I2C1, I2C_FLAG_ADDSEND);  
  37.   // DMA
  38.   i2c_dma_enable(I2C1, I2C_DMA_ON);
  39.   
  40.   i2c_dma_last_transfer_config(I2C1, I2C_DMALST_OFF);
  41.   
  42.   dma_channel_enable(DMA_CH3);
  43.   
  44.   while (!dma_interrupt_flag_get(DMA_CH3, DMA_INT_FLAG_FTF));
  45.   dma_flag_clear(DMA_CH3, DMA_INT_FLAG_FTF);
  46.   
  47.   while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));
  48.   i2c_stop_on_bus(I2C_PERIPH);
  49.   while(I2C_CTL0(I2C_PERIPH) & 0x0200);
  50.   
  51.   return err;
  52. }


它卡在了线上:while(!i2c_flag_get(I2C1,I2C_FLAG_BTC));;第二次我尝试写作。有人遇到过这个问题吗?
如果我不这样说的话。 DMA不发送数据。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

1

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部