 Hello, and welcome back for the second video of TouchFX Custom SPI Display Implementation. In the past video, we had seen a brief introduction of the project and its creation. Now, we will start with the inclusion of the display drivers and its implementation with TouchFX, finalizing with a screen creation to be shown in the display. Now that we already have the code generated for our application, we need to include the display drivers. For that, you can just drag and drop the driver folder in the ID, and now just make sure that cop files and folder option is checked, then press OK. After that, we need to convert this folder into a source folder. So, give a right click over the folder, then go to new, source folder. In the open it menu, click on browse, then select the display folder and press finish. We need to warn the compiler that we have some header files inside this folder. To do that, just give a right click over the include folder, then select add and remove include path, then just press OK. Now that we already included the display driver into our project, we need to link the generated peripheral code to the driver, then add the display code in utilization and finally link the driver to the TouchFX. So, here in my code, I will open the configuration header file for my display. Note that in this driver, I have three defines for the peripheral hanglers which will be used, one for the SPI, another for the MA, and also one for the timer. To get access to these resources, the main.8 file will be used. So, I will open the main.c file, copy the hanglers, then go to the main.8 file, paste these variables here, convert the two extern variables, then I will save and close this file. Doing that, all the steps for configuring my driver are done. The steps for configuring your driver may be different depending on the driver you are using. Now we need to link these drivers to the TouchFX API. So, open the TouchFX.how.cpp file, and here the first thing we need to do is to comment this warning. Then, within the user code section, we need to include the header file of our display driver. And inside the TouchFX initialize, we can call the init function for our display. To link the driver to the TouchFX, we need to implement three functions in this file. The first function is called TouchFXDisplayDriverTransmitActivity. In this function, we need to warn the TouchFX when the driver is transmitting data to the display. For that, we need to return true or false for this function. I will go back to my display driver code just to show you that here, I have a variable which is set in my transmit function before a transmission is started. Then, I reset this variable in my transmit callback function in the end of the transmission. So, I will use this variable to return the value for the TouchFX. I will copy that and just paste it here in the return variable of the function. The next function which should be implemented is called TouchFXDisplayDriverTransmitBlock. Just take care with the structure of this function because it should be the same as shown here. It's true this function that TouchFX sends us an image block to be shown in the display. So, within this function, we need to call our drawbitmap function from our display driver. And then, we need to pass the pointer to the address that contains the image content, then the x and y position where the image should be drawn, and finally the dimensions of the image. And that's all that we need to implement in this function. Before we continue to the last function, I will need to present a brief explanation on how the tearing effect is working in this application. This is the timing diagram for the tearing effect signal. Please note that depending on the display controller you are using, the method for managing the v-sync pulse may differ. First, we have the internal display v-sync signal, which is externalized through the tearing effect pin. This pin is connected to the MCU EXTI line 0. The next signal is the TouchFX update frame, which represents the time that TouchFX is sending a frame to the display. And finally, we have a signal that reflects the content of a variable flag. During the first add, the v-sync signal goes low, which causes a raising at the tearing effect pin. This results in a rising edge interrupt on the MCU side. Within this interrupt callback, we will add a code to set the TE flag to hash through that a v-sync pulse has occurred. The most important action at this point is to call the TouchFX signal v-sync function. This is an internal TouchFX API function that must be called every time a v-sync pulse occurs. At the second edge, the rising edge of TouchFX update framing means that TouchFX began transmitting a frame to the display. At this time, the TouchFX HowBeginFrame function is called by the TouchFX API to signalize our application that the frame transmission has started. Within this function, we will add some code to reset the TE flag, has turned to our display driver that the screen has been updated in this frame. I would like to highlight here that the TE variable flag is not part of the TouchFX API. It's just a resource used by the custom display driver, which is being used in this example to help us to handle the flow of our application. At the third edge, we see the v-sync signal going high and the TE pin going low. Each will generate a falling edge external interrupt, and within its interrupt callback, we will add some code to start the timer 6. This timer was configured to match its tick frequency with the display internal h-sync signal, so its counter value will be approximately the line number which is being updated by the display controller. On the fourth edge, we see that TouchFX has finished updating the frame. At this time, the TouchFX EndFrame function is called by the TouchFX API to notify our application that the frame transmission has ended. In this function, we will add some code to check if a v-sync pulse occurred during the update period by checking the TE variable. If a pulse occurred, we must call the TouchFX signal v-sync function again. Finally, we return to the first scenario, and the cycle restarts. Here, the timer 6 is stopped and its counter is reset inside the GPIO external interrupt callback function for the rising edge of the TE pin. I didn't talk about timer 6 stop and reset before, just to make it easier to be understood. This stop and reset action happens on our rising edge of the TearingEffect pin. Now that we know how the TearingEffect is working, we can implement the TouchFX display driver shouldTransferBlock function. The TouchFX API uses this function to ask your application if it should transfer the next image block. In this function, we need to return true if the image block should be transmitted and false if not. We only want to transmit the block to the display if the last line of the block is smaller than the last line updated by the display controller. Therefore, we have developed a logic that compares if the bottom is smaller than the timer counter, which reflects the line number being updated by the display controller, as explained before. This is done to avoid the TearingEffect on the display. Now that we have eradicated the three necessary functions, we can scroll to the beginning of the code and implement its prototypes. In my next implementation, I would like to warn my display driver that the screen was updated in the last-of-a-sync pulse. To do that, I use the TouchFX BeginFrame function, which is called when the TouchFX starts to transmit our image block to the display. Here, I will just set the TeVariable to 0. Just to recap, this variable is set to 1 in the external interrupt callback whenever a v-sync pulse occurs. Finally, in the TouchFX EndFrame function, I will check if a v-sync pulse occurred. If it so, I will signalize a v-sync to the TouchFX to let it prepare the next image block to be sent. This function is called whenever an image block is fully transmitted, and to call this function here, we need to include the OS Rappers library. Now, I will go back to the display driver file to implement the code to handle the signal over the TearingEffect pin. In this driver, we have this GPIO callback function, which should be called every time we have changes in the TearingEffect pin. The most important thing here is that we use the signal to call the TouchFX v-sync function, which is a function that should be called every time you have a v-sync pulse in your application. In addition, this function increments the TeVariable, stops and reset the Timer 6 in the rising callback, and starts the timer in the falling callback as explained before. To call the TouchFX signal v-sync function in this file, we need to add its function prototype at the beginning of the code. Since the presented GPIO callback function is not a standard callback, it will not be automatically called when the interrupt happens. Therefore, we need to manually call this function in the howextern interrupt callback function. For that, we need to take the how GPIO EXTI callback function inside the how GPIO driver file. So, let's open it within drivers, how, search, stm32howgpao.cfile. Once opened the file, I will search for the how GPIO EXTI callback function, then I will select it and copy. After that, I will go back to the touchfxhow.cpp file and paste it in the final of the code. We think this function I will check if the pink which generated the interrupt was the tearing effect pink, and if it's so, I will call the driver GPIO callback function. Here, I will just go back to my driver file to copy the function name. Then, I will go back to the touchfxhow.cpp file and paste it here. Now, only two steps remain to finish this implementation. Firstly, we need to notify touchfx every time a buffer transmission is completed. To achieve this, we should call the display driver transfer complete callback function. In this example, it's done within the driver DMA callback function, which should be called whenever an SPI with DMA transfer ends. We also need to add the prototype of this function to the header file, so it will be exported to the rest of the application. Finally, the last step is to call the display driver DMA callback in the howDMA it handler. So, going back to the driver code, I will copy the name of DMA callback function, then I will open the stm32g4it.c file, and here I will search for the DMA handler. And within this function, I will paste the function call. Since my driver is already handling the interrupt flags, I will also add an ifdef with a dummy name here to prevent the howDMA handler from being executed. By doing this, our code will not be overwriting in case of a new generation. Finally, I will just press contrast to save this file, and then we can close it. Now that all the code implementation is done, we can open the application template.touchFX.part file to access the TouchFX designer and begin designing our screens. Once you open the TouchFX designer tool, I will design a simple screen with a dark blue background and a touchFX label to be presented in the display. Finishing the design, we should click here to generate the code. Now, going back to the IDE, we need to give a right click over the project, then click on refresh. It will update the file reference of our project. And now that everything is done, I will open the bug session to show the application running. After the debug session is fully opened, we can run the code and observe the TouchFX application in action, drawing our screen in the display. And that concludes what I wanted to show you today. I hope you enjoyed the video and found it helpful for your projects using this powerful tool called TouchFX. Best wishes for your future in the universe and I will see you in the next videos. Goodbye.