mirror of
https://github.com/google/pebble.git
synced 2025-05-04 17:01:40 -04:00
185 lines
4.7 KiB
C
185 lines
4.7 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "drivers/led_controller.h"
|
|
|
|
#include "board/board.h"
|
|
#include "drivers/gpio.h"
|
|
#include "drivers/i2c.h"
|
|
#include "drivers/periph_config.h"
|
|
#include "system/logging.h"
|
|
#include "system/passert.h"
|
|
|
|
#define STM32F2_COMPATIBLE
|
|
#define STM32F4_COMPATIBLE
|
|
#include <mcu.h>
|
|
|
|
enum {
|
|
RegShutdown = 0x00,
|
|
RegLedCtrl = 0x01,
|
|
RegConfig1 = 0x03,
|
|
RegConfig2 = 0x04,
|
|
RegRampingMode = 0x05,
|
|
RegBreathingMark = 0x06,
|
|
RegPwmOut1 = 0x07,
|
|
RegPwmOut2 = 0x08,
|
|
RegPwmOut3 = 0x09,
|
|
RegPwmOut4 = 0x0a,
|
|
RegPwmOut5 = 0x0b,
|
|
RegPwmOut6 = 0x0c,
|
|
RegDataUpdate = 0x10,
|
|
RegT0Out1 = 0x11,
|
|
RegT0Out2 = 0x12,
|
|
RegT0Out3 = 0x13,
|
|
RegT0Out4 = 0x14,
|
|
RegT0Out5 = 0x15,
|
|
RegT0Out6 = 0x16,
|
|
RegT1T3Rgb1 = 0x1a,
|
|
RegT1T3Rgb2 = 0x1b,
|
|
RegT4Out1 = 0x1d,
|
|
RegT4Out2 = 0x1e,
|
|
RegT4Out3 = 0x1f,
|
|
RegT4Out4 = 0x20,
|
|
RegT4Out5 = 0x21,
|
|
RegT4Out6 = 0x22,
|
|
RegTimeUpdate = 0x26,
|
|
RegReset = 0xff
|
|
};
|
|
|
|
static bool s_backlight_off;
|
|
static bool s_initialized = false;
|
|
static uint32_t s_rgb_current_color = LED_BLACK;
|
|
|
|
static bool write_register(uint8_t register_address, uint8_t value) {
|
|
return i2c_write_register(I2C_LED, register_address, value);
|
|
}
|
|
|
|
// used to bring hardware shutdown pin on led controller low, this brings down our shutdown current
|
|
static void prv_shutdown(bool shutdown) {
|
|
periph_config_acquire_lock();
|
|
gpio_output_set(&BOARD_CONFIG_BACKLIGHT.ctl, !shutdown);
|
|
periph_config_release_lock();
|
|
}
|
|
|
|
static void prv_init_pins(void) {
|
|
periph_config_acquire_lock();
|
|
gpio_output_init(&BOARD_CONFIG_BACKLIGHT.ctl, GPIO_OType_PP, GPIO_Speed_2MHz);
|
|
gpio_output_set(&BOARD_CONFIG_BACKLIGHT.ctl, false);
|
|
periph_config_release_lock();
|
|
}
|
|
|
|
void led_controller_init(void) {
|
|
PBL_ASSERTN(BOARD_CONFIG_BACKLIGHT.options & ActuatorOptions_IssiI2C);
|
|
|
|
prv_init_pins();
|
|
prv_shutdown(false);
|
|
|
|
i2c_use(I2C_LED);
|
|
|
|
// reset the LED controller
|
|
if (!write_register(RegReset, 0xaa)) {
|
|
PBL_LOG(LOG_LEVEL_ERROR, "LED Controller is MIA");
|
|
goto cleanup;
|
|
} else {
|
|
s_initialized = true;
|
|
}
|
|
|
|
// take the led controller out of shutdown
|
|
write_register(RegShutdown, 0x01);
|
|
|
|
// set config1 to 0x00 (PWM, Audio disable, AGC enable, AGC fast mode)
|
|
write_register(RegConfig1, 0x00);
|
|
|
|
// set config2 to 0x40 (master control, 25mA drive, 0dB gain)
|
|
write_register(RegConfig2, 0x70);
|
|
|
|
// set ramping_mode to 0x00 (disable ramping)
|
|
// TODO: this is potentially quite useful for us
|
|
write_register(RegRampingMode, 0x00);
|
|
|
|
// set breathing mark to 0x00 (disable breathing)
|
|
// TODO: this is potentially quite useful for us for the RGB LEDs
|
|
write_register(RegBreathingMark, 0x00);
|
|
|
|
s_backlight_off = true;
|
|
s_rgb_current_color = LED_BLACK;
|
|
|
|
cleanup:
|
|
i2c_release(I2C_LED);
|
|
prv_shutdown(true);
|
|
}
|
|
|
|
void led_controller_backlight_set_brightness(uint8_t brightness) {
|
|
if ((BOARD_CONFIG_BACKLIGHT.options & ActuatorOptions_IssiI2C) == 0 || !s_initialized) {
|
|
return;
|
|
}
|
|
|
|
prv_shutdown(false);
|
|
i2c_use(I2C_LED);
|
|
|
|
write_register(RegPwmOut1, brightness);
|
|
write_register(RegPwmOut2, brightness);
|
|
write_register(RegPwmOut3, brightness);
|
|
|
|
write_register(RegDataUpdate, 0xaa);
|
|
|
|
i2c_release(I2C_LED);
|
|
|
|
s_backlight_off = (brightness == 0);
|
|
|
|
if (s_backlight_off && s_rgb_current_color == LED_BLACK) {
|
|
prv_shutdown(true);
|
|
}
|
|
}
|
|
|
|
|
|
void led_controller_rgb_set_color(uint32_t rgb_color) {
|
|
if ((BOARD_CONFIG_BACKLIGHT.options & ActuatorOptions_IssiI2C) == 0 || !s_initialized) {
|
|
return;
|
|
}
|
|
|
|
s_rgb_current_color = rgb_color;
|
|
|
|
uint8_t red = (s_rgb_current_color & 0x00FF0000) >> 16;
|
|
uint8_t green = (s_rgb_current_color & 0x0000FF00) >> 8;
|
|
uint8_t blue = (s_rgb_current_color & 0x000000FF);
|
|
|
|
prv_shutdown(false);
|
|
i2c_use(I2C_LED);
|
|
|
|
write_register(RegPwmOut4, red);
|
|
write_register(RegPwmOut6, blue);
|
|
write_register(RegPwmOut5, green);
|
|
|
|
write_register(RegDataUpdate, 0xaa);
|
|
|
|
i2c_release(I2C_LED);
|
|
|
|
if (s_backlight_off && s_rgb_current_color == LED_BLACK) {
|
|
prv_shutdown(true);
|
|
}
|
|
}
|
|
|
|
uint32_t led_controller_rgb_get_color(void) {
|
|
return s_rgb_current_color;
|
|
}
|
|
|
|
void command_rgb_set_color(const char* color) {
|
|
uint32_t color_val = strtol(color, NULL, 16);
|
|
|
|
led_controller_rgb_set_color(color_val);
|
|
}
|
|
|