aboutsummaryrefslogtreecommitdiff
path: root/hw/loneoceans/lume-x1-avr32dd20/hwdef.c
blob: 275037b1c42938a2ba9eddb036a0b230cc4c7f65 (plain)
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
// Copyright (C) 2017-2023 Selene ToyKeeper
//               2021-2024 loneoceans
// SPDX-License-Identifier: GPL-3.0-or-later

//***********************************************
//**  HELPER FUNCTIONS FOR LUME-X1-AVR32DD20   **
//***********************************************

#pragma once

#include "fsm/chan-rgbaux.c"

// Declare variables and functions to support UDR multiple power paths
uint8_t power_path_level = 0;        // 0 = off, 1 = firefly, 2 = low, 3 = high
uint8_t is_boost_currently_on = 0;   // for turn-on delay during first turn on

void set_level_udr(uint8_t level);
void set_power_path(uint8_t ramp_level);
void set_level_zero();
bool gradual_tick_main(uint8_t gt);

Channel channels[] = {
    { // main LEDs
        .set_level    = set_level_udr,
        .gradual_tick = gradual_tick_main
    },
    RGB_AUX_CHANNELS
};

// turn off
void set_level_zero() {

    power_path_level = 0;   // set power path level to 0
    DAC_LVL  = 0;           // set DAC to 0
    DAC_VREF = V10;         // set DAC Vref to lowest 

    // turn off DC/DC converter and amplifier 
    BST_ENABLE_PORT &= ~(1 << BST_ENABLE_PIN);
    is_boost_currently_on = 0;

    // turn off all UDR paths
    LED_PATH1_PORT &= ~LED_PATH1_PIN;   
    LED_PATH2_PORT &= ~LED_PATH2_PIN;
    LED_PATH3_PORT &= ~LED_PATH3_PIN;
}

// UDR for set_level, which sets the led brightness based on ramp tables.
// single set of LED(s), fully regulated boost at all levels
void set_level_udr(uint8_t level) {
    if (level == actual_level - 1) return;  //  no-op

    // get the ramp data
    PWM1_DATATYPE dac_lvl  = PWM1_GET(level) << 6;  // dac register is left-aligned
    PWM2_DATATYPE dac_vref = PWM2_GET(level);

    if(is_boost_currently_on != 1){
        // boost is not on, enable buck and add boot-up delay
        is_boost_currently_on = 1;
        BST_ENABLE_PORT |= (1 << BST_ENABLE_PIN);   // turn on buck and amplifier
        delay_4ms(BST_ON_DELAY/4);                  // boot-up delay
    }
    // set the DAC
    DAC_LVL  = dac_lvl;
    DAC_VREF = dac_vref;

    // set the power paths
    set_power_path(level);
}

// handles dynamic Vref used in the ramp tables 
bool gradual_tick_main(uint8_t gt) {
    // TODO overall smoothness can be improved due to gt using linear
    // adjustments, but ramp table is non-linear.

    // if Vref is the same, make gradual adjustments. 
    // else, jump to the next ramp level and use set_level() to handle power paths.
    PWM2_DATATYPE vref_next = PWM2_GET(gt); // DAC ramp table Vref

    // if different vref level, make a ramp level adjustment..
    if (vref_next != DAC_VREF) return true;  // use set_level() to handle normally

    // .. else, same vref, adjust level gradually. 
    PWM1_DATATYPE dac_next  = PWM1_GET(gt); // DAC ramp table data
    PWM1_DATATYPE dac_curr  = DAC_LVL >> 6; // register is left-aligned

    GRADUAL_ADJUST_SIMPLE(dac_next, dac_curr);
    DAC_LVL = dac_curr << 6;
    
    if (dac_next == dac_curr) return true;  // done

    return false;
}

// handles dynamic power pathways based on threshold levels  
void set_power_path(uint8_t ramp_level){

    ramp_level++; // convert to 1-based indexing

    // check if the ramp level corresponds to a new power path or not;
    // if it doesn't, no need to change anything.
    if (ramp_level>=LED_PATH3_PIN_LEVEL_MIN){
        if (power_path_level != 3){
            // high Mode
            LED_PATH1_PORT |= LED_PATH1_PIN;
            LED_PATH2_PORT |= LED_PATH2_PIN;
            LED_PATH3_PORT |= LED_PATH3_PIN;
            power_path_level = 3;
        }
    }
    else if (ramp_level>=LED_PATH2_PIN_LEVEL_MIN){
        if (power_path_level != 2){
            // low Mode
            //LED_PATH1_PORT &= ~LED_PATH1_PIN;
            LED_PATH1_PORT |= LED_PATH1_PIN;
            LED_PATH2_PORT |= LED_PATH2_PIN;
            LED_PATH3_PORT &= ~LED_PATH3_PIN;
            power_path_level = 2;
        }
    }
    else if (ramp_level>=LED_PATH1_PIN_LEVEL_MIN){
        if (power_path_level != 1){
            // firefly mode
            LED_PATH1_PORT |= LED_PATH1_PIN;
            LED_PATH2_PORT &= ~LED_PATH2_PIN;
            LED_PATH3_PORT &= ~LED_PATH3_PIN;
            power_path_level = 1;
        }
    }
}