~aleteoryx/muditaos

ref: cfd044be28eb8bc1ae76a3c6b5a95039538d8c24 muditaos/module-bsp/devices/power/MP2639B.cpp -rw-r--r-- 4.4 KiB
cfd044be — Lefucjusz [BH-1874] Fix underline appearing when setting alarm time 2 years ago
                                                                                
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
104
105
106
107
108
109
110
111
112
113
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "MP2639B.hpp"

namespace bsp::devices::power
{
    MP2639B::MP2639B(const Configuration &conf) : configuration{conf}
    {
        irq_filter_timer =
            xTimerCreate("irq_charger_filter", pdMS_TO_TICKS(50), pdFALSE, this, [](TimerHandle_t xTimer) {
                MP2639B *inst = static_cast<MP2639B *>(pvTimerGetTimerID(xTimer));
                /// Charging disable is done automatically if the conditions are met.
                if (not inst->is_valid_voltage()) {
                    inst->enable_charging(false);
                }
                if (inst->configuration.notification) {
                    inst->configuration.notification(inst->get_charge_status());
                }
            });

        drivers::DriverGPIOPinParams mode_pin_params{};
        mode_pin_params.dir      = drivers::DriverGPIOPinParams::Direction::Output;
        mode_pin_params.irqMode  = drivers::DriverGPIOPinParams::InterruptMode::NoIntmode;
        mode_pin_params.defLogic = 0;
        mode_pin_params.pin      = configuration.mode_pin;
        configuration.mode_gpio->ConfPin(mode_pin_params);

        /// Always start with charging disabled
        enable_charging(false);
    }

    MP2639B::~MP2639B()
    {
        xTimerDelete(irq_filter_timer, pdMS_TO_TICKS(100));
        configuration.chgok_gpio->DisableInterrupt(1 << configuration.chgok_pin);
        configuration.acok_gpio->DisableInterrupt(1 << configuration.acok_pin);

        enable_charging(false);
    }
    MP2639B::ChargingStatus MP2639B::get_charge_status()
    {
        /// For more info, please refer to the Table 1 "Charging Status Indication" in reference manual.

        ChargingStatus status{};

        const auto valid_voltage = is_valid_voltage();
        const auto charging      = is_charging();

        if (not valid_voltage) {
            status = ChargingStatus::Discharging;
        }
        else if (valid_voltage and is_charging_enabled()) {
            status = charging ? ChargingStatus::Charging : ChargingStatus::Complete;
        }
        else if (valid_voltage and not is_charging_enabled()) {
            status = ChargingStatus::PluggedNotCharging;
        }
        return status;
    }
    void MP2639B::enable_charging(bool ctrl)
    {
        if (ctrl) {
            configuration.mode_gpio->WritePin(configuration.mode_pin, 0);
        }
        else {
            configuration.mode_gpio->WritePin(configuration.mode_pin, 1);
        }
    }
    void MP2639B::enable_irq()
    {
        drivers::DriverGPIOPinParams ACOKPinConfig{};
        ACOKPinConfig.dir      = drivers::DriverGPIOPinParams::Direction::Input;
        ACOKPinConfig.irqMode  = drivers::DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge;
        ACOKPinConfig.defLogic = 0;
        ACOKPinConfig.pin      = configuration.acok_pin;
        configuration.acok_gpio->ConfPin(ACOKPinConfig);

        drivers::DriverGPIOPinParams CHGOKPinConfig{};
        CHGOKPinConfig.dir      = drivers::DriverGPIOPinParams::Direction::Input;
        CHGOKPinConfig.irqMode  = drivers::DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge;
        CHGOKPinConfig.defLogic = 0;
        CHGOKPinConfig.pin      = configuration.chgok_pin;
        configuration.chgok_gpio->ConfPin(CHGOKPinConfig);

        configuration.chgok_gpio->EnableInterrupt(1U << configuration.chgok_pin);
        configuration.acok_gpio->EnableInterrupt(1U << configuration.acok_pin);
    }

    void MP2639B::handle_irq()
    {
        if (xTimerIsTimerActive(irq_filter_timer) == pdFALSE) {
            xTimerStart(irq_filter_timer, pdMS_TO_TICKS(500));
        }
    }
    bool MP2639B::is_charging_enabled() const
    {
        return configuration.mode_gpio->ReadPin(configuration.mode_pin) == 0;
    }
    bool MP2639B::is_valid_voltage() const
    {
        /// ACOK -> Valid Input Supply Indicator. A logic Low on this pin indicates the presence of a valid input power
        /// supply.
        return configuration.acok_gpio->ReadPin(configuration.acok_pin) == 0;
    }
    bool MP2639B::is_charging() const
    {
        /// CHGOK -> Charging Completion Indicator. A logic Low indicates charging operation. The pin will become an
        /// open drain once the charge is completed or suspended.
        return configuration.chgok_gpio->ReadPin(configuration.chgok_pin) == 0;
    }

} // namespace bsp::devices::power