Connect with LM75 through I2C/DMA on ST32100B
Hi,
I am try to develop a simple I2C “receive data�? type of function; I took most of the code from the zip file that I was able to download from the st webpages.
The main function of interest getBytesI2C1DMA() sends a “0�? to the onboard LM75 and receives two bytes that contain the temperature information. I see the two temperature related bytes in the logic analyzer, but I don’t see the value getting copied into the LM75_BufferRX buffer. LM75_BufferRX[0] and LM75_BufferRX[1] are both reporting 0x0B and the final value that is stored in “tmp�? is wrong. It looks like the DMA copy is failing. I have spent hours trying to figure out whats going wrong here. Can you please point me to the flaw in this code?
Any suggestions/advice is highly appreciated.
typedef
enum { TX = 0, RX = 1 } DMADirection_TypeDef;uint16_t getBytesI2C1DMA(
intaddress,
inttotalBytes) // <---- Problem FUNCTION
{ uint8_t LM75_BufferRX[10] ={1,1,0,0,0,0,0,0,0,0}; if(totalBytes>10)
return0;
sendByteI2C1(address, 0); // Configure DMA Peripheral DMA_Config(RX, (uint8_t*)LM75_BufferRX, totalBytes); // Enable DMA NACK automatic generation I2C_DMALastTransferCmd(I2C1, ENABLE); // Send START condition a second time I2C_GenerateSTART(I2C1, ENABLE); /* Test on SB Flag */ I1C1_Timeout = FLAG_TIMEOUT; while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_SB)) {
if((I1C1_Timeout--) == 0)
return0;
} /* Send LM75 address for read */ I2C_Send7bitAddress(I2C1, address, I2C_Direction_Receiver); /* Test on ADDR Flag */ I1C1_Timeout = FLAG_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
if((I1C1_Timeout--) == 0)
return0;
} // Enable I2C DMA request I2C_DMACmd(I2C1,ENABLE); // Enable DMA RX Channel DMA_Cmd(DMA1_Channel7, ENABLE); // Wait until DMA Transfer Complete I1C1_Timeout = LONG_TIMEOUT; while(!DMA_GetFlagStatus(DMA1_FLAG_TC7)) {
if((I1C1_Timeout--) == 0)
return0;
} // Send STOP Condition I2C_GenerateSTOP(I2C1, ENABLE); // Disable DMA RX Channel DMA_Cmd(DMA1_Channel7, DISABLE); // Disable I2C DMA request I2C_DMACmd(I2C1, DISABLE); // Clear DMA RX Transfer Complete Flag DMA_ClearFlag(DMA1_FLAG_TC7); //!< Store LM75_I2C received data tmp = (uint16_t)(LM75_BufferRX[0] << 8); <------- LM75_BufferRX[0] & [1] contain 0x0B which is not the value I see in the logic analyzer tmp |= LM75_BufferRX[1]; //!< Return Temperature value tmp=(uint16_t)(tmp >> 7); returntmp;
} static void DMA_Config(DMADirection_TypeDef Direction, uint8_t* buffer, uint8_t NumData) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Initialize the DMA_PeripheralBaseAddr member */ DMA_InitStructure.DMA_PeripheralBaseAddr = I2C1_BASE; /* Initialize the DMA_MemoryBaseAddr member */ DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buffer; /* Initialize the DMA_PeripheralInc member */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* Initialize the DMA_MemoryInc member */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* Initialize the DMA_PeripheralDataSize member */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /* Initialize the DMA_MemoryDataSize member */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* Initialize the DMA_Mode member */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* Initialize the DMA_Priority member */ DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; /* Initialize the DMA_M2M member */ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* If using DMA for Reception */ if (Direction == RX) { /* Initialize the DMA_DIR member */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* Initialize the DMA_BufferSize member */ DMA_InitStructure.DMA_BufferSize = NumData; DMA_DeInit(DMA1_Channel7); DMA_Init(DMA1_Channel7, &DMA_InitStructure); } /* If using DMA for Transmission */ else if (Direction == TX) { /* Initialize the DMA_DIR member */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; /* Initialize the DMA_BufferSize member */ DMA_InitStructure.DMA_BufferSize = NumData; DMA_DeInit(DMA1_Channel6); DMA_Init(DMA1_Channel6, &DMA_InitStructure); } } int sendByteI2C1( int address, int byte) { /* Test on BUSY Flag */ I1C1_Timeout = LONG_TIMEOUT; while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)) if ((I1C1_Timeout--) == 0) return 0; /* Enable the I2C peripheral */ I2C_GenerateSTART(I2C1, ENABLE); // Test on SB Flag I1C1_Timeout = FLAG_TIMEOUT; while (!I2C_GetFlagStatus(I2C1,I2C_FLAG_SB)) if ((I1C1_Timeout--) == 0) return 0; /* Send device address for write */ I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter); /* Test on ADDR Flag */ I1C1_Timeout = FLAG_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) if ((I1C1_Timeout--) == 0) return 0; I2C_SendData(I2C1, byte); /* Test on ADDR Flag */ I1C1_Timeout = FLAG_TIMEOUT; while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) // EV-8 if ((I1C1_Timeout--) == 0) return 0; return 1; } This is how I initialize the I2C interfacevoid
initI2C() { I2C_InitTypeDef I2C_InitStructure; //--------------------------------------------------------- //-------------- Initialize GPIO GPIO_InitTypeDef GPIO_InitStructure; /*!< I2C1 Periph clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /*!< LM75_I2C_SCL_GPIO_CLK, LM75_I2C_SDA_GPIO_CLK and LM75_I2C_SMBUSALERT_GPIO_CLK Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOB, ENABLE); /*!< Configure I2C1 pins: SCL */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); /*!< Configure I2C1 pins: SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); /*!< Configure I2C1 pin: SMBUS ALERT */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); //----------------------------------------------------------- I2C_DeInit(I2C1); /*!< I2C1 Init */ I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = L2C_SPEED; I2C_Init(I2C1, &I2C_InitStructure); /*!< Enable SMBus Alert interrupt */ I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); /*!< I2C1 Init */ I2C_Cmd(I2C1, ENABLE); } #i2c-lm75-dma #stm32-i2c-dma