#include "PublicDataRequest.h"
#include "PublicData.h"
-#include "panels/I2CLCD.h"
-#include "panels/VikiLCD.h"
-#include "panels/Smoothiepanel.h"
#include "panels/ReprapDiscountGLCD.h"
#include "panels/ST7565.h"
#include "panels/UniversalAdapter.h"
#include "version.h"
#include "checksumm.h"
#include "ConfigValue.h"
+#include "Config.h"
#define panel_checksum CHECKSUM("panel")
#define enable_checksum CHECKSUM("enable")
#define lcd_checksum CHECKSUM("lcd")
-#define i2c_lcd_checksum CHECKSUM("i2c_lcd")
-#define viki_lcd_checksum CHECKSUM("viki_lcd")
-#define smoothiepanel_checksum CHECKSUM("smoothiepanel")
-#define panelolu2_checksum CHECKSUM("panelolu2")
#define rrd_glcd_checksum CHECKSUM("reprap_discount_glcd")
#define st7565_glcd_checksum CHECKSUM("st7565_glcd")
#define universal_adapter_checksum CHECKSUM("universal_adapter")
// Initialise the LCD, see which LCD to use
if (this->lcd != NULL) delete this->lcd;
- int lcd_cksm = get_checksum(THEKERNEL->config->value(panel_checksum, lcd_checksum)->by_default("i2c")->as_string());
+ int lcd_cksm = get_checksum(THEKERNEL->config->value(panel_checksum, lcd_checksum)->by_default("reprap_discount_glcd")->as_string());
// Note checksums are not const expressions when in debug mode, so don't use switch
- if (lcd_cksm == i2c_lcd_checksum) {
- this->lcd = new I2CLCD();
- } else if (lcd_cksm == viki_lcd_checksum) {
- this->lcd = new VikiLCD();
- this->lcd->set_variant(0);
- } else if (lcd_cksm == panelolu2_checksum) {
- this->lcd = new VikiLCD();
- this->lcd->set_variant(1);
- } else if (lcd_cksm == smoothiepanel_checksum) {
- this->lcd = new Smoothiepanel();
- } else if (lcd_cksm == rrd_glcd_checksum) {
+ if (lcd_cksm == rrd_glcd_checksum) {
this->lcd = new ReprapDiscountGLCD();
} else if (lcd_cksm == st7565_glcd_checksum) {
this->lcd = new ST7565();
} else if (lcd_cksm == universal_adapter_checksum) {
this->lcd = new UniversalAdapter();
} else {
- // no lcd type defined
+ // no known lcd type defined
+ delete this;
return;
}
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef I2CLCD_H
-#define I2CLCD_H
-
-#include "LcdBase.h"
-
-#include "I2C.h" // mbed.h lib
-#include "wait_api.h" // mbed.h lib
-#include "libs/Config.h"
-#include "checksumm.h"
-#include "ConfigValue.h"
-
-using namespace std;
-#include <vector>
-#include <string>
-#include <cstdio>
-#include <cstdarg>
-
-// commands
-#define LCD_CLEARDISPLAY 0x01
-#define LCD_RETURNHOME 0x02
-#define LCD_ENTRYMODESET 0x04
-#define LCD_DISPLAYCONTROL 0x08
-#define LCD_CURSORSHIFT 0x10
-#define LCD_FUNCTIONSET 0x20
-#define LCD_SETCGRAMADDR 0x40
-#define LCD_SETDDRAMADDR 0x80
-
-// flags for display entry mode
-#define LCD_ENTRYRIGHT 0x00
-#define LCD_ENTRYLEFT 0x02
-#define LCD_ENTRYSHIFTINCREMENT 0x01
-#define LCD_ENTRYSHIFTDECREMENT 0x00
-
-// flags for display on/off control
-#define LCD_DISPLAYON 0x04
-#define LCD_DISPLAYOFF 0x00
-#define LCD_CURSORON 0x02
-#define LCD_CURSOROFF 0x00
-#define LCD_BLINKON 0x01
-#define LCD_BLINKOFF 0x00
-
-// flags for display/cursor shift
-#define LCD_DISPLAYMOVE 0x08
-#define LCD_CURSORMOVE 0x00
-#define LCD_MOVERIGHT 0x04
-#define LCD_MOVELEFT 0x00
-
-// flags for function set
-#define LCD_8BITMODE 0x10
-#define LCD_4BITMODE 0x00
-#define LCD_2LINE 0x08
-#define LCD_1LINE 0x00
-#define LCD_5x10DOTS 0x04
-#define LCD_5x8DOTS 0x00
-
-// flags for backlight control
-#define LCD_BACKLIGHT 0x08
-#define LCD_NOBACKLIGHT 0x00
-
-#define En 1<<2 // Enable bit
-#define Rw 1<<1 // Read/Write bit
-#define Rs 1<<0 // Register select bit
-
-// config settings
-#define panel_checksum CHECKSUM("panel")
-#define encoder_a_pin_checksum CHECKSUM("encoder_a_pin")
-#define encoder_b_pin_checksum CHECKSUM("encoder_b_pin")
-#define up_button_pin_checksum CHECKSUM("up_button_pin")
-#define down_button_pin_checksum CHECKSUM("down_button_pin")
-#define click_button_pin_checksum CHECKSUM("click_button_pin")
-
-class I2CLCD : public LcdBase {
- public:
- I2CLCD() {
- // Default values
- this->i2c_address = 0x27;
- this->backlightval = 0x00;
- this->displaycontrol = 0x00;
- this->displayfunction = 0x00;
- this->displaymode = 0x00;
-
- // I2C com
- this->i2c = new mbed::I2C(P0_27, P0_28);
-
- // configure the pins to use
- this->encoder_a_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_a_pin_checksum)->by_default("nc")->as_string())->as_input()->pull_up();
- this->encoder_b_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_b_pin_checksum)->by_default("nc")->as_string())->as_input()->pull_up();
- this->click_pin.from_string(THEKERNEL->config->value( panel_checksum, click_button_pin_checksum )->by_default("nc")->as_string())->as_input()->pull_up();
- this->up_pin.from_string(THEKERNEL->config->value( panel_checksum, up_button_pin_checksum)->by_default("nc")->as_string())->as_input()->pull_up();
- this->down_pin.from_string(THEKERNEL->config->value( panel_checksum, down_button_pin_checksum)->by_default("nc")->as_string())->as_input()->pull_up();
-
- }
- virtual ~I2CLCD() {
- delete this->i2c;
- }
-
- int getEncoderResolution() {
- return 1;
- }
-
- uint8_t readButtons() {
- uint8_t state= 0;
- state |= (this->click_pin.get() ? BUTTON_SELECT : 0);
- state |= (this->up_pin.get() ? BUTTON_UP : 0);
- state |= (this->down_pin.get() ? BUTTON_DOWN : 0);
- return state;
- }
-
- int readEncoderDelta() {
- static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
- static uint8_t old_AB = 0;
- old_AB <<= 2; //remember previous state
- old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) ); //add current state
- return enc_states[(old_AB&0x0f)];
- }
-
- void expanderWrite(char data){
- this->i2c->start();
- this->i2c->write(this->i2c_address<<1);
- this->i2c->write((char)((char)data | (char)backlightval));
- this->i2c->stop();
- }
-
- void pulseEnable(char data){
- this->expanderWrite(data | En); // En high
- wait_us(1); // enable pulse must be >450ns
- this->expanderWrite(data & ~En); // En low
- wait_us(50); // commands need > 37us to settle
- }
-
- void write4bits(char value) {
- this->expanderWrite(value);
- this->pulseEnable(value);
- }
-
- void send(char value, char mode) {
- uint8_t highnib=value&0xf0;
- uint8_t lownib=(value<<4)&0xf0;
- this->write4bits((highnib)|mode);
- this->write4bits((lownib)|mode);
- }
-
- void command(char value) {
- this->send(value, 0);
- }
-
- void write(const char* line, int len) {
- for (int i = 0; i < len; ++i) {
- this->send(*line++, Rs);
- }
- }
-
- void home(){
- this->command(LCD_RETURNHOME); // set cursor position to zero
- wait_us(2000); // this command takes a long time!
- }
-
- void clear(){
- this->command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
- wait_us(2000); // this command takes a long time!
- }
-
- void display() {
- this->displaycontrol |= LCD_DISPLAYON;
- this->command(LCD_DISPLAYCONTROL | this->displaycontrol);
- }
-
- void setCursor(uint8_t col, uint8_t row){
- int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
- if ( row > 4 ) {
- row = 4-1; // we count rows starting w/0
- }
- this->command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
- }
-
- void init(){
- // Setup
- this->displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS;
- this->backlightval = LCD_NOBACKLIGHT;
-
- // Now we pull both RS and R/W low to begin commands
- wait_ms(50);
- this->expanderWrite(this->backlightval);
- wait_ms(1000);
-
- // we start in 8bit mode, try to set 4 bit mode
- for( char i=0;i<3;i++){
- this->write4bits(0x03 << 4);
- wait_us(4500);
- }
-
- // finally, set to 4-bit interface
- this->write4bits(0x02 << 4);
-
- // set # lines, font size, etc.
- this->command(LCD_FUNCTIONSET | this->displayfunction);
-
- // turn the display on with no cursor or blinking default
- this->displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
- this->display();
-
- // clear it off
- this->clear();
-
- // Initialize to default text direction (for roman languages)
- this->displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
-
- // set the entry mode
- this->command(LCD_ENTRYMODESET | displaymode);
-
- this->home();
- wait(0.1);
-
- this->backlightval=LCD_BACKLIGHT;
- expanderWrite(0);
-
- }
-
- private:
- char displaymode;
- char displayfunction;
- char displaycontrol;
- char i2c_address;
- char backlightval;
-
- mbed::I2C* i2c;
-
- Pin encoder_a_pin;
- Pin encoder_b_pin;
- Pin click_pin;
- Pin up_pin;
- Pin down_pin;
-};
-
-
-#endif
+++ /dev/null
-/*
-This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
-Smoothie 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.
-Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "Smoothiepanel.h"
-#include "Kernel.h"
-
-#include "smoothiepanel/LCDBang.h"
-
-#include "smoothiepanel/Colors.h"
-#include "Config.h"
-#include "checksumm.h"
-#include "ConfigValue.h"
-
-// commands
-#define LCD_CLEARDISPLAY 0x01
-#define LCD_RETURNHOME 0x02
-#define LCD_ENTRYMODESET 0x04
-#define LCD_DISPLAYCONTROL 0x08
-#define LCD_CURSORSHIFT 0x10
-#define LCD_FUNCTIONSET 0x20
-#define LCD_SETCGRAMADDR 0x40
-#define LCD_SETDDRAMADDR 0x80
-
-// flags for display entry mode
-#define LCD_ENTRYRIGHT 0x00
-#define LCD_ENTRYLEFT 0x02
-#define LCD_ENTRYSHIFTINCREMENT 0x01
-#define LCD_ENTRYSHIFTDECREMENT 0x00
-
-// flags for display on/off control
-#define LCD_DISPLAYON 0x04
-#define LCD_DISPLAYOFF 0x00
-#define LCD_CURSORON 0x02
-#define LCD_CURSOROFF 0x00
-#define LCD_BLINKON 0x01
-#define LCD_BLINKOFF 0x00
-
-// flags for display/cursor shift
-#define LCD_DISPLAYMOVE 0x08
-#define LCD_CURSORMOVE 0x00
-#define LCD_MOVERIGHT 0x04
-#define LCD_MOVELEFT 0x00
-
-// flags for function set
-#define LCD_8BITMODE 0x10
-#define LCD_4BITMODE 0x00
-#define LCD_2LINE 0x08
-#define LCD_1LINE 0x00
-#define LCD_5x10DOTS 0x04
-#define LCD_5x8DOTS 0x00
-
-// flags for backlight control
-#define LCD_BACKLIGHT 0x08
-#define LCD_NOBACKLIGHT 0x00
-
-
-#define LCD_WRITE 0x00
-#define LCD_READ 0x01
-#define LCD_ACK 0x01
-
-Smoothiepanel::Smoothiepanel() {
- // Default values
- this->backlightval = 0x00;
- this->displaycontrol = 0x00;
- this->displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS; // in case they forget to call begin() at least we have somethin
- this->displaymode = 0x00;
- this->_numlines = 4;
-
- this->wii_connected = false;
-
- // I2C com
- int i2c_pins = THEKERNEL->config->value(panel_checksum, i2c_pins_checksum)->by_default(3)->as_number();
- if(i2c_pins == 0){
- this->i2c = new mbed::I2C(P0_0, P0_1);
- }else if(i2c_pins == 1){
- this->i2c = new mbed::I2C(P0_10, P0_11);
- }else if(i2c_pins == 2){
- this->i2c = new mbed::I2C(P0_19, P0_20);
- }else{ // 3, default
- this->i2c = new mbed::I2C(P0_27, P0_28);
- }
- this->wii = new Wiichuck(this->i2c);
-
- this->i2c_address = (char)THEKERNEL->config->value(panel_checksum, i2c_address_checksum)->by_default(0)->as_number();
- this->i2c_address = (this->i2c_address & 0x07) << 1;
- this->i2c_frequency = THEKERNEL->config->value(panel_checksum, i2c_frequency_checksum)->by_default(20000)->as_number();
- i2c->frequency(this->i2c_frequency);
- this->lcd_contrast = THEKERNEL->config->value(panel_checksum, lcd_contrast_checksum)->by_default(0)->as_number();
- this->backlight_red = THEKERNEL->config->value(panel_checksum, lcd_led_checksum)->by_default(255)->as_number();
- this->backlight_red = THEKERNEL->config->value(panel_checksum, lcd_led_red_checksum)->by_default(this->backlight_red)->as_number();
- this->backlight_green = THEKERNEL->config->value(panel_checksum, lcd_led_green_checksum)->by_default(255)->as_number();
- this->backlight_blue = THEKERNEL->config->value(panel_checksum, lcd_led_blue_checksum)->by_default(255)->as_number();
- this->playledval = THEKERNEL->config->value(panel_checksum, play_led_brightness_checksum)->by_default(255)->as_number();
- this->backledval = THEKERNEL->config->value(panel_checksum, back_led_brightness_checksum)->by_default(255)->as_number();
-
-// this->interrupt_pin.from_string(THEKERNEL->config->value(panel_checksum, i2c_interrupt_pin_checksum)->by_default("nc")->as_string())->as_input();
- 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();
- this->encoder_hue = THEKERNEL->config->value(panel_checksum, encoder_led_hue_checksum)->by_default(220)->as_number();
-}
-
-Smoothiepanel::~Smoothiepanel() {
- delete this->wii;
- delete this->i2c;
-}
-
-void pca9634_init(I2C i2c, int address){
- const int leds = PCA9634_ADDRESS | (address & 0x0E);
- char cmd[2];
-
- // initialize led controller
- cmd[0] = 0x00;
- cmd[1] = 0x00;
- i2c.write(leds, cmd, 2);
- cmd[0] = 0x01;
- cmd[1] = 0x02;
- i2c.write(leds, cmd, 2);
- cmd[0] = 0x0C;
- cmd[1] = 0xAA;
- i2c.write(leds, cmd, 2);
- cmd[0] = 0x0D;
- i2c.write(leds, cmd, 2);
-}
-
-void pca9634_setLed(I2C *i2c, int address, char led, char val){
- const int leds = PCA9634_ADDRESS | (address & 0x0E);
- char cmd[2];
-
- cmd[0] = led; // lcd blue
- cmd[1] = val;
- i2c->write(leds, cmd, 2);
-}
-
-void pca9505_write(I2C *i2c, int address, char reg, char val){
- const int expander = PCA9505_ADDRESS | (address & 0x0E);
- char cmd[2];
-
- cmd[0] = reg;
- cmd[1] = val;
- i2c->write(expander, cmd, 2);
-}
-
-char pca9505_read(I2C *i2c, int address, char reg){
- const int expander = PCA9505_ADDRESS | (address & 0x0E);
- char cmd[1];
-
- cmd[0] = 0x04;
- i2c->write(expander, cmd, 1, false);
- i2c->read(expander, cmd, 1);
- return cmd[0];
-}
-
-void Smoothiepanel::init(){
- // init lcd and buzzer
- lcdbang_init(*this->i2c);
-// lcdbang_print(*this->i2c, " Smoothiepanel Beta - design by Logxen -");
- lcdbang_contrast(*this->i2c, this->lcd_contrast);
-
- pca9634_init(*this->i2c, this->i2c_address);
- setEncoderByHue(this->encoder_hue);
- setBacklightColor(this->backlight_red, this->backlight_green, this->backlight_blue);
- setPlayLED(this->playledval);
- setBackLED(this->backledval);
-
- pca9505_write(this->i2c, this->i2c_address, 0x18, 0xAA); // enable leds for button/led wing on port0
- pca9505_write(this->i2c, this->i2c_address, 0x08, 0x01); // enable leds for button/led wing on port0
-// wait_us(3000);
-// this->clear();
-}
-
-void Smoothiepanel::setLed(int led, bool on){
- // LED turns on when bit is cleared
- char saved = pca9505_read(this->i2c, this->i2c_address, 0x08);
- if(on) {
- switch(led) {
- case LED_FAN_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x40); break; // on
- case LED_HOTEND_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x10); break; // on
- case LED_BED_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x04); break; // on
- }
- }else{
- switch(led) {
- case LED_FAN_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x40); break; // off
- case LED_HOTEND_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x10); break; // off
- case LED_BED_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x04); break; // off
- }
- }
-}
-
-void Smoothiepanel::setLedBrightness(int led, int val){
- switch(led){
-// case LED_FAN_ON: this->backlight_green = val; break; // on
-// case LED_HOTEND_ON: this->backlight_red = val; break; // on
-// case LED_BED_ON: this->backlight_blue = val; break; // on
- }
-}
-
-// cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
-void Smoothiepanel::buzz(long duration, uint16_t freq) {
- const int expander = PCA9505_ADDRESS | this->i2c_address;
- char cmd[2];
- char saved;
-
- // save register state
- cmd[0] = 0x04;
- this->i2c->write(expander, cmd, 1, false);
- this->i2c->read(expander, cmd, 1);
- saved = cmd[0];
-
- // buzz
- cmd[0] = 0x0C;
- cmd[1] = saved & 0xFE;
- this->i2c->write(expander, cmd, 2);
- wait_ms(duration); // TODO: Make this not hold up the whole system
- cmd[1] = saved;
- this->i2c->write(expander, cmd, 2);
-}
-
-uint8_t Smoothiepanel::readButtons(void) {
- const int expander = PCA9505_ADDRESS | this->i2c_address;
- uint8_t button_bits = 0x00;
- char cmd[1];
-
- cmd[0] = 0x03;
- this->i2c->write(expander, cmd, 1, false);
- this->i2c->read(expander, cmd, 1);
- //cmd[0] = ~cmd[0];
- if((cmd[0] & 0x10) > 0) button_bits |= BUTTON_SELECT; // encoder click
- if((cmd[0] & 0x02) > 0) button_bits |= BUTTON_LEFT; // back button
- if((cmd[0] & 0x01) > 0) button_bits |= BUTTON_PAUSE; // play button
- if((cmd[0] & 0x20) > 0){ // wii accessory connected
- if(!this->wii_connected){
- this->wii->init_device();
- if(this->wii->device_type >= 0){
- this->wii_connected = true;
- wait_ms(100);
- }
- }
- if(this->wii_connected){
- this->wii->poll_device();
- if(this->wii->data_ready){
- if(this->wii->device_type == DEVICE_NUNCHUCK){
- if(this->wii->SY > 192) button_bits |= BUTTON_UP;
- else if(this->wii->SY < 64) button_bits |= BUTTON_DOWN;
- if(this->wii->SX > 192) button_bits |= BUTTON_RIGHT;
- else if(this->wii->SX < 64) button_bits |= BUTTON_LEFT;
- if(!this->wii->BC) button_bits |= BUTTON_SELECT;
- if(!this->wii->BZ) button_bits |= BUTTON_LEFT;
- }else if(this->wii->device_type == DEVICE_CLASSIC){
- if(this->wii->LY > 192) button_bits |= BUTTON_UP;
- else if(this->wii->LY < 64) button_bits |= BUTTON_DOWN;
- if(this->wii->LX > 192) button_bits |= BUTTON_RIGHT;
- else if(this->wii->LX < 64) button_bits |= BUTTON_LEFT;
- if(!this->wii->BDU) button_bits |= BUTTON_UP;
- else if(!this->wii->BDD) button_bits |= BUTTON_DOWN;
- if(!this->wii->BDL) button_bits |= BUTTON_LEFT;
- else if(!this->wii->BDR) button_bits |= BUTTON_RIGHT;
- if(!this->wii->BA) button_bits |= BUTTON_SELECT;
- if(!this->wii->BB) button_bits |= BUTTON_LEFT;
- }
- }else this->wii_connected = false;
- }
- }else this->wii_connected = false;
-
- // update the encoder color
- if(this->encoder_changed){
- if(this->encoder_hue > 360) this->encoder_hue -= 360;
- else if(this->encoder_hue < 0) this->encoder_hue += 360;
- this->encoder_changed = false;
-
- setEncoderByHue(this->encoder_hue);
- }
-
- return button_bits;
-}
-
-int Smoothiepanel::readEncoderDelta() {
- static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
- static uint8_t old_AB = 0;
- int8_t state;
- old_AB <<= 2; //remember previous state
- old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) ); //add current state
- state = enc_states[(old_AB&0x0f)];
- if(state != 0){
- this->encoder_hue += state;
- this->encoder_changed = true;
- }
- return state;
-}
-
-void Smoothiepanel::clear()
-{
- command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
-//#ifndef USE_FASTMODE
-// wait_ms(50); // this command takes a long time!
-//#endif
-}
-
-void Smoothiepanel::home()
-{
- command(LCD_RETURNHOME); // set cursor position to zero
-//#ifndef USE_FASTMODE
-// wait_us(2000); // this command takes a long time!
-//#endif
-}
-
-void Smoothiepanel::setCursor(uint8_t col, uint8_t row)
-{
- int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
- if ( row > _numlines ) row = _numlines - 1; // we count rows starting w/0
- command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
-}
-
-// Turn the display on/off (quickly)
-void Smoothiepanel::noDisplay() {
- displaycontrol &= ~LCD_DISPLAYON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-void Smoothiepanel::display() {
- displaycontrol |= LCD_DISPLAYON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// Turns the underline cursor on/off
-void Smoothiepanel::noCursor() {
- displaycontrol &= ~LCD_CURSORON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-void Smoothiepanel::cursor() {
- displaycontrol |= LCD_CURSORON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// Turn on and off the blinking cursor
-void Smoothiepanel::noBlink() {
- displaycontrol &= ~LCD_BLINKON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-void Smoothiepanel::blink() {
- displaycontrol |= LCD_BLINKON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// These commands scroll the display without changing the RAM
-void Smoothiepanel::scrollDisplayLeft(void) {
- command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
-}
-void Smoothiepanel::scrollDisplayRight(void) {
- command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
-}
-
-// This is for text that flows Left to Right
-void Smoothiepanel::leftToRight(void) {
- displaymode |= LCD_ENTRYLEFT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This is for text that flows Right to Left
-void Smoothiepanel::rightToLeft(void) {
- displaymode &= ~LCD_ENTRYLEFT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This will 'right justify' text from the cursor
-void Smoothiepanel::autoscroll(void) {
- displaymode |= LCD_ENTRYSHIFTINCREMENT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This will 'left justify' text from the cursor
-void Smoothiepanel::noAutoscroll(void) {
- displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-void Smoothiepanel::command(uint8_t value) {
- lcdbang_write(*this->i2c, value>>4, true);
- lcdbang_write(*this->i2c, value, true);
-}
-
-void Smoothiepanel::write(const char* line, int len) {
- for (int i = 0; i < len; ++i) {
- lcdbang_write(*this->i2c, *line++);
- }
-}
-
-// Allows to set the backlight, if the LCD backpack is used
-void Smoothiepanel::setBacklight(uint8_t status) {
-/* // LED turns on when bit is cleared
- _backlightBits = M17_BIT_LB|M17_BIT_LG|M17_BIT_LR; // all off
- if (status & LED_RED) _backlightBits &= ~M17_BIT_LR; // red on
- if (status & LED_GREEN) _backlightBits &= ~M17_BIT_LG; // green on
- if (status & LED_BLUE) _backlightBits &= ~M17_BIT_LB; // blue on
-
- burstBits16(_backlightBits);
-*/
-}
-
-void Smoothiepanel::setBacklightColor(uint8_t r, uint8_t g, uint8_t b) {
- const int leds = PCA9634_ADDRESS | this->i2c_address;
- char cmd[2];
-
- cmd[0] = 0x07; // lcd blue
- cmd[1] = b;
- this->i2c->write(leds, cmd, 2);
- cmd[0] = 0x08; // lcd green
- cmd[1] = g;
- this->i2c->write(leds, cmd, 2);
- cmd[0] = 0x09; // lcd red
- cmd[1] = r;
- this->i2c->write(leds, cmd, 2);
-}
-
-void Smoothiepanel::setBacklightByHue(int h) {
- float r, g, b;
- HSVtoRGB(&r, &g, &b, h, 1.0, 1.0);
- setBacklightColor(r*0xFF, g*0xFF, b*0xFF);
-}
-
-void Smoothiepanel::setEncoderLED(uint8_t r, uint8_t g, uint8_t b) {
- const int leds = PCA9634_ADDRESS | this->i2c_address;
- char cmd[2];
-
- cmd[0] = 0x04; // encoder red
- cmd[1] = r;
- this->i2c->write(leds, cmd, 2);
- cmd[0] = 0x05; // encoder green
- cmd[1] = g;
- this->i2c->write(leds, cmd, 2);
- cmd[0] = 0x06; // encoder blue
- cmd[1] = b;
- this->i2c->write(leds, cmd, 2);
-}
-
-void Smoothiepanel::setEncoderByHue(int h) {
- float r, g, b;
- HSVtoRGB(&r, &g, &b, h, 1.0, 1.0);
- setEncoderLED(r*0xFF, g*0xFF, b*0xFF);
-}
-
-void Smoothiepanel::setPlayLED(uint8_t v) {
- const int leds = PCA9634_ADDRESS | this->i2c_address;
- char cmd[2];
-
- cmd[0] = 0x02; // play
- cmd[1] = v;
- this->i2c->write(leds, cmd, 2);
-}
-
-void Smoothiepanel::setBackLED(uint8_t v) {
- const int leds = PCA9634_ADDRESS | this->i2c_address;
- char cmd[2];
-
- cmd[0] = 0x03; // back
- cmd[1] = v;
- this->i2c->write(leds, cmd, 2);
-}
-
-/*
-// write either command or data, burst it to the expander over I2C.
-void Smoothiepanel::send(uint8_t value, uint8_t mode) {
-#ifdef USE_FASTMODE
- // polls for ready. not sure on I2C this is any faster
-
- // set Data pins as input
- char data[2];
- data[0]= MCP23017_IODIRB;
- data[1]= 0x1E;
- i2c->write(this->i2c_address, data, 2);
- uint8_t b= _backlightBits >> 8;
- burstBits8b((M17_BIT_RW>>8)|b); // RW hi,RS lo
- char busy;
- data[0] = MCP23017_GPIOB;
- do {
- burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi
- i2c->write(this->i2c_address, data, 1);
- i2c->read(this->i2c_address, &busy, 1); // Read D7
- burstBits8b((M17_BIT_RW>>8)|b); // EN lo
- burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi
- burstBits8b((M17_BIT_RW>>8)|b); // EN lo
- } while ((busy&(M17_BIT_D7>>8)) != 0);
-
- // reset data bits as output
- data[0]= MCP23017_IODIRB;
- data[1]= 0x00;
- i2c->write(this->i2c_address, data, 2);
- burstBits8b(b); // RW lo
-
-#else
-// wait_us(320);
-#endif
-
- // BURST SPEED, OH MY GOD
- // the (now High Speed!) I/O expander pinout
- // B7 B6 B5 B4 B3 B2 B1 B0 A7 A6 A5 A4 A3 A2 A1 A0 - MCP23017
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // RS RW EN D4 D5 D6 D7 B G R B4 B3 B2 B1 B0
-
- // n.b. RW bit stays LOW to write
- uint8_t buf = _backlightBits >> 8;
- // send high 4 bits
- if (value & 0x10) buf |= M17_BIT_D4 >> 8;
- if (value & 0x20) buf |= M17_BIT_D5 >> 8;
- if (value & 0x40) buf |= M17_BIT_D6 >> 8;
- if (value & 0x80) buf |= M17_BIT_D7 >> 8;
-
- if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN
- else buf |= M17_BIT_EN >> 8; // EN
-
- burstBits8b(buf);
-
- // resend w/ EN turned off
- buf &= ~(M17_BIT_EN >> 8);
- burstBits8b(buf);
-
- // send low 4 bits
- buf = _backlightBits >> 8;
- // send high 4 bits
- if (value & 0x01) buf |= M17_BIT_D4 >> 8;
- if (value & 0x02) buf |= M17_BIT_D5 >> 8;
- if (value & 0x04) buf |= M17_BIT_D6 >> 8;
- if (value & 0x08) buf |= M17_BIT_D7 >> 8;
-
- if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN
- else buf |= M17_BIT_EN >> 8; // EN
-
- burstBits8b(buf);
-
- // resend w/ EN turned off
- buf &= ~(M17_BIT_EN >> 8);
- burstBits8b(buf);
-}
-
-// We pause the system
-uint32_t Smoothiepanel::on_pause_release(uint32_t dummy){
- if(!paused) {
- THEKERNEL->pauser->take();
- paused= true;
- }else{
- THEKERNEL->pauser->release();
- paused= false;
- }
- return 0;
-}
-*/
-
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-
-Much of this was copied from LiquidTWI2
- LiquidTWI2 High Performance i2c LCD driver for MCP23008 & MCP23017
- hacked by Sam C. Lin / http://www.lincomatic.com
- from
- LiquidTWI by Matt Falcon (FalconFour) / http://falconfour.com
- logic gleaned from Adafruit RGB LCD Shield library
-*/
-
-#ifndef SMOOTHIEPANEL_H
-#define SMOOTHIEPANEL_H
-#include "LcdBase.h"
-#include "libs/Pin.h"
-#include "Button.h"
-#include "smoothiepanel/Wiichuck.h"
-
-
-// Smoothiepanel specific settings
-
-// readButtons() will only return these bit values
-//#define ALL_BUTTON_BITS (BUTTON_AUX2|BUTTON_AUX1|BUTTON_SELECT)
-
-
-#define PCA9505_ADDRESS 0x40
-#define PCA9634_ADDRESS 0x50
-
-// config settings for Smoothiepanel
-#define panel_checksum CHECKSUM("panel")
-#define i2c_pins_checksum CHECKSUM("i2c_pins")
-#define i2c_address_checksum CHECKSUM("i2c_address")
-#define i2c_frequency_checksum CHECKSUM("i2c_frequency")
-#define i2c_interrupt_pin_checksum CHECKSUM("i2c_interrupt_pin")
-
-#define lcd_contrast_checksum CHECKSUM("lcd_contrast")
-#define lcd_led_checksum CHECKSUM("lcd_led")
-#define lcd_led_red_checksum CHECKSUM("lcd_led_red")
-#define lcd_led_green_checksum CHECKSUM("lcd_led_green")
-#define lcd_led_blue_checksum CHECKSUM("lcd_led_blue")
-
-#define encoder_a_pin_checksum CHECKSUM("encoder_a_pin")
-#define encoder_b_pin_checksum CHECKSUM("encoder_b_pin")
-#define encoder_led_hue_checksum CHECKSUM("encoder_led_hue")
-
-#define play_led_brightness_checksum CHECKSUM("play_led_brightness")
-#define back_led_brightness_checksum CHECKSUM("back_led_brightness")
-
-class Smoothiepanel : public LcdBase {
- public:
- Smoothiepanel();
- ~Smoothiepanel();
-
- void home();
- void clear();
- void display();
- void setCursor(uint8_t col, uint8_t row);
- void init();
- void write(const char* line, int len);
-
- void setBacklight(uint8_t status);
- void setBacklightColor(uint8_t r, uint8_t g, uint8_t b);
- void setBacklightByHue(int h);
- void setEncoderLED(uint8_t r, uint8_t g, uint8_t b);
- void setEncoderByHue(int h);
- void setPlayLED(uint8_t v);
- void setBackLED(uint8_t v);
-
- uint8_t readButtons();
- int readEncoderDelta();
- int getEncoderResolution() { return 4; }
-
- void setLed(int led, bool on);
- void setLedBrightness(int led, int val);
- void buzz(long,uint16_t);
-
- void noCursor();
- void cursor();
- void noBlink();
- void blink();
- void scrollDisplayLeft();
- void scrollDisplayRight();
- void leftToRight();
- void rightToLeft();
- void autoscroll();
- void noAutoscroll();
- void noDisplay();
-
- private:
-/*
- void send(uint8_t, uint8_t);
-*/
- void command(uint8_t value);
-/*
- void burstBits16(uint16_t);
- void burstBits8b(uint8_t);
-*/
- char displaymode;
- char displayfunction;
- char displaycontrol;
- char i2c_address;
- int i2c_frequency;
- int lcd_contrast;
- int encoder_hue;
- char backlight_red;
- char backlight_green;
- char backlight_blue;
- char backlightval;
- char playledval;
- char backledval;
- uint8_t _numlines,_currline;
-// uint16_t _backlightBits; // only for MCP23017
- mbed::I2C* i2c;
-
- Pin interrupt_pin;
- Pin encoder_a_pin;
- Pin encoder_b_pin;
- Wiichuck* wii;
- bool wii_connected;
- bool encoder_changed;
-};
-
-#endif // SMOOTHIEPANEL_H
+++ /dev/null
-/*
-This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
-Smoothie 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.
-Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "VikiLCD.h"
-
-#include "Kernel.h"
-#include "Button.h"
-#include "Config.h"
-#include "checksumm.h"
-#include "ConfigValue.h"
-
-// config settings for Viki LCD
-#define panel_checksum CHECKSUM("panel")
-#define encoder_a_pin_checksum CHECKSUM("encoder_a_pin")
-#define encoder_b_pin_checksum CHECKSUM("encoder_b_pin")
-#define button_pause_pin_checksum CHECKSUM("button_pause_pin")
-#define i2c_pins_checksum CHECKSUM("i2c_pins")
-#define i2c_frequency_checksum CHECKSUM("i2c_frequency")
-
-// if this is defined we use the R/W poll mode instead of fixed delays
-// However at the slower I2C frequency required for Viki long cables it is slower than fixed delay
-// taken from LiquidCrystalFast.cpp and implemented for Viki LCD here by Jim Morris
-//#define USE_FASTMODE
-
-// readButtons() will only return these bit values
-#define VIKI_ALL_BUTTON_BITS (BUTTON_PAUSE|BUTTON_UP|BUTTON_DOWN|BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SELECT)
-
-#define MCP23017_ADDRESS 0x20<<1
-
-// registers
-#define MCP23017_IODIRA 0x00
-#define MCP23017_IPOLA 0x02
-#define MCP23017_GPINTENA 0x04
-#define MCP23017_DEFVALA 0x06
-#define MCP23017_INTCONA 0x08
-#define MCP23017_IOCONA 0x0A
-#define MCP23017_GPPUA 0x0C
-#define MCP23017_INTFA 0x0E
-#define MCP23017_INTCAPA 0x10
-#define MCP23017_GPIOA 0x12
-#define MCP23017_OLATA 0x14
-
-
-#define MCP23017_IODIRB 0x01
-#define MCP23017_IPOLB 0x03
-#define MCP23017_GPINTENB 0x05
-#define MCP23017_DEFVALB 0x07
-#define MCP23017_INTCONB 0x09
-#define MCP23017_IOCONB 0x0B
-#define MCP23017_GPPUB 0x0D
-#define MCP23017_INTFB 0x0F
-#define MCP23017_INTCAPB 0x11
-#define MCP23017_GPIOB 0x13
-#define MCP23017_OLATB 0x15
-
-//MCP23017 - Adafruit RGB LCD Shield and VikiLCD
-// bit pattern for the burstBits function is
-//
-// B7 B6 B5 B4 B3 B2 B1 B0 A7 A6 A5 A4 A3 A2 A1 A0 - MCP23017
-// RS RW EN D4 D5 D6 D7 LB LG LR BZ B4 B3 B2 B1 B0
-// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
-#define M17_BIT_RS 0x8000
-#define M17_BIT_RW 0x4000
-#define M17_BIT_EN 0x2000
-#define M17_BIT_D4 0x1000
-#define M17_BIT_D5 0x0800
-#define M17_BIT_D6 0x0400
-#define M17_BIT_D7 0x0200
-#define M17_BIT_LB 0x0100
-#define M17_BIT_LG 0x0080
-#define M17_BIT_LR 0x0040
-#define M17_BIT_BZ 0x0020 //Added a buzzer on this pin
-#define M17_BIT_B4 0x0010
-#define M17_BIT_B3 0x0008
-#define M17_BIT_B2 0x0004
-#define M17_BIT_B1 0x0002
-#define M17_BIT_B0 0x0001
-
-// commands
-#define LCD_CLEARDISPLAY 0x01
-#define LCD_RETURNHOME 0x02
-#define LCD_ENTRYMODESET 0x04
-#define LCD_DISPLAYCONTROL 0x08
-#define LCD_CURSORSHIFT 0x10
-#define LCD_FUNCTIONSET 0x20
-#define LCD_SETCGRAMADDR 0x40
-#define LCD_SETDDRAMADDR 0x80
-
-// flags for display entry mode
-#define LCD_ENTRYRIGHT 0x00
-#define LCD_ENTRYLEFT 0x02
-#define LCD_ENTRYSHIFTINCREMENT 0x01
-#define LCD_ENTRYSHIFTDECREMENT 0x00
-
-// flags for display on/off control
-#define LCD_DISPLAYON 0x04
-#define LCD_DISPLAYOFF 0x00
-#define LCD_CURSORON 0x02
-#define LCD_CURSOROFF 0x00
-#define LCD_BLINKON 0x01
-#define LCD_BLINKOFF 0x00
-
-// flags for display/cursor shift
-#define LCD_DISPLAYMOVE 0x08
-#define LCD_CURSORMOVE 0x00
-#define LCD_MOVERIGHT 0x04
-#define LCD_MOVELEFT 0x00
-
-// flags for function set
-#define LCD_8BITMODE 0x10
-#define LCD_4BITMODE 0x00
-#define LCD_2LINE 0x08
-#define LCD_1LINE 0x00
-#define LCD_5x10DOTS 0x04
-#define LCD_5x8DOTS 0x00
-
-// flags for backlight control
-#define LCD_BACKLIGHT 0x08
-#define LCD_NOBACKLIGHT 0x00
-
-VikiLCD::VikiLCD() {
- // I2C com
- int i2c_pins = THEKERNEL->config->value(panel_checksum, i2c_pins_checksum)->by_default(3)->as_number();
- if(i2c_pins == 0){
- this->i2c = new mbed::I2C(P0_0, P0_1);
- }else if(i2c_pins == 1){
- this->i2c = new mbed::I2C(P0_10, P0_11);
- }else if(i2c_pins == 2){
- this->i2c = new mbed::I2C(P0_19, P0_20);
- }else{ // 3, default
- this->i2c = new mbed::I2C(P0_27, P0_28);
- }
-
- this->i2c_frequency = THEKERNEL->config->value(panel_checksum, i2c_frequency_checksum)->by_default(60000)->as_number();
- i2c->frequency(this->i2c_frequency);
-
- // Default values
- this->i2c_address = MCP23017_ADDRESS;
- this->displaycontrol = 0x00;
- this->displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS; // in case they forget to call begin() at least we have somethin
- this->displaymode = 0x00;
- this->_numlines = 4;
-
- // configure the pins to use
- 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();
-
- this->button_pause_pin.from_string(THEKERNEL->config->value( panel_checksum, button_pause_pin_checksum)->by_default("nc")->as_string())->as_input();
-}
-
-VikiLCD::~VikiLCD() {
- delete this->i2c;
-}
-
-
-void VikiLCD::init(){
- // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
- // according to datasheet, we need at least 40ms after power rises above 2.7V
- // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
-
- char data[2];
-
- // Setup
- this->displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS;
- this->_backlightBits = M17_BIT_LB|M17_BIT_LG|M17_BIT_LR; // all off
-
- wait_ms(50);
-
- // now set up input/output pins in MCP23017
- data[0]= MCP23017_IODIRA;
- data[1]= 0x1F; // buttons input, all others output
- i2c->write(this->i2c_address, data, 2);
-
-
- // set the button pullups
- data[0]= MCP23017_GPPUA;
- data[1]= 0x1F;
- i2c->write(this->i2c_address, data, 2);
-
- data[0]= MCP23017_IODIRB;
- data[1]= 0x00; // all pins output
- i2c->write(this->i2c_address, data, 2);
-
- //put the LCD into 4 bit mode
- // start with a non-standard command to make it realize we're speaking 4-bit here
- // per LCD datasheet, first command is a single 4-bit burst, 0011.
- //-----
- // we cannot assume that the LCD panel is powered at the same time as
- // the arduino, so we have to perform a software reset as per page 45
- // of the HD44780 datasheet - (kch)
- //-----
-
- // bit pattern for the burstBits function is
- //
- // B7 B6 B5 B4 B3 B2 B1 B0 A7 A6 A5 A4 A3 A2 A1 A0 - MCP23017
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // RS RW EN D4 D5 D6 D7 B G R B4 B3 B2 B1 B0
- for (uint8_t i=0;i < 3;i++) {
- burstBits8b((M17_BIT_EN|M17_BIT_D5|M17_BIT_D4) >> 8);
- burstBits8b((M17_BIT_D5|M17_BIT_D4) >> 8);
- }
- burstBits8b((M17_BIT_EN|M17_BIT_D5) >> 8);
- burstBits8b(M17_BIT_D5 >> 8);
-
-
- wait_ms(5); // this shouldn't be necessary, but sometimes 16MHz is stupid-fast.
-
- command(LCD_FUNCTIONSET | displayfunction); // then send 0010NF00 (N=lines, F=font)
- wait_ms(5); // for safe keeping...
- command(LCD_FUNCTIONSET | displayfunction); // ... twice.
- wait_ms(5); // done!
-
- // turn on the LCD with our defaults. since these libs seem to use personal preference, I like a cursor.
- displaycontrol = (LCD_DISPLAYON|LCD_BACKLIGHT);
- display();
- // clear it off
- clear();
-
- displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
- // set the entry mode
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// we use this to burst bits to the GPIO chip whenever we need to. avoids repetitive code.
-void VikiLCD::burstBits8b(uint8_t value) {
- char data[2];
- data[0] = MCP23017_GPIOB;
- data[1]= value;
- i2c->write(this->i2c_address, data, 2);
-}
-
-// value byte order is BA
-void VikiLCD::burstBits16(uint16_t value) {
- char data[3];
- data[0] = MCP23017_GPIOA;
- data[1]= value&0xFF;
- data[2]= value>>8;
- i2c->write(this->i2c_address, data, 3);
-}
-
-// cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
-void VikiLCD::buzz(long duration, uint16_t freq) {
- char data[2];
- int currentRegister = 0;
- // read gpio register
- data[0] = MCP23017_GPIOA;
- i2c->write(this->i2c_address, data, 1);
- i2c->read(this->i2c_address, data, 1); // Read from selected Register
- currentRegister= data[0];
-
- duration *=1000; //convert from ms to us
- long period = 1000000 / freq; // period in us
- long elapsed_time = 0;
- while (elapsed_time < duration) {
- data[0]= MCP23017_GPIOA;
- data[1]= currentRegister |= M17_BIT_BZ;
- i2c->write(this->i2c_address, data, 2);
-
- wait_us(period / 2);
-
- data[0]= MCP23017_GPIOA;
- data[1]= currentRegister &= ~M17_BIT_BZ;
- i2c->write(this->i2c_address, data, 2);
-
- wait_us(period / 2);
- elapsed_time += (period);
- }
-}
-
-uint8_t VikiLCD::readButtons(void) {
- char data[2];
- data[0] = MCP23017_GPIOA;
- i2c->write(this->i2c_address, data, 1);
- i2c->read(this->i2c_address, data, 1); // Read from selected Register
-
- // check the button pause
- if(this->button_pause_pin.connected() && this->button_pause_pin.get()) data[0] |= BUTTON_PAUSE;
-
- // if it is the variant Panelolu2 swap the buttons around
- if(this->isPanelolu2) {
- // the select button bit is on GPA2 not GPA0
- if((data[0]&M17_BIT_B2) == 0) return BUTTON_SELECT;
- return 0; // only one button on Panelolu2 ignore the ena_a and en_b
-
- } else {
- return (~data[0]) & VIKI_ALL_BUTTON_BITS;
- }
-}
-
-void VikiLCD::on_refresh(){
- // FIXME this is a hack to get around I2C noise
- // Update Only every 20 refreshes, 1 a second
- static int update_counts = 0;
- update_counts++;
- if( update_counts % 20 == 0 && i2c->is_timed_out()) {
- // if there was a timeout on i2c then reset the lcd
- this->init();
- }
-}
-
-int VikiLCD::readEncoderDelta() {
- static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
- static uint8_t old_AB = 0;
- old_AB <<= 2; //remember previous state
- old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) ); //add current state
- return enc_states[(old_AB&0x0f)];
-}
-
-void VikiLCD::clear()
-{
- command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
-#ifndef USE_FASTMODE
- wait_us(2000); // this command takes a long time!
-#endif
-}
-
-void VikiLCD::home()
-{
- command(LCD_RETURNHOME); // set cursor position to zero
-#ifndef USE_FASTMODE
- wait_us(2000); // this command takes a long time!
-#endif
-}
-
-void VikiLCD::setCursor(uint8_t col, uint8_t row)
-{
- int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
- if ( row > _numlines ) row = _numlines - 1; // we count rows starting w/0
- command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
-}
-
-// Turn the display on/off (quickly)
-void VikiLCD::noDisplay() {
- displaycontrol &= ~LCD_DISPLAYON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-void VikiLCD::display() {
- displaycontrol |= LCD_DISPLAYON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// Turns the underline cursor on/off
-void VikiLCD::noCursor() {
- displaycontrol &= ~LCD_CURSORON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-void VikiLCD::cursor() {
- displaycontrol |= LCD_CURSORON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// Turn on and off the blinking cursor
-void VikiLCD::noBlink() {
- displaycontrol &= ~LCD_BLINKON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-void VikiLCD::blink() {
- displaycontrol |= LCD_BLINKON;
- command(LCD_DISPLAYCONTROL | displaycontrol);
-}
-
-// These commands scroll the display without changing the RAM
-void VikiLCD::scrollDisplayLeft(void) {
- command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
-}
-void VikiLCD::scrollDisplayRight(void) {
- command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
-}
-
-// This is for text that flows Left to Right
-void VikiLCD::leftToRight(void) {
- displaymode |= LCD_ENTRYLEFT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This is for text that flows Right to Left
-void VikiLCD::rightToLeft(void) {
- displaymode &= ~LCD_ENTRYLEFT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This will 'right justify' text from the cursor
-void VikiLCD::autoscroll(void) {
- displaymode |= LCD_ENTRYSHIFTINCREMENT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-// This will 'left justify' text from the cursor
-void VikiLCD::noAutoscroll(void) {
- displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
- command(LCD_ENTRYMODESET | displaymode);
-}
-
-void VikiLCD::command(uint8_t value) {
- send(value, 0);
-}
-
-void VikiLCD::write(const char* line, int len) {
- for (int i = 0; i < len; ++i) {
- send(*line++, 1);
- }
-}
-
-// Sets the indicator leds
-void VikiLCD::setLed(int led, bool onoff) {
- // LED turns on when bit is cleared
- if(onoff) {
- switch(led) {
- case LED_FAN_ON: _backlightBits &= ~M17_BIT_LR; break; // on
- case LED_HOTEND_ON: _backlightBits &= ~M17_BIT_LG; break; // on
- case LED_BED_ON: _backlightBits &= ~M17_BIT_LB; break; // on
- }
- }else{
- switch(led) {
- case LED_FAN_ON: _backlightBits |= M17_BIT_LR; break; // off
- case LED_HOTEND_ON: _backlightBits |= M17_BIT_LG; break; // off
- case LED_BED_ON: _backlightBits |= M17_BIT_LB; break; // off
- }
- }
- burstBits16(_backlightBits);
-}
-
-// write either command or data, burst it to the expander over I2C.
-void VikiLCD::send(uint8_t value, uint8_t mode) {
-#ifdef USE_FASTMODE
- // polls for ready. not sure on I2C this is any faster
-
- // set Data pins as input
- char data[2];
- data[0]= MCP23017_IODIRB;
- data[1]= 0x1E;
- i2c->write(this->i2c_address, data, 2);
- uint8_t b= _backlightBits >> 8;
- burstBits8b((M17_BIT_RW>>8)|b); // RW hi,RS lo
- char busy;
- data[0] = MCP23017_GPIOB;
- do {
- burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi
- i2c->write(this->i2c_address, data, 1);
- i2c->read(this->i2c_address, &busy, 1); // Read D7
- burstBits8b((M17_BIT_RW>>8)|b); // EN lo
- burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi
- burstBits8b((M17_BIT_RW>>8)|b); // EN lo
- } while ((busy&(M17_BIT_D7>>8)) != 0);
-
- // reset data bits as output
- data[0]= MCP23017_IODIRB;
- data[1]= 0x00;
- i2c->write(this->i2c_address, data, 2);
- burstBits8b(b); // RW lo
-
-#else
-// wait_us(320);
-#endif
-
- // BURST SPEED, OH MY GOD
- // the (now High Speed!) I/O expander pinout
- // B7 B6 B5 B4 B3 B2 B1 B0 A7 A6 A5 A4 A3 A2 A1 A0 - MCP23017
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // RS RW EN D4 D5 D6 D7 B G R B4 B3 B2 B1 B0
-
- // n.b. RW bit stays LOW to write
- uint8_t buf = _backlightBits >> 8;
- // send high 4 bits
- if (value & 0x10) buf |= M17_BIT_D4 >> 8;
- if (value & 0x20) buf |= M17_BIT_D5 >> 8;
- if (value & 0x40) buf |= M17_BIT_D6 >> 8;
- if (value & 0x80) buf |= M17_BIT_D7 >> 8;
-
- if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN
- else buf |= M17_BIT_EN >> 8; // EN
-
- burstBits8b(buf);
-
- // resend w/ EN turned off
- buf &= ~(M17_BIT_EN >> 8);
- burstBits8b(buf);
-
- // send low 4 bits
- buf = _backlightBits >> 8;
- // send high 4 bits
- if (value & 0x01) buf |= M17_BIT_D4 >> 8;
- if (value & 0x02) buf |= M17_BIT_D5 >> 8;
- if (value & 0x04) buf |= M17_BIT_D6 >> 8;
- if (value & 0x08) buf |= M17_BIT_D7 >> 8;
-
- if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN
- else buf |= M17_BIT_EN >> 8; // EN
-
- burstBits8b(buf);
-
- // resend w/ EN turned off
- buf &= ~(M17_BIT_EN >> 8);
- burstBits8b(buf);
-}
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-
-Much of this was copied from LiquidTWI2
- LiquidTWI2 High Performance i2c LCD driver for MCP23008 & MCP23017
- hacked by Sam C. Lin / http://www.lincomatic.com
- from
- LiquidTWI by Matt Falcon (FalconFour) / http://falconfour.com
- logic gleaned from Adafruit RGB LCD Shield library
-*/
-
-#ifndef VIKILCD_H
-#define VIKILCD_H
-#include "LcdBase.h"
-#include "libs/Pin.h"
-#include "mbed.h"
-
-// VikiLcd specific settings
-
-class VikiLCD : public LcdBase {
- public:
- VikiLCD();
- virtual ~VikiLCD();
- void home();
- void clear();
- void display();
- void setCursor(uint8_t col, uint8_t row);
- void init();
- void write(const char* line, int len);
- void on_refresh();
-
- // added viki commands
- void setLed(int led, bool onoff);
-
- uint8_t readButtons();
- int readEncoderDelta();
-
- // this is the number of clicks per detent
- int getEncoderResolution() { return 2; }
-
- void set_variant(int n) { isPanelolu2= (n==1); }
-
- void buzz(long,uint16_t);
- void noCursor();
- void cursor();
- void noBlink();
- void blink();
- void scrollDisplayLeft();
- void scrollDisplayRight();
- void leftToRight();
- void rightToLeft();
- void autoscroll();
- void noAutoscroll();
- void noDisplay();
-
- private:
- void send(uint8_t, uint8_t);
- void command(uint8_t value);
-
- void burstBits16(uint16_t);
- void burstBits8b(uint8_t);
- char displaymode;
- char displayfunction;
- char displaycontrol;
- char i2c_address;
- uint8_t _numlines,_currline;
- uint16_t _backlightBits; // only for MCP23017
- mbed::I2C* i2c;
- int i2c_frequency;
- Pin encoder_a_pin;
- Pin encoder_b_pin;
- Pin button_pause_pin;
- bool isPanelolu2;
-};
-
-
-#endif
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef COLORS_H
-#define COLORS_H
-
-void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
-{
- int i;
- float f, p, q, t;
- if( s == 0 ) {
- // achromatic (grey)
- *r = *g = *b = v;
- return;
- }
- h /= 60.0; // sector 0 to 5
- i = floor( h );
- f = h - i; // factorial part of h
- p = v * ( 1.0 - s );
- q = v * ( 1.0 - s * f );
- t = v * ( 1.0 - s * ( 1.0 - f ) );
- switch( i ) {
- case 0:
- *r = v;
- *g = t;
- *b = p;
- break;
- case 1:
- *r = q;
- *g = v;
- *b = p;
- break;
- case 2:
- *r = p;
- *g = v;
- *b = t;
- break;
- case 3:
- *r = p;
- *g = q;
- *b = v;
- break;
- case 4:
- *r = t;
- *g = p;
- *b = v;
- break;
- default: // case 5:
- *r = v;
- *g = p;
- *b = q;
- break;
- }
-}
-
-#endif // COLORS_H
-
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef I2CBANG_H
-#define I2CBANG_H
-#include "mbed.h" // mbed.h lib
-
-void i2cbang_init(I2C i2c){
- const int addr = 0x40;
- char cmd[2];
- cmd[0] = 0x1B;
- cmd[1] = 0x3F;
- i2c.write(addr, cmd, 2);
- cmd[0] = 0x0B;
- cmd[1] = 0xC0;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-}
-
-void i2cbang_start(I2C i2c){
- const int addr = 0x40;
- char cmd[2];
- cmd[0] = 0x0B;
- cmd[1] = 0xBF;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
- cmd[1] = 0x3F;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-}
-
-void i2cbang_stop(I2C i2c){
- const int addr = 0x40;
- char cmd[2];
- cmd[0] = 0x0B;
- cmd[1] = 0xBF;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
- cmd[1] = 0xFF;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-}
-
-void i2cbang_writebit(I2C i2c, bool bit){
- const int addr = 0x40;
- char cmd[2];
- cmd[0] = 0x0B;
- if(bit){
- cmd[1] = 0x7F;
- }else{
- cmd[1] = 0x3F;
- }
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
- if(bit){
- cmd[1] = 0xFF;
- }else{
- cmd[1] = 0xBF;
- }
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
- if(bit){
- cmd[1] = 0x7F;
- }else{
- cmd[1] = 0x3F;
- }
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
- if(bit){
- cmd[1] = 0x3F;
- i2c.write(addr, cmd, 2);
- }
- wait_ms(1);
-}
-
-char i2cbang_readbit(I2C i2c){
- const int addr = 0x40;
- char cmd[2];
- char res;
- cmd[0] = 0x0B;
- cmd[1] = 0x7F;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
- cmd[1] = 0xFF;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
- cmd[0] = 0x03;
- i2c.write(addr, cmd, 1, false);
- i2c.read(addr, cmd, 1);
- res = cmd[0];
- wait_ms(1);
-
- cmd[0] = 0x0B;
- cmd[1] = 0x7F;
- i2c.write(addr, cmd, 2);
- wait_ms(1);
-
-// cmd[1] = 0x3F;
-// i2c.write(addr, cmd, 2);
-// wait_ms(1);
-
- //res = (~res) & 0x40;
- return res;
-}
-
-int i2cbang_write(I2C i2c, char c){
- for (int i=0;i<8;i++){
- i2cbang_writebit(i2c, (c&0x80) > 0);
- c<<=1;
- }
-
- return i2cbang_readbit(i2c);
-/*
- const int addr = 0x40;
- char cmd[2];
- char d = 0x00;
- //data
- for (int i=7;i>=0;i--){
- i2c.write(0x3F | d);
- d = ((c>>i)&1)<<6;
- i2c.write(0x3F | d);
- i2c.write(0xBF | d);
- }
- //ack
- i2c.write(0x3F | d);
- i2c.write(0xBF);
- i2c.stop();
- cmd[0] = 0x1B;
- cmd[1] = 0x7F;
- i2c.write(addr, cmd, 2);
- cmd[0] = 0x03;
- i2c.write(addr, cmd, 1, false);
- i2c.start();
- i2c.write(addr | 0x01);
- cmd[1] = i2c.read(false);
-// int res = (~cmd[1]) & 0x40;
- int res = cmd[1];
- i2c.stop();
- cmd[0] = 0x1B;
- cmd[1] = 0x3F;
- i2c.write(addr, cmd, 2);
- cmd[0] = 0x0B;
- cmd[1] = 0xBF;
- i2c.write(addr, cmd, 2, false);
- return res;
-*/
-}
-
-char i2cbang_read(I2C i2c, bool ack){
- char res = 0;
- for(int i=0;i<8;i++){
- res<<=1;
- res |= i2cbang_readbit(i2c);
- }
-
- if(ack){
- i2cbang_writebit(i2c, 0);
- }else{
- i2cbang_writebit(i2c, 1);
- }
-
- wait_ms(1);
-
- return res;
-}
-
-#endif // I2CBANG_H
-
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef LCDBANG_H
-#define LCDBANG_H
-#include "mbed.h" // mbed.h lib
-#include "I2CBang.h"
-
-void lcdbang_writenibble(I2C i2c, char c, bool command = false){
- const int addr = 0x40;
- char cmd[2];
- c <<= 4;
- c &= 0xF0;
- c |= 0x01;
- if(!command) c |= 0x02;
-
- cmd[0] = 0x0C;
- cmd[1] = c;
- i2c.write(addr, cmd, 2);
- cmd[1] = c | 0x08;
- i2c.write(addr, cmd, 2);
- cmd[1] = c;
- i2c.write(addr, cmd, 2);
-// wait_ms(1);
-}
-
-void lcdbang_write(I2C i2c, char c, bool command = false){
- if(command){
- lcdbang_writenibble(i2c, c, command);
- }else{
- lcdbang_writenibble(i2c, c >> 4, command);
- lcdbang_writenibble(i2c, c, command);
- }
-}
-
-void lcdbang_init(I2C i2c){
- const int addr = 0x40;
- char cmd[2];
- cmd[0] = 0x1C;
- cmd[1] = 0x00;
- i2c.write(addr, cmd, 2);
-
- lcdbang_write(i2c, 0x3, true);
- wait_ms(50);
- lcdbang_write(i2c, 0x3, true);
- wait_ms(10);
- lcdbang_write(i2c, 0x3, true);
- wait_ms(10);
- lcdbang_write(i2c, 0x2, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x2, true);
- lcdbang_write(i2c, 0x8, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x0, true);
- lcdbang_write(i2c, 0x8, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x0, true);
- lcdbang_write(i2c, 0x1, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x0, true);
- lcdbang_write(i2c, 0x6, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x0, true);
- lcdbang_write(i2c, 0x2, true);
- wait_ms(1);
-
- lcdbang_write(i2c, 0x0, true);
- lcdbang_write(i2c, 0xC, true);
- wait_ms(1);
-}
-
-void lcdbang_print(I2C i2c, const char* msg){
- for(int i=0;msg[i];i++){
- lcdbang_write(i2c, msg[i]);
- }
-}
-
-void lcdbang_contrast(I2C i2c, int contrast){
- // set dac pins as output and set dac
- i2cbang_init(i2c);
- i2cbang_start(i2c);
- i2cbang_write(i2c, 0xC0);
- i2cbang_write(i2c, 0x60);
- i2cbang_write(i2c, contrast >> 8);
- i2cbang_write(i2c, (contrast << 8) & 0xF0 );
- i2cbang_stop(i2c);
-}
-
-#endif // LCDBANG_H
-
+++ /dev/null
-/*
- This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
- Smoothie 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.
- Smoothie 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 Smoothie. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef WIICHUCK_H
-#define WIICHUCK_H
-#include "mbed.h" // mbed.h lib
-
-using namespace std;
-#include <vector>
-#include <string>
-#include <cstdio>
-#include <cstdarg>
-
-#define DEVICE_NUNCHUCK 0x0000
-#define DEVICE_CLASSIC 0x0101
-#define DEVICE_INACT_WMP 0x0005
-#define DEVICE_WMP 0x0405
-#define DEVICE_WMP_NUNCHUCK 0x0505
-#define DEVICE_WMP_CLASSIC 0x0705
-
-#define WIICHUCK 0xA4
-
-class Wiichuck {
-public:
- Wiichuck(PinName sda, PinName scl, int frequency = 10000){
- this->i2c_mine = true;
-
- this->i2c = new mbed::I2C(sda, scl);
- this->i2c->frequency(frequency);
- }
-
- Wiichuck(I2C* i2c){
- this->i2c_mine = false;
-
- this->i2c = i2c;
- }
-
- ~Wiichuck(){
- if(this->i2c_mine)
- delete this->i2c;
- }
-
- void init_device(){
- char cmd[2];
- data_ready = false;
-
- cmd[0] = 0xF0; // first two writes are a magic init sequence
- cmd[1] = 0x55;
- this->i2c->write(WIICHUCK, cmd, 2);
- wait_ms(10);
- cmd[0] = 0xFB;
- cmd[1] = 0x00;
- this->i2c->write(WIICHUCK, cmd, 2);
- wait_ms(10);
- cmd[0] = 0xFA; // read out the device type
- this->i2c->write(WIICHUCK, cmd, 1, false);
- int res = this->i2c->read(WIICHUCK, data_buf, 6);
- cmd[0] = 0x00; // request first sensor readings
- this->i2c->write(WIICHUCK, cmd, 1);
- if(res == 0 && data_buf[2] == 0xA4){
- device_type = (data_buf[4] << 8) + data_buf[5];
- }else{
- device_type = -1;
- }
- }
-
- void poll_device() {
- data_ready = false;
- if(device_type < 0) {
- init_device();
- wait_ms(100);
- }
- // if there is a connected device read it and if it responds right parse the data
- if(device_type >= 0 && read_device() == 0) {
- switch(device_type) {
- case DEVICE_NUNCHUCK: parse_nunchuck(); break;
- case DEVICE_CLASSIC: parse_classic(); break;
- case DEVICE_INACT_WMP: init_wmp(); break;
- case DEVICE_WMP: parse_wmp(); break;
- default:
- break;
- }
- }
- }
-
- int read_device() {
- char cmd = 0x00;
- int res = this->i2c->read(WIICHUCK, data_buf, 6); // read sensors
- this->i2c->write(WIICHUCK, &cmd, 1); // request next sensor readings
- return res;
- }
-
- void parse_nunchuck() {
- SX = data_buf[0];
- SY = data_buf[1];
- AX = (data_buf[2] << 2) + ((data_buf[5] >> 2) & 0x03);
- AY = (data_buf[3] << 2) + ((data_buf[5] >> 4) & 0x03);
- AZ = (data_buf[5] << 2) + ((data_buf[5] >> 6) & 0x03);
- BC = (data_buf[5] >> 1) & 0x01;
- BZ = data_buf[5] & 0x01;
- data_ready = true;
- }
-
- void parse_classic() {
- LX = data_buf[0] << 2;
- LY = data_buf[1] << 2;
- RX = (data_buf[0] & 0xC0) + ((data_buf[1] & 0xC0) >> 2) + ((data_buf[2] & 0x80) >> 4);
- RY = data_buf[2] << 3;
- LT = ((data_buf[2] & 0x60) << 1) + ((data_buf[3] & 0xE0) >> 2);
- RT = data_buf[3] << 3;
- BDU = data_buf[5] & 0x01;
- BDD = (data_buf[4] >> 6) & 0x01;
- BDL = (data_buf[5] >> 1) & 0x01;
- BDR = (data_buf[4] >> 7) & 0x01;
- BLT = (data_buf[4] >> 5) & 0x01;
- BRT = (data_buf[4] >> 1) & 0x01;
- BH = (data_buf[4] >> 3) & 0x01;
- BP = (data_buf[4] >> 2) & 0x01;
- BM = (data_buf[4] >> 4) & 0x01;
- BA = (data_buf[5] >> 4) & 0x01;
- BB = (data_buf[5] >> 6) & 0x01;
- BX = (data_buf[5] >> 3) & 0x01;
- BY = (data_buf[5] >> 5) & 0x01;
- BZL = (data_buf[5] >> 7) & 0x01;
- BZR = (data_buf[5] >> 2) & 0x01;
- data_ready = true;
- }
-
- void init_wmp() {
- }
-
- void activate_wmp() {
- }
-
- void deactivate_wmp() {
- }
-
- void parse_wmp() {
- }
-
- char* get_raw() {
- return data_buf;
- }
-
- // nunchuck input state variables
- char SX,SY; // 8-bit joystick
- short AX,AY,AZ; // 10-bit accelerometer
- bool BC,BZ; // buttons
-
- // classic input state variables
- char LX,LY,RX,RY,LT,RT; // 6-bit left joystick, 5-bit right joystick and triggers
- bool BDU,BDD,BDL,BDR; // d-pad buttons
- bool BLT,BRT; // digital click of triggers
- bool BH,BP,BM; // home, plus, minus buttons
- bool BA,BB,BX,BY,BZL,BZR; // buttons
-
- bool i2c_mine;
- bool data_ready = false;
- char data_buf[6];
- int device_type = -1;
- mbed::I2C* i2c;
-};
-
-
-#endif // WIICHUCK_H
-