Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STM Nucleo I2C not sending all data

Edit:

The solution was to turn down the I2C clock in the initialization block. Although the STM could handle it, the data sheet for the LCD stated it could handle only up to 10kHz.
For the DMA there is an IRQ that must be enabled and setup in the CubeMX software that will enable DMA TX/RX lines.


I'm using an STM32 - Nucleo-F401RE board with freeRTOS. I've used freeRTOS a bit recently, but I have never really used I2C.

Trying to setup a simple LCD display using the I2C drivers that CubeMX generates.

So far it only sends about half the data I request to send. I've tested it with the simple "show firmware" command and this works. So I can verify that the I2C instance is setup correctly.

/* I2C1 init function */
static void MX_I2C1_Init(void)
{

  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

}

It has international pull-up resistors set as well.

/* vdebugTask function */
void vdebugTask(void const * argument)
{
  /* USER CODE BEGIN vdebugTask */

  /* Infinite loop */
  for(;;)
  {
        char hi[6];
        hi[0]   = 'h';
        hi[1]   = 'e';
        hi[2]   = 'y';
        hi[3]   = 'a';
        hi[4]   = 'h';
        hi[5]   = '!';

        HAL_I2C_Master_Transmit_DMA(&hi2c1, (0x50), hi, 6);
        vTaskDelay(10);
  }
  /* USER CODE END vdebugTask */
}

This is the code I am trying to run, I have not changed the HAL function at all. I don't think that it could be more simple than this, however this is all that happens.

I followed the timing constraints in the data sheet for the LCD, and the CubeMX software didn't warn or state anywhere that their I2C drivers had any special requirements. Am I doing something wrong with the program?

missignletters

I have also tried using the non-DMA blocking mode polling transfer function that was also created by CubeMX

HAL_I2C_Master_Transmit(&hi2c1, (0x50), hi, 6, 1000);

This is even worse and just continuously spams the screen with unintelligible text.

like image 238
Tropical_Peach Avatar asked Oct 30 '22 18:10

Tropical_Peach


1 Answers

The solution was to turn down the I2C clock in the initialization block. Although the STM could handle it, the data sheet for the LCD stated it could handle only up to 10kHz. For the DMA there is an IRQ that must be enabled and setup in the CubeMX software that will enable DMA TX/RX lines.

Note that the clock still must adhere to the hardware limitations. I assume that roughly 20% less than maximum stated in the data sheet will suffice. For my LCD this means that I am going to be using 80kHz.

First go to configuration : step 1

And then click on DMA to setup a DMA request. I've only selected TX as I don't care about an RX DMA from the LCD. step 2

like image 85
Tropical_Peach Avatar answered Nov 15 '22 07:11

Tropical_Peach