cancel
Showing results for 
Search instead for 
Did you mean: 

I2C using DMA

viktor3
Associate II
Posted on April 30, 2008 at 14:15

I2C using DMA

2 REPLIES 2
viktor3
Associate II
Posted on May 17, 2011 at 12:34

HI

I wrote code to read ann eeprom using DMA. It works when you call the first time. The problem seems to be after generating a STOP condition. The BUSY flag never goes to 0 when using DMA after a STOP condition. Any idea ?

viktor3
Associate II
Posted on May 17, 2011 at 12:34

Problem solved. For those interested in the code :

#define EEPROM_ADDRESS 0xA0

/* Reads ''len'' bytes from EEPROM starting at address ''addr'' and transfer to ram pointed by ''buffer'' */

s16 rd_i2c_dma_n(I2C_TypeDef *I2C, u8* buffer, u16 addr, u16 len)

{

u8 device_addr = (EEPROM_ADDRESS | addr >> 7) & 0xfe;

DMA_Channel7->CCR = 0;

DMA->IFCR |= ((u32)0x0F000000);

DMA_Channel7->CCR = (DMA_Channel6->CCR & 0xFFFF800F) |

DMA_DIR_PeripheralSRC |

DMA_Mode_Normal |

DMA_PeripheralInc_Disable |

DMA_MemoryInc_Enable |

DMA_MemoryDataSize_Byte |

DMA_MemoryDataSize_Byte |

DMA_Priority_VeryHigh |

DMA_M2M_Disable;

DMA_Channel7->CNDTR = len;

DMA_Channel7->CPAR = (u32) (u32) &I2C->DR;

DMA_Channel7->CMAR = (u32) buffer;

I2C->CR1 |= (1<

while(!check_event(I2C, 0x00030001));

I2C->CR1 |= (1<

I2C->DR = device_addr;

while(!check_event(I2C, 0x00070082));

I2C->DR = addr;

while(!check_event(I2C, 0x00070084));

I2C->CR1 |= (1<

while(!check_event(I2C, 0x00030001));

I2C->DR = device_addr | 1;

while(!check_event(I2C, 0x00030002));

I2C->CR2 |= (1<

DMA_Channel7->CCR |= 1;

while(!(DMA->ISR & 0x02000000));

I2C->CR1 |= (1<

while(!check_event(I2C, 0x00000000))(void) I2C->DR;

return 0;

}

static u32 check_event(I2C_TypeDef* I2C, u32 I2C_EVENT)

{

return (I2C->SR1 | (I2C->SR2 << 16)) == I2C_EVENT;

}

[ This message was edited by: viktor2 on 30-04-2008 17:56 ]