TFT LCD on Nucleo64-F303 + problems...

What are you developing?
alfsch
Posts: 6
Joined: Thu Feb 13, 2020 4:50 pm

TFT LCD on Nucleo64-F303 + problems...

Post by alfsch »

now i got the TFT , 400x240 pix, ST7793 controller, running on arduino; thx to the MCUFRIEND-kbv lib. (..and David ;) , who made it ).
BUT: i want some fast ADC data, so the arduino "analogRead(A5)" is much too slow. (about 10 ks , i want 800 ks , what should be really no problem for 5 Ms ADC.)
now...tried to do a call to HAL functions , to get fast data from adc....but this i didnt get to any working output.
so: how to do a HAL call , working (!!!) (yes, the "Correct usage of HAL functions in Arduino code" and others i was reading - but there is no working example !! more discussion about sense or nonsense of 32bit cpu in arduino...not very helpful. )

so please, can anybody show me, how to get some working HAL calls to arduino?

here is, what i tried in arduino:

Code: Select all

static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */
 GPIO_InitTypeDef          GPIO_InitStruct;
 RCC_PeriphCLKInitTypeDef  PeriphClkInit;
  /* USER CODE END ADC1_Init 0 */


  ADC_ChannelConfTypeDef sConfig;// = {0};

  /* USER CODE BEGIN ADC1_Init 1 */
/* Enable clock of ADCx peripheral */
  __HAL_RCC_ADC1_CLK_ENABLE();

   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV6;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
  /* USER CODE END ADC1_Init 1 */
  /** Common config 
  */
  AdcHandle.Instance = ADC1;
//  AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
//  AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
  AdcHandle.Init.ScanConvMode = ADC_SCAN_DISABLE;
  AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.NbrOfConversion = 1;

  if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the ADC multi-mode 
  */
/*  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES_5;

  if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
/* Configure GPIO pin of the selected ADC channel */
  GPIO_InitStruct.Pin = ADC_CHANNEL_6;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_PIN_0;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  /* USER CODE END ADC1_Init 2 */

}

extern "C" void HAL_ADC_ErrorCallback(ADC_HandleTypeDef * )
{
  /* In case of ADC error, call main error handler */
  Error_Handler();
}
and use:

Code: Select all

 HAL_ADC_Start(&AdcHandle);
        while ((HAL_ADC_GetState(&AdcHandle), HAL_ADC_STATE_READY) == 0);
        adval = HAL_ADC_GetValue(&AdcHandle);
but only 0 data. :oops:

lzb
Posts: 3
Joined: Wed Feb 12, 2020 8:09 am

Re: TFT LCD on Nucleo64-F303 + problems...

Post by lzb »

Arduino itself is a hardware abstraction layer above stm32/avr. If you want faster adc, you must write library yourself.
AFAIK :)

User avatar
fpiSTM
Posts: 182
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 3
Location: Le Mans
Contact:

Re: TFT LCD on Nucleo64-F303 + problems...

Post by fpiSTM »

Hi alfsch
Here an example of HAL usage for ADC:
viewtopic.php?f=41&t=110


To be able to use the HAL for ADC you have to disable the high level Arduino API which use it to avoid any issue.
To achieve this I simply disable the HAL ADC usage by the arduino API by defining -DHAL_ADC_MODULE_ONLY in build_opt.h file.
See https://github.com/stm32duino/wiki/wiki ... uild_opt.h
and https://github.com/stm32duino/wiki/wiki ... odule-only

lzb
Posts: 3
Joined: Wed Feb 12, 2020 8:09 am

Re: TFT LCD on Nucleo64-F303 + problems...

Post by lzb »

fpiSTM wrote:
Fri Feb 14, 2020 6:16 am
To be able to use the HAL for ADC you have to disable the high level Arduino API which use it to avoid any issue.
To achieve this I simply disable the HAL ADC usage by the arduino API by defining -DHAL_ADC_MODULE_ONLY in build_opt.h file.
In stm32duino i can use HAL instead of plain arduino api? This is great!

p.s. im newbie-newbie in stm32duino

User avatar
fpiSTM
Posts: 182
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 3
Location: Le Mans
Contact:

Re: TFT LCD on Nucleo64-F303 + problems...

Post by fpiSTM »

lzb wrote:
Fri Feb 14, 2020 7:09 am

In stm32duino i can use HAL instead of plain arduino api? This is great!

p.s. im newbie-newbie in stm32duino
Yes and also LL ;)

alfsch
Posts: 6
Joined: Thu Feb 13, 2020 4:50 pm

Re: TFT LCD on Nucleo64-F303 + problems...

Post by alfsch »

thx , Frederic ( right ? ) ;)
now i get about 1 Ms from ADC1 , with software call:

Code: Select all

 HAL_ADC_Start(&AdcHandle);
        while ((HAL_ADC_GetState(&AdcHandle), HAL_ADC_STATE_READY) == 0);
        ii[j] = HAL_ADC_GetValue(&AdcHandle);
the important thing was: to create this build_opt.h file , omg.

btw: direct access is working now also, giving about 4 Ms . (with 4.5 sampling time )
loops=0;
ADC1->CR = 0x10000005; // adc start
while( (ADC1->ISR & 0x4 ) ) // adc ready ?
{ loops++; if(loops == 10) break; }

ii[j] = ADC1->DR ;

now..next problem: the TFT has also touch screen, simple resistive; the touch-lib uses (i suppose) standard analogRead(x) - but this hangs up now. :(
how to get this working...AND my fast ADC calls ??
Last edited by alfsch on Fri Feb 14, 2020 1:50 pm, edited 1 time in total.

User avatar
fpiSTM
Posts: 182
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 3
Location: Le Mans
Contact:

Re: TFT LCD on Nucleo64-F303 + problems...

Post by fpiSTM »

You can also use the hal_conf_extra.h file for your custom definition.

To use your custom "Fast ADC" then you will have to modify the TFT library to call it instead of analogRead().
Wen you use HAL_ADC_MODULE_ONLY then the analogRead() simply do nothing.

alfsch
Posts: 6
Joined: Thu Feb 13, 2020 4:50 pm

Re: TFT LCD on Nucleo64-F303 + problems...

Post by alfsch »

ok, i try...

alfsch
Posts: 6
Joined: Thu Feb 13, 2020 4:50 pm

Re: TFT LCD on Nucleo64-F303 + problems...

Post by alfsch »

ok, got it working. was a bit hard fight...init ADC1 , 2, and 3 to hi speed
and then mod the touch lib, to read ADC /analog in 10bits and 20x oversampling (otherwise ADC too fast for "touch"... )

now its running...
Image

just to help others... the "howto" :

A: make new file in sketch folder: build_opt.h ; in file text :" -DHAL_ADC_MODULE_ONLY "

B: copy from cube generated code the HAL calls: here for ADC1 , 2 , 3

Code: Select all

static void ADC1_Config(void)
{
  ADC_ChannelConfTypeDef   sConfig;
  

  /* Configuration of ADCx init structure: ADC parameters and regular group */
  Adc1Handle.Instance = ADC1;

  Adc1Handle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  Adc1Handle.Init.ScanConvMode          = ADC_SCAN_DISABLE;              /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
#if defined ADC_TRIGGER_FROM_TIMER
  Adc1Handle.Init.ContinuousConvMode    = DISABLE;                       /* Continuous mode disabled to have only 1 conversion at each conversion trig */
#else
  Adc1Handle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode to have maximum conversion speed (no delay between conversions) */
#endif
  Adc1Handle.Init.NbrOfConversion       = 1;                             /* Parameter discarded because sequencer is disabled */
  Adc1Handle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  Adc1Handle.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
#if defined ADC_TRIGGER_FROM_TIMER
  Adc1Handle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_Tx_TRGO;  /* Trig of conversion start done by external event */
#else
  Adc1Handle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
#endif

  if (HAL_ADC_Init(&Adc1Handle) != HAL_OK)
  {
    /* ADC initialization error */
    Error_Handler();
  }

  /* Configuration of channel on ADCx regular group on sequencer rank 1 */
  /* Note: Considering IT occurring after each ADC conversion if ADC          */
  /*       conversion is out of the analog watchdog window selected (ADC IT   */
  /*       enabled), select sampling time and ADC clock with sufficient       */
  /*       duration to not create an overhead situation in IRQHandler.        */
  sConfig.Channel      = ADC_CHANNEL_2;
  sConfig.Rank         = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;

  if (HAL_ADC_ConfigChannel(&Adc1Handle, &sConfig) != HAL_OK)
  {
    /* Channel Configuration Error */
    Error_Handler();
  }


}
C: and the needed clocks :

Code: Select all

 extern "C" void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;
  static DMA_HandleTypeDef  DmaHandle;
  RCC_PeriphCLKInitTypeDef  PeriphClkInit;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable clock of GPIO associated to the peripheral channels */
  //  __HAL_RCC_GPIOA_CLK_ENABLE();

  /* Enable clock of ADCx peripheral */
  __HAL_RCC_ADC12_CLK_ENABLE();
  __HAL_RCC_ADC34_CLK_ENABLE();

  /* Configure ADCx clock prescaler */
 
  
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_ADC12
                              |RCC_PERIPHCLK_ADC34;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV4;
  PeriphClkInit.Adc34ClockSelection = RCC_ADC34PLLCLK_DIV1;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);


}
D: add the variables:

Code: Select all

int16_t ii[NN+4];
ADC_HandleTypeDef    Adc1Handle, Adc2Handle, Adc3Handle;
E: use it...

Code: Select all

 
 pinMode(A1, INPUT_ANALOG);

 HAL_ADC_Start(&Adc1Handle);
        while ((HAL_ADC_GetState(&Adc1Handle), HAL_ADC_STATE_READY) == 0);
       
 ii[n]; = (HAL_ADC_GetValue(&Adc1Handle)  );  
    
thx. 8-)

Image

just...how to know, what to write to build_opt.h file ? i.e. for using an opamp or comp , where to look for the needed statement ?
:?:
Attachments
tft-tests.JPG
tft-tests.JPG (77.86 KiB) Viewed 98 times
Last edited by alfsch on Sat Feb 15, 2020 10:11 am, edited 1 time in total.

User avatar
fpiSTM
Posts: 182
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 3
Location: Le Mans
Contact:

Re: TFT LCD on Nucleo64-F303 + problems...

Post by fpiSTM »

Great.

For COMP and OPAMP you have to enable the HAL MODULE:

Using build_opt.h

Code: Select all

-DHAL_COMP_MODULE_ENABLED  -DHAL_OPAMP_MODULE_ENABLED
or using hal_conf_extra.h

Code: Select all

#define HAL_OPAMP_MODULE_ENABLED
#define HAL_COMP_MODULE_ENABLED
build_opt.h is a Read command-line options from file for GCC while the hal_conf_extra.h is a standard header.

Post Reply

Return to “Projects”