2018-02-15 08:12 AM
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
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-dma2018-02-15 05:58 PM
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); }2018-02-19 05:10 AM
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
2018-03-28 04:14 PM
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.