cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030 - I2C Master read with DMA first byte wrong

Posted on May 19, 2015 at 08:00

I use STM32F030x8 as I2C-Masterwith StdLib V1.5.0.

First i write 6 Bytes to a slave device with DMA and itis working like expected. Then a restart with Read-Address is generated to read back the 6 Byte Response from this slave. Sometimes the error occur that the first Byte in my RxBuffer is 0x00 and the second Byte is the expected first. I checked the bus with an oscilloscope and the data stream is ok. Have any other also made this experience an exists an Workaround? Can you also please check my code because something could be wrong:


void
test(
void
) 

{ 

case
eI2CTask_Idle: 

/* Check if new message to transmit is in fifo */

if
(fifoRead(&master_MessageList, &master_Message)) 

{ 

//Fill I2C TxBuffer 

master_TxBuffer[0] = master_Message.Command; 

master_TxBuffer[1] = master_Message.Data>>24; 

master_TxBuffer[2] = master_Message.Data>>16; 

master_TxBuffer[3] = master_Message.Data>>8; 

master_TxBuffer[4] = master_Message.Data; 

master_TxBuffer[5] = CRC_GetValue((
void
*)&master_TxBuffer, bufferSize-1); 



//Start to Write without StopCondition 

DMA_Cmd(I2C_DMA_TxCHANNEL, DISABLE); 

DMA_SetCurrDataCounter(I2C_DMA_TxCHANNEL, bufferSize); 

DMA_Cmd(I2C_DMA_TxCHANNEL, ENABLE); 

//Enable Tx DMA request 

I2C_DMACmd(I2C_PERIPH, I2C_DMAReq_Tx, ENABLE); 


I2C_TransferHandling(I2C_PERIPH, master_Message.Address<<1, bufferSize, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); 


i2c_Task = eI2CTask_MasterWrite; 

} 

break
; 

case
eI2CTask_MasterWrite: 

if
(I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TC) == SET) 

{ 

//Start to Read with StopCondition 

DMA_Cmd(I2C_DMA_RxCHANNEL, DISABLE); 

DMA_SetCurrDataCounter(I2C_DMA_RxCHANNEL, bufferSize); 

DMA_Cmd(I2C_DMA_RxCHANNEL, ENABLE); 

//Enable RX DMA request 

I2C_DMACmd(I2C_PERIPH, I2C_DMAReq_Rx, ENABLE); 

I2C_TransferHandling(I2C_PERIPH, master_Message.Address<<1, bufferSize, I2C_SoftEnd_Mode, I2C_Generate_Start_Read); 


i2c_Task = eI2CTask_MasterRead; 

} 

break
; 

case
eI2CTask_MasterRead: 

if
(I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_BUSY) == RESET) 

{ 

I2C_GenerateSTOP(I2C_PERIPH, ENABLE); 


/* Check CRC-Byte of received buffer*/

if
(master_Message.Command != master_RxBuffer[0]) 

{ 

i2c_Task = eI2CTask_Error; 

} 

else

{ 

i2c_Task = eI2CTask_Finished; 

} 

} 

break
; 

} 

} 


void
configure_GPIO(
void
) 

{ 

/* Initialize CLK */

RCC_AHBPeriphClockCmd(I2C_SDA_GPIO_CLK|I2C_SCL_GPIO_CLK, ENABLE); 


/* Initialize GPIO */

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1); 
//SDA 

GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1); 
//SCL 


GPIO_InitTypeDef GPIO_InitStructure; 

GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN; 

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; 

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 

GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure); 


GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN; 

GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure); 

} 

void
configure_DMA(
void
) 

{ 

/* Initialize CLK */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 

/* Initialize DMA */

DMA_DeInit(I2C_DMA_TxCHANNEL); 

DMA_DeInit(I2C_DMA_RxCHANNEL); 


DMA_InitTypeDef DMA_InitStructure; 

DMA_StructInit(&DMA_InitStructure); 

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 

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_DIR = DMA_DIR_PeripheralSRC; 

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(I2C_PERIPH->RXDR); 

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&master_RxBuffer; 

DMA_InitStructure.DMA_BufferSize = 
sizeof
(master_RxBuffer); 

DMA_Init(I2C_DMA_RxCHANNEL, &DMA_InitStructure); 


DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(I2C_PERIPH->TXDR); 

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&master_TxBuffer; 

DMA_InitStructure.DMA_BufferSize = 
sizeof
(master_TxBuffer); 

DMA_Init(I2C_DMA_TxCHANNEL, &DMA_InitStructure); 


DMA_Cmd(I2C_DMA_TxCHANNEL, DISABLE); 

DMA_Cmd(I2C_DMA_RxCHANNEL, DISABLE); 

} 

void
configure_I2C(
void
) 

{ 

/* Initialize CLK */

RCC_APB1PeriphClockCmd(I2C_CLK, ENABLE); 


/* Initialize I2C */

I2C_DeInit(I2C_PERIPH); 

I2C_Cmd(I2C_PERIPH, DISABLE); 


I2C_InitTypeDef I2C_InitStructure; 

I2C_StructInit(&I2C_InitStructure); 

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; 

I2C_InitStructure.I2C_Timing = 0x0040D4FF; 
// 50 kHz at 24 MHz, normal mode 

I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; 

I2C_InitStructure.I2C_DigitalFilter = 1; 

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; 

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 

I2C_InitStructure.I2C_OwnAddress1 = I2C_OWNADDRESS<<1; 

I2C_Init(I2C_PERIPH, &I2C_InitStructure); 


I2C_ITConfig(I2C_PERIPH, I2C_IT_ADDRI, ENABLE); 
// Enable Address IT 

I2C_ITConfig(I2C_PERIPH, I2C_IT_ERRI, ENABLE); 
// Enable Error IT 


//NVIC_SetPriority(I2C1_IRQn, 0); 

//NVIC_EnableIRQ(I2C1_IRQn); 


I2C_DMACmd(I2C_PERIPH, I2C_DMAReq_Tx, DISABLE); 

I2C_DMACmd(I2C_PERIPH, I2C_DMAReq_Rx, DISABLE); 

I2C_Cmd(I2C_PERIPH, ENABLE); 

}

Best regards #stm32
0 REPLIES 0