~aleteoryx/muditaos

ref: f9490f61e42a1740bbbf5c7df937a2bc77c477d9 muditaos/module-bsp/board/rt1051/bsp/torch/torch.cpp -rw-r--r-- 6.4 KiB
f9490f61 — Lefucjusz Revert "[BH-1673] Harmony random resets fixes" 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/torch/torch.hpp"
#include "AL3644TT.hpp"

#include "board/BoardDefinitions.hpp"
#include "drivers/i2c/DriverI2C.hpp"

#include "fsl_common.h"
#include <log/log.hpp>

using namespace drivers;

namespace bsp
{
    namespace torch
    {
        namespace
        {
            std::shared_ptr<drivers::DriverI2C> i2c;
            constexpr auto powerStateTransitionDelayMs = 5;

            I2CAddress addr = {.deviceAddress = 0x63, .subAddress = 0, .subAddressSize = 1};

            std::shared_ptr<DriverGPIO> gpio;
            constexpr unsigned short max_current_mA = 150;
            ColourTemperature currentColourTemp     = ColourTemperature::warmest;

            void powerOnTorch()
            {
                gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_ENABLE);
            }

            void powerOffTorch()
            {
                gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_DISABLE);
            }

            void enablePowerSupply()
            {
                // Make sure torch power is supplied to write or read i2c message and wait a bit
                if (getState() == State::off) {
                    powerOnTorch();
                    vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
                }
            }

            bool write(const drivers::I2CAddress &addr, const uint8_t *txBuff, const size_t size)
            {
                enablePowerSupply();
                auto writeBytes = i2c->Write(addr, txBuff, size);
                return writeBytes == size;
            }

            bool read(const drivers::I2CAddress &addr, uint8_t *rxBuff, const size_t size)
            {
                enablePowerSupply();
                auto readBytes = i2c->Read(addr, rxBuff, size);
                return readBytes == size;
            }
        } // namespace

        std::int32_t init()
        {
            i2c = DriverI2C::Create(
                static_cast<I2CInstances>(BoardDefinitions::TORCH_DRIVER_I2C),
                DriverI2CParams{.baudrate = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_I2C_BAUDRATE)});

            gpio =
                DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::TORCH_DRIVER_GPIO), DriverGPIOParams{});

            // OUTPUT
            gpio->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Output,
                                              .irqMode  = DriverGPIOPinParams::InterruptMode::NoIntmode,
                                              .defLogic = 0,
                                              .pin = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN)});
            powerOffTorch();
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
            powerOnTorch();
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));

            auto present = isPresent();
            turn(State::off);

            return present ? kStatus_Success : kStatus_Fail;
        }

        void deinit()
        {
            turn(State::off);

            /* Explicitly release peripherals */
            i2c.reset();
            gpio.reset();
        }

        bool isPresent(void)
        {
            al3644tt_device_id_reg id;
            addr.subAddress = AL3644TT_DEVICE_ID_REG;
            auto status     = read(addr, reinterpret_cast<std::uint8_t *>(&id), sizeof(al3644tt_device_id_reg));

            if (!status) {
                return false;
            }

            if (id.device_id == AL3644TT_ID && (id.silicon_rev == AL3644TT_REV_1 || id.silicon_rev == AL3644TT_REV_2)) {
                return true;
            }
            LOG_WARN("Something is present at the torch LED driver address (0x%lx), but not the AL3644TT",
                     addr.deviceAddress);
            return false;
        }

        bool setCurrent(const unsigned short mA)
        {
            // set the same current for both channels
            addr.subAddress = AL3644TT_LED1_TORCH_BRIGHTNESS_REG;
            al3644tt_led1_torch_brightness_reg led1_brightness{
                .brightness_code          = al3644tt_current_convert(mA > max_current_mA ? max_current_mA : mA),
                .led2_brightness_override = AL3644TT_LED1_TORCH_BRIGHTNESS_OVERRIDE,
            };
            return write(
                addr, reinterpret_cast<std::uint8_t *>(&led1_brightness), sizeof(al3644tt_led1_torch_brightness_reg));
        }

        bool turn(State state, ColourTemperature colourTemp)
        {
            if (state == State::on) {
                powerOnTorch();
                setCurrent(max_current_mA);
            }

            if (colourTemp != ColourTemperature::noChange) {
                currentColourTemp = colourTemp;
            }

            addr.subAddress = AL3644TT_ENABLE_REG;
            al3644tt_enable_reg en_reg{
                .led1_en = static_cast<std::uint8_t>(
                    currentColourTemp == ColourTemperature::warmest && state == State::on ? AL3644TT_LED_ENABLED
                                                                                          : AL3644TT_LED_DISABLED),
                .led2_en = static_cast<std::uint8_t>(
                    currentColourTemp == ColourTemperature::coldest && state == State::on ? AL3644TT_LED_ENABLED
                                                                                          : AL3644TT_LED_DISABLED),
                .mode          = 0b10,
                .torch_temp_en = 0,
                .strobe_en     = 0,
                .strobe_type   = 0,
                .tx_pin_en     = 0,
            };

            auto status = write(addr, reinterpret_cast<std::uint8_t *>(&en_reg), sizeof(al3644tt_enable_reg));

            if (state == State::off) {
                powerOffTorch();
            }

            return status;
        }

        State getState()
        {
            auto read = gpio->ReadPin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN));
            return read ? State::on : State::off;
        }

        ColourTemperature getColorTemp()
        {
            return currentColourTemp;
        }

        bool toggle()
        {
            auto state = getState();
            return turn(state == State::off ? State::on : State::off);
        }
    } // namespace torch
} // namespace bsp