AnsweredAssumed Answered

I2C execution speed, with vs without DMA using HAL driver

Question asked by designer on Dec 1, 2014
Latest reply on Dec 2, 2014 by designer
Hello, I am interfacing SC620 LED driver using I2C. 

Here is a function where writing to the LED driver occurs.

/**
 * Write data to SC620 led driver register.
 *
 * @param[in] reg      Select register.
 * @param[in] value   Data to write in the above register.
 * @return                     HAL status (ok, error, busy or timeout).
 */
static HAL_StatusTypeDef hmi_setRegister(SC620_Register reg, uint8_t value)
{
  uint8_t ledBuf[2];
  ledBuf[0] = reg;    // register address
  ledBuf[1] = value;  // data
//  return HAL_I2C_Master_Transmit_DMA(&I2cHandle, SC620_ADDRESS, ledBuf, sizeof(ledBuf));  //DMA tranfer
  return HAL_I2C_Master_Transmit(&I2cHandle, SC620_ADDRESS, ledBuf, sizeof(ledBuf),I2C_TIMEOUT);  // pooling
}

There are two ways writing can happen. First way is usign DMA, and second is using pooling method. Methods have only been taken over from peripheral driver and have not been changed. 

The strange thing is the execution time with DMA transfer is cca 112 microseconds, and with pooling is 106 microseconds. 

The execution time is measured by pin setting inside ISR.

void TIM9_IRQHandler(void)
{
  if(TIM9->SR & TIM_SR_UIF) // if UIF flag is set
  {
    TIM9->SR &= ~TIM_SR_UIF; // clear UIF flag
    gpio_setPin(ISR_DEBUG,1); // heartbeat
    hmi_evaluateHMI();
    gpio_setPin(ISR_DEBUG,0); 
  }
}

Why does DMA take so long to execute? I would expect to see drastic decrease in time execution with DMA, i.e. when data is ready to be tranfered via I2C, CPU would enable DMA transfer and return to do other things, and let DMA do the actual transfer. However, it turns out the DMA is actually slower than pooling.

Can the size of the data I am trying to send be the cause? Would DMA be better only if I have to transfer say 30 bytes, instead of only 2 I am transferring right now? 

I have checked what is using the most time inside of the HAL_I2C_Master_Transmit_DMA function, and it turns out that out of 112 microsecs, __HAL_I2C_CLEAR_ADDRFLAG(hi2c); takes 58 microseconds, and in fact it is reading the SR2 that is taking all this time. Why does reading a register take so much time?

Thanks in advance!

Outcomes