/* * Copyright 2020-2021 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_dcic.h" /******************************************************************************* * Definitions ******************************************************************************/ /* Component ID definition, used by tools. */ #ifndef FSL_COMPONENT_ID #define FSL_COMPONENT_ID "platform.drivers.dcic" #endif /******************************************************************************* * Prototypes ******************************************************************************/ /*! * @brief Get instance number for DCIC module. * * @param base DCIC peripheral base address. */ static uint32_t DCIC_GetInstance(DCIC_Type *base); static void DCIC_ResetRegister(DCIC_Type *base); /******************************************************************************* * Variables ******************************************************************************/ /*! @brief Pointers to DCIC bases for each instance. */ static DCIC_Type *const s_dcicBases[] = DCIC_BASE_PTRS; #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to dcic clocks for each instance. */ static const clock_ip_name_t s_dcicClocks[] = DCIC_CLOCKS; #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code ******************************************************************************/ static uint32_t DCIC_GetInstance(DCIC_Type *base) { uint32_t instance; /* Find the instance index from base address mappings. */ for (instance = 0; instance < ARRAY_SIZE(s_dcicBases); instance++) { if (s_dcicBases[instance] == base) { break; } } assert(instance < ARRAY_SIZE(s_dcicBases)); return instance; } #define DCIC_DCCIC_RESET_VALUE (DCIC_DCICC_VSYNC_POL_MASK | DCIC_DCICC_HSYNC_POL_MASK | DCIC_DCICC_DE_POL_MASK) #define DCIC_DCICIC_RESET_VALUE (DCIC_DCICIC_FI_MASK_MASK | DCIC_DCICIC_EI_MASK_MASK) static void DCIC_ResetRegister(DCIC_Type *base) { uint32_t i; base->DCICC = DCIC_DCCIC_RESET_VALUE; base->DCICIC = DCIC_DCICIC_RESET_VALUE; /* Reset region registers. */ for (i = 0; i < DCIC_REGION_COUNT; i++) { base->REGION[i].DCICRC = 0UL; base->REGION[i].DCICRS = 0UL; base->REGION[i].DCICRRS = 0UL; } /* Clear all status. */ base->DCICS = (DCIC_DCICS_EI_STAT_MASK | DCIC_DCICS_FI_STAT_MASK | DCIC_DCICS_ROI_MATCH_STAT_MASK); } /* * brief Initializes the DCIC. * * param base DCIC peripheral base address. * param config Pointer to the configuration. */ void DCIC_Init(DCIC_Type *base, const dcic_config_t *config) { #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock. */ (void)CLOCK_EnableClock(s_dcicClocks[DCIC_GetInstance(base)]); #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ DCIC_ResetRegister(base); base->DCICC = config->polarityFlags; DCIC_EnableMismatchExternalSignal(base, config->enableExternalSignal); DCIC_EnableInterrupts(base, config->enableInterrupts); } /* * brief Disable the DCIC. * * param base DCIC peripheral base address. */ void DCIC_Deinit(DCIC_Type *base) { base->DCICC = 0U; #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock. */ (void)CLOCK_DisableClock(s_dcicClocks[DCIC_GetInstance(base)]); #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! * Get the default configuration to initialize DCIC. * * The default configuration is: * config->polarityFlags = kDCIC_VsyncActiveLow | kDCIC_HsyncActiveLow | kDCIC_DataEnableActiveLow | kDCIC_DriveDataOnFallingClkEdge; config->enableExternalSignal = false; config->enableInterrupts = 0; * * param config Pointer to the configuration. */ void DCIC_GetDefaultConfig(dcic_config_t *config) { assert(NULL != config); config->polarityFlags = (uint8_t)kDCIC_VsyncActiveLow | (uint8_t)kDCIC_HsyncActiveLow | (uint8_t)kDCIC_DataEnableActiveLow | (uint8_t)kDCIC_DriveDataOnFallingClkEdge; config->enableExternalSignal = false; config->enableInterrupts = 0; } /* * brief Enable the region of interest (ROI) with configuration. * * Enable the ROI with configuration. To change the configuration except reference * CRC value, the region should be disabled first by ref DCIC_DisableRegion, * then call this function again. The reference CRC value could be changed by * ref DCIC_SetRegionRefCrc without disabling the region. * If the configuration is locked, only the reference CRC value could be changed, * the region size and position, enable status could not be changed until reset. * * param base DCIC peripheral base address. * param regionIdx Region index, from 0 to (DCIC_REGION_COUNT - 1). * param config Pointer to the configuration. */ void DCIC_EnableRegion(DCIC_Type *base, uint8_t regionIdx, const dcic_region_config_t *config) { assert(regionIdx < DCIC_REGION_COUNT); assert(NULL != config); base->REGION[regionIdx].DCICRRS = config->refCrc; base->REGION[regionIdx].DCICRS = (((uint32_t)config->lowerRightX << DCIC_DCICRS_END_OFFSET_X_SHIFT) | ((uint32_t)config->lowerRightY << DCIC_DCICRS_END_OFFSET_Y_SHIFT)); base->REGION[regionIdx].DCICRC = (((uint32_t)config->upperLeftX << DCIC_DCICRC_START_OFFSET_X_SHIFT) | ((uint32_t)config->upperLeftY << DCIC_DCICRC_START_OFFSET_Y_SHIFT) | (config->lock ? DCIC_DCICRC_ROI_FREEZE_MASK : 0UL) | DCIC_DCICRC_ROI_EN_MASK); }