cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to transmit more than 4 bytes using I2C DMA LL examples

Nikhil D&K
Senior

Hello,

I am currently using STM32L0538 for my project. I have refereed I2C DMA LL examples from STM32Cube_FW_L0_V1.12.1 and ported the same for STM32L0538 discovery board.

I also got it working, i am able to transmit and receive data using i2c DMA. But issue is i am unable to trasnmit more than 3 bytes of data in single transfer. I would like to transfer 255 bytes of data in single transfer but don't understand how to achieve the same.

I think the issue is DMA accepts buffer of uint32_t as source buffer but my data is of uint8_t type. I have performed the typecasting as done in the demo example for STM32L0 firmware but it didn't work.

Can anyone please help me in this issue.

Can anyone please point out my mistake or how could i transfer more bytes using i2c dma ll example

/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
#if (USE_TIMEOUT == 1)
uint32_t Timeout                             = 0; /* Variable used for Timeout management */
#endif /* USE_TIMEOUT */
uint8_t aLedOn[5]                 =  {0x12,0x34,0x56,0x77,88};
__IO uint8_t  ubNbDataToTransmit       = sizeof(aLedOn);
uint8_t*      pTransmitBuffer          = (uint8_t*)aLedOn;
__IO uint8_t  ubTransferComplete       = 0;
 
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
 
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
 
  /* System interrupt init*/
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
 
  /* USER CODE BEGIN 2 */
  Configure_DMA();
  Configure_I2C_Master();
  LL_mDelay(1000);
  Handle_I2C_Master();
 
  while (1)
  {
 
  }
 
}
 
 
 
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
 
  /* GPIO Ports Clock Enable */
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
 
}
 
/* USER CODE BEGIN 4 */
void Configure_DMA(void)
{
 
  /* (1) Enable the clock of DMA1 */
	  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
 
 
  /* (2) Configure NVIC for DMA transfer complete/error interrupts */
	  /* DMA interrupt init */
	  /* DMA1_Channel4_5_6_7_IRQn interrupt configuration */
	  NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0);
	  NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);
 
 
  /* (4) Configure the DMA1_Channel2 functionnal parameters */
  LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_4, LL_DMA_DIRECTION_MEMORY_TO_PERIPH | \
                                                LL_DMA_PRIORITY_HIGH              | \
                                                LL_DMA_MODE_NORMAL                | \
                                                LL_DMA_PERIPH_NOINCREMENT           | \
                                                LL_DMA_MEMORY_INCREMENT           | \
                                                LL_DMA_PDATAALIGN_BYTE            | \
                                                LL_DMA_MDATAALIGN_BYTE);
  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, ubNbDataToTransmit);
  LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_4, (uint32_t)pTransmitBuffer, (uint32_t)LL_I2C_DMA_GetRegAddr(I2C2, LL_I2C_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4));
  LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_4, LL_DMA_REQUEST_7);
 
//  /* (4) Enable DMA interrupts complete/error */
 
  LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_4);
  LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_4);
}
 
 
 
void Configure_I2C_Master(void)
{
	  LL_I2C_InitTypeDef I2C_InitStruct = {0};
 
	  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 
 
  /* Enable the peripheral clock of GPIOC */
	  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
	  /**I2C2 GPIO Configuration
	  PB13   ------> I2C2_SCL
	  PB14   ------> I2C2_SDA
	  */
	  GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
	  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
	  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
	  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
	  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
	  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
	  GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
	  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
	  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
	  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
	  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
	  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
 
  /* (2) Enable the I2C3 peripheral clock and I2C3 clock source ***************/
 
  /* Enable the peripheral clock for I2C3 */
 
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2);
 
 
  LL_I2C_Disable(I2C2);
 
  /* Configure the SDA setup, hold time and the SCL high, low period */
  /* (uint32_t)0x00601B28 = I2C_TIMING*/
  LL_I2C_SetTiming(I2C2, 0x00100E16);
 
  /* USER CODE END I2C2_Init 1 */
   /** I2C Initialization
   */
 
 
  /* Configure the Own Address1                   */
  /* Reset Values of :
   *     - OwnAddress1 is 0x00
   *     - OwnAddrSize is LL_I2C_OWNADDRESS1_7BIT
   *     - Own Address1 is disabled
   */
  LL_I2C_SetOwnAddress1(I2C2, 0x00, LL_I2C_OWNADDRESS1_7BIT);
  LL_I2C_DisableOwnAddress1(I2C2);
 
  /* Enable Clock stretching */
  /* Reset Value is Clock stretching enabled */
  LL_I2C_EnableClockStretching(I2C2);
 
  /* Configure Digital Noise Filter */
  /* Reset Value is 0x00            */
  LL_I2C_SetDigitalFilter(I2C2, 0x00);
 
  /* Enable Analog Noise Filter           */
  /* Reset Value is Analog Filter enabled */
  LL_I2C_EnableAnalogFilter(I2C2);
 
  /* Enable General Call                  */
  /* Reset Value is General Call disabled */
  LL_I2C_EnableGeneralCall(I2C2);
 
  /* Configure the 7bits Own Address2               */
  /* Reset Values of :
   *     - OwnAddress2 is 0x00
   *     - OwnAddrMask is LL_I2C_OWNADDRESS2_NOMASK
   *     - Own Address2 is disabled
   */
  LL_I2C_SetOwnAddress2(I2C2, 0x00, LL_I2C_OWNADDRESS2_NOMASK);
  LL_I2C_DisableOwnAddress2(I2C2);
 
  /* Configure the Master to operate in 7-bit or 10-bit addressing mode */
  /* Reset Value is LL_I2C_ADDRESSING_MODE_7BIT                         */
  LL_I2C_SetMasterAddressingMode(I2C2, LL_I2C_ADDRESSING_MODE_7BIT);
 
  /* Enable Peripheral in I2C mode */
  /* Reset Value is I2C mode */
  LL_I2C_SetMode(I2C2, LL_I2C_MODE_I2C);
 
 
  LL_I2C_EnableDMAReq_TX(I2C2);
  LL_I2C_Enable(I2C2);
}
 
 
void Handle_I2C_Master(void)
{
	ubTransferComplete = 0;
 
  /* (1) Enable DMA transfer **************************************************/
  LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
 
  /* (2) Initiate a Start condition to the Slave device ***********************/
 
  /* Master Generate Start condition for a write request:
   *  - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS
   *  - with a auto stop condition generation when transmit all bytes
   */
  LL_I2C_HandleTransfer(I2C2, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubNbDataToTransmit, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
 
  /* (3) Loop until end of transfer completed (DMA TC raised) *****************/
 
 
  /* Loop until DMA transfer complete event */
  while(!ubTransferComplete)
  {
  }
 
 
  /* (4) Loop until end of master transfer completed (STOP flag raised) *******/
 
  /* Loop until STOP flag is raised  */
  while(!LL_I2C_IsActiveFlag_STOP(I2C2))
  {
  }
 
  /* (5) Clear pending flags, Data consistency are checking into Slave process */
 
  /* End of I2C_SlaveReceiver_MasterTransmitter_DMA Process */
  LL_I2C_ClearFlag_STOP(I2C2);
 
  /* Turn LED2 On:
   *  - Expected bytes have been sent
   *  - Master Tx sequence completed successfully
   */
}
 

0 REPLIES 0