/** * @file sdrv_g2dlite.c * @brief SemiDrive G2DLite driver file. * * @copyright Copyright (c) 2022 Semidrive Semiconductor. * All rights reserved. */ #include #include #include #include #include #include #include #if CONFIG_OS_FREERTOS #include #include #include #include SemaphoreHandle_t g2dlite_lock; SemaphoreHandle_t done_sema; #endif unsigned int G2DLITE_CMD_ARRAY[G2DLITE_CMDFILE_MAX_MEM] = {0}; static void g2dlite_done(void) { #if CONFIG_OS_FREERTOS BaseType_t xReturn = xSemaphoreTake(done_sema, pdMS_TO_TICKS(5000)); if (pdTRUE != xReturn) { G2DLITE_LOG_ERR("timeout for 5s !"); } #endif } /** * @brief sdrv g2dlite_probe * * This funtion probe the g2dlite device. * * @param [in] dev g2dlite device struct. * @param [in] g2dlite_cfg g2dlite dev config information. * @return SDRV_G2DLITE_STATUS_OK g2dlite probe successfully. */ status_t sdrv_g2dlite_probe(struct g2dlite_device *dev, const struct g2dlite_config *g2dlite_cfg) { if (dev->inited) return SDRV_G2DLITE_STATUS_OK; dev->reg_base = g2dlite_cfg->base; dev->cmd_info[0].arg = G2DLITE_CMD_ARRAY; G2DLITE_LOG_INFO("dev->cmd_info[0].arg = 0x%p", dev->cmd_info[0].arg); for (int i = 1; i < G2DLITE_CMDFILE_MAX_NUM; i++) { dev->cmd_info[i].arg = dev->cmd_info[i - 1].arg + G2DLITE_CMDFILE_MAX_LEN * 2; } dev->write_mode = G2DLITE_CMD_WRITE; dev->ops = &ops; dev->irq = g2dlite_cfg->irq; dev->irq_handler = ops.irq_handler; #if CONFIG_OS_FREERTOS done_sema = xSemaphoreCreateBinary(); g2dlite_lock = xSemaphoreCreateMutex(); #endif if (dev->ops->init) dev->ops->init(dev); irq_attach(dev->irq, dev->irq_handler, dev); irq_enable(dev->irq); dev->inited = 1; return SDRV_G2DLITE_STATUS_OK; } /** * @brief sdrv g2dlite update. * * This function perform multiple transformations at a time according to * customer input and output settings. * * @param [in] dev g2dlite device struct. * @param [in] input g2dlite input information. * @return SDRV_G2DLITE_STATUS_OK g2dlite update successfully, * SDRV_G2DLITE_STATUS_FAIL g2dlite update fail, * SDRV_G2DLITE_STATUS_TIMEOUT g2dlite update timeout, * SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite update param invalid. * */ status_t sdrv_g2dlite_update(struct g2dlite_device *dev, struct g2dlite_input *input) { status_t ret = SDRV_G2DLITE_STATUS_OK; if ((input->output.width <= 0) || ((input->output.height <= 0))) return SDRV_G2DLITE_STATUS_INVALID_PARAM; #if CONFIG_OS_FREERTOS xSemaphoreTake(g2dlite_lock, portMAX_DELAY); #endif if (dev->ops->update) { if (dev->ops->update(dev, input)) { G2DLITE_LOG_ERR("update failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("update is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } if (dev->ops->reset) dev->ops->reset(dev); if (dev->ops->enable) { if (dev->ops->enable(dev)) { G2DLITE_LOG_ERR("enable failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("enable is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } g2dlite_done(); EXIT: #if CONFIG_OS_FREERTOS xSemaphoreGive(g2dlite_lock); #endif return ret; } /** * @brief sdrv g2dlite rotation. * * This function implements rotation operation. * * @param [in] dev g2dlite device struct. * @param [in] input g2dlite input information. * @return SDRV_G2DLITE_STATUS_OK g2dlite rotaion successfully, * SDRV_G2DLITE_STATUS_FAIL g2dlite rotaion fail, * SDRV_G2DLITE_STATUS_TIMEOUT g2dlite rotaion timeout, * SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite rotaion param invalid. */ status_t sdrv_g2dlite_rotaion(struct g2dlite_device *dev, struct g2dlite_input *input) { status_t ret = SDRV_G2DLITE_STATUS_OK; if ((input->output.width <= 0) || ((input->output.height <= 0))) return SDRV_G2DLITE_STATUS_INVALID_PARAM; #if CONFIG_OS_FREERTOS xSemaphoreTake(g2dlite_lock, portMAX_DELAY); #endif if (dev->ops->rotation) { if (dev->ops->rotation(dev, input)) { G2DLITE_LOG_ERR("rotation failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("rotation is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } if (dev->ops->reset) dev->ops->reset(dev); if (dev->ops->enable) { if (dev->ops->enable(dev)) { G2DLITE_LOG_ERR("enable failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("enable is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } g2dlite_done(); EXIT: #if CONFIG_OS_FREERTOS xSemaphoreGive(g2dlite_lock); #endif return ret; } /** * @brief sdrv g2dlite fill rect. * * This function enables 2D monochrome rendering, and can be used to generate * rectangular images using global Alpha or as pixel alpha buffer data. * * @param [in] dev g2dlite device struct. * @param [in] bgcfg g2dlite background config information. * @param [in] output g2dlite output config information. * @return SDRV_G2DLITE_STATUS_OK g2dlite fill rect successfully, * SDRV_G2DLITE_STATUS_FAIL g2dlite fill rect fail, * SDRV_G2DLITE_STATUS_TIMEOUT g2dlite fill rect timeout, * SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite fill rect param invalid. */ status_t sdrv_g2dlite_fill_rect(struct g2dlite_device *dev, struct g2dlite_bg_cfg *bgcfg, struct g2dlite_output_cfg *output) { status_t ret = SDRV_G2DLITE_STATUS_OK; if ((output->width <= 0) || ((output->height <= 0))) return SDRV_G2DLITE_STATUS_INVALID_PARAM; #if CONFIG_OS_FREERTOS xSemaphoreTake(g2dlite_lock, portMAX_DELAY); #endif if (dev->ops->fill_rect) { if (dev->ops->fill_rect(dev, bgcfg, output)) { G2DLITE_LOG_ERR("fill_rect failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("fill_rect is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } if (dev->ops->reset) dev->ops->reset(dev); if (dev->ops->enable) { if (dev->ops->enable(dev)) { G2DLITE_LOG_ERR("enable failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("enable is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } g2dlite_done(); EXIT: #if CONFIG_OS_FREERTOS xSemaphoreGive(g2dlite_lock); #endif return ret; } /** * @brief sdrv g2dlite fastcopy. * * This function implements fast memory copy. * * @param [in] dev g2dlite device struct. * @param [in] in g2dlite fcopy input config information. * @param [in] out g2dlite fcopy output config information. * @return SDRV_G2DLITE_STATUS_OK g2dlite fastcopy rect successfully, * SDRV_G2DLITE_STATUS_FAIL g2dlite fastcopy fail, * SDRV_G2DLITE_STATUS_TIMEOUT g2dlite fastcopy timeout, * SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite fastcopy param invalid. */ status_t sdrv_g2dlite_fastcopy(struct g2dlite_device *dev, struct fcopy_t *in, struct fcopy_t *out) { status_t ret = SDRV_G2DLITE_STATUS_OK; if ((out->width <= 0) || ((out->height <= 0))) return SDRV_G2DLITE_STATUS_INVALID_PARAM; #if CONFIG_OS_FREERTOS xSemaphoreTake(g2dlite_lock, portMAX_DELAY); #endif if (dev->ops->fastcopy) { if (dev->ops->fastcopy(dev, in, out)) { G2DLITE_LOG_ERR("fastcopy failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("fastcopy is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } if (dev->ops->reset) dev->ops->reset(dev); if (dev->ops->enable) { if (dev->ops->enable(dev)) { G2DLITE_LOG_ERR("enable failed"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; goto EXIT; } } else { G2DLITE_LOG_ERR("enable is null"); ret = SDRV_G2DLITE_STATUS_FAIL; goto EXIT; } g2dlite_done(); EXIT: #if CONFIG_OS_FREERTOS xSemaphoreGive(g2dlite_lock); #endif return ret; } /** * @brief sdrv g2dlite clut setting. * * This function implements CLUT settings. * * @param [in] dev g2dlite device struct. * @param [in] clut_table g2dlite clut config information. * @return SDRV_G2DLITE_STATUS_OK g2dlite clut set successfully, * SDRV_G2DLITE_STATUS_FAIL g2dlite clut set fail, * SDRV_G2DLITE_STATUS_INVALID_PARAM g2dlite clut param invalid. */ status_t sdrv_g2dlite_clut_setting(struct g2dlite_device *dev, char *clut_table) { status_t ret = SDRV_G2DLITE_STATUS_OK; if (dev->ops->clut_index_set) { if (dev->ops->clut_index_set(dev, clut_table)) { G2DLITE_LOG_ERR("clut setting failed"); ret = SDRV_G2DLITE_STATUS_FAIL; return ret; } } else { G2DLITE_LOG_ERR("clut index set is null"); ret = SDRV_G2DLITE_STATUS_INVALID_PARAM; return ret; } return ret; }