2013-06-11 12:12 PM
Using a STM32L152RB
I'm trying to send some data out on the I2C bus using DMA, but I can't quite get the data to transmit like I expected. This is how I'm initializing the DMA. My memory source is a 4-element array of 32-bit values (defined uint32_t i2cTxBuffer[]), and I am setting the peripheral to an 8-bit data size./* DMA1 channel 4 configuration ---------------------------------------------*/
/* Enable DMA1 clock -------------------------------------------------------*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure_I2cTx.DMA_PeripheralBaseAddr = (uint32_t) I2C2_DR_ADDR;
DMA_InitStructure_I2cTx.DMA_MemoryBaseAddr = (uint32_t) i2cTxBuffer;
DMA_InitStructure_I2cTx.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure_I2cTx.DMA_BufferSize = 4;
DMA_InitStructure_I2cTx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure_I2cTx.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure_I2cTx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure_I2cTx.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure_I2cTx.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure_I2cTx.DMA_Priority = DMA_Priority_High;
DMA_InitStructure_I2cTx.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure_I2cTx);
/* Enable DMA1 Channel6 Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel4, DMA_IT_HT, ENABLE);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
/* Enable DMA1 channel6 IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
However, when the DMA takes over, it seems to be sending only the least-significant 16 bits of each 32-bit piece of data. I'm wondering why this is. Is a 'word' considered only 16 bits on this micro? Is it an I2C thing? I can't seem to find any info in the manual.
Thanks in advance!
EDIT: Ignore the comments that say 'Channel 6'. Those were just copy-pasted. Also, I realize I could accomplish what I want by simply using an 8-element array of 16-bit values, I just don't want to split the data if at all possible.
#dma
2013-06-13 05:17 AM
Hello Kevin,
Table 39 in the Reference manual (RM0038) may help you. Regards, ST.MCUTo give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2013-06-13 06:57 AM
Your DMA is set up for memory word to peripheral byte transfers. Does that particular processor support unpacking words to bytes with DMA? On the F2/F4 it requires using DMA FIFO mode. As I recall (haven't worked on one in a while) the F1 series doesn't unpack, so you might try memory set to same size as peripheral.
Jack Peacock2013-06-13 07:18 AM
Also, I realize I could accomplish what I want by simply using an 8-element array of 16-bit values, I just don't want to split the data if at all possible.
It's easier than that, you'd just tell the DMA to use 16 byte transfers, and it would use your array in-place.