cancel
Showing results for 
Search instead for 
Did you mean: 

I2C DMA data sizes

kevin
Associate II
Posted on June 11, 2013 at 21:12

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
3 REPLIES 3
Amel NASRI
ST Employee
Posted on June 13, 2013 at 14:17

Hello Kevin,

Table 39 in the Reference manual (RM0038) may help you.

Regards,

ST.MCU

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

jpeacock2399
Associate II
Posted on June 13, 2013 at 15:57

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 Peacock
Posted on June 13, 2013 at 16:18

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..