2022-04-18 01:28 AM
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
if(hi2c->State == HAL_I2C_STATE_READY)
{
if((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
/* Wait until BUSY flag is reset */
if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK)
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
/* Disable Pos */
hi2c->Instance->CR1 &= ~I2C_CR1_POS;
hi2c->State = HAL_I2C_STATE_BUSY_TX;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
hi2c->pBuffPtr = pData;
hi2c->XferSize = Size;
hi2c->XferCount = Size;
/* Set the I2C DMA transfer complete callback */
hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
/* Set the DMA error callback */
hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
/* Enable the DMA Stream */
HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->DR, Size);
/* Send Slave Address */
if(I2C_MasterRequestWrite(hi2c, DevAddress, I2C_TIMEOUT_FLAG) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
else
{
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_TIMEOUT;
}
}
/* Enable DMA Request */
hi2c->Instance->CR2 |= I2C_CR2_DMAEN;
/* Clear ADDR flag */
__HAL_I2C_CLEAR_ADDRFLAG(hi2c);
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB8 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = CS_PIN_I2C1_SCL_DPSENSOR_Pin|CS_PIN_I2C1_SDA_DPSENSOR_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I2C1 clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* I2C1 DMA Init */
/* I2C1_RX Init */
hdma_i2c1_rx.Instance = DMA1_Stream0;
hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1;
hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_rx.Init.Mode = DMA_NORMAL;
hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx);
/* I2C1_TX Init */
hdma_i2c1_tx.Instance = DMA1_Stream6;
hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1;
hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c1_tx);
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
...........................
}
2022-04-23 05:58 PM
the slave manufacturer specifies that the slave device will reply with series of bytes after receiveing 0x36 and 0x7C. obviously, it even doesn't set ACK bit.
2022-04-23 07:03 PM
2022-04-23 07:46 PM
yes. I have change several slave devices of same type they all has the same problem.
2022-04-24 02:51 AM
The yellow rectangle at the left side of image before sending the 0x36 is not a correct START sequence. Solve that problem first.