cancel
Showing results for 
Search instead for 
Did you mean: 

FT812, Correct way to manually configure SPI?

StandardVs
Associate

Hi guys, I'm fairly a newbie to stm32 so please forgive me if I make some mistakes, I'm trying to configure a driver code for a SPI FT812 NHD display on STM32G474VETx chipset, so far I've been able find a driver code and ported it over onto STM32, however the driver code configured its SPI manually so I figured I'd follow the way it does that as well but I'm worried that I might did it wrong since the program can't seem to get the correct ID bit from the LCD register and I suspect the way I configured SPI pins might be the problem.

I have 2 gpio_init functions, MX_GPIO_Init is for other peripherals and EVE_init_spi is for the display, which I'm having trouble with, the 3 SPI1 pins are SCK -PA5 , MOSI/D1 -PA6 and MISO/D0 -PB5, this is one of the thing that I changed from the original driver code because it appears SPI1 pins on other chipsets are in the order of PA5,PA6,PA7, and they are all on GPIOA whereas mine is separate into GPIOA and GPIOB? bellow is my attached init function 

 

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, Exp2_CS_Pin|Exp1_CS_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin : OutBRotaryEncoder_Pin */
  GPIO_InitStruct.Pin = OutBRotaryEncoder_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(OutBRotaryEncoder_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : SwitchRotaryEncoder_Pin OutARotaryEncoder_Pin */
  GPIO_InitStruct.Pin = SwitchRotaryEncoder_Pin|OutARotaryEncoder_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : RST_Pin */
  GPIO_InitStruct.Pin = RST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : Exp2_CS_Pin Exp1_CS_Pin */
  GPIO_InitStruct.Pin = Exp2_CS_Pin|Exp1_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

  HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

 

and 

 

#if !defined (EVE_CS)
    #define EVE_CS_PORT_NUM 3U
    #define EVE_CS GPIO_PIN_7 // equivalent to PC7 to replace previous CS spi
#endif

#if !defined (EVE_PD)
    #define EVE_PD_PORT_NUM 1U
    #define EVE_PD GPIO_PIN_8 //equivalent to PA8 to replace previous DC pin
#endif

#if !defined (EVE_SPI_NUM)
    #define EVE_SPI_NUM 1U// Equivalent to SPI 1
    #define EVE_SPI_PORT_NUM 1U // Equivalent to Port A but we manually configured it
    #define EVE_SCK GPIO_PIN_5 //PA5 SCK
    #define EVE_MOSI GPIO_PIN_6//PA6 D1
    #define EVE_MISO GPIO_PIN_5//PB5 D0
    #define EVE_SPI_PRESCALER SPI_BAUDRATEPRESCALER_32
    #define EVE_SPI_GPIO_ALT_FUNCTION GPIO_AF5_SPI1//announce that Spi protocol is on spi1
#endif
#if EVE_SPI_NUM == 1U
    #define EVE_SPI SPI1
#endif
#if EVE_SPI_PORT_NUM == 1U
    #define EVE_SPI_PORT GPIOA
#endif
#if EVE_PD_PORT_NUM == 1U
    #define EVE_PD_PORT GPIOA
#endif
#if EVE_CS_PORT_NUM == 3U
    #define EVE_CS_PORT GPIOC
#endif

SPI_HandleTypeDef eve_spi_handle = {0};

void EVE_init_spi(void)
{

#if (EVE_CS_PORT_NUM == 1U) || (EVE_PDN_PORT_NUM == 1U) || (EVE_SPI_PORT_NUM == 1U)
    __HAL_RCC_GPIOA_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 2U) || (EVE_PDN_PORT_NUM == 2U) || (EVE_SPI_PORT_NUM == 2U)
    __HAL_RCC_GPIOB_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 3U) || (EVE_PDN_PORT_NUM == 3U) || (EVE_SPI_PORT_NUM == 3U)
    __HAL_RCC_GPIOC_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 4U) || (EVE_PDN_PORT_NUM == 4U) || (EVE_SPI_PORT_NUM == 4U)
    __HAL_RCC_GPIOD_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 5U) || (EVE_PDN_PORT_NUM == 5U) || (EVE_SPI_PORT_NUM == 5U)
    __HAL_RCC_GPIOE_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 6U) || (EVE_PDN_PORT_NUM == 6U) || (EVE_SPI_PORT_NUM == 6U)
    __HAL_RCC_GPIOF_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 7U) || (EVE_PDN_PORT_NUM == 7U) || (EVE_SPI_PORT_NUM == 7U)
    __HAL_RCC_GPIOG_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 8U) || (EVE_PDN_PORT_NUM == 8U) || (EVE_SPI_PORT_NUM == 8U)
    __HAL_RCC_GPIOH_CLK_ENABLE();
#endif

#if (EVE_CS_PORT_NUM == 9U) || (EVE_PDN_PORT_NUM == 9U) || (EVE_SPI_PORT_NUM == 9U)
    __HAL_RCC_GPIOI_CLK_ENABLE();
#endif

#if (EVE_SPI_NUM == 1U)
    __HAL_RCC_SPI1_CLK_ENABLE();
#elif (EVE_SPI_NUM == 2U)
    __HAL_RCC_SPI2_CLK_ENABLE();
#elif (EVE_SPI_NUM == 3U)
    __HAL_RCC_SPI3_CLK_ENABLE();
#elif (EVE_SPI_NUM == 4U)
    __HAL_RCC_SPI4_CLK_ENABLE();
#elif (EVE_SPI_NUM == 5U)
    __HAL_RCC_SPI5_CLK_ENABLE();
#elif (EVE_SPI_NUM == 6U)
    __HAL_RCC_SPI6_CLK_ENABLE();
#endif

    GPIO_InitTypeDef gpio_init = {0};

    gpio_init.Pin = EVE_CS;
    gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init.Pull = GPIO_NOPULL;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(EVE_CS_PORT, &gpio_init);

    HAL_GPIO_WritePin(EVE_CS_PORT, EVE_CS, GPIO_PIN_SET);

    gpio_init.Pin = EVE_PD;
    gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init.Pull = GPIO_NOPULL;
    gpio_init.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(EVE_PD_PORT, &gpio_init);

    HAL_GPIO_WritePin(EVE_PD_PORT, EVE_PD, GPIO_PIN_SET);

    /* SPIx GPIO Configuration: */
    gpio_init.Pin = EVE_SCK|EVE_MOSI;
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_NOPULL;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = EVE_SPI_GPIO_ALT_FUNCTION;
    HAL_GPIO_Init(GPIOA, &gpio_init);
    //hard code this port since orientation is different and not on same port

    gpio_init.Pin = EVE_MISO;
    gpio_init.Mode = GPIO_MODE_AF_PP;
    gpio_init.Pull = GPIO_NOPULL;
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    gpio_init.Alternate = EVE_SPI_GPIO_ALT_FUNCTION;
    HAL_GPIO_Init(GPIOB, &gpio_init);

    eve_spi_handle.Instance = EVE_SPI;
    eve_spi_handle.Init.Mode = SPI_MODE_MASTER;
    eve_spi_handle.Init.Direction = SPI_DIRECTION_2LINES;
    eve_spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;
    eve_spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;
    eve_spi_handle.Init.CLKPhase = SPI_PHASE_1EDGE;
    eve_spi_handle.Init.NSS = SPI_NSS_SOFT;
    eve_spi_handle.Init.BaudRatePrescaler = EVE_SPI_PRESCALER;
    eve_spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;


    HAL_SPI_Init(&eve_spi_handle);

    __HAL_SPI_ENABLE(&eve_spi_handle);

}

 

then I initialized them simply by calling

 

  MX_GPIO_Init();   //Init peripheral
  MX_DMA_Init();
  MX_SPI3_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
  EVE_init_spi();	//intialize pins for main display

 

the EVE initialization then be used with 

static inline void spi_transmit(uint8_t data)
{
    if (LL_SPI_IsActiveFlag_RXNE(EVE_SPI)) /* if the previous transmit left data in the RX buffer, we need to clear it */
    { /* this is significantly faster than to wait after each transfer for RX to finish */
        (void) EVE_SPI->DR; /* dummy read to clear SPI_SR_RXNE */
    }
    LL_SPI_TransmitData8(EVE_SPI, data);
    while (!LL_SPI_IsActiveFlag_TXE(EVE_SPI)) {}
}



I do suspect clock speed could be a factor as to why my screen doesn't work so I've changed my BAUDRATEPRESCALER around from 8-256, currently its SCK is sitting at 4.5MHz but to no avails, still nothing can be read from the display register, I planned on doing some more research on this and see if it could be a factor later but as of now, initilize gpio correctly is my main concern. Is there anything I'm doing wrong here guys? Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions

Hi,

no...spi should look more like this :

 

 

 

static void WriteCommand(uint8_t cmd) 
{
	HAL_SPI_Transmit(&SPI_PORT, &cmd, sizeof(cmd), 4);
	
}

 

 

 

How to write etc. , just open the project -> drivers -> xxHAL_Driver -> src -> xx_hal_spi.c

and see at function xx the description :

 

 

 

  ==============================================================================
                      ##### IO operation functions #####
 ===============================================================================
 [..]
    This subsection provides a set of functions allowing to manage the SPI
    data transfers.

    [..] The SPI supports master and slave mode :

    (#) There are two modes of transfer:
       (++) Blocking mode: The communication is performed in polling mode.
            The HAL status of all data processing is returned by the same function
            after finishing transfer.
       (++) No-Blocking mode: The communication is performed using Interrupts
            or DMA, These APIs return the HAL status.
            The end of the data processing will be indicated through the
            dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
            using DMA mode.
            The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
            will be executed respectively at the end of the transmit or Receive process
            The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected

    (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
        exist for 1Line (simplex) and 2Lines (full duplex) modes.

@endverbatim
  * @{
  */

/**
  * @brief  Transmit an amount of data in blocking mode.
  *   hspi pointer to a SPI_HandleTypeDef structure that contains
  *               the configuration information for SPI module.
  *   pData pointer to data buffer
  *   Size amount of data to be sent
  *   Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{

 

 

 

+

My biggest problem , on starting with the EVE TFT, was : TFT doing nothing....was about the hardware/spi port settings, too much ringing on the wires . (on H743 - these H7 are damned fast ; your Gxx might be similar.)

So set cpu ->  spi port pins to medium drive speed and see EVE ds, what it expects (clock speed, rising or falling edge etc.)

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3
AScha.3
Chief III

Hi,

for a TFT with EVE controller, i used the lib from Rudolph...

 

https://github.com/RudolphRiedel/FT800-FT813

Just using the HAL , its working fine - and fast. (iirr needs about 60us for a full new screen on 7" TFT )

If you feel a post has answered your question, please click "Accept as Solution".

Hi @AScha.3 , I think I also ported my lib over from Rudolph for my 7inch screen as well, I saw him using LL_SPI_Transmit in his spi transsmit instead of HAL_SPI so I was afraid to modify it at first haha, I will give it a try tomorrow to swap it out to HAL_SPI, configure the pins with ioc file in stm32Cube and report back to here.

As a clarification, the point is just to swap out 

 

static inline void spi_transmit(uint8_t data)
{
    if (LL_SPI_IsActiveFlag_RXNE(EVE_SPI)) /* if the previous transmit left data in the RX buffer, we need to clear it */
    { /* this is significantly faster than to wait after each transfer for RX to finish */
        (void) EVE_SPI->DR; /* dummy read to clear SPI_SR_RXNE */
    }
    LL_SPI_TransmitData8(EVE_SPI, data);
    while (!LL_SPI_IsActiveFlag_TXE(EVE_SPI)) {}
}

 

to 

 

static inline void spi_transmit(uint8_t data)
{
HAL_SPI_TRANSMIT(EVE_SPI, data)
}

 

is that correct? Thank you!

Hi,

no...spi should look more like this :

 

 

 

static void WriteCommand(uint8_t cmd) 
{
	HAL_SPI_Transmit(&SPI_PORT, &cmd, sizeof(cmd), 4);
	
}

 

 

 

How to write etc. , just open the project -> drivers -> xxHAL_Driver -> src -> xx_hal_spi.c

and see at function xx the description :

 

 

 

  ==============================================================================
                      ##### IO operation functions #####
 ===============================================================================
 [..]
    This subsection provides a set of functions allowing to manage the SPI
    data transfers.

    [..] The SPI supports master and slave mode :

    (#) There are two modes of transfer:
       (++) Blocking mode: The communication is performed in polling mode.
            The HAL status of all data processing is returned by the same function
            after finishing transfer.
       (++) No-Blocking mode: The communication is performed using Interrupts
            or DMA, These APIs return the HAL status.
            The end of the data processing will be indicated through the
            dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
            using DMA mode.
            The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
            will be executed respectively at the end of the transmit or Receive process
            The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected

    (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
        exist for 1Line (simplex) and 2Lines (full duplex) modes.

@endverbatim
  * @{
  */

/**
  * @brief  Transmit an amount of data in blocking mode.
  *   hspi pointer to a SPI_HandleTypeDef structure that contains
  *               the configuration information for SPI module.
  *   pData pointer to data buffer
  *   Size amount of data to be sent
  *   Timeout Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{

 

 

 

+

My biggest problem , on starting with the EVE TFT, was : TFT doing nothing....was about the hardware/spi port settings, too much ringing on the wires . (on H743 - these H7 are damned fast ; your Gxx might be similar.)

So set cpu ->  spi port pins to medium drive speed and see EVE ds, what it expects (clock speed, rising or falling edge etc.)

If you feel a post has answered your question, please click "Accept as Solution".