Skip to content

Cleaning up GFX/LVGL code. #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 25, 2022
104 changes: 58 additions & 46 deletions src/Braccio++.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,43 @@

#include "mbed.h"

void my_print( const char * dsc )
#if LV_USE_LOG
void lvgl_my_print(const char * dsc)
{
Serial.println(dsc);
Serial.println(dsc);
}
#endif /* #if LV_USE_LOG */

extern "C" {
void braccio_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void braccio_read_keypad(lv_indev_drv_t * indev, lv_indev_data_t * data);
};

using namespace std::chrono_literals;

BraccioClass::BraccioClass()
: serial485{Serial1, 0, 7, 8} /* TX, DE, RE */
, servos{serial485}
, PD_UFP{PD_LOG_LEVEL_VERBOSE}
, expander{TCA6424A_ADDRESS_ADDR_HIGH}
, bl{}
, _display_thd{}
, _expander{TCA6424A_ADDRESS_ADDR_HIGH}
, _is_ping_allowed{true}
, _is_motor_connected{false}
, _motors_connected_mtx{}
, _motors_connected_thd{}
, _customMenu{nullptr}
, _bl{}
, _gfx{}
, _lvgl_disp_drv{}
, _lvgl_indev_drv{}
, _lvgl_disp_buf{}
, _lvgl_draw_buf{}
, _lvgl_p_obj_group{nullptr}
, _lvgl_kb_indev{nullptr}
, _display_thd{}
{

}

bool BraccioClass::begin(voidFuncPtr customMenu)
bool BraccioClass::begin(voidFuncPtr custom_menu)
{
Wire.begin();
Serial.begin(115200);
Expand All @@ -57,33 +69,33 @@ bool BraccioClass::begin(voidFuncPtr customMenu)
SPI.begin();

i2c_mutex.lock();
bl.begin();
if (bl.getChipID() != 0xCE) {
_bl.begin();
if (_bl.getChipID() != 0xCE) {
return false;
}
bl.setColor(red);
_bl.setColor(red);

int ret = expander.testConnection();
int ret = _expander.testConnection();

if (ret == false) {
return ret;
}

for (int i = 0; i < 14; i++) {
expander.setPinDirection(i, 0);
_expander.setPinDirection(i, 0);
}

// Set SLEW to low
expander.setPinDirection(21, 0); // P25 = 8 * 2 + 5
expander.writePin(21, 0);
_expander.setPinDirection(21, 0); // P25 = 8 * 2 + 5
_expander.writePin(21, 0);

// Set TERM to HIGH (default)
expander.setPinDirection(19, 0); // P23 = 8 * 2 + 3
expander.writePin(19, 1);
_expander.setPinDirection(19, 0); // P23 = 8 * 2 + 3
_expander.writePin(19, 1);

expander.setPinDirection(18, 0); // P22 = 8 * 2 + 2
expander.writePin(18, 0); // reset LCD
expander.writePin(18, 1); // LCD out of reset
_expander.setPinDirection(18, 0); // P22 = 8 * 2 + 2
_expander.writePin(18, 0); // reset LCD
_expander.writePin(18, 1); // LCD out of reset

/* Set all motor status LEDs to red. */
for (int id = SmartServoClass::MIN_MOTOR_ID; id <= SmartServoClass::MAX_MOTOR_ID; id++) {
Expand All @@ -99,25 +111,25 @@ bool BraccioClass::begin(voidFuncPtr customMenu)
pinMode(BTN_ENTER, INPUT_PULLUP);

#if LV_USE_LOG
lv_log_register_print_cb( my_print );
lv_log_register_print_cb(lvgl_my_print);
#endif

lv_init();

lv_disp_draw_buf_init(&disp_buf, buf, NULL, 240 * 240 / 10);
lv_disp_draw_buf_init(&_lvgl_disp_buf, _lvgl_draw_buf, NULL, LVGL_DRAW_BUFFER_SIZE);

/*Initialize the display*/
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 240;
disp_drv.ver_res = 240;
disp_drv.flush_cb = braccio_disp_flush;
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);

lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_KEYPAD;
indev_drv.read_cb = read_keypad;
kb_indev = lv_indev_drv_register(&indev_drv);
lv_disp_drv_init(&_lvgl_disp_drv);
_lvgl_disp_drv.hor_res = 240;
_lvgl_disp_drv.ver_res = 240;
_lvgl_disp_drv.flush_cb = braccio_disp_flush;
_lvgl_disp_drv.draw_buf = &_lvgl_disp_buf;
lv_disp_drv_register(&_lvgl_disp_drv);

lv_indev_drv_init(&_lvgl_indev_drv);
_lvgl_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
_lvgl_indev_drv.read_cb = braccio_read_keypad;
_lvgl_kb_indev = lv_indev_drv_register(&_lvgl_indev_drv);

lv_style_init(&_lv_style);

Expand All @@ -126,8 +138,8 @@ bool BraccioClass::begin(voidFuncPtr customMenu)
_gfx.fillScreen(TFT_WHITE);
_gfx.setAddrWindow(0, 0, 240, 240);

p_objGroup = lv_group_create();
lv_group_set_default(p_objGroup);
_lvgl_p_obj_group = lv_group_create();
lv_group_set_default(_lvgl_p_obj_group);

_display_thd.start(mbed::callback(this, &BraccioClass::display_thread_func));

Expand All @@ -154,11 +166,10 @@ bool BraccioClass::begin(voidFuncPtr customMenu)
check_power_func();
lv_obj_clean(lv_scr_act());

if (customMenu) {
customMenu();
} else {
defaultMenu();
}
if (custom_menu)
custom_menu();
else
lvgl_defaultMenu();

servos.begin();
servos.setTime(SmartServoClass::BROADCAST, SLOW);
Expand Down Expand Up @@ -228,9 +239,10 @@ void BraccioClass::positions(float & a1, float & a2, float & a3, float & a4, flo
a6 = servos.getPosition(6);
}

void BraccioClass::connectJoystickTo(lv_obj_t* obj) {
lv_group_add_obj(p_objGroup, obj);
lv_indev_set_group(kb_indev, p_objGroup);
void BraccioClass::connectJoystickTo(lv_obj_t* obj)
{
lv_group_add_obj(_lvgl_p_obj_group, obj);
lv_indev_set_group(_lvgl_kb_indev, _lvgl_p_obj_group);
}

void BraccioClass::lvgl_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
Expand Down Expand Up @@ -282,10 +294,10 @@ void BraccioClass::display_thread_func()
}
}

#include <extra/libs/gif/lv_gif.h>

void BraccioClass::lvgl_splashScreen(unsigned long const duration_ms, std::function<void()> check_power_func)
{
extern const lv_img_dsc_t img_bulb_gif;

LV_IMG_DECLARE(img_bulb_gif);
lv_obj_t* img = lv_gif_create(lv_scr_act());
lv_gif_set_src(img, &img_bulb_gif);
Expand Down Expand Up @@ -314,7 +326,7 @@ void BraccioClass::lvgl_pleaseConnectPower()
lv_obj_set_pos(label1, 0, 0);
}

void BraccioClass::defaultMenu()
void BraccioClass::lvgl_defaultMenu()
{
// TODO: create a meaningful default menu
lv_style_set_text_font(&_lv_style, &lv_font_montserrat_32);
Expand Down Expand Up @@ -392,7 +404,7 @@ extern "C" void braccio_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, l
}

/* Reading input device (simulated encoder here) */
extern "C" void read_keypad(lv_indev_drv_t * drv, lv_indev_data_t* data)
extern "C" void braccio_read_keypad(lv_indev_drv_t * drv, lv_indev_data_t* data)
{
static uint32_t last_key = 0;

Expand Down
67 changes: 28 additions & 39 deletions src/Braccio++.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@
#include "lib/TFT_eSPI/TFT_eSPI.h" // Hardware-specific library
#include <lvgl.h>

extern const lv_img_dsc_t img_bulb_gif;

extern "C" {
void braccio_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void read_keypad(lv_indev_drv_t * indev, lv_indev_data_t * data);
};

enum speed_grade_t {
FAST = 10,
MEDIUM = 100,
Expand All @@ -36,7 +29,7 @@ class BraccioClass
BraccioClass();

inline bool begin() { return begin(nullptr); }
bool begin(voidFuncPtr customMenu);
bool begin(voidFuncPtr custom_menu);


void pingOn();
Expand Down Expand Up @@ -75,27 +68,15 @@ class BraccioClass
void lvgl_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);

protected:
// ioexpander APIs
void digitalWrite(int pin, uint8_t value);

// default display APIs
void lvgl_splashScreen(unsigned long const duration_ms, std::function<void()> check_power_func);
void lvgl_pleaseConnectPower();
void defaultMenu();

void setID(int id) {
servos.setID(id);
}
inline void setID(int const id) { servos.setID(id); }

private:

RS485Class serial485;
SmartServoClass servos;
PD_UFP_log_c PD_UFP;
TCA6424A expander;
Backlight bl;
rtos::Thread _display_thd;
void display_thread_func();
TCA6424A _expander;

bool _is_ping_allowed;
bool _is_motor_connected[SmartServoClass::NUM_MOTORS];
Expand All @@ -105,23 +86,31 @@ class BraccioClass
void setMotorConnectionStatus(int const id, bool const is_connected);
void motorConnectedThreadFunc();

voidFuncPtr _customMenu;

const int BTN_LEFT = 3;
const int BTN_RIGHT = 4;
const int BTN_UP = 5;
const int BTN_DOWN = 2;
const int BTN_SEL = A0;
const int BTN_ENTER = A1;
static int constexpr BTN_LEFT = 3;
static int constexpr BTN_RIGHT = 4;
static int constexpr BTN_UP = 5;
static int constexpr BTN_DOWN = 2;
static int constexpr BTN_SEL = A0;
static int constexpr BTN_ENTER = A1;


static size_t constexpr LVGL_DRAW_BUFFER_SIZE = 240 * 240 / 10;

Backlight _bl;
TFT_eSPI _gfx;
lv_disp_drv_t disp_drv;
lv_indev_drv_t indev_drv;
lv_disp_draw_buf_t disp_buf;
lv_color_t buf[240 * 240 / 10];
lv_group_t* p_objGroup;
lv_indev_t *kb_indev;
lv_disp_drv_t _lvgl_disp_drv;
lv_indev_drv_t _lvgl_indev_drv;
lv_disp_draw_buf_t _lvgl_disp_buf;
lv_color_t _lvgl_draw_buf[LVGL_DRAW_BUFFER_SIZE];
lv_group_t * _lvgl_p_obj_group;
lv_indev_t * _lvgl_kb_indev;
lv_style_t _lv_style;
rtos::Thread _display_thd;
void display_thread_func();
void lvgl_splashScreen(unsigned long const duration_ms, std::function<void()> check_power_func);
void lvgl_pleaseConnectPower();
void lvgl_defaultMenu();

#ifdef __MBED__
rtos::EventFlags pd_events;
Expand All @@ -140,13 +129,13 @@ class BraccioClass
}

void setGreen(int i) {
expander.writePin(i * 2 - 1, 0);
expander.writePin(i * 2 - 2, 1);
_expander.writePin(i * 2 - 1, 0);
_expander.writePin(i * 2 - 2, 1);
}

void setRed(int i) {
expander.writePin(i * 2 - 1, 1);
expander.writePin(i * 2 - 2, 0);
_expander.writePin(i * 2 - 1, 1);
_expander.writePin(i * 2 - 2, 0);
}

void pd_thread();
Expand Down