2010-04-30 3:03 AM
I2C EEPROM Read with DMA
2011-05-17 4:49 AM
With own risk!!!!
void fram_write(uint16_t address, uint8_t* buffer, uint32_t length) { DMA_InitTypeDef DMA_InitStructure; if(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) == SET) { i2c_bus_reset(); } /* Care! Other FRAM Memory Sizes use different addressing (1 byte or 2 byte etc.)*/ //((((uint8_t*) &address)[2] << 1) | I2C2_SLAVE_ADDRESS7); fram_slave_Address = I2C2_SLAVE_ADDRESS7; fram_RW_DataBuffer[0] = ((uint8_t*) &address)[1]; fram_RW_DataBuffer[1] = ((uint8_t*) &address)[0]; if(length > 0) { /* The first 2 bytes are address bytes msb first */ memcpy(&fram_RW_DataBuffer[2], buffer, length); } iic_direction = IIC_DIRECTION_TRANSMITTER; I2C_AcknowledgeConfig(I2C1, DISABLE); DMA_DeInit(DMA1_Channel6); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C1_DR_Address; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)fram_RW_DataBuffer; DMA_InitStructure.DMA_BufferSize = length + 2; DMA_Init(DMA1_Channel6, &DMA_InitStructure); I2C_DMACmd(I2C1, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); I2C_GenerateSTART(I2C1, ENABLE); fram_wait_ready(); } void fram_read(uint16_t address, uint8_t* buffer, uint32_t length) { DMA_InitTypeDef DMA_InitStructure; fram_write(address, NULL, 0); iic_direction = IIC_DIRECTION_RECEIVER; DMA_DeInit(DMA1_Channel7); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C1_DR_Address; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)fram_RW_DataBuffer; DMA_InitStructure.DMA_BufferSize = length; DMA_Init(DMA1_Channel7, &DMA_InitStructure); I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE); /* Set Last bit to have a NACK on the last received byte */ I2C_DMALastTransferCmd(I2C1, ENABLE); I2C_DMACmd(I2C1, ENABLE); /* Enable the DMA Channel7 Transfer Complete IT */ DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE); I2C_AcknowledgeConfig(I2C1, ENABLE); /* Generate the START */ I2C_GenerateSTART(I2C1, ENABLE); fram_wait_ready(); memcpy(buffer, fram_RW_DataBuffer, length); }2011-05-17 4:49 AM
Joachim, the I2C documentation says that DMA only works for receiving 2 bytes or more.
So, it looks like the code you have won't work for one byte. What do you do if you want to read only one byte?We’re moving the ST Community to a new platform to give you a better and more reliable community experience.