2010-04-30 03:03 AM
I2C EEPROM Read with DMA
2011-05-17 04: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 04: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?