cancel
Showing results for 
Search instead for 
Did you mean: 

I2C interface through DMA

khouja_houssem
Associate II
Posted on September 28, 2013 at 18:03

Hi,

I have a long configuration to be done through I2C interface, so I thought I have to do it using DMA.I am trying to read device ID as a start. The problem is that the I2C sequence doesn't reach the end (I2C_GenerateSTOP), but I can see that the value I need to get (the ID) in the DR register with the System Viewer in Keil. I think that I am missing something. Here is my DMA configuration and I2C reading sequence.

static void I2C2_DMA_Config(uint8_t* buffer)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* Initialize the DMA_Channel member */
DMA_InitStructure.DMA_Channel = DMA_Channel_1;
/* Initialize the DMA_PeripheralBaseAddr member */
DMA_InitStructure.DMA_PeripheralBaseAddr = I2C2->DR; //((uint32_t)0x40005410)
/* Initialize the DMA_Memory0BaseAddr member */
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer;
/* Initialize the DMA_PeripheralInc member */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/* Initialize the DMA_MemoryInc member */
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/* Initialize the DMA_PeripheralDataSize member */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
/* Initialize the DMA_MemoryDataSize member */
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
/* Initialize the DMA_Mode member */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
/* Initialize the DMA_Priority member */
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
/* Initialize the DMA_FIFOMode member */
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
/* Initialize the DMA_FIFOThreshold member */
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
/* Initialize the DMA_MemoryBurst member */
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
/* Initialize the DMA_PeripheralBurst member */
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/* If using DMA for Reception */
// if (Direction == IOE_DMA_RX)
// { 
/* Initialize the DMA_DIR member */
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
/* Initialize the DMA_BufferSize member */
DMA_InitStructure.DMA_BufferSize = 2;
DMA_DeInit(DMA1_Stream0);
DMA_Init(DMA1_Stream0, &DMA_InitStructure);
// }
// /* If using DMA for Transmission */
// else if (Direction == IOE_DMA_TX)
// { 
// /* Initialize the DMA_DIR member */
// DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
// 
// /* Initialize the DMA_BufferSize member */
// DMA_InitStructure.DMA_BufferSize = 1;
// 
// DMA_DeInit(IOE_DMA_TX_STREAM);
// 
// DMA_Init(IOE_DMA_TX_STREAM, &DMA_InitStructure);
// }
}
uint8_t DCMI_SingleRandomRead1(uint8_t Device, uint16_t Addr)
{
uint8_t LSB_Addr, MSB_Addr;
uint32_t timeout = DCMI_TIMEOUT_MAX;
uint8_t Data = 0;
// uint8_t IOE_BufferRX[2] = {0x00, 0x00};
LSB_Addr=(uint8_t)(Addr);
MSB_Addr=(uint8_t)(Addr>>8);
/* Configure DMA Peripheral */
I2C2_DMA_Config((uint8_t*)Data);
/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(I2C2, ENABLE);
/* Generate the Start Condition */
I2C_GenerateSTART(I2C2, ENABLE);
/* Test on I2C2 EV5 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
} 
/* Send DCMI selcted device slave Address for write */
I2C_Send7bitAddress(I2C2, Device, I2C_Direction_Transmitter);
/* Test on I2C2 EV6 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
} 
/* Send I2C2 location address MSB */
I2C_SendData(I2C2, (uint8_t)(MSB_Addr));
/* Test on I2C2 EV8 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
}
/* Send I2C2 location address LSB */
I2C_SendData(I2C2, (uint8_t)(LSB_Addr));
/* Test on I2C2 EV8 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
}
/* Clear AF flag if arised */
I2C2->SR1 |= (uint16_t)0x0400; 
/* Generate the Start Condition */
I2C_GenerateSTART(I2C2, ENABLE);
/* Test on I2C2 EV6 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
} 
/* Send DCMI selcted device slave Address for write */
I2C_Send7bitAddress(I2C2, 0x79, I2C_Direction_Receiver);
/* Test on I2C2 EV6 and clear it */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
/* If the timeout delay is exeeded, exit with error code */
if ((timeout--) == 0) return 0xFF;
}
/* Enable I2C DMA request */
I2C_DMACmd(I2C2,ENABLE);
/* Enable DMA RX Channel */
DMA_Cmd(DMA1_Stream0, ENABLE);
/* Wait until DMA Transfer Complete */
timeout = DCMI_TIMEOUT_MAX; /* Initialize timeout value */
while (!DMA_GetFlagStatus(DMA1_Stream0, DMA_FLAG_TCIF0))
{
if ((timeout--) == 0) return 0xFF;
} 
/* Send STOP Condition */
I2C_GenerateSTOP(I2C2, ENABLE);
/* Disable DMA RX Channel */
DMA_Cmd(DMA1_Stream0, DISABLE);
/* Disable I2C DMA request */ 
I2C_DMACmd(I2C2,DISABLE);
/* Clear DMA RX Transfer Complete Flag */
DMA_ClearFlag(DMA1_Stream0,DMA_FLAG_TCIF0);
/* return a pointer to the IOE_Buffer */
return Data;

0 REPLIES 0