cancel
Showing results for 
Search instead for 
Did you mean: 

ST32F1 CubeMX - I2C DMA - help needed

Frank Knarf
Associate II
Posted on February 15, 2018 at 17:12

Hi I'm trying to run I2C in DMA mode with LIS35 (accelerometer). I wrote simple code as below but each time when I try to run or debug it I'm getting back return ''LIS35_ERROR;'' which means that LIS35_I2C_Init(void) function goes wrong.

Previously (I mean yesterday) I wrote two similarly projects:

> First was based on HAL_I2C_Mem_Write / 

HAL_I2C_Mem_Read  functions

- and all works properly (return LIS35_OK;)

> Second was based on HAL_I2C_Mem_Write_IT / HAL_I2C_Mem_Read_IT 

functions

- and all works properly(return LIS35_OK;)

Environment:

- STM32CubeMX - updated today,

- Board - Nucleo-F103RB

- CubeMX project added as attachment

- I2C configuration al on pictures below

0690X00000604LDQAY.jpg0690X00000604OGQAY.jpg

current code:

/* USER CODE BEGIN 4 */

char LIS35_I2C_Init(void)

{

uint8_t Sett_Lis35_cr2_boot = LIS35_REG_CR2_BOOT;

uint8_t RegVal, LIS35Settings;

HAL_StatusTypeDef state1, state2, state3;

volatile long int i;

//reset LIS35 settings

if(HAL_I2C_Mem_Write_DMA(&hi2c2, LIS35_Addr, LIS35_REG_CR2, 1, &Sett_Lis35_cr2_boot, 1) != HAL_OK) {

   //led blink info

}

while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){}

//Write settings - activate all axis

LIS35Settings = LIS35_REG_CR1_XEN | LIS35_REG_CR1_YEN | LIS35_REG_CR1_ZEN | LIS35_REG_CR1_ACTIVE;

//WRITE CONFIGURATION TO LIS35 CHIP

if(HAL_I2C_Mem_Write_DMA(&hi2c2, LIS35_Addr, LIS35_REG_CR1, 1, &LIS35Settings, 1)!= HAL_OK) {

   //led blink info

}

while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){}

//Read configuration - if OK, LIS35 is up and running

if(HAL_I2C_Mem_Read_DMA(&hi2c2, LIS35_Addr, LIS35_REG_CR1, 1, &RegVal, 1) != HAL_OK) {

   //led blink info

}

while (HAL_I2C_GetState(&hi2c2) != HAL_I2C_STATE_READY){}

if (RegVal == LIS35Settings){

   HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);

   return LIS35_OK;

}

return LIS35_ERROR;

}

void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c){

static uint8_t cntTx;

cntTx++;

}

void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c){

static uint8_t cntRx;

cntRx++;

}

/* USER CODE END 4 */

Thanks in advance for any help 🙂 

Farnk

#dma-problem #i2c #dma-transfer #i2c-hal-dma #stm32f1-i2c-dma
3 REPLIES 3
T J
Lead
Posted on February 16, 2018 at 02:58

do you really need to use interrupts and DMA ?

it only takes a few hundred uSeconds. maybe a few mS..

it is extremely simple to use without that.

void write4Dacs(void) {  // set voltage to show Dac Number

    char buf[16];

    struct DacIIC MCP4728IIC;   

    HAL_StatusTypeDef IIC_Response;

 

       Dac0_Value  = (4096 * 1) / 5;      // 1V         // Dac1

    

    //Channel 0

    MCP4728IIC.DacTxBuffer[0] =  (Dac0_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[1] =   Dac0_Value & 0x00ff;

    //Channel 1

    Dac1_Value  = Dac0_Value + (4096 * 1) / 5;      // 2V    // Dac 2

    MCP4728IIC.DacTxBuffer[2] =  (Dac1_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[3] =   Dac1_Value & 0x00ff;

    //Channel 2

    Dac2_Value  = Dac1_Value + (4096 * 1) / 5;      // 3V    //Dac 3

    MCP4728IIC.DacTxBuffer[4] =  (Dac2_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[5] =   Dac2_Value & 0x00ff;

    //Channel 3

    Dac3_Value  = Dac2_Value + (4096 * 1) / 5;      // 4V    //Dac 4

    MCP4728IIC.DacTxBuffer[6] =  (Dac3_Value & 0x0f00) >> 8;

    MCP4728IIC.DacTxBuffer[7] =   Dac3_Value & 0x00ff;

    //DAC_IIC.write(DAC_ADDR + (Dac_Address << 1), buf, 8);   

    IIC_Response = HAL_I2C_Master_Transmit(&hi2c1, MCP4728_DacAddress, &MCP4728IIC.DacTxBuffer[0], 8, 10);

 

}
Posted on February 19, 2018 at 13:10

TJ  thank you for your fast reply. There is no need to use interrupts in this case but it will change nothing. I have a need to use I2C in DMA mode, example code is above but don't works, and I have no idea why.

Additionally as I mention (also)above I have ready code based on 'blocking mode' as yours exaple (

HAL_I2C_Master_Transmit

) (and I agree with you - This mode is simple and nice), my question is how to use I2C in DMA mode.

BR's,

Frank

Frank CA
Associate II
Posted on March 29, 2018 at 01:14

Do you see any change in your counters (cntTx, cntRx)?

I have a similar non-working issue with I2C mem Tx with DMA, and I think I have found bugs in the HAL driver code but require more investigation. Your answer to the above question will help, also do you have any other debug information? Are the I2C callbacks activated by DMA transfer complete (Rx and Tx)? Do you know the state of I2C at failure eg I2C_Tx_Busy or I2C_Rx_Busy, and do you have a logic analyzer or DSO to monitor SCL and SDA?

I will post a separate topic on what I find with my application, even if there are no bugs in HAL code there are many traps to be aware of that may help others.