fpwm_intr.c 3.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
/*
 * Copyright : (C) 2022 Phytium Information Technology, Inc.
 * All Rights Reserved.
 *
 * This program is OPEN SOURCE software: you can redistribute it and/or modify it
 * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
 * either version 1.0 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the Phytium Public License for more details.
 *
 *
 * FilePath: fpwm_intr.c
 * Date: 2022-02-10 14:53:42
 * LastEditTime: 2022-02-25 11:45:05
 * Description:  This files is for
 *
 * Modify History:
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 */
#include "fparameters.h"
#include "fassert.h"
#include "finterrupt.h"
#include "fpwm.h"
#include "fpwm_hw.h"

#define FT_PWM_DEBUG_TAG "FT_PWM_INTR"
#define FPWM_DEBUG(format, ...) FT_DEBUG_PRINT_D(FT_PWM_DEBUG_TAG, format, ##__VA_ARGS__)
#define FPWM_INFO(format, ...) FT_DEBUG_PRINT_I(FT_PWM_DEBUG_TAG, format, ##__VA_ARGS__)
#define FPWM_WARN(format, ...) FT_DEBUG_PRINT_W(FT_PWM_DEBUG_TAG, format, ##__VA_ARGS__)
#define FPWM_ERROR(format, ...) FT_DEBUG_PRINT_E(FT_PWM_DEBUG_TAG, format, ##__VA_ARGS__)

#define FPWM_CALL_INTR_EVENT_HANDLDER(instance_p, event) \
    if (instance_p->event_handler[event])                 \
        instance_p->event_handler[event](instance_p->event_param[event])

/**
 * @name: FPwmRegisterInterruptHandler
 * @msg: register FPwm interrupt handler function
 * @param {FPwm} *instance_p, pointer to the pwm instance
 * @param {FPwmIntrEvtType} event_type, interrupt event type
 * @param {FPwmEvtHandler} handler, interrupt event handler
 * @param {void} *param, contains a pointer to the driver instance
 * @return {*}
 */
void FPwmRegisterInterruptHandler(FPwmCtrl *instance_p, FPwmIntrEventType event_type, FPwmIntrEventHandler handler, void *param)
{
    FASSERT(instance_p);
    FASSERT(event_type < FPWM_INTR_EVENT_NUM);
    instance_p->event_handler[event_type] = handler;
    instance_p->event_param[event_type] = param;
}

/**
 * @name: FPwmIntrHandler
 * @msg:  This function is the interrupt handler for the driver.
 *          It must be connected to an interrupt system by the application such that it
 *          can be called when an interrupt occurs.
 * @param vector Irq num ,Don't need attention .
 * @param args  contains a pointer to the driver instance
 */
void FPwmIntrHandler(s32 vector, void *args)
{
    u32 status;
    static int i = 0;
    FPwmCtrl *pctrl = (FPwmCtrl *)args;

    FASSERT(pctrl != NULL);
    FASSERT(pctrl->is_ready == FT_COMPONENT_IS_READY);
    uintptr pwm_base_addr = 0;
    u8 channel = 0;

    for (channel = 0; channel < FPWM_MODE_CHANNEL; channel++)
    {
        pwm_base_addr = pctrl->config.pwm_base_addr + FPWM_N(channel);

        status = FPWM_READ_REG32(pwm_base_addr, FPWM_CTRL_OFFSET);
        if (!(status & (FPWM_CTRL_INTR_COUNTER_ENABLE | FPWM_CTRL_INTR_FIFO_EMPTY_ENABLE)))
            continue;

        status = FPWM_READ_REG32(pwm_base_addr, FPWM_STATE_OFFSET);
        if (0 == status)
            continue;

        /* Check for the type of error interrupt and Processing it */
        if (status & FPWM_STATE_OVFIF_COUNTER)
        {
            status &= (~FPWM_STATE_OVFIF_COUNTER);
            FPWM_SETBIT(pwm_base_addr, FPWM_STATE_OFFSET, FPWM_STATE_COUNTER_CLEAR);
            FPWM_CALL_INTR_EVENT_HANDLDER(pctrl, FPWM_INTR_EVENT_COUNTER);
        }

        if (status & FPWM_STATE_FIFO_EMPTY)
        {
            FPWM_SETBIT(pwm_base_addr, FPWM_STATE_OFFSET, FPWM_STATE_FIFO_EMPTY);
            FPWM_CALL_INTR_EVENT_HANDLDER(pctrl, FPWM_INTR_EVENT_FIFO_EMPTY);
        }
    }

}