mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-08 08:58:29 -04:00
891447d798
the NuttX driver tries to send a sync every 4s, but actually ends up sending at around 4.1s due to poor scheduling. Rather strangely, the oreoled firmware seems to rely on this inaccuracy, and doesn't work with exactly 4s under ChibiOS
199 lines
7.2 KiB
C++
199 lines
7.2 KiB
C++
/*
|
|
OreoLED I2C driver
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <AP_HAL/AP_HAL.h>
|
|
#include "NotifyDevice.h"
|
|
|
|
#define OREOLED_NUM_LEDS 4 // maximum number of individual LEDs connected to the oreo led cpu
|
|
#define OREOLED_INSTANCE_ALL 0xff // instance number to indicate all LEDs (used for set_rgb and set_macro)
|
|
#define OREOLED_BRIGHT 0xff // maximum brightness when flying (disconnected from usb)
|
|
|
|
#define CUSTOM_HEADER_LENGTH 4 // number of bytes in the custom LED buffer that are used to identify the command
|
|
|
|
class OreoLED_I2C : public NotifyDevice {
|
|
public:
|
|
// constuctor
|
|
OreoLED_I2C(uint8_t bus, uint8_t theme);
|
|
|
|
// init - initialised the device
|
|
bool init(void) override;
|
|
|
|
// update - updates device according to timed_updated. Should be
|
|
// called at 50Hz
|
|
void update() override;
|
|
|
|
// handle a LED_CONTROL message, by default device ignore message
|
|
void handle_led_control(mavlink_message_t *msg) override;
|
|
|
|
private:
|
|
enum oreoled_pattern {
|
|
OREOLED_PATTERN_OFF = 0,
|
|
OREOLED_PATTERN_SINE = 1,
|
|
OREOLED_PATTERN_SOLID = 2,
|
|
OREOLED_PATTERN_SIREN = 3,
|
|
OREOLED_PATTERN_STROBE = 4,
|
|
OREOLED_PATTERN_FADEIN = 5,
|
|
OREOLED_PATTERN_FADEOUT = 6,
|
|
OREOLED_PATTERN_PARAMUPDATE = 7,
|
|
OREOLED_PATTERN_ENUM_COUNT
|
|
};
|
|
|
|
/* enum of available macros defined by hardware */
|
|
enum oreoled_macro {
|
|
OREOLED_PARAM_MACRO_RESET = 0,
|
|
OREOLED_PARAM_MACRO_COLOUR_CYCLE = 1,
|
|
OREOLED_PARAM_MACRO_BREATH = 2,
|
|
OREOLED_PARAM_MACRO_STROBE = 3,
|
|
OREOLED_PARAM_MACRO_FADEIN = 4,
|
|
OREOLED_PARAM_MACRO_FADEOUT = 5,
|
|
OREOLED_PARAM_MACRO_RED = 6,
|
|
OREOLED_PARAM_MACRO_GREEN = 7,
|
|
OREOLED_PARAM_MACRO_BLUE = 8,
|
|
OREOLED_PARAM_MACRO_YELLOW = 9,
|
|
OREOLED_PARAM_MACRO_WHITE = 10,
|
|
OREOLED_PARAM_MACRO_AUTOMOBILE = 11,
|
|
OREOLED_PARAM_MACRO_AVIATION = 12,
|
|
OREOLED_PARAM_MACRO_ENUM_COUNT
|
|
};
|
|
|
|
/* enum passed to OREOLED_SET_MODE defined by hardware */
|
|
enum oreoled_param {
|
|
OREOLED_PARAM_BIAS_RED = 0,
|
|
OREOLED_PARAM_BIAS_GREEN = 1,
|
|
OREOLED_PARAM_BIAS_BLUE = 2,
|
|
OREOLED_PARAM_AMPLITUDE_RED = 3,
|
|
OREOLED_PARAM_AMPLITUDE_GREEN = 4,
|
|
OREOLED_PARAM_AMPLITUDE_BLUE = 5,
|
|
OREOLED_PARAM_PERIOD = 6,
|
|
OREOLED_PARAM_REPEAT = 7,
|
|
OREOLED_PARAM_PHASEOFFSET = 8,
|
|
OREOLED_PARAM_MACRO = 9,
|
|
OREOLED_PARAM_RESET = 10,
|
|
OREOLED_PARAM_APP_CHECKSUM = 11,
|
|
OREOLED_PARAM_ENUM_COUNT
|
|
};
|
|
|
|
// update_timer - called by scheduler and updates PX4 driver with commands
|
|
void update_timer(void);
|
|
|
|
// set_rgb - set color as a combination of red, green and blue values for one or all LEDs, pattern defaults to solid color
|
|
void set_rgb(uint8_t instance, uint8_t red, uint8_t green, uint8_t blue);
|
|
|
|
// set_rgb - set color as a combination of red, green and blue values for one or all LEDs, using the specified pattern
|
|
void set_rgb(uint8_t instance, enum oreoled_pattern pattern, uint8_t red, uint8_t green, uint8_t blue);
|
|
|
|
// set_rgb - set color as a combination of red, green and blue values for one or all LEDs, using the specified pattern and other parameters
|
|
void set_rgb(uint8_t instance, oreoled_pattern pattern, uint8_t red, uint8_t green, uint8_t blue,
|
|
uint8_t amplitude_red, uint8_t amplitude_green, uint8_t amplitude_blue,
|
|
uint16_t period, uint16_t phase_offset);
|
|
|
|
// set_macro - set macro for one or all LEDs
|
|
void set_macro(uint8_t instance, enum oreoled_macro macro);
|
|
|
|
// send_sync - force a syncronisation of the all LED's
|
|
void send_sync();
|
|
|
|
// functions to set LEDs to specific patterns. These functions return true if no further updates should be made to LEDs this iteration
|
|
bool slow_counter(void);
|
|
bool mode_firmware_update(void);
|
|
bool mode_init(void);
|
|
bool mode_failsafe_radio(void);
|
|
bool set_standard_colors(void);
|
|
bool mode_failsafe_batt(void);
|
|
bool mode_auto_flight(void);
|
|
bool mode_pilot_flight(void);
|
|
|
|
// Clear the desired state
|
|
void clear_state(void);
|
|
|
|
// oreo led modes (pattern, macro or rgb)
|
|
enum oreoled_mode {
|
|
OREOLED_MODE_NONE=0,
|
|
OREOLED_MODE_MACRO,
|
|
OREOLED_MODE_RGB,
|
|
OREOLED_MODE_RGB_EXTENDED,
|
|
};
|
|
|
|
// Oreo LED modes
|
|
enum Oreo_LED_Theme {
|
|
OreoLED_Disabled = 0,
|
|
OreoLED_Aircraft = 1,
|
|
OreoLED_Automobile = 2,
|
|
};
|
|
|
|
// oreo_state structure holds possible state of an led
|
|
struct oreo_state {
|
|
enum oreoled_mode mode;
|
|
enum oreoled_pattern pattern;
|
|
enum oreoled_macro macro;
|
|
uint8_t red;
|
|
uint8_t green;
|
|
uint8_t blue;
|
|
uint8_t amplitude_red;
|
|
uint8_t amplitude_green;
|
|
uint8_t amplitude_blue;
|
|
uint16_t period;
|
|
int8_t repeat;
|
|
uint16_t phase_offset;
|
|
|
|
oreo_state();
|
|
|
|
void clear_state();
|
|
|
|
void set_macro(oreoled_macro new_macro);
|
|
|
|
void set_rgb(enum oreoled_pattern new_pattern, uint8_t new_red, uint8_t new_green, uint8_t new_blue);
|
|
|
|
void set_rgb(enum oreoled_pattern new_pattern, uint8_t new_red, uint8_t new_green,
|
|
uint8_t new_blue, uint8_t new_amplitude_red, uint8_t new_amplitude_green, uint8_t new_amplitude_blue,
|
|
uint16_t new_period, uint16_t new_phase_offset);
|
|
|
|
bool operator==(const oreo_state &os);
|
|
};
|
|
|
|
typedef struct {
|
|
uint8_t led_num;
|
|
uint8_t num_bytes;
|
|
uint8_t buff[32];
|
|
} oreoled_cmd_t;
|
|
|
|
|
|
// send a I2C command
|
|
bool command_send(oreoled_cmd_t &cmd);
|
|
void boot_leds(void);
|
|
|
|
// private members
|
|
uint8_t _bus;
|
|
HAL_Semaphore_Recursive _sem;
|
|
AP_HAL::OwnPtr<AP_HAL::I2CDevice> _dev;
|
|
bool _send_required; // true when we need to send an update to at least one led
|
|
oreo_state _state_desired[OREOLED_NUM_LEDS]; // desired state
|
|
oreo_state _state_sent[OREOLED_NUM_LEDS]; // last state sent to led
|
|
uint8_t _pattern_override; // holds last processed pattern override, 0 if we are not overriding a pattern
|
|
uint8_t _oreo_theme; // theme (1=AirCraft, 2=Ground Vehicle)
|
|
uint8_t _rear_color_r = 255; // the rear LED red value
|
|
uint8_t _rear_color_g = 255; // the rear LED green value
|
|
uint8_t _rear_color_b = 255; // the rear LED blue value
|
|
|
|
uint8_t _slow_count;
|
|
uint8_t _boot_count;
|
|
uint32_t _last_boot_ms;
|
|
uint32_t _last_sync_ms;
|
|
};
|
|
|