1 /*
2  * Copyright 2019-2021, 2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_FBDEV_H_
9 #define _FSL_FBDEV_H_
10 
11 #include "fsl_video_common.h"
12 #include "fsl_dc_fb.h"
13 #include "rtthread.h"
14 
15 /*
16  * Change Log:
17  *
18  * 1.0.3:
19  *   - Bug Fixes:
20  *     - Fixed the issue that frame buffer content changed when saved
21  *       to free frame buffer list.
22  *
23  * 1.0.2:
24  *   - Bug Fixes:
25  *     - Fixed MISRA 2012 issues.
26  *
27  * 1.0.1:
28  *   - Bug Fixes:
29  *     - Fixed coverity warnings that return values unchedked.
30  *
31  * 1.0.0:
32  *   - Initial version.
33  */
34 
35 /*!
36  * @addtogroup fbdev
37  * @{
38  *
39  * To use the fbdev, follow the workflow:
40  *
41    @code
42    uint8_t layer = 0;
43    fbdev_t fbdev;
44    fbdev_fb_info_t fbInfo;
45    extern const dc_fb_t dc;
46 
47    FBDEV_Open(&fbdev, &dc, layer);
48 
49    fbInfo.bufInfo.pixelFormat = DEMO_BUFFER_PIXEL_FORMAT;
50    fbInfo.bufInfo.width       = DEMO_BUFFER_WIDTH;
51    fbInfo.bufInfo.height      = DEMO_BUFFER_HEIGHT;
52    fbInfo.bufInfo.strideBytes = DEMO_BUFFER_STRIDE_BYTE;
53    fbInfo.buffers[0] = DEMO_BUFFER0_ADDR;
54    fbInfo.buffers[1] = DEMO_BUFFER1_ADDR;
55 
56    FBDEV_SetFrameBufferInfo(&fbdev, &fbInfo);
57 
58    buffer = FBDEV_GetFrameBuffer(&fbdev, 0);
59 
60    fill the buffer here.
61 
62    FBDEV_SetFrameBuffer(&fbdev, buffer, 0);
63 
64    FBDEV_Enable(&fbdev);
65 
66    buffer = FBDEV_GetFrameBuffer(&fbdev, 0);
67 
68    fill the buffer here.
69 
70    FBDEV_SetFrameBuffer(&fbdev, buffer, 0);
71 
72    ...
73 
74    @endcode
75  *
76  */
77 
78 /*******************************************************************************
79  * Definitions
80  ******************************************************************************/
81 /*! @brief How many frame buffers used in each fbdev. */
82 #ifndef FBDEV_MAX_FRAME_BUFFER
83 #define FBDEV_MAX_FRAME_BUFFER 3
84 #endif
85 
86 #define FBDEV_DEFAULT_FRAME_BUFFER 2
87 
88 /*! @brief Frame buffer information. */
89 typedef struct _fbdev_fb_info
90 {
91     uint8_t bufferCount;                   /*!< How many frame buffers used. */
92     void *buffers[FBDEV_MAX_FRAME_BUFFER]; /*!< Address of the frame buffers */
93     dc_fb_info_t bufInfo;                  /*!< Frame buffers information */
94 } fbdev_fb_info_t;
95 
96 /*! @brief FBDEV handle, user should not touch the members directly. */
97 typedef struct _fbdev
98 {
99     fbdev_fb_info_t fbInfo;                /*!< Frame buffer information. */
100     video_stack_t fbManager;               /*!< Manage the framebuffers used by this device. */
101     void *buffers[FBDEV_MAX_FRAME_BUFFER]; /*!< Memory used by @ref fbManager, to save the free frame buffers. */
102     const dc_fb_t *dc;                     /*!< Display controller handle. */
103     uint8_t layer;                         /*!< Layer in the display controller. */
104     bool enabled;                          /*!< The fbdev is enabled or not by @ref FBDEV_Enable. */
105     rt_sem_t semaFbManager;                /*!< Semaphore for the @ref fbManager. */
106     rt_sem_t semaFramePending;             /*!< Semaphore for the @ref framePending. */
107 } fbdev_t;
108 
109 /*! @brief Flags used for FBDEV operations. */
110 enum _fbdev_flag
111 {
112     kFBDEV_NoWait = (1 << 0), /*!< Don't wait until available, but return directly. */
113 };
114 
115 /*******************************************************************************
116  * API
117  ******************************************************************************/
118 
119 #if defined(__cplusplus)
120 extern "C" {
121 #endif
122 
123 /*!
124  * @brief Open the FBDEV.
125  *
126  * @param fbdev The FBDEV handle.
127  * @param dc The display controller used.
128  * @param layer The layer in the display controller.
129  * @return Returns @ref kStatus_Success if success, otherwise returns
130  * error code.
131  */
132 status_t FBDEV_Open(fbdev_t *fbdev, const dc_fb_t *dc, uint8_t layer);
133 
134 /*!
135  * @brief Close the FBDEV.
136  *
137  * @param fbdev The FBDEV handle.
138  * @return Returns @ref kStatus_Success if success, otherwise returns
139  * error code.
140  */
141 status_t FBDEV_Close(fbdev_t *fbdev);
142 
143 /*!
144  * @brief Enable the FBDEV.
145  *
146  * After enabled, the FBDEV will be shown in the panel. This function should be
147  * called after @ref FBDEV_SetFrameBufferInfo.
148  *
149  * @param fbdev The FBDEV handle.
150  * @return Returns @ref kStatus_Success if success, otherwise returns
151  * error code.
152  */
153 status_t FBDEV_Enable(fbdev_t *fbdev);
154 
155 /*!
156  * @brief Disable the FBDEV.
157  *
158  * After disabled, the FBDEV will not be shown in the panel. Don't call
159  * @ref FBDEV_SetFrameBuffer when the FBDEV is disabled.
160  *
161  * @param fbdev The FBDEV handle.
162  * @return Returns @ref kStatus_Success if success, otherwise returns
163  * error code.
164  */
165 status_t FBDEV_Disable(fbdev_t *fbdev);
166 
167 /*!
168  * @brief Get the frame buffer information of the FBDEV.
169  *
170  * @param fbdev The FBDEV handle.
171  * @param info Pointer to the frame buffer information.
172  */
173 void FBDEV_GetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info);
174 
175 /*!
176  * @brief Set the frame buffer information of the FBDEV.
177  *
178  * This function could be used to configure the FRDEV, including set witdh, height,
179  * pixel format, frame buffers, and so on. This function should only be called once
180  * after @ref FBDEV_Open and before @ref FBDEV_Enable.
181  *
182  * @param fbdev The FBDEV handle.
183  * @param info Pointer to the frame buffer information.
184  * @return Returns @ref kStatus_Success if success, otherwise returns
185  * error code.
186  */
187 status_t FBDEV_SetFrameBufferInfo(fbdev_t *fbdev, fbdev_fb_info_t *info);
188 
189 /*!
190  * @brief Get available frame buffer from the FBDEV.
191  *
192  * Upper layer could call this function to get an available frame buffer from
193  * the FBDEV, render send to show.
194  *
195  * @param fbdev The FBDEV handle.
196  * @param flags OR'ed value of @ref _fbdev_flag. If @ref kFBDEV_NoWait is used,
197  * the function returns NULL immediately if no available buffer. If @ref kFBDEV_NoWait
198  * is not used, this function waits until available.
199  *
200  * @return Returns the address of the frame buffer. If no available, returns NULL.
201  */
202 void *FBDEV_GetFrameBuffer(fbdev_t *fbdev, uint32_t flags);
203 
204 /*!
205  * @brief Send frame buffer to the FBDEV.
206  *
207  * Upper layer could call this function to send a frame buffer to the FBDEV. This
208  * function should only be used when the FBDEV is enabled.
209  *
210  * @param fbdev The FBDEV handle.
211  * @param flags OR'ed value of @ref _fbdev_flag. If @ref kFBDEV_NoWait is used,
212  * the function returns NULL immediately if the previous frame buffer is pending.
213  * If @ref kFBDEV_NoWait is not used, this function waits until previous frame
214  * buffer not pending.
215  *
216  * @return Returns @ref kStatus_Success if success, otherwise returns
217  * error code.
218  */
219 status_t FBDEV_SetFrameBuffer(fbdev_t *fbdev, void *frameBuffer, uint32_t flags);
220 
221 #if defined(__cplusplus)
222 }
223 #endif
224 
225 /*! @} */
226 
227 #endif /* _FSL_FBDEV_H_ */
228