/* * Copyright (c) 2020, Actions Semi Co., Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief DMA2D Public API */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef FRAMEWORK_DMA2D_HAL_H_ #define FRAMEWORK_DMA2D_HAL_H_ #include <zephyr.h> #include <sys/atomic.h> #include <drivers/display/display_engine.h> #include <display/display_hal.h> /** * @brief Display DMA2D Interface * @defgroup display_dma2d_interface Display DMA2D Interface * @ingroup display_libraries * @{ */ #ifdef __cplusplus extern "C" { #endif #define HAL_DMA2D_MAX_LAYER 2U /*!< DMA2D maximum number of layers */ #define HAL_DMA2D_SCALE_NONE 256U /*!< DMA2D maximum number of layers */ /** * @brief DMA2D output structure definition */ typedef struct { uint32_t color_format; /*!< Configures the color format of the output image. This parameter can be one value of @ref HAL_PIXEL_FORMAT_*. */ uint32_t output_pitch; /*!< Specifies the output pitch value. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x01FF. */ uint16_t mode; /*!< Configures the DMA2D transfer mode. This parameter can be one value of @ref DMA2D_MODE. */ } hal_dma2d_output_cfg_t; /** * @brief DMA2D Layer structure definition */ typedef struct { uint32_t color_format; /*!< Configures the DMA2D foreground or background color format. This parameter can be one value of @ref HAL_PIXEL_FORMAT_*. */ uint32_t input_width; /*!< Configures the DMA2D foreground or background width. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. */ uint32_t input_height; /*!< Configures the DMA2D foreground or background height. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. */ uint32_t input_pitch; /*!< Configures the DMA2D foreground or background pitch. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. */ uint8_t input_xofs; /*!< Configures the DMA2D foreground or background x offset per row. This parameter is only for A1/2/4 and I1/2/4 color formats, accepted values: 0, 1 for A4, I4 0, 1, 2, 3 for A2, I2 0, 1, 2, 3, 4, 5, 6, 7 for A1, I1 0 for others */ uint8_t alpha_mode; /*!< Configures the DMA2D foreground or background alpha mode. This parameter can be one value of @ref DMA2D_ALPHA_Mode. */ uint32_t input_alpha; /*!< Specifies the DMA2D foreground or background alpha value and color value both of Ax color formats and rotation fill-color. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF except for the color formats detailed below. @note In case of A8 or A4 color mode (ARGB), this parameter must be a number between Min_Data = 0x00000000 and Max_Data = 0xFFFFFFFF where - input_alpha[24:31] is the alpha value ALPHA[0:7] - input_alpha[16:23] is the red value RED[0:7] - input_alpha[8:15] is the green value GREEN[0:7] - input_alpha[0:7] is the blue value BLUE[0:7]. */ } hal_dma2d_layer_cfg_t; /** * @brief DMA2D Transform structure definition */ typedef struct { uint16_t mode; /*!< Transform mode, This parameter can be one value of @ref DMA2D_Transform_Mode: - HAL_DMA2D_ROT2D Similarity transfrom, can set any scale and rotation - Others predefined transform, whose top-left corner after transformation keep the same as before (image_x0, image_y0) */ uint16_t angle; /*!< Anti-clockwise rotation angle in 0.1 degree [0, 3600) in the display coordinate */ int16_t image_x0; /*!< Coord X of top-left corner of image src before rotation in the display coordinate */ int16_t image_y0; /*!< Coord Y of top-left corner of image src before rotation in the display coordinate */ union { struct { uint16_t outer_diameter; /*!< Outer Diameter in pixels of the ring area of the Source, and must equal to the source image width and height */ uint16_t inner_diameter; /*!< Inner Diameter in pixels of the ring area of the Source */ } circle; struct { int16_t pivot_x; /*!< Rotate/scale pivot X offset relative to top-left corner of the Image Source */ int16_t pivot_y; /*!< Rotate/scale pivot Y offset relative to top-left corner of the Image Source */ /*!< Scale factor in fixedpoint, equal to (HAL_DMA2D_SCALE_NONE * dest / src) * > HAL_DMA2D_SCALE_NONE, scaling up * < HAL_DMA2D_SCALE_NONE, scaling down * = HAL_DMA2D_SCALE_NONE, no scaling * only scaling up supported so far */ uint16_t scale_x; /*!< scale factor X */ uint16_t scale_y; /*!< scale factor Y */ } rect; }; display_engine_transform_param_t hw_param; } hal_dma2d_transform_cfg_t; /** * @brief HAL DMA2D State structures definition */ typedef enum { HAL_DMA2D_STATE_RESET = 0x00U, /*!< DMA2D not yet initialized or disabled */ HAL_DMA2D_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ HAL_DMA2D_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ HAL_DMA2D_STATE_TIMEOUT = 0x03U, /*!< timeout state */ HAL_DMA2D_STATE_ERROR = 0x04U, /*!< DMA2D state error */ } hal_dma2d_state_e; struct _hal_dma2d_handle; /** * @brief HAL DMA2D Callback pointer definition provided the current command sequence and the error code */ typedef void (* hal_dma2d_callback_t)(struct _hal_dma2d_handle * hdma2d, uint16_t cmd_seq, uint32_t error_code); /** * @brief DMA2D handle Structure definition */ typedef struct _hal_dma2d_handle { const void *device; /*!< DMA2D Device Handle */ int instance; /*!< DMA2D Device Instance ID */ atomic_t xfer_count; /*!< DMA2D pending transfer count */ hal_dma2d_callback_t xfer_callback; /*!< DMA2D transfer callback. */ hal_dma2d_output_cfg_t output_cfg; /*!< DMA2D output parameters. */ hal_dma2d_layer_cfg_t layer_cfg[HAL_DMA2D_MAX_LAYER]; /*!< DMA2D Layers parameters */ hal_dma2d_transform_cfg_t trans_cfg; /*!< DMA2D Transform parameters */ uint32_t error_code; /*!< DMA2D error code. */ } hal_dma2d_handle_t; /** * @brief HAL DMA2D_Layers DMA2D Layers */ #define HAL_DMA2D_BACKGROUND_LAYER 0x0000U /*!< DMA2D Background Layer (layer 0) */ #define HAL_DMA2D_FOREGROUND_LAYER 0x0001U /*!< DMA2D Foreground Layer (layer 1) */ /** * @brief HAL DMA2D_Offset DMA2D Offset */ #define HAL_DMA2D_PITCH 2048U /*!< maximum Line Offset */ /** * @brief HAL DMA2D_Size DMA2D Size */ #define HAL_DMA2D_PIXEL UINT32_MAX /*!< DMA2D maximum number of pixels per line */ #define HAL_DMA2D_LINE UINT16_MAX /*!< DMA2D maximum number of lines */ /** * @brief HAL DMA2D_Error_Code DMA2D Error Code */ #define HAL_DMA2D_ERROR_NONE 0x0000U /*!< No error */ #define HAL_DMA2D_ERROR_TE 0x0001U /*!< Transfer error */ #define HAL_DMA2D_ERROR_CE 0x0002U /*!< Configuration error */ #define HAL_DMA2D_ERROR_TIMEOUT 0x0020U /*!< Timeout error */ #define HAL_DMA2D_ERROR_INVALID_CALLBACK 0x0040U /*!< Invalid callback error */ /** * @brief HAL DMA2D_MODE DMA2D Mode */ #define HAL_DMA2D_R2M 0x0001U /*!< DMA2D register to memory transfer mode */ #define HAL_DMA2D_M2M 0x0002U /*!< DMA2D memory to memory transfer mode, optionally with pixel format conversion */ #define HAL_DMA2D_M2M_BLEND 0x0004U /*!< DMA2D memory to memory with blending transfer mode */ #define HAL_DMA2D_M2M_BLEND_FG 0x0008U /*!< DMA2D memory to memory with blending transfer mode and fixed color FG */ #define HAL_DMA2D_M2M_BLEND_BG 0x0010U /*!< DMA2D memory to memory with blending transfer mode and fixed color BG */ #define HAL_DMA2D_M2M_TRANSFORM 0x0020U /*!< DMA2D memory to memory with transform transfer mode */ #define HAL_DMA2D_M2M_TRANSFORM_BLEND 0x0040U /*!< DMA2D memory to memory with transform and blending transfer mode */ #define HAL_DMA2D_M2M_TRANSFORM_CIRCLE 0x0080U /*!< DMA2D memory to memory with transform circle transfer mode */ #define HAL_DMA2D_LITE_MODES \ (HAL_DMA2D_R2M | HAL_DMA2D_M2M) #define HAL_DMA2D_FULL_MODES \ (HAL_DMA2D_R2M | HAL_DMA2D_M2M | HAL_DMA2D_M2M_BLEND | HAL_DMA2D_M2M_BLEND_FG | HAL_DMA2D_M2M_BLEND_BG | \ HAL_DMA2D_M2M_TRANSFORM | HAL_DMA2D_M2M_TRANSFORM_BLEND | HAL_DMA2D_M2M_TRANSFORM_CIRCLE) /** * @brief HAL DMA2D_Alpha_Mode DMA2D Alpha Mode */ #define HAL_DMA2D_NO_MODIF_ALPHA 0x0000U /*!< No modification of the alpha channel value */ #define HAL_DMA2D_REPLACE_ALPHA 0x0001U /*!< Replace original alpha channel value by programmed alpha value */ #define HAL_DMA2D_COMBINE_ALPHA 0x0002U /*!< Replace original alpha channel value by programmed alpha value with original alpha channel value */ /** * @brief HAL DMA2D_Transform_Mode DMA2D Transform Mode */ #define HAL_DMA2D_ROT2D 0x0000U /*!< Similarity transfrom, can set any scale and rotation */ #define HAL_DMA2D_FLIP_H 0x0001U /*!< Flip source image horizontally */ #define HAL_DMA2D_FLIP_V 0x0002U /*!< Flip source image verticallye */ #define HAL_DMA2D_ROT_90 0x0004U /*!< Rotate source image 90 degrees clock-wise */ #define HAL_DMA2D_ROT_180 0x0003U /*!< Rotate source image 180 degrees */ #define HAL_DMA2D_ROT_270 0x0007U /*!< Rotate source image 270 degrees clock-wise */ /* Exported functions --------------------------------------------------------*/ /* Initialization and de-initialization functions *******************************/ /** * @brief Initialize the DMA2D peripheral and create the associated handle. * @param hdma2d pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param preferred_modes "bitwise or" of output modes that maybe used. * Different hardware device may be chosen as accelerator according this. * @retval 0 on success else negative errno code. */ int hal_dma2d_init(hal_dma2d_handle_t *hdma2d, uint32_t preferred_modes); /** * @brief Deinitializes the DMA2D peripheral registers to their default reset * values. * @param hdma2d pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @retval 0 on success else negative errno code. */ int hal_dma2d_deinit(hal_dma2d_handle_t *hdma2d); /* Callbacks Register/UnRegister functions ***********************************/ /** * @brief Register a User DMA2D Callback * To be used instead of the weak (surcharged) predefined callback * @param hdma2d DMA2D handle * @param callback_fn pointer to the callback function * @retval 0 on success else negative errno code. */ int hal_dma2d_register_callback(hal_dma2d_handle_t *hdma2d, hal_dma2d_callback_t callback_fn); /** * @brief Unregister a DMA2D Callback * DMA2D Callback is redirected to the weak (surcharged) predefined callback * @param hdma2d DMA2D handle * @retval 0 on success else negative errno code. */ int hal_dma2d_unregister_callback(hal_dma2d_handle_t *hdma2d); /* IO operation functions *******************************************************/ /** * @brief Start the DMA2D Transfer. * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param pdata Configure the source memory Buffer address if * Memory-to-Memory or Memory-to-Memory with pixel format * conversion mode is selected, or configure * the color value if Register-to-Memory mode is selected. * @param dst_address The destination memory Buffer address. * @param width The width of data to be transferred from source to destination (expressed in number of pixels per line). * @param height The height of data to be transferred from source to destination (expressed in number of lines). * @retval command sequence (uint16_t) on success else negative errno code. */ int hal_dma2d_start(hal_dma2d_handle_t *hdma2d, uint32_t pdata, uint32_t dst_address, uint32_t width, uint32_t height); /** * @brief Start the multi-source DMA2D Transfer. * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param fg_address The source memory Buffer address for the foreground layer. * @param bg_address The source memory Buffer address for the background layer. * @param dst_address The destination memory Buffer address. * @param width The width of data to be transferred from source to destination (expressed in number of pixels per line). * @param height The height of data to be transferred from source to destination (expressed in number of lines). * @retval command sequence (uint16_t) on success else negative errno code. */ int hal_dma2d_blending_start(hal_dma2d_handle_t *hdma2d, uint32_t fg_address, uint32_t bg_address, uint32_t dst_address, uint32_t width, uint32_t height); /** * @brief Start the DMA2D Rotation Transfer with interrupt enabled. * * The source size must be square, and only the ring area defined in hal_dma2d_rotation_cfg_t * is rotated, and the pixels inside the inner ring can be filled with constant * color defined in hal_dma2d_rotation_cfg_t. * * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param src_address The source memory Buffer start address. * @param dst_address The destination memory Buffer address. * @param x X coord of top-left corner of dest area in the display coordinate. * @param y Y coord of top-left corner of dest area in the display coordinate. * @param width Width of dest area. * @param height Height of dest area. * @retval command sequence (uint16_t) on success else negative errno code. */ int hal_dma2d_transform_start(hal_dma2d_handle_t *hdma2d, uint32_t src_address, uint32_t dst_address, int16_t x, int16_t y, uint16_t width, uint16_t height); /** * @brief Start DMA2D CLUT Loading. * @param hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains * the configuration information for the DMA2D. * @param layer_idx DMA2D Layer index. * This parameter can be one of the following values: * DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1) * @param size Number of colors in the color look up table * @param clut Pointer to the color look up table. * @retval command sequence (uint16_t) on success else negative errno code. */ int hal_dma2d_clut_load_start(hal_dma2d_handle_t *hdma2d, uint16_t layer_idx, uint16_t size, const uint32_t *clut); /** * @brief Polling for transfer complete. * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param timeout timeout duration in milliseconds, if negative, means wait forever * @retval 0 on success else negative errno code. */ int hal_dma2d_poll_transfer(hal_dma2d_handle_t *hdma2d, int32_t timeout); /* Peripheral Control functions *************************************************/ /** * @brief Configure the DMA2D transfer mode and output according to the * specified parameters in the hal_dma2d_handle_t. * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @retval 0 on success else negative errno code. */ int hal_dma2d_config_output(hal_dma2d_handle_t *hdma2d); /** * @brief Configure the DMA2D Layer according to the specified * parameters in the hal_dma2d_handle_t. * * hal_dma2d_config_output() must be invoked to configure the correct mode first. * * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @param layer_idx DMA2D Layer index. * This parameter can be one of the following values: * HAL_DMA2D_BACKGROUND_LAYER(0) / HAL_DMA2D_FOREGROUND_LAYER(1) * @retval 0 on success else negative errno code. */ int hal_dma2d_config_layer(hal_dma2d_handle_t *hdma2d, uint16_t layer_idx); /** * @brief Configure the DMA2D Rotation according to the specified * parameters in the hal_dma2d_handle_t. * * hal_dma2d_config_output() must be invoked to configure correct mode first. * * @param hdma2d Pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @retval 0 on success else negative errno code. */ int hal_dma2d_config_transform(hal_dma2d_handle_t *hdma2d); /* Peripheral State functions ***************************************************/ /** * @brief Return the DMA2D state * @param hdma2d pointer to a hal_dma2d_handle_t structure that contains * the configuration information for the DMA2D. * @retval HAL state */ hal_dma2d_state_e hal_dma2d_get_state(hal_dma2d_handle_t *hdma2d); /** * @brief Return the DMA2D error code * @param hdma2d pointer to a hal_dma2d_handle_t structure that contains * the configuration information for DMA2D. * @retval DMA2D Error Code */ uint32_t hal_dma2d_get_error(hal_dma2d_handle_t *hdma2d); /** * @cond INTERNAL_HIDDEN */ /** * @brief Global enable/disable DMAD functions * @param enabled enable or not * @retval N/A */ void hal_dma2d_set_global_enabled(bool enabled); /** * INTERNAL_HIDDEN @endcond */ #ifdef __cplusplus } #endif /** * @} */ #endif /* FRAMEWORK_DMA2D_HAL_H_ */