/*
|
* 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
|
}
|