#define lcd_checksum CHECKSUM("lcd")
#define rrd_glcd_checksum CHECKSUM("reprap_discount_glcd")
#define st7565_glcd_checksum CHECKSUM("st7565_glcd")
+#define viki2_checksum CHECKSUM("viki2")
+#define mini_viki2_checksum CHECKSUM("mini_viki2")
#define universal_adapter_checksum CHECKSUM("universal_adapter")
#define menu_offset_checksum CHECKSUM("menu_offset")
this->lcd = new ReprapDiscountGLCD();
} else if (lcd_cksm == st7565_glcd_checksum) {
this->lcd = new ST7565();
+ } else if (lcd_cksm == viki2_checksum) {
+ this->lcd = new ST7565();
+ this->lcd->set_variant(1);
+ } else if (lcd_cksm == mini_viki2_checksum) {
+ this->lcd = new ST7565();
+ this->lcd->set_variant(2);
} else if (lcd_cksm == universal_adapter_checksum) {
this->lcd = new UniversalAdapter();
} else {
virtual void buzz(long,uint16_t){};
virtual bool hasGraphics() { return false; }
virtual bool encoderReturnsDelta() { return false; } // set to true if the panel handles encoder clicks and returns a delta
+ virtual uint8_t getContrast() { return 0; }
+ virtual void setContrast(uint8_t c) { }
// on graphics panels, the input bitmap is in X windows XBM format but
// with the bits in a byte reversed so bit7 is left most and bit0 is
virtual void on_main_loop(){};
// override this if the panel can handle more or less screen lines
virtual uint16_t get_screen_lines() { return 4; }
- // used to set a variant for a panel (like viki vs panelolou2)
+ // used to set a variant for a panel (like viki2 vs st7565)
virtual void set_variant(int n) {};
protected:
this->encoder_a_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_a_pin_checksum)->by_default("nc")->as_string())->as_input();
this->encoder_b_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_b_pin_checksum)->by_default("nc")->as_string())->as_input();
- // contrast, mviki needs 0x018
+ // contrast
this->contrast= THEKERNEL->config->value(panel_checksum, contrast_checksum)->by_default(9)->as_number();
// reverse display
this->reversed= THEKERNEL->config->value(panel_checksum, reverse_checksum)->by_default(false)->as_bool();
- framebuffer= (uint8_t *)AHB0.alloc(FB_SIZE); // grab some memoery from USB_RAM
+ framebuffer= (uint8_t *)AHB0.alloc(FB_SIZE); // grab some memory from USB_RAM
if(framebuffer == NULL) {
THEKERNEL->streams->printf("Not enough memory available for frame buffer");
}
+
+ // set default for sub variants
+ is_viki2 = is_mini_viki2= false; // defaults to Wulfnors panel
}
ST7565::~ST7565() {
AHB0.dealloc(framebuffer);
}
+// variant 0 is Wulfnor panel, 1 is viki2, 2 is miniviki2
+void ST7565::set_variant(int n) {
+ switch(n) {
+ case 1:
+ is_viki2= true;
+ this->reversed= true;
+ break;
+ case 2:
+ is_mini_viki2= true;
+ this->reversed= true;
+ break;
+ }
+};
+
//send commands to lcd
void ST7565::send_commands(const unsigned char* buf, size_t size){
cs.set(0);
send_commands(init_seq, sizeof(init_seq));
clear();
}
+
+void ST7565::setContrast(uint8_t c){
+ const unsigned char contrast_seq[] = {
+ 0x27, //Contrast set
+ 0x81,
+ c //contrast value
+ };
+ this->contrast= c;
+ send_commands(contrast_seq, sizeof(contrast_seq));
+}
+
int ST7565::drawChar(int x, int y, unsigned char c, int color){
int retVal=-1;
if(c=='\n'){
//encoder which dosent exist :/
uint8_t readButtons();
int readEncoderDelta();
- int getEncoderResolution() { return 2; }
+ int getEncoderResolution() { return (is_viki2 || is_mini_viki2) ? 4 : 2; }
uint16_t get_screen_lines() { return 8; }
bool hasGraphics() { return true; }
void renderGlyph(int x, int y, const uint8_t *g, int pixelWidth, int pixelHeight);
void pixel(int x, int y, int colour);
+ uint8_t getContrast() { return contrast; }
+ void setContrast(uint8_t c);
+
+ void set_variant(int n);
+
private:
//buffer
unsigned char *framebuffer;
// text cursor position
uint8_t tx, ty;
uint8_t contrast;
- bool reversed;
+ struct {
+ bool reversed:1;
+ bool is_viki2:1;
+ bool is_mini_viki2:1;
+ };
};
#endif /* ST7565_H_ */
0.1F
);
+ mvs->addMenuItem("Contrast",
+ []() -> float { return THEPANEL->lcd->getContrast(); },
+ [this](float v) { THEPANEL->lcd->setContrast(v); },
+ 1,
+ 0,
+ 255,
+ true // instant update
+ );
+
THEPANEL->enter_screen(mvs);
}
}
THEPANEL->lcd->setCursor(0, 2);
THEPANEL->lcd->printf("%10.3f ", value);
+ if(this->instant) {
+ // NOTE this cannot be something that needs to be set in on_main_loop
+ std::get<2>(menu_items[selected_item])(value);
+ }
}
} else {
THEPANEL->enter_control_mode(inc, inc / 10);
this->min_value= std::get<4>(menu_items[line]);
this->max_value= std::get<5>(menu_items[line]);
+ this->instant= std::get<6>(menu_items[line]);
THEPANEL->set_control_value(value);
THEPANEL->lcd->clear();
menu_items.push_back(item);
}
-void ModifyValuesScreen::addMenuItem(const char *name, std::function<float()> getter, std::function<void(float)> setter, float inc, float min, float max)
+void ModifyValuesScreen::addMenuItem(const char *name, std::function<float()> getter, std::function<void(float)> setter, float inc, float min, float max, bool instant)
{
string n(name);
if(n.size() > 10) {
n= n.substr(0, 10);
}
- addMenuItem(make_tuple(strdup(n.c_str()), getter, setter, inc, min, max));
+ addMenuItem(make_tuple(strdup(n.c_str()), getter, setter, inc, min, max, instant));
}
void clicked_menu_entry(uint16_t line);
int idle_timeout_secs(){ return 60; }
- typedef std::tuple<char *, std::function<float()>, std::function<void(float)>, float, float, float> MenuItemType;
- void addMenuItem(const char *name, std::function<float()> getter, std::function<void(float)> setter, float inc= 1.0F, float min= NAN, float max= NAN);
+ typedef std::tuple<char *, std::function<float()>, std::function<void(float)>, float, float, float, bool> MenuItemType;
+ void addMenuItem(const char *name, std::function<float()> getter, std::function<void(float)> setter, float inc= 1.0F, float min= NAN, float max= NAN, bool instant= false);
private:
std::vector<MenuItemType> menu_items;
char control_mode;
- bool delete_on_exit;
+ struct {
+ bool delete_on_exit:1;
+ bool instant:1;
+ };
};