This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems with the Touch Interface and I2C

Good afternoon,

using here the STM32F429ZIT6 Discovery board and Keil uVision 5.14
I am developing a prototype for a DSP project with a GUI that makes use of the touch screen.
The DSP part works ok, as it does the GUI display built with GUIBuilder.
The problem is in the touch interface... the touch controller makes use of the I2C3 port, which has been configured as per the example program contained in apnt_268, i.e. with I2C3_SCL assigned to PA8 and I2C3_SDA assigned to PC9.

What happens is that the program apparently hangs. I traced its execution and found this sequence of calls :
GUI_Init => GUI_X_Init => GUI_TOUCH_Initialize => Touch_Initialize => Touch_Write

Inside Touch_Write there is this statement :

  while (ptrI2C->GetStatus().busy);

Well, that is where the program hangs... it looks like the I2C controller is always busy and the while loops continuously...

Does anybody have words of wisdom to help me to surpass this impasse ?
Thanks

Alberto

  • You should first check if the I2C interface is correctly initialized.

    Therefore verify if the functions I2C_Uninitialize and I2C_PowerControl are called with the correct driver struct.

  • Thanks for your answer. Following in debug the flow of instructions it is possible to see that at the very beginning of the routine Touch_Initialize there are these statement :

      ptrI2C->Initialize  (NULL);
      ptrI2C->PowerControl(ARM_POWER_FULL);
      ptrI2C->Control     (ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_FAST);
      ptrI2C->Control     (ARM_I2C_BUS_CLEAR, 0);
    


    and the routine I2C_PowerControl returns with this statement :

      return ARM_DRIVER_OK;
    


    So I suppose everything went well in the initialization of the I2C controller...

    Still scratching my head...

    Alberto

  • As a follow-on, I saw that these instructions are executed inside I2C_PowerControl :

              __I2C3_CLK_ENABLE();
    
              __I2C3_FORCE_RESET();
              __NOP(); __NOP(); __NOP(); __NOP();
              __I2C3_RELEASE_RESET();
    


    I suppose those four __NOP() are meant for giving some delay during the FORCE_RESET().
    Maybe four are not enough ? The STM32F429 is running at 180 MHz. Unfortunately I cannot add further __NOP() as that part of the code is unmodifiable...

    Alberto

  • Well, it looks like I solved myself the problem, though not in the most satisfactory way...
    I saw in routine I2C_STM32F4xx.c these statements :

            case ARM_I2C_BUS_SPEED_FAST:
              /* Clock = 400kHz,  Rise Time = 300ns */
              if (pclk > 42000000U) { return ARM_DRIVER_ERROR_UNSUPPORTED; }
    


    The "if" was satisfied, as pclk had the value 45000000, so the routine returned with the error code ARM_DRIVER_ERROR_UNSUPPORTED.

    At this point I reduced the clock speed from 180 MHz to 168 MHz, and.. lo and behold.. everything now worked....

    Given that I have to do DSP computations at the maximum possible speed, I would have preferred to have the processor running at its maximum speed of 180 MHz... does anybody know if there is the possibility to convince the I2C interface to function also at that speed ?

    Thanks

    Alberto

  • According to the STM32F4 Reference Manual the maximum APB frequency for I2C is 42MHz. Actually the whole APB1 clock domain has the 42MHz limitation.

    You could set the APB1 prescaler to 8 when running at 180MHZ which would lead to APB1 clock of 22.5MHz. This would be acceptable for I2C but has an impact on all peripherals clocked from APB1 clock domain.

  • It seems that ST has updated the clock information in the latest reference manuals. The APB1 maximum clock frequency is now 45MHz and allows the selection of APB1 prescaler 4 when running at 180MHz.

    Current I2C driver still uses the 42MHz limit. It should be fairly easy to modify the existing driver and changing the max clock from 42MHz to 45MHz.

  • Thanks for pointing to that problem. It just highlights how important it is to check error codes.

    We will fix the issue in the next release of the ST Software Pack

  • Thanks Reinhard and Robert,

    following your advice I manually edited the file

    \Keil_v5\ARM\Pack\Keil\STM32F4xx_DFP\2.4.0\CMSIS\Driver\I2C_STM32F4xx.c

    replacing that 42000000 value with 45000000 in two places.
    Now everything works beautifully at 180 MHz clock speed.

    TNX again

    Alberto