/* * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into an MKSEMI * integrated circuit in a product or a software update for such product, * must reproduce the above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of MKSEMI nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * 4. This software, with or without modification, must only be used with a * MKSEMI integrated circuit. * * 5. Any software provided in binary form under this license must not be * reverse engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "mk_acmp.h" static struct ACMP_HANDLE_T acmp_handle[ACMP_MAX_NUM] = { { .irq = ACMP0_IRQn, .config = { .channel_p = ACMP_EXTPIN5, .channel_n = ACMP_EXTPIN6, .int_en = true, .edge_int = ACMP_BOTHEDGE_INT, .hyst_en = true, .callback = NULL, }, }, { .irq = ACMP1_IRQn, .config = { .channel_p = ACMP_EXTPIN5, .channel_n = ACMP_EXTPIN6, .int_en = true, .edge_int = ACMP_BOTHEDGE_INT, .hyst_en = true, .callback = NULL, }, }, }; int acmp_open(enum ACMP_DEV_T id, struct ACMP_CFG_T *config) { if (id >= ACMP_MAX_NUM) { return DRV_ERROR; } if (config) { memcpy(&acmp_handle[id].config, config, sizeof(struct ACMP_CFG_T)); } // enable acmp uint32_t acmp_cfg = SYSCON->ACMP_CFG; if (id == ACMP_ID0) { acmp_cfg &= 0xFFFFFF00; acmp_cfg |= SYSCON_ACMP_CFG_ACMP0_EN_MSK | SYSCON_ACMP_CFG_ACMP0_MUX_SP(acmp_handle[id].config.channel_p) | SYSCON_ACMP_CFG_ACMP0_MUX_SN(acmp_handle[id].config.channel_n) | SYSCON_ACMP_CFG_ACMP0_EDGE_INT_SET(acmp_handle[id].config.edge_int) | SYSCON_ACMP_CFG_ACMP0_HYST_EN(acmp_handle[id].config.hyst_en); } else { acmp_cfg &= 0xFF00FFFF; acmp_cfg |= SYSCON_ACMP_CFG_ACMP1_EN_MSK | SYSCON_ACMP_CFG_ACMP1_MUX_SP(acmp_handle[id].config.channel_p) | SYSCON_ACMP_CFG_ACMP1_MUX_SN(acmp_handle[id].config.channel_n) | SYSCON_ACMP_CFG_ACMP1_EDGE_INT_SET(acmp_handle[id].config.edge_int) | SYSCON_ACMP_CFG_ACMP1_HYST_EN(acmp_handle[id].config.hyst_en); } SYSCON->ACMP_CFG = acmp_cfg; #if ACMP_INT_MODE_EN if (acmp_handle[id].config.int_en) { NVIC_SetPriority(acmp_handle[id].irq, IRQ_PRIORITY_NORMAL); NVIC_ClearPendingIRQ(acmp_handle[id].irq); NVIC_EnableIRQ(acmp_handle[id].irq); } #endif return DRV_OK; } int acmp_close(enum ACMP_DEV_T id) { if (id >= ACMP_MAX_NUM) { return DRV_ERROR; } // disable acmp SYSCON->ACMP_CFG &= ~(SYSCON_ACMP_CFG_ACMP0_EN_MSK << (16 * id)); #if ACMP_INT_MODE_EN if (acmp_handle[id].config.int_en) { NVIC_DisableIRQ(acmp_handle[id].irq); NVIC_ClearPendingIRQ(acmp_handle[id].irq); } #endif return DRV_OK; } int acmp_get(enum ACMP_DEV_T id) { int ret = DRV_DEV_UNAVAILABLE; if (id == ACMP_ID0) { ret = (int)SYSCON->ACMP_CFG; ret = SYSCON_ACMP_CFG_ACMP0_GET_DATA(ret); } else if (id == ACMP_ID1) { ret = (int)SYSCON->ACMP_CFG; ret = SYSCON_ACMP_CFG_ACMP1_GET_DATA(ret); } return ret; } void ACMP0_IRQHandler(void) { #if ACMP_INT_MODE_EN enum ACMP_DEV_T id = ACMP_ID0; if (acmp_handle[id].config.callback) { acmp_handle[id].config.callback(&id, 0); } #endif } void ACMP1_IRQHandler(void) { #if ACMP_INT_MODE_EN enum ACMP_DEV_T id = ACMP_ID1; if (acmp_handle[id].config.callback) { acmp_handle[id].config.callback(&id, 0); } #endif }