openmv/lib/alif/Alif_CMSIS/Source/Driver_MIPI_DSI.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

823 lines
26 KiB
C

/* Copyright (C) 2022 Alif Semiconductor - All Rights Reserved.
* Use, distribution and modification of this code is permitted under the
* terms stated in the Alif Semiconductor Software License Agreement
*
* You should have received a copy of the Alif Semiconductor Software
* License Agreement with this file. If not, please write to:
* contact@alifsemi.com, or visit: https://alifsemi.com/license
*
*/
/**************************************************************************//**
* @file Driver_MIPI_DSI.c
* @author Prasanna Ravi
* @email prasanna.ravi@alifsemi.com
* @version V1.0.0
* @date 28-Sep-2023
* @brief CMSIS-Driver for MIPI DSI.
* @bug None.
* @Note None.
******************************************************************************/
#include "Driver_MIPI_DSI.h"
#include "Driver_DSI_Private.h"
#include "RTE_Device.h"
#include "DPHY_DSI.h"
#include "display.h"
#define ARM_MIPI_DSI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /*driver version*/
#if !(RTE_MIPI_DSI)
#error "MIPI DSI is not enabled in the RTE_Device.h"
#endif
#if (!defined(RTE_Drivers_MIPI_DSI))
#error "MIPI DSI not configured in RTE_Components.h!"
#endif
/* High speed transition timing range */
static const DSI_DPHY_HS_TRANSITION_TIMINGS_RANGE hstransition_timing_range[] =
{
{ 80, 21, 17, 15, 10 }, { 90, 23, 17, 16, 10 }, { 100, 22, 17, 16, 10 },
{ 110, 25, 18, 17, 11 }, { 120, 26, 20, 18, 11 }, { 130, 27, 19, 19, 11 },
{ 140, 27, 19, 19, 11 }, { 150, 28, 20, 20, 12 }, { 160, 30, 21, 22, 13 },
{ 170, 30, 21, 23, 13 }, { 180, 31, 21, 23, 13 }, { 190, 32, 22, 24, 13 },
{ 205, 35, 22, 25, 13 }, { 220, 37, 26, 27, 15 }, { 235, 38, 28, 27, 16 },
{ 250, 41, 29, 30, 17 }, { 275, 43, 29, 32, 18 }, { 300, 45, 32, 35, 19 },
{ 325, 48, 33, 36, 18 }, { 350, 51, 35, 40, 20 }, { 400, 59, 37, 44, 21 },
{ 450, 65, 40, 49, 23 }, { 500, 71, 41, 54, 24 }, { 550, 77, 44, 57, 26 },
{ 600, 82, 46, 64, 27 }, { 650, 87, 48, 67, 28}, { 700, 94, 52, 71, 29 },
{ 750, 99, 52, 75, 31 }, { 800, 105, 55, 82, 32 }, { 850, 110, 58, 85, 32 },
{ 900, 115, 58, 88, 35 }, { 950, 120, 62, 93, 36 }, { 1000, 128, 63, 99, 38 },
{ 1050, 132, 65, 102, 38 }, { 1100, 138, 67, 106, 39 }, { 1150, 146, 69, 112, 42 },
{ 1200, 151, 71, 117, 43 }, { 1250, 153, 74, 120, 45 }, { 1300, 160, 73, 124, 46 },
{ 1350, 165, 76, 130, 47 }, { 1400, 172, 78, 134, 49 }, { 1450, 177, 80, 138, 49 },
{ 1500, 183, 81, 143, 52 }, { 1550, 191, 84, 147, 52 }, { 1600, 194, 85, 152, 52 },
{ 1650, 201, 86, 155, 53 }, { 1700, 208, 88, 161, 53 }, { 1750, 212, 89, 165, 53 },
{ 1800, 220, 90, 171, 54 }, { 1850, 223, 92, 175, 54 }, { 1900, 231, 91, 180, 55 },
{ 1950, 236, 95, 185, 56 }, { 2000, 243, 97, 190, 56 }, { 2050, 248, 99, 194, 58 },
{ 2100, 252, 100, 199, 59 }, { 2150, 259, 102, 204, 61 }, { 2200, 266, 105, 210, 62 },
{ 2250, 269, 109, 213, 63 }, { 2300, 272, 109, 217, 65 }, { 2350, 281, 112, 225, 66},
{ 2400, 283, 115, 226, 66 }, { 2450, 282, 115, 226, 67 }, { 2500, 281, 118, 227, 67 }
};
/* CDC config informations */
static CDC_INFO cdc_info;
/*Driver Version*/
static const ARM_DRIVER_VERSION DriverVersion =
{
ARM_MIPI_DSI_API_VERSION,
ARM_MIPI_DSI_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_MIPI_DSI_CAPABILITIES DriverCapabilities =
{
0, /* Not supports reentrant_operation */
1, /* DPI interface supported*/
0, /* DBI interface not supported*/
0 /* reserved (must be zero) */
};
/**
\fn ARM_DRIVER_VERSION ARM_MIPI_DSI_GetVersion (void)
\brief Get MIPI DSI driver version.
\return \ref ARM_DRIVER_VERSION
*/
static ARM_DRIVER_VERSION ARM_MIPI_DSI_GetVersion (void)
{
return DriverVersion;
}
/**
\fn ARM_MIPI_DSI_CAPABILITIES MIPI_DSI_GetCapabilities (void)
\brief Get MIPI DSI driver capabilities
\return \ref ARM_MIPI_DPHY_CAPABILITIES
*/
static ARM_MIPI_DSI_CAPABILITIES ARM_MIPI_DSI_GetCapabilities (void)
{
return DriverCapabilities;
}
/**
\fn int32_t DSI_Initialize (ARM_MIPI_DSI_SignalEvent_t cb_event,
DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief Initialize MIPI DSI Interface.
\param[in] cb_event Pointer to ARM_MIPI_DSI_SignalEvent_t.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_Initialize (ARM_MIPI_DSI_SignalEvent_t cb_event,
DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
int32_t ret = ARM_DRIVER_OK;
DSI_INFO *dsi_info;
uint32_t pixclk;
if(dsi->state.initialized == 1)
{
return ARM_DRIVER_OK;
}
if (!cb_event)
{
return ARM_DRIVER_ERROR_PARAMETER;
}
dsi_info = display_panel->dsi_info;
if (!(display_panel && dsi_info))
{
return ARM_DRIVER_ERROR_PARAMETER;
}
/* LCD Manufacturer provides the Frame timing values
* HTOTAL = WIDTH + HSYNC + HFP + HBP
* VTOTAL = HEIGHT + VSYNC + VFP + VBP
* Calculate the pixel clock for DPI controller
* PIXCLK = FPS x HTOTAL x VTOTAL
*/
dsi->horizontal_timing = (display_panel->hsync_time
+ display_panel->hbp_time
+ display_panel->hfp_time
+ display_panel->hactive_time);
dsi->vertical_timing = (display_panel->vsync_line
+ display_panel->vbp_line
+ display_panel->vfp_line
+ display_panel->vactive_line);
pixclk = (dsi->horizontal_timing * dsi->vertical_timing * RTE_CDC200_DPI_FPS);
/* SCALE = LANEBYTECLK / PIXCLK
* MIPI data rate must be exactly equal, not greater than, for 1.5 scale to work
* MIPI data rate + 33% allows for scaling times 2
* 24 x 1.333 / 16 = 2
* LANEBYTECLK = PIXCLK * SCALE
* lanebyteclk frequency is 1/4th of the DPHY frequency
* PLL frequency = LANEBYTECLK * 4
* = PIXCLK * SCALE * 4
*/
dsi->frequency = pixclk * 2 * 4;
/*Checking LCD Panel supports MIPI DSI DPHY data rate*/
if((dsi->frequency * 2) > (dsi_info->max_bitrate * 1000000))
{
return ARM_DRIVER_ERROR_PARAMETER;
}
if(dsi_dpi_get_hsync_polarity(dsi->reg_base) == DSI_POLARITY_ACTIVE_LOW)
{
cdc_info.hsync_polarity = CDC_POLARITY_ACTIVE_LOW;
}
else
{
cdc_info.hsync_polarity = CDC_POLARITY_ACTIVE_HIGH;
}
if(dsi_dpi_get_vsync_polarity(dsi->reg_base) == DSI_POLARITY_ACTIVE_LOW)
{
cdc_info.vsync_polarity = CDC_POLARITY_ACTIVE_LOW;
}
else
{
cdc_info.vsync_polarity = CDC_POLARITY_ACTIVE_HIGH;
}
cdc_info.pclk_polarity = CDC_PIXCLK_POLARITY_FEED_THROUGH;
if(dsi_dpi_get_dataen_polarity(dsi->reg_base) == DSI_POLARITY_ACTIVE_LOW)
{
cdc_info.blank_polarity = CDC_POLARITY_ACTIVE_HIGH;
}
else
{
cdc_info.blank_polarity = CDC_POLARITY_ACTIVE_LOW;
}
/* Registering CPI Info related to CSI */
display_panel->cdc_info = &cdc_info;
dsi->cb_event = cb_event;
/*DPHY initialization*/
ret = DSI_DPHY_Initialize(dsi->frequency, dsi_info->n_lanes);
if(ret != ARM_DRIVER_OK)
{
return ret;
}
/*LCD Panel Initialization*/
ret = display_panel->ops->Init();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
dsi->dpi_info->vid_pkt_size = display_panel->hactive_time;
dsi->state.initialized = 1;
return ret;
}
/**
\fn int32_t DSI_Uninitialize (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief uninitialize MIPI DSI Interface.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_Uninitialize (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
int32_t ret = ARM_DRIVER_OK;
dsi->cb_event = NULL;
if(dsi->state.initialized == 0)
{
return ARM_DRIVER_OK;
}
if (dsi->state.powered == 1)
{
return ARM_DRIVER_ERROR;
}
/*DPHY Uninitialization*/
ret = DSI_DPHY_Uninitialize();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
/*LCD Panel Un-Initialization*/
ret = display_panel->ops->Uninit();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
dsi->state.initialized = 0;
return ret;
}
/**
\fn int32_t DSI_PowerControl (ARM_POWER_STATE state,
DSI_RESOURCES *dsi)
\brief Control DSI Interface Power.
\param[in] state Power state.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_PowerControl (ARM_POWER_STATE state,
DSI_RESOURCES *dsi)
{
if (dsi->state.initialized == 0)
{
return ARM_DRIVER_ERROR;
}
switch (state)
{
case ARM_POWER_OFF:
{
if (dsi->state.powered == 0)
{
return ARM_DRIVER_OK;
}
NVIC_DisableIRQ (dsi->irq);
NVIC_ClearPendingIRQ (dsi->irq);
dsi->state.powered = 0;
break;
}
case ARM_POWER_FULL:
{
if (dsi->state.powered == 1)
{
return ARM_DRIVER_OK;
}
NVIC_ClearPendingIRQ (dsi->irq);
NVIC_SetPriority (dsi->irq, dsi->irq_priority);
NVIC_EnableIRQ (dsi->irq);
dsi->state.powered = 1;
break;
}
case ARM_POWER_LOW:
default:
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t DSI_ConfigureHost (DSI_RESOURCES *dsi)
\brief Configure DSI Host Interface.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_ConfigureHost (DSI_RESOURCES *dsi)
{
if (dsi->state.powered == 0)
{
return ARM_DRIVER_ERROR;
}
dsi_irq0_enable(dsi->reg_base, DSI_IRQ0_ACK_WITH_ERR_0 | \
DSI_IRQ0_ACK_WITH_ERR_1 | \
DSI_IRQ0_ACK_WITH_ERR_2 | \
DSI_IRQ0_ACK_WITH_ERR_3 | \
DSI_IRQ0_ACK_WITH_ERR_4 | \
DSI_IRQ0_ACK_WITH_ERR_5 | \
DSI_IRQ0_ACK_WITH_ERR_6 | \
DSI_IRQ0_ACK_WITH_ERR_7 | \
DSI_IRQ0_ACK_WITH_ERR_8 | \
DSI_IRQ0_ACK_WITH_ERR_9 | \
DSI_IRQ0_ACK_WITH_ERR_10 | \
DSI_IRQ0_ACK_WITH_ERR_11 | \
DSI_IRQ0_ACK_WITH_ERR_12 | \
DSI_IRQ0_ACK_WITH_ERR_13 | \
DSI_IRQ0_ACK_WITH_ERR_14 | \
DSI_IRQ0_ACK_WITH_ERR_15 | \
DSI_IRQ0_DPHY_ERRORS_0 | \
DSI_IRQ0_DPHY_ERRORS_1 | \
DSI_IRQ0_DPHY_ERRORS_2 | \
DSI_IRQ0_DPHY_ERRORS_3 | \
DSI_IRQ0_DPHY_ERRORS_4);
dsi_irq1_enable(dsi->reg_base, DSI_IRQ1_TO_HS_TX | \
DSI_IRQ1_TO_LP_RX | \
DSI_IRQ1_ECC_SINGLE_ERR | \
DSI_IRQ1_ECC_MILTI_ERR | \
DSI_IRQ1_CRC_ERR | \
DSI_IRQ1_PKT_SIZE_ERR | \
DSI_IRQ1_EOPT_ERR | \
DSI_IRQ1_DPI_PLD_WR_ERR | \
DSI_IRQ1_GEN_CMD_WR_ERR | \
DSI_IRQ1_GEN_PLD_WR_ERR | \
DSI_IRQ1_GEN_PLD_SEND_ERR | \
DSI_IRQ1_GEN_PLD_RD_ERR | \
DSI_IRQ1_GEN_PLD_RECEV_ERR);
dsi->state.host_configured = 1;
return ARM_DRIVER_OK;
}
/**
\fn int32_t DSI_ConfigureDPI (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief Configure DSI DPI Interface.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_ConfigureDPI (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
DSI_INFO *dsi_info;
DSI_DPI_INFO *dpi_info = (DSI_DPI_INFO *)dsi->dpi_info;
dsi_info = display_panel->dsi_info;
if(dsi->state.host_configured == 0)
{
return ARM_DRIVER_ERROR;
}
dsi_dpi_set_color_coding(dsi->reg_base, dsi_info->color_coding);
dsi_set_video_packet_size(dsi->reg_base, dpi_info->vid_pkt_size);
dsi_set_video_number_chunks(dsi->reg_base, dpi_info->vid_num_chunks);
dsi_set_video_null_packet_size(dsi->reg_base, dpi_info->vid_null_size);
dsi_set_video_hsa_time(dsi->reg_base, display_panel->hsync_time << 1);
dsi_set_video_hbp_time(dsi->reg_base, display_panel->hbp_time << 1);
dsi_set_video_hline_time(dsi->reg_base, ((display_panel->hsync_time << 1) \
+ (display_panel->hbp_time << 1) \
+ (display_panel->hfp_time << 1) \
+ (display_panel->hactive_time << 1)));
dsi_set_video_vsa_lines(dsi->reg_base, display_panel->vsync_line);
dsi_set_video_vbp_lines(dsi->reg_base, display_panel->vbp_line);
dsi_set_video_vfp_lines(dsi->reg_base, display_panel->vfp_line);
dsi_set_video_vactive_lines(dsi->reg_base, display_panel->vactive_line);
dsi->state.dpi_configured = 1;
return ARM_DRIVER_OK;
}
/**
\fn int32_t DSI_Control (ARM_MIPI_DSI_CONTROL control, uint32_t arg,
DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief Control DSI Interface.
\param[in] control DSI host and DPI Configuration.
\param[in] arg Argument of operation (optional)
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_Control (ARM_MIPI_DSI_CONTROL control, uint32_t arg,
DISPLAY_PANEL_DEVICE *display_panel,DSI_RESOURCES *dsi)
{
ARG_UNUSED(arg);
int32_t ret = ARM_DRIVER_OK;
switch(control)
{
case DSI_CONFIGURE_HOST:
{
ret = DSI_ConfigureHost(dsi);
if(ret != ARM_DRIVER_OK)
{
return ret;
}
break;
}
case DSI_CONFIGURE_DPI:
{
ret = DSI_ConfigureDPI(display_panel, dsi);
if(ret != ARM_DRIVER_OK)
{
return ret;
}
break;
}
default:
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
return ret;
}
/**
\fn int32_t DSI_StartCommandMode (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief Configure DSI to start Command mode.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_StartCommandMode (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
int32_t ret = ARM_DRIVER_OK;
DSI_DPI_INFO *dpi_info = (DSI_DPI_INFO *)dsi->dpi_info;
uint16_t clklp2hs_time, lp2hs_time, clkhs2lp_time, hs2lp_time;
uint32_t bitrate_mbps;
uint8_t range = 0;
if(dsi->state.host_configured == 0)
{
return ARM_DRIVER_ERROR;
}
bitrate_mbps = (dsi->frequency * 2)/1000000;
for(range = 0; (range < ARRAY_SIZE(hstransition_timing_range) - 1) &&
((bitrate_mbps) > hstransition_timing_range[range].bitrate_mbps);
++range);
clklp2hs_time = hstransition_timing_range[range].clklp2hs_time;
clkhs2lp_time = hstransition_timing_range[range].clkhs2lp_time;
lp2hs_time = hstransition_timing_range[range].lp2hs_time;
hs2lp_time = hstransition_timing_range[range].hs2lp_time;
dsi_power_up_disable(dsi->reg_base);
dsi_auto_clklane_enable(dsi->reg_base);
dsi_set_phy_clklp2hs_time(dsi->reg_base, clklp2hs_time);
dsi_set_phy_clkhs2lp_time(dsi->reg_base, clkhs2lp_time);
dsi_set_phy_lp2hs_time(dsi->reg_base, lp2hs_time);
dsi_set_phy_hs2lp_time(dsi->reg_base, hs2lp_time);
dsi_reception_enable(dsi->reg_base);
dsi_command_mode_enable(dsi->reg_base);
dsi_set_video_mode_type(dsi->reg_base, dpi_info->vid_mode);
dsi_command_transmission_enable(dsi->reg_base);
dsi_set_tx_escap_clock_divider(dsi->reg_base, dsi->tx_ecs_clk_div);
dsi_set_command_mode_config(dsi->reg_base, DSI_CMD_MODE_CFG_GEN_SW_0P_TX | \
DSI_CMD_MODE_CFG_GEN_SW_1P_TX | \
DSI_CMD_MODE_CFG_GEN_SW_2P_TX | \
DSI_CMD_MODE_CFG_GEN_SR_0P_TX | \
DSI_CMD_MODE_CFG_GEN_SR_1P_TX | \
DSI_CMD_MODE_CFG_GEN_SR_2P_TX | \
DSI_CMD_MODE_CFG_GEN_LW_TX | \
DSI_CMD_MODE_CFG_DCS_SW_0P_TX | \
DSI_CMD_MODE_CFG_DCS_SW_1P_TX | \
DSI_CMD_MODE_CFG_DCS_SR_0P_TX | \
DSI_CMD_MODE_CFG_DCS_LW_TX | \
DSI_CMD_MODE_CFG_MAX_RD_PKT_SIZE);
dsi_power_up_enable(dsi->reg_base);
/*Configure LCD Panel*/
ret = display_panel->ops->Control(DISPALY_PANEL_CONFIG);
if(ret != ARM_DRIVER_OK)
{
return ret;
}
dsi->state.panel_initialized = 1;
return ret;
}
/**
\fn int32_t DSI_StartVideoMode (DISPLAY_PANEL_DEVICE *display_panel,DSI_RESOURCES *dsi)
\brief Configure DSI to start Video mode.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources.
\return \ref execution_status.
*/
static int32_t DSI_StartVideoMode (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
int32_t ret = ARM_DRIVER_OK;
if((dsi->state.dpi_configured == 0) && (dsi->state.panel_initialized) == 0)
{
return ARM_DRIVER_ERROR;
}
dsi_power_up_disable(dsi->reg_base);
dsi_auto_clklane_disable(dsi->reg_base);
dsi_phy_txrequestclkhs_enable(dsi->reg_base);
dsi_hs_eotp_enable(dsi->reg_base);
dsi_video_mode_enable(dsi->reg_base);
dsi_power_up_enable(dsi->reg_base);
/*Start LCD Panel*/
ret = display_panel->ops->Start();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
return ret;
}
/**
\fn int32_t DSI_Stop (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
\brief Shutdown DSI.
\param[in] display_panel Pointer to display panel resources.
\param[in] dsi Pointer to DSI resources
\return \ref execution_status
*/
static int32_t DSI_Stop (DISPLAY_PANEL_DEVICE *display_panel, DSI_RESOURCES *dsi)
{
int32_t ret = ARM_DRIVER_OK;
if(dsi->state.powered == 0)
{
return ARM_DRIVER_ERROR;
}
dsi_power_up_disable(dsi->reg_base);
/*Stop LCD Panel*/
ret = display_panel->ops->Stop();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
return ret;
}
/**
\fn void MIPI_DSI_ISR (DSI_RESOURCES *dsi)
\brief MIPI DSI interrupt service routine
\param[in] dsi Pointer to DSI resources
*/
static void MIPI_DSI_ISR (DSI_RESOURCES *dsi)
{
uint32_t int_st = dsi_irq0_status(dsi->reg_base);
if(int_st & (DSI_IRQ0_ACK_WITH_ERR_0 | DSI_IRQ0_ACK_WITH_ERR_1 | \
DSI_IRQ0_ACK_WITH_ERR_2 | DSI_IRQ0_ACK_WITH_ERR_3 | \
DSI_IRQ0_ACK_WITH_ERR_4 | DSI_IRQ0_ACK_WITH_ERR_5 | \
DSI_IRQ0_ACK_WITH_ERR_6 | DSI_IRQ0_ACK_WITH_ERR_7 | \
DSI_IRQ0_ACK_WITH_ERR_8 | DSI_IRQ0_ACK_WITH_ERR_9 | \
DSI_IRQ0_ACK_WITH_ERR_10 | DSI_IRQ0_ACK_WITH_ERR_11 | \
DSI_IRQ0_ACK_WITH_ERR_12 | DSI_IRQ0_ACK_WITH_ERR_13 | \
DSI_IRQ0_ACK_WITH_ERR_14 | DSI_IRQ0_ACK_WITH_ERR_15))
{
dsi->cb_event(DSI_PHY_ERROR_EVENT);
}
if(int_st & (DSI_IRQ0_DPHY_ERRORS_0 | DSI_IRQ0_DPHY_ERRORS_1 | \
DSI_IRQ0_DPHY_ERRORS_3 | DSI_IRQ0_DPHY_ERRORS_4))
{
dsi->cb_event(DSI_ACK_ERROR_EVENT);
}
int_st = dsi_irq1_status(dsi->reg_base);
if(int_st & (DSI_IRQ1_TO_HS_TX | DSI_IRQ1_TO_LP_RX | \
DSI_IRQ1_ECC_SINGLE_ERR | DSI_IRQ1_ECC_MILTI_ERR | \
DSI_IRQ1_CRC_ERR | DSI_IRQ1_PKT_SIZE_ERR | \
DSI_IRQ1_EOPT_ERR))
{
dsi->cb_event(DSI_PKT_ERROR_EVENT);
}
if(int_st & (DSI_IRQ1_DPI_PLD_WR_ERR | DSI_IRQ1_GEN_CMD_WR_ERR | \
DSI_IRQ1_GEN_PLD_WR_ERR | DSI_IRQ1_GEN_PLD_SEND_ERR | \
DSI_IRQ1_GEN_PLD_RD_ERR | DSI_IRQ1_GEN_PLD_RECEV_ERR | \
DSI_IRQ1_DPI_BUFF_PLD_UNDER))
{
dsi->cb_event(DSI_DPI_ERROR_EVENT);
}
}
/* DSI LCD Panel access structure */
static DISPLAY_PANEL_DEVICE *display_panel;
static DSI_DPI_INFO DPI_INFO =
{
.vid_mode = RTE_MIPI_DSI_VID_MODE_TYPE,
.vid_num_chunks = RTE_MIPI_DSI_VID_NUM_CHUNKS,
.vid_null_size = RTE_MIPI_DSI_VID_NULL_SIZE,
};
static DSI_RESOURCES DSI_RES =
{
.reg_base = (DSI_Type*)DSI_BASE,
.tx_ecs_clk_div = RTE_MIPI_DSI_TX_ESC_CLK_DIVISION,
.dpi_info = &DPI_INFO,
.irq = DSI_IRQ_IRQn,
.irq_priority = RTE_MIPI_DSI_IRQ_PRI,
};
/**
\fn void DSI_DCS_Short_Write (uint8_t cmd, uint8_t data)
\brief Perform MIPI DSI DCS Short write.
\param[in] cmd is DCS command info.
\param[in] data to send.
*/
void DSI_DCS_Short_Write (uint8_t cmd, uint8_t data)
{
dsi_dcs_short_write(DSI_RES.reg_base, cmd, data, display_panel->dsi_info->vc_id);
sys_busy_loop_us(100);
}
/**
\fn void DSI_DCS_CMD_Short_Write (uint8_t cmd)
\brief Perform MIPI DSI DCS Short write only command.
\param[in] cmd is DCS command info.
*/
void DSI_DCS_CMD_Short_Write (uint8_t cmd)
{
dsi_dcs_cmd_short_write(DSI_RES.reg_base, cmd, display_panel->dsi_info->vc_id);
sys_busy_loop_us(100);
}
/**
\fn void DSI_DCS_Long_Write (uint8_t cmd, uint32_t data)
\brief Perform MIPI DSI DCS Short write.
\param[in] data pointer to data buffer.
\param[in] len data buffer length.
*/
void DSI_DCS_Long_Write (uint8_t* data, uint32_t len)
{
dsi_dcs_long_write(DSI_RES.reg_base, data, len, display_panel->dsi_info->vc_id);
sys_busy_loop_us(100);
}
/**
\fn int32_t ARM_MIPI_DSI_Initialize (ARM_MIPI_DSI_SignalEvent_t cb_event)
\brief Initialize MIPI DSI Interface.
\param[in] cb_event Pointer to ARM_MIPI_DSI_SignalEvent_t
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_Initialize (ARM_MIPI_DSI_SignalEvent_t cb_event)
{
display_panel = Get_Display_Panel();
return DSI_Initialize (cb_event, display_panel, &DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_Uninitialize (void)
\brief uninitialize MIPI DSI Interface.
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_Uninitialize (void)
{
return DSI_Uninitialize (display_panel, &DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_PowerControl (ARM_POWER_STATE state)
\brief Control DSI Interface Power.
\param[in] state Power state
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_PowerControl (ARM_POWER_STATE state)
{
return DSI_PowerControl (state, &DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_Control (ARM_MIPI_DSI_CONTROL control, uint32_t arg)
\brief Control DSI Interface.
\param[in] control DSI host and DPI Configuration.
\param[in] arg Argument of operation (optional)
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_Control (ARM_MIPI_DSI_CONTROL control, uint32_t arg)
{
return DSI_Control (control, arg, display_panel, &DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_StartCommandMode (void)
\brief Configure DSI to start Command mode.
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_StartCommandMode (void)
{
return DSI_StartCommandMode (display_panel,&DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_StartVideoMode (void)
\brief Configure DSI to start Video mode.
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_StartVideoMode (void)
{
return DSI_StartVideoMode (display_panel, &DSI_RES);
}
/**
\fn int32_t ARM_MIPI_DSI_Stop (void)
\brief Shutdown DSI.
\return \ref execution_status
*/
static int32_t ARM_MIPI_DSI_Stop (void)
{
return DSI_Stop (display_panel, &DSI_RES);
}
/**
\fn void DSI_IRQHandler (void)
\brief DSi IRQ Handler.
*/
void DSI_IRQHandler(void)
{
MIPI_DSI_ISR (&DSI_RES);
}
/**
\brief Access structure of the MIPI DSI Driver.
*/
extern ARM_DRIVER_MIPI_DSI Driver_MIPI_DSI;
ARM_DRIVER_MIPI_DSI Driver_MIPI_DSI =
{
ARM_MIPI_DSI_GetVersion,
ARM_MIPI_DSI_GetCapabilities,
ARM_MIPI_DSI_Initialize,
ARM_MIPI_DSI_Uninitialize,
ARM_MIPI_DSI_PowerControl,
ARM_MIPI_DSI_Control,
ARM_MIPI_DSI_StartCommandMode,
ARM_MIPI_DSI_StartVideoMode,
ARM_MIPI_DSI_Stop
};