STM32F103 and I2C TX using DMA, byte array issue
Hello, i have the following setup code for i2c and DMA, where i use i2c1 to send some buffer data to a display.
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_BufferSize = DMA_I2C_BUFFER_SIZE;//BufferSize;
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_PeripheralBaseAddr = (uint32_t)I2C1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SSD1306_Buffer;//I2C1_Buffer_Tx;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // enable acknoledge
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000; //400kHz (Fast Mode) (
I2C_Init(I2C1, &I2C_InitStructure);
DMA_Cmd(DMA1_Channel6, ENABLE);And i have the buffer function to send the data via DMA
void I2C_Master_BufferWrite(uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress )
{
//__IO uint32_t Adress = 0;
__IO uint32_t temp = 0;
__IO uint32_t Timeout = 0;
/* Configure the DMA channel for I2Cx transmission */
DMA_InitTypeDef I2CDMA_InitStructure;
I2CDMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer;
I2CDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
I2CDMA_InitStructure.DMA_BufferSize = (uint32_t)NumByteToWrite;
I2CDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C1_DR_Address;
DMA_Cmd(DMA1_Channel6, DISABLE);
DMA_Init(DMA1_Channel6, &I2CDMA_InitStructure);
DMA_Cmd(DMA1_Channel6, ENABLE);
/* Enable the I2Cx DMA requests */
I2C_DMACmd(I2C1, ENABLE);
//I2C1->CR2 |= CR2_DMAEN_Set;
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
//I2C1->CR1 |= CR1_START_Set;
/* Wait until SB flag is set: EV5 */
while ((I2C1->SR1&0x0001) != 0x0001);
/* Send slave address */
I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter);
/* Wait until ADDR is set: EV6 */
while ((I2C1->SR1&0x0002) != 0x0002);
/* Clear ADDR flag by reading SR2 register */
temp = I2C1->SR2;
/* Wait until DMA end of transfer */
while (!DMA_GetFlagStatus(DMA1_FLAG_TC6));
/* Disable the DMA1 Channel 6 */
DMA_Cmd(DMA1_Channel6, DISABLE);
/* Clear the DMA Transfer complete flag */
DMA_ClearFlag(DMA1_FLAG_TC6);
/* EV8_2: Wait until BTF is set before programming the STOP */
while ((I2C1->SR1 & 0x00004) != 0x000004);
/* Program the STOP */
I2C_GenerateSTOP(I2C1,ENABLE);
/* Make sure that the STOP bit is cleared by Hardware */
while ((I2C1->CR1&0x200) == 0x200);
}This piece of code is working somehow strange when i try to send more than 1 byte
I have the following example
uint8_t mm[7]={0x11,0x22,0x33,0x44,0x55,0x66, 0x77 };
I2C_Master_BufferWrite(mm, 5, 0x7A );With a logic analyzer i get the followings.
So i would expect that it sends 5 bytes in order like 0x11 0x22 0x33 0x44 0x55, but it acts like it jumps some certain memory addresses.
What i am doing wrong here?