2024-10-20 01:17 PM
Hi I'm using the STM32F446RE with the latest FW Package - SMT32Cube_FW_F4 V1.28.1, and i have a MCP3221 connected to an I2C port.
Its a strange ADC that returns a sample every 2 bytes when its setup to send data to the I2C master. There are no addresses like most I2C devices.
Since it works in this way i can take advantage of this and I'd like to read it continuously in DMA mode, with no interruptions and so i tried DMA circular mode. The problem is that it runs 1 time trough the recv process and stops after the callback. I'm using CubeMX to setup the peripherals.
I2C init code.
/* USER CODE END I2C3_Init 1 */
hi2c3.Instance = I2C3;
hi2c3.Init.ClockSpeed = 400000;
hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c3.Init.OwnAddress1 = 0;
hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c3.Init.OwnAddress2 = 0;
hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c3) != HAL_OK)
{
Error_Handler();
}
DMA Init code.
/* I2C3 DMA Init */
/* I2C3_RX Init */
hdma_i2c3_rx.Instance = DMA1_Stream1;
hdma_i2c3_rx.Init.Channel = DMA_CHANNEL_1;
hdma_i2c3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_i2c3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_i2c3_rx.Init.Mode = DMA_CIRCULAR;
hdma_i2c3_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_i2c3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_i2c3_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hi2c,hdmarx,hdma_i2c3_rx);
/* I2C3 interrupt Init */
HAL_NVIC_SetPriority(I2C3_EV_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(I2C3_EV_IRQn);
HAL_NVIC_SetPriority(I2C3_ER_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(I2C3_ER_IRQn);
/* USER CODE BEGIN I2C3_MspInit 1 */
Call code.
static volatile uint8_t data_buff[200*2]; //Global variable.
HAL_I2C_Master_Receive_DMA(&hi2c3, I2C_ADDRESS_ADC, (uint8_t *)data_buff, 200/2);
currently my void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) is just blank. I just use it with a breakpoint to check, if it got there. it gets there once and then it stops.
Currently i have it bodged where i start a new transfer as soon as the previous one ends, but I'd prefer to have it with proper circular mode.
Any help would be highly appreciated.