~aleteoryx/muditaos

ref: 1d2f5cf7a49cf1fb9463d289daa1492a2bec2d1d muditaos/module-bsp/board/rt1051/bsp/torch/torch.cpp -rw-r--r-- 5.5 KiB
1d2f5cf7 — Piotr Tański [EGD-7754] Dates bumped in disclaimers 4 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
// Copyright (c) 2017-2021, 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"

using namespace drivers;

static std::shared_ptr<drivers::DriverI2C> i2c;

namespace bsp
{

    namespace torch
    {
        static xQueueHandle qHandleIrq = NULL;

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

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

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

            qHandleIrq = qHandle;

            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<uint32_t>(BoardDefinitions::TORCH_DRIVER_EN)});
            gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), 0);
            vTaskDelay(pdMS_TO_TICKS(5));
            gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), 1);
            vTaskDelay(pdMS_TO_TICKS(5));

            if (isPresent()) {
                turn(State::off);
                setCurrent(max_current_mA);
                return kStatus_Success;
            }
            return kStatus_Fail;
        }

        void deinit()
        {
            qHandleIrq = NULL;
            turn(State::off);
        }

        bool isPresent(void)
        {
            al3644tt_device_id id;
            addr.subAddress = AL3644TT_DEVICE_ID_REG;
            auto read       = i2c->Read(addr, (uint8_t *)(&id), 1);

            if (read != 1) {
                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 led1_brightness{
                .brightness_code          = al3644tt_current_convert(mA > max_current_mA ? max_current_mA : mA),
                .led2_brightness_override = AL3644TT_LED1_TORCH_BRIGHTNESS_OVERRIDE,
            };
            auto wrote = i2c->Write(addr, (uint8_t *)(&led1_brightness), 1);
            if (wrote != 1) {
                return false;
            }
            return true;
        };
        bool turn(State state, ColourTemperature colourTemp)
        {
            if (colourTemp != ColourTemperature::noChange) {
                currentColourTemp = colourTemp;
            }

            addr.subAddress = AL3644TT_ENABLE_REG;
            al3644tt_enable_reg en_reg{
                .led1_en = static_cast<uint8_t>(currentColourTemp == ColourTemperature::warmest && state == State::on
                                                    ? AL3644TT_LED_ENABLED
                                                    : AL3644TT_LED_DISABLED),
                .led2_en = static_cast<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 wrote = i2c->Write(addr, (uint8_t *)(&en_reg), 1);
            if (wrote != 1) {
                return false;
            }
            return true;
        }

        std::pair<bool, State> getState()
        {
            addr.subAddress = AL3644TT_ENABLE_REG;
            al3644tt_enable_reg en_reg;
            auto read = i2c->Read(addr, (uint8_t *)(&en_reg), 1);
            if (read != 1) {
                return std::make_pair(false, State::off); // invalid
            }
            return std::make_pair(true,
                                  (en_reg.led1_en == AL3644TT_LED_ENABLED || en_reg.led2_en == AL3644TT_LED_ENABLED)
                                      ? State::on
                                      : State::off);
        }

        ColourTemperature getColorTemp()
        {
            return currentColourTemp;
        }

        bool toggle()
        {
            auto [success, state] = getState();
            if (success == false) {
                return false;
            }
            else {
                return turn(state == State::off ? State::on : State::off);
            }
        }
    } // namespace torch
} // namespace bsp