in CMake-armcc/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c [2744:2875]
HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
{
uint32_t tickstart;
uint32_t xfermode;
HAL_StatusTypeDef dmaxferstatus;
/* Check the parameters */
assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
if (hi2c->State == HAL_I2C_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
return HAL_ERROR;
}
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
/* Init tickstart for timeout management*/
tickstart = HAL_GetTick();
hi2c->State = HAL_I2C_STATE_BUSY_TX;
hi2c->Mode = HAL_I2C_MODE_MEM;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
/* Prepare transfer parameters */
hi2c->pBuffPtr = pData;
hi2c->XferCount = Size;
hi2c->XferOptions = I2C_NO_OPTION_FRAME;
hi2c->XferISR = I2C_Master_ISR_DMA;
if (hi2c->XferCount > MAX_NBYTE_SIZE)
{
hi2c->XferSize = MAX_NBYTE_SIZE;
xfermode = I2C_RELOAD_MODE;
}
else
{
hi2c->XferSize = hi2c->XferCount;
xfermode = I2C_AUTOEND_MODE;
}
/* Send Slave Address and Memory Address */
if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
{
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
if (hi2c->hdmatx != NULL)
{
/* Set the I2C DMA transfer complete callback */
hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
/* Set the DMA error callback */
hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
/* Set the unused DMA callbacks to NULL */
hi2c->hdmatx->XferHalfCpltCallback = NULL;
hi2c->hdmatx->XferAbortCallback = NULL;
/* Enable the DMA channel */
dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
}
else
{
/* Update I2C state */
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
/* Update I2C error code */
hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
if (dmaxferstatus == HAL_OK)
{
/* Send Slave Address */
/* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
/* Update XferCount value */
hi2c->XferCount -= hi2c->XferSize;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
/* Note : The I2C interrupts must be enabled after unlocking current process
to avoid the risk of I2C interrupt handle execution before current
process unlock */
/* Enable ERR and NACK interrupts */
I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
/* Enable DMA Request */
hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
}
else
{
/* Update I2C state */
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;
/* Update I2C error code */
hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}