1 /*
2  * Copyright 2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _FSL_PNGDEC_H_
8 #define _FSL_PNGDEC_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup pngdec
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @name Driver version */
22 /*@{*/
23 /*! @brief PNGDEC driver version 2.0.0. */
24 #define FSL_PNGDEC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
25 /*@}*/
26 
27 /*! @brief Error codes for the PNGDEC driver. */
28 enum
29 {
30     kStatus_PNGDEC_NotSupported  = MAKE_STATUS(kStatusGroup_PNGDEC, 0), /*!< Interlace data chunk is not supported. */
31     kStatus_PNGDEC_WidthTooLarge = MAKE_STATUS(kStatusGroup_PNGDEC, 1), /*!< The image width is larger than 1024. */
32 };
33 
34 /*! @brief Interrupt enable/disable mask. */
35 enum _pngdec_interrupt_enable
36 {
37     kPNGDEC_ChecksumErrorFlag   = (1U << 0U), /*!< ADLER-32 checksum error status and interrupt enable. */
38     kPNGDEC_CrcErrorFlag        = (1U << 1U), /*!< CRC error status and interrupt enable. */
39     kPNGDEC_HeaderErrorFlag     = (1U << 2U), /*!< Header error status and interrupt enable. */
40     kPNGDEC_BtypeErrorFlag      = (1U << 3U), /*!< B type error status and interrupt enable. TODO*/
41     kPNGDEC_ZlibHeaderErrorFlag = (1U << 4U), /*!< Zlib header error status and interrupt enable. */
42     kPNGDEC_BitDepthErrorFlag =
43         (1U << 5U), /*!< Bit depth error status and interrupt enable. Bit depth less than 8 bit not supported. */
44     kPNGDEC_InterlaceErrorFlag =
45         (1U << 6U), /*!< Interlace error status and interrupt enable. Interlace is not supported. */
46     kPNGDEC_WidthErrorFlag          = (1U << 7U), /*!< Width error status and interrupt enable. Max image width 1024. */
47     kPNGDEC_EncodeDataDoneFlag      = (1U << 8U), /*!< Data encoding done status and interrupt enable. */
48     kPNGDEC_DecodePixelDoneFlag     = (1U << 9U), /*!< Pixel data decoding done status and interrupt enable. */
49     kPNGDEC_DecodeAncillaryDoneFlag = (1U << 10U), /*!< Ancillary data decoding done status and interrupt enable. */
50 
51     kPNGDEC_ErrorFlags = kPNGDEC_ChecksumErrorFlag | kPNGDEC_CrcErrorFlag | kPNGDEC_HeaderErrorFlag |
52                          kPNGDEC_BtypeErrorFlag | kPNGDEC_ZlibHeaderErrorFlag | kPNGDEC_BitDepthErrorFlag |
53                          kPNGDEC_InterlaceErrorFlag | kPNGDEC_WidthErrorFlag,
54 };
55 
56 /*!
57  * @brief PNG decode endian mode.
58  */
59 typedef enum _pngdec_endian_mode
60 {
61     kPNGDEC_LittleEndian = 0U, /*!< Little endian. */
62     kPNGDEC_BigEndian    = 1U, /*!< Big endian. */
63 } pngdec_endian_mode_t;
64 
65 /*! @brief Configuration for PNGDEC. */
66 typedef struct _pngdec_config
67 {
68     bool enableAncillary;            /*!< Enable ancillary data drop. */
69     bool enable;                     /*!< Enables the decode IP. */
70 } pngdec_config_t;
71 
72 /*!
73  * @brief PNG color type.
74  */
75 typedef enum _pngdec_color_type
76 {
77     kPNGDEC_PixelFormatY8              = 0U, /*!< 8-bit monochrome(gray scale). */
78     kPNGDEC_PixelFormatYA88            = 1U, /*!< 16-bit monochrome(gray scale) with alpha. */
79     kPNGDEC_PixelFormatRGB888          = 2U, /*!< 24-bit RGB true color, 8-bit each palette. */
80     kPNGDEC_PixelFormatRGBA8888        = 3U, /*!< 32-bit RGBA true color with alpha, 8-bit each palette. */
81     kPNGDEC_PixelFormatRGB16_16_16     = 4U, /*!< 48-bit RGB true color, 16-bit each palette. */
82     kPNGDEC_PixelFormatRGBA16_16_16_16 = 5U, /*!< 64-bit RGBA true color with alpha, 16-bit each palette. */
83     kPNGDEC_PixelFormatLUT8            = 6U, /*!< 8-bit Indexed Color. */
84 } pngdec_color_type_t;
85 
86 /*! @brief The decoded image info structure. */
87 typedef struct _pngdec_image
88 {
89     uint32_t width;                /*!< Decoded image width. */
90     uint32_t height;               /*!< Decoded image height. */
91     pngdec_color_type_t colorType; /*!< Color type for the generated image. */
92     uint8_t *imageData;            /*!< Pointer to the buffer for decoded image data. */
93     uint8_t *ancillaryData;        /*!< Pointer to the buffer for decoded ancillary data. */
94     uint32_t ancillaryLength;      /*!< Length of the ancillary data. */
95 } pngdec_image_t;
96 
97 #if defined(__cplusplus)
98 extern "C" {
99 #endif
100 
101 /*******************************************************************************
102  * API
103  ******************************************************************************/
104 /*!
105  * @name Initialization and deinitialization
106  * @{
107  */
108 /*!
109  * @brief Initializes the PNGDEC.
110  *
111  * The default configuration can be got by calling PNGDEC_GetDefaultConfig().
112  *
113  * @param base PNGDEC peripheral base address.
114  * @param config Pointer to PNGDEC configuration structure.
115  */
116 void PNGDEC_Init(PNGDEC_Type *base, const pngdec_config_t *config);
117 
118 /*!
119  * @brief Deinitializes the PNGDEC.
120  *
121  * @param base PNGDEC peripheral base address.
122  */
123 void PNGDEC_Deinit(PNGDEC_Type *base);
124 
125 /*!
126  * @brief Gets the default configuration for PNGDEC.
127  *
128  * This function initializes the user configuration structure to default value. The default value are:
129  *
130  * Example:
131    @code
132    config->enableAncillary = false;
133    config->enable = false;
134    @endcode
135  *
136  * @param config Pointer to PNGDEC configuration structure.
137  */
138 void PNGDEC_GetDefaultConfig(pngdec_config_t *config);
139 /* @} */
140 
141 /*!
142  * @name Interrupts
143  * @{
144  */
145 /*!
146  * @brief Enables interrupts.
147  *
148  * @param base PNGDEC peripheral base address.
149  * @param mask Interrupts mask. See "_pngdec_interrupt_enable".
150  */
PNGDEC_EnableInterrupts(PNGDEC_Type * base,uint32_t mask)151 static inline void PNGDEC_EnableInterrupts(PNGDEC_Type *base, uint32_t mask)
152 {
153     base->DEC_INT_STS_EN |= mask;
154 }
155 
156 /*!
157  * @brief Disables interrupts.
158  *
159  * @param base PNGDEC peripheral base address.
160  * @param mask Interrupts mask. See "_pngdec_interrupt_enable".
161  */
PNGDEC_DisableInterrupts(PNGDEC_Type * base,uint32_t mask)162 static inline void PNGDEC_DisableInterrupts(PNGDEC_Type *base, uint32_t mask)
163 {
164     base->DEC_INT_STS_EN &= ~mask;
165 }
166 /* @} */
167 
168 /*!
169  * @name Status
170  * @{
171  */
172 /*!
173  * @brief Gets status flags.
174  *
175  * @param base PNGDEC peripheral base address.
176  * @return Status flags asserted mask. See "_pngdec_status_flags".
177  */
PNGDEC_GetStatusFlags(PNGDEC_Type * base)178 static inline uint32_t PNGDEC_GetStatusFlags(PNGDEC_Type *base)
179 {
180     return base->DEC_INT_STS;
181 }
182 
183 /*!
184  * @brief Clears status flags.
185  *
186  * @param base PNGDEC peripheral base address.
187  * @param mask Status flags mask. See "_pngdec_status_flags".
188  */
PNGDEC_ClearStatusFlags(PNGDEC_Type * base,uint32_t mask)189 static inline void PNGDEC_ClearStatusFlags(PNGDEC_Type *base, uint32_t mask)
190 {
191     base->DEC_INT_STS = mask;
192 }
193 /* @} */
194 
195 /*!
196  * @name Basic Operations
197  * @{
198  */
199 /*!
200  * @brief Resets the PNGDEC code and DMA logic.
201  *
202  * @param base PNGDEC peripheral base address.
203  */
PNGDEC_Reset(PNGDEC_Type * base)204 static inline void PNGDEC_Reset(PNGDEC_Type *base)
205 {
206     base->GLB_CTRL |= (PNGDEC_GLB_CTRL_DMA_SW_LOGIC_RST_EN_MASK | PNGDEC_GLB_CTRL_IPCORE_SW_LOGIC_RST_EN_MASK);
207     base->CNT_CTRL_CLR = PNGDEC_CNT_CTRL_CLR_CNT_CTRL_CLR_MASK;
208     base->GLB_CTRL &= ~(PNGDEC_GLB_CTRL_DMA_SW_LOGIC_RST_EN_MASK | PNGDEC_GLB_CTRL_IPCORE_SW_LOGIC_RST_EN_MASK);
209     base->CNT_CTRL_CLR = 0U;
210 }
211 
212 /*!
213  * @brief Enables or disables the PNGDEC.
214  *
215  * @param base PNGDEC peripheral base address.
216  * @param enable True to enable the PNGDEC.
217  */
PNGDEC_Enable(PNGDEC_Type * base,bool enable)218 static inline void PNGDEC_Enable(PNGDEC_Type *base, bool enable)
219 {
220     if (enable)
221     {
222         base->GLB_CTRL |= PNGDEC_GLB_CTRL_DEC_EN_MASK;
223     }
224     else
225     {
226         base->GLB_CTRL &= ~PNGDEC_GLB_CTRL_DEC_EN_MASK;
227     }
228 }
229 
230 /*!
231  * @brief Enables or disables the PNGDEC ancillary drop.
232  *
233  * @param base PNGDEC peripheral base address.
234  * @param enable True to enable the PNGDEC ancillary drop.
235  */
PNGDEC_EnableAncillary(PNGDEC_Type * base,bool enable)236 static inline void PNGDEC_EnableAncillary(PNGDEC_Type *base, bool enable)
237 {
238     if (enable)
239     {
240         base->GLB_CTRL |= PNGDEC_GLB_CTRL_ANC_DROP_EN_MASK;
241     }
242     else
243     {
244         base->GLB_CTRL &= ~PNGDEC_GLB_CTRL_ANC_DROP_EN_MASK;
245     }
246 }
247 
248 /*!
249  * @brief Starts the PNG decode
250  *
251  * @param base PNGDEC peripheral base address.
252  */
PNGDEC_StartDecode(PNGDEC_Type * base)253 static inline void PNGDEC_StartDecode(PNGDEC_Type *base) // TODO self clear?
254 {
255     base->DMA_TRIG = PNGDEC_DMA_TRIG_DMA_TRIG_MASK;
256     base->DMA_TRIG = 0U;
257 }
258 /* @} */
259 
260 /*!
261  * @name Image decode
262  * @{
263  */
264 
265 /*!
266  * @brief Sets the address and length of the raw PNG image.
267  *
268  * @param base PNGDEC peripheral base address.
269  * @param data Start address of the buffer of the raw PNG image, shall be 8-byte aligned.
270  * @param length Size of the buffer.
271  */
272 void PNGDEC_SetPngBuffer(PNGDEC_Type *base, uint8_t *buffer, size_t length);
273 
274 /*!
275  * @brief Sets the address of the decoded data.
276  *
277  * @param base PNGDEC peripheral base address.
278  * @param imageData Start address of the buffer for the decoded image data, shall be 8-byte aligned.
279  * @param ancillaryData Start address of the buffer for the decoded ancillary data, shall be 8-byte aligned.
280  */
PNGDEC_SetOutputBuffer(PNGDEC_Type * base,uint8_t * imageData,uint8_t * ancillaryData)281 static inline void PNGDEC_SetOutputBuffer(PNGDEC_Type *base, uint8_t *imageData, uint8_t *ancillaryData)
282 {
283     assert(((uint32_t)imageData & 0x7U) == 0U);
284     assert(((uint32_t)ancillaryData & 0x7U) == 0U);
285 
286     base->DEC_PIXEL_DMA_DES_ADDR = (uint32_t)imageData;
287     base->DEC_ANC_DMA_DES_ADDR   = (uint32_t)ancillaryData;
288 }
289 
290 /*!
291  * @brief Parses the PNG header and stores the info in the decoded image info structure.
292  *
293  * @param image Pointer to PNGDEC decoded image info structure.
294  * @param pngBuf Pointer to PNG file buffer.
295  * @retval kStatus_Success Header parsing success.
296  * @retval kStatus_Fail PNG header parsing failed due corrupted header.
297  * @retval kStatus_PNGDEC_WidthTooLarge Header parsing failed due to the image width is larger than 1024.
298  * @retval kStatus_PNGDEC_NotSupported Header parsing failed due to the image is interlaced or the bit depth is less
299    than 8.
300  */
301 status_t PNGDEC_ParseHeader(pngdec_image_t *image, uint8_t *pngBuf);
302 
303 /*!
304  * @brief Decodes the PNG image.
305  *
306  * This function performs the PNG decoding in blocking way and stores the decoded info in decoded image info structure.
307  *
308  * @param base PNGDEC peripheral base address.
309  * @param image Pointer to PNGDEC decoded image info structure.
310  * @param status Pointer to decoded status. When retval is kStatus_Fail, Checksum/Crc/Header/Btype/ZlibHeader error may occur
311    due to PNG file corruption, user can check which error(s) occured if necessary.
312  * @retval kStatus_Success PNG decoding success.
313  * @retval kStatus_Fail PNG decoding failed due to CRC/header/B type/Alder error or invalid PNG file.
314  * @retval kStatus_PNGDEC_WidthTooLarge PNG decoding failed due to the image width is larger than 1024.
315  * @retval kStatus_PNGDEC_NotSupported PNG decoding failed due to the image is interlaced or the bit depth is less
316    than 8.
317  */
318 status_t PNGDEC_Decode(PNGDEC_Type *base, pngdec_image_t *image, uint32_t *status);
319 /* @} */
320 
321 #if defined(__cplusplus)
322 }
323 #endif
324 
325 /*! @}*/
326 
327 #endif /* _FSL_PNGDEC_H_ */
328