Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
Smoothiepanel.cpp
00001 /* 00002 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl). 00003 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. 00004 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. 00005 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>. 00006 */ 00007 #include "Smoothiepanel.h" 00008 #include "smoothiepanel/LCDBang.h" 00009 00010 #include "smoothiepanel/Colors.h" 00011 00012 // commands 00013 #define LCD_CLEARDISPLAY 0x01 00014 #define LCD_RETURNHOME 0x02 00015 #define LCD_ENTRYMODESET 0x04 00016 #define LCD_DISPLAYCONTROL 0x08 00017 #define LCD_CURSORSHIFT 0x10 00018 #define LCD_FUNCTIONSET 0x20 00019 #define LCD_SETCGRAMADDR 0x40 00020 #define LCD_SETDDRAMADDR 0x80 00021 00022 // flags for display entry mode 00023 #define LCD_ENTRYRIGHT 0x00 00024 #define LCD_ENTRYLEFT 0x02 00025 #define LCD_ENTRYSHIFTINCREMENT 0x01 00026 #define LCD_ENTRYSHIFTDECREMENT 0x00 00027 00028 // flags for display on/off control 00029 #define LCD_DISPLAYON 0x04 00030 #define LCD_DISPLAYOFF 0x00 00031 #define LCD_CURSORON 0x02 00032 #define LCD_CURSOROFF 0x00 00033 #define LCD_BLINKON 0x01 00034 #define LCD_BLINKOFF 0x00 00035 00036 // flags for display/cursor shift 00037 #define LCD_DISPLAYMOVE 0x08 00038 #define LCD_CURSORMOVE 0x00 00039 #define LCD_MOVERIGHT 0x04 00040 #define LCD_MOVELEFT 0x00 00041 00042 // flags for function set 00043 #define LCD_8BITMODE 0x10 00044 #define LCD_4BITMODE 0x00 00045 #define LCD_2LINE 0x08 00046 #define LCD_1LINE 0x00 00047 #define LCD_5x10DOTS 0x04 00048 #define LCD_5x8DOTS 0x00 00049 00050 // flags for backlight control 00051 #define LCD_BACKLIGHT 0x08 00052 #define LCD_NOBACKLIGHT 0x00 00053 00054 00055 #define LCD_WRITE 0x00 00056 #define LCD_READ 0x01 00057 #define LCD_ACK 0x01 00058 00059 Smoothiepanel::Smoothiepanel() { 00060 // Default values 00061 this->backlightval = 0x00; 00062 this->displaycontrol = 0x00; 00063 this->displayfunction = LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS; // in case they forget to call begin() at least we have somethin 00064 this->displaymode = 0x00; 00065 this->_numlines = 4; 00066 00067 this->wii_connected = false; 00068 00069 // I2C com 00070 int i2c_pins = THEKERNEL->config->value(panel_checksum, i2c_pins_checksum)->by_default(3)->as_number(); 00071 if(i2c_pins == 0){ 00072 this->i2c = new mbed::I2C(P0_0, P0_1); 00073 }else if(i2c_pins == 1){ 00074 this->i2c = new mbed::I2C(P0_10, P0_11); 00075 }else if(i2c_pins == 2){ 00076 this->i2c = new mbed::I2C(P0_19, P0_20); 00077 }else{ // 3, default 00078 this->i2c = new mbed::I2C(P0_27, P0_28); 00079 } 00080 this->wii = new Wiichuck(this->i2c); 00081 00082 this->i2c_address = (char)THEKERNEL->config->value(panel_checksum, i2c_address_checksum)->by_default(0)->as_number(); 00083 this->i2c_address = (this->i2c_address & 0x07) << 1; 00084 this->i2c_frequency = THEKERNEL->config->value(panel_checksum, i2c_frequency_checksum)->by_default(20000)->as_number(); 00085 i2c->frequency(this->i2c_frequency); 00086 this->lcd_contrast = THEKERNEL->config->value(panel_checksum, lcd_contrast_checksum)->by_default(0)->as_number(); 00087 this->backlight_red = THEKERNEL->config->value(panel_checksum, lcd_led_checksum)->by_default(255)->as_number(); 00088 this->backlight_red = THEKERNEL->config->value(panel_checksum, lcd_led_red_checksum)->by_default(this->backlight_red)->as_number(); 00089 this->backlight_green = THEKERNEL->config->value(panel_checksum, lcd_led_green_checksum)->by_default(255)->as_number(); 00090 this->backlight_blue = THEKERNEL->config->value(panel_checksum, lcd_led_blue_checksum)->by_default(255)->as_number(); 00091 this->playledval = THEKERNEL->config->value(panel_checksum, play_led_brightness_checksum)->by_default(255)->as_number(); 00092 this->backledval = THEKERNEL->config->value(panel_checksum, back_led_brightness_checksum)->by_default(255)->as_number(); 00093 00094 // this->interrupt_pin.from_string(THEKERNEL->config->value(panel_checksum, i2c_interrupt_pin_checksum)->by_default("nc")->as_string())->as_input(); 00095 this->encoder_a_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_a_pin_checksum)->by_default("nc")->as_string())->as_input(); 00096 this->encoder_b_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_b_pin_checksum)->by_default("nc")->as_string())->as_input(); 00097 this->encoder_hue = THEKERNEL->config->value(panel_checksum, encoder_led_hue_checksum)->by_default(220)->as_number(); 00098 } 00099 00100 Smoothiepanel::~Smoothiepanel() { 00101 delete this->wii; 00102 delete this->i2c; 00103 } 00104 00105 void pca9634_init(I2C i2c, int address){ 00106 const int leds = PCA9634_ADDRESS | (address & 0x0E); 00107 char cmd[2]; 00108 00109 // initialize led controller 00110 cmd[0] = 0x00; 00111 cmd[1] = 0x00; 00112 i2c.write(leds, cmd, 2); 00113 cmd[0] = 0x01; 00114 cmd[1] = 0x02; 00115 i2c.write(leds, cmd, 2); 00116 cmd[0] = 0x0C; 00117 cmd[1] = 0xAA; 00118 i2c.write(leds, cmd, 2); 00119 cmd[0] = 0x0D; 00120 i2c.write(leds, cmd, 2); 00121 } 00122 00123 void pca9634_setLed(I2C *i2c, int address, char led, char val){ 00124 const int leds = PCA9634_ADDRESS | (address & 0x0E); 00125 char cmd[2]; 00126 00127 cmd[0] = led; // lcd blue 00128 cmd[1] = val; 00129 i2c->write(leds, cmd, 2); 00130 } 00131 00132 void pca9505_write(I2C *i2c, int address, char reg, char val){ 00133 const int expander = PCA9505_ADDRESS | (address & 0x0E); 00134 char cmd[2]; 00135 00136 cmd[0] = reg; 00137 cmd[1] = val; 00138 i2c->write(expander, cmd, 2); 00139 } 00140 00141 char pca9505_read(I2C *i2c, int address, char reg){ 00142 const int expander = PCA9505_ADDRESS | (address & 0x0E); 00143 char cmd[1]; 00144 00145 cmd[0] = 0x04; 00146 i2c->write(expander, cmd, 1, false); 00147 i2c->read(expander, cmd, 1); 00148 return cmd[0]; 00149 } 00150 00151 void Smoothiepanel::init(){ 00152 // init lcd and buzzer 00153 lcdbang_init(*this->i2c); 00154 // lcdbang_print(*this->i2c, " Smoothiepanel Beta - design by Logxen -"); 00155 lcdbang_contrast(*this->i2c, this->lcd_contrast); 00156 00157 pca9634_init(*this->i2c, this->i2c_address); 00158 setEncoderByHue(this->encoder_hue); 00159 setBacklightColor(this->backlight_red, this->backlight_green, this->backlight_blue); 00160 setPlayLED(this->playledval); 00161 setBackLED(this->backledval); 00162 00163 pca9505_write(this->i2c, this->i2c_address, 0x18, 0xAA); // enable leds for button/led wing on port0 00164 pca9505_write(this->i2c, this->i2c_address, 0x08, 0x01); // enable leds for button/led wing on port0 00165 // wait_us(3000); 00166 // this->clear(); 00167 } 00168 00169 void Smoothiepanel::setLed(int led, bool on){ 00170 // LED turns on when bit is cleared 00171 char saved = pca9505_read(this->i2c, this->i2c_address, 0x08); 00172 if(on) { 00173 switch(led) { 00174 case LED_FAN_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x40); break; // on 00175 case LED_HOTEND_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x10); break; // on 00176 case LED_BED_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved | 0x04); break; // on 00177 } 00178 }else{ 00179 switch(led) { 00180 case LED_FAN_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x40); break; // off 00181 case LED_HOTEND_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x10); break; // off 00182 case LED_BED_ON: pca9505_write(this->i2c, this->i2c_address, 0x08, saved & ~0x04); break; // off 00183 } 00184 } 00185 } 00186 00187 void Smoothiepanel::setLedBrightness(int led, int val){ 00188 switch(led){ 00189 // case LED_FAN_ON: this->backlight_green = val; break; // on 00190 // case LED_HOTEND_ON: this->backlight_red = val; break; // on 00191 // case LED_BED_ON: this->backlight_blue = val; break; // on 00192 } 00193 } 00194 00195 // cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms) 00196 void Smoothiepanel::buzz(long duration, uint16_t freq) { 00197 const int expander = PCA9505_ADDRESS | this->i2c_address; 00198 char cmd[2]; 00199 char saved; 00200 00201 // save register state 00202 cmd[0] = 0x04; 00203 this->i2c->write(expander, cmd, 1, false); 00204 this->i2c->read(expander, cmd, 1); 00205 saved = cmd[0]; 00206 00207 // buzz 00208 cmd[0] = 0x0C; 00209 cmd[1] = saved & 0xFE; 00210 this->i2c->write(expander, cmd, 2); 00211 wait_ms(duration); // TODO: Make this not hold up the whole system 00212 cmd[1] = saved; 00213 this->i2c->write(expander, cmd, 2); 00214 } 00215 00216 uint8_t Smoothiepanel::readButtons(void) { 00217 const int expander = PCA9505_ADDRESS | this->i2c_address; 00218 uint8_t button_bits = 0x00; 00219 char cmd[1]; 00220 00221 cmd[0] = 0x03; 00222 this->i2c->write(expander, cmd, 1, false); 00223 this->i2c->read(expander, cmd, 1); 00224 //cmd[0] = ~cmd[0]; 00225 if((cmd[0] & 0x10) > 0) button_bits |= BUTTON_SELECT; // encoder click 00226 if((cmd[0] & 0x02) > 0) button_bits |= BUTTON_LEFT; // back button 00227 if((cmd[0] & 0x01) > 0) button_bits |= BUTTON_PAUSE; // play button 00228 if((cmd[0] & 0x20) > 0){ // wii accessory connected 00229 if(!this->wii_connected){ 00230 this->wii->init_device(); 00231 if(this->wii->device_type >= 0){ 00232 this->wii_connected = true; 00233 wait_ms(100); 00234 } 00235 } 00236 if(this->wii_connected){ 00237 this->wii->poll_device(); 00238 if(this->wii->data_ready){ 00239 if(this->wii->device_type == DEVICE_NUNCHUCK){ 00240 if(this->wii->SY > 192) button_bits |= BUTTON_UP; 00241 else if(this->wii->SY < 64) button_bits |= BUTTON_DOWN; 00242 if(this->wii->SX > 192) button_bits |= BUTTON_RIGHT; 00243 else if(this->wii->SX < 64) button_bits |= BUTTON_LEFT; 00244 if(!this->wii->BC) button_bits |= BUTTON_SELECT; 00245 if(!this->wii->BZ) button_bits |= BUTTON_LEFT; 00246 }else if(this->wii->device_type == DEVICE_CLASSIC){ 00247 if(this->wii->LY > 192) button_bits |= BUTTON_UP; 00248 else if(this->wii->LY < 64) button_bits |= BUTTON_DOWN; 00249 if(this->wii->LX > 192) button_bits |= BUTTON_RIGHT; 00250 else if(this->wii->LX < 64) button_bits |= BUTTON_LEFT; 00251 if(!this->wii->BDU) button_bits |= BUTTON_UP; 00252 else if(!this->wii->BDD) button_bits |= BUTTON_DOWN; 00253 if(!this->wii->BDL) button_bits |= BUTTON_LEFT; 00254 else if(!this->wii->BDR) button_bits |= BUTTON_RIGHT; 00255 if(!this->wii->BA) button_bits |= BUTTON_SELECT; 00256 if(!this->wii->BB) button_bits |= BUTTON_LEFT; 00257 } 00258 }else this->wii_connected = false; 00259 } 00260 }else this->wii_connected = false; 00261 00262 // update the encoder color 00263 if(this->encoder_changed){ 00264 if(this->encoder_hue > 360) this->encoder_hue -= 360; 00265 else if(this->encoder_hue < 0) this->encoder_hue += 360; 00266 this->encoder_changed = false; 00267 00268 setEncoderByHue(this->encoder_hue); 00269 } 00270 00271 return button_bits; 00272 } 00273 00274 int Smoothiepanel::readEncoderDelta() { 00275 static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; 00276 static uint8_t old_AB = 0; 00277 int8_t state; 00278 old_AB <<= 2; //remember previous state 00279 old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) ); //add current state 00280 state = enc_states[(old_AB&0x0f)]; 00281 if(state != 0){ 00282 this->encoder_hue += state; 00283 this->encoder_changed = true; 00284 } 00285 return state; 00286 } 00287 00288 void Smoothiepanel::clear() 00289 { 00290 command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero 00291 //#ifndef USE_FASTMODE 00292 // wait_ms(50); // this command takes a long time! 00293 //#endif 00294 } 00295 00296 void Smoothiepanel::home() 00297 { 00298 command(LCD_RETURNHOME); // set cursor position to zero 00299 //#ifndef USE_FASTMODE 00300 // wait_us(2000); // this command takes a long time! 00301 //#endif 00302 } 00303 00304 void Smoothiepanel::setCursor(uint8_t col, uint8_t row) 00305 { 00306 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; 00307 if ( row > _numlines ) row = _numlines - 1; // we count rows starting w/0 00308 command(LCD_SETDDRAMADDR | (col + row_offsets[row])); 00309 } 00310 00311 // Turn the display on/off (quickly) 00312 void Smoothiepanel::noDisplay() { 00313 displaycontrol &= ~LCD_DISPLAYON; 00314 command(LCD_DISPLAYCONTROL | displaycontrol); 00315 } 00316 00317 void Smoothiepanel::display() { 00318 displaycontrol |= LCD_DISPLAYON; 00319 command(LCD_DISPLAYCONTROL | displaycontrol); 00320 } 00321 00322 // Turns the underline cursor on/off 00323 void Smoothiepanel::noCursor() { 00324 displaycontrol &= ~LCD_CURSORON; 00325 command(LCD_DISPLAYCONTROL | displaycontrol); 00326 } 00327 void Smoothiepanel::cursor() { 00328 displaycontrol |= LCD_CURSORON; 00329 command(LCD_DISPLAYCONTROL | displaycontrol); 00330 } 00331 00332 // Turn on and off the blinking cursor 00333 void Smoothiepanel::noBlink() { 00334 displaycontrol &= ~LCD_BLINKON; 00335 command(LCD_DISPLAYCONTROL | displaycontrol); 00336 } 00337 void Smoothiepanel::blink() { 00338 displaycontrol |= LCD_BLINKON; 00339 command(LCD_DISPLAYCONTROL | displaycontrol); 00340 } 00341 00342 // These commands scroll the display without changing the RAM 00343 void Smoothiepanel::scrollDisplayLeft(void) { 00344 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 00345 } 00346 void Smoothiepanel::scrollDisplayRight(void) { 00347 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 00348 } 00349 00350 // This is for text that flows Left to Right 00351 void Smoothiepanel::leftToRight(void) { 00352 displaymode |= LCD_ENTRYLEFT; 00353 command(LCD_ENTRYMODESET | displaymode); 00354 } 00355 00356 // This is for text that flows Right to Left 00357 void Smoothiepanel::rightToLeft(void) { 00358 displaymode &= ~LCD_ENTRYLEFT; 00359 command(LCD_ENTRYMODESET | displaymode); 00360 } 00361 00362 // This will 'right justify' text from the cursor 00363 void Smoothiepanel::autoscroll(void) { 00364 displaymode |= LCD_ENTRYSHIFTINCREMENT; 00365 command(LCD_ENTRYMODESET | displaymode); 00366 } 00367 00368 // This will 'left justify' text from the cursor 00369 void Smoothiepanel::noAutoscroll(void) { 00370 displaymode &= ~LCD_ENTRYSHIFTINCREMENT; 00371 command(LCD_ENTRYMODESET | displaymode); 00372 } 00373 00374 void Smoothiepanel::command(uint8_t value) { 00375 lcdbang_write(*this->i2c, value>>4, true); 00376 lcdbang_write(*this->i2c, value, true); 00377 } 00378 00379 void Smoothiepanel::write(const char* line, int len) { 00380 for (int i = 0; i < len; ++i) { 00381 lcdbang_write(*this->i2c, *line++); 00382 } 00383 } 00384 00385 // Allows to set the backlight, if the LCD backpack is used 00386 void Smoothiepanel::setBacklight(uint8_t status) { 00387 /* // LED turns on when bit is cleared 00388 _backlightBits = M17_BIT_LB|M17_BIT_LG|M17_BIT_LR; // all off 00389 if (status & LED_RED) _backlightBits &= ~M17_BIT_LR; // red on 00390 if (status & LED_GREEN) _backlightBits &= ~M17_BIT_LG; // green on 00391 if (status & LED_BLUE) _backlightBits &= ~M17_BIT_LB; // blue on 00392 00393 burstBits16(_backlightBits); 00394 */ 00395 } 00396 00397 void Smoothiepanel::setBacklightColor(uint8_t r, uint8_t g, uint8_t b) { 00398 const int leds = PCA9634_ADDRESS | this->i2c_address; 00399 char cmd[2]; 00400 00401 cmd[0] = 0x07; // lcd blue 00402 cmd[1] = b; 00403 this->i2c->write(leds, cmd, 2); 00404 cmd[0] = 0x08; // lcd green 00405 cmd[1] = g; 00406 this->i2c->write(leds, cmd, 2); 00407 cmd[0] = 0x09; // lcd red 00408 cmd[1] = r; 00409 this->i2c->write(leds, cmd, 2); 00410 } 00411 00412 void Smoothiepanel::setBacklightByHue(int h) { 00413 float r, g, b; 00414 HSVtoRGB(&r, &g, &b, h, 1.0, 1.0); 00415 setBacklightColor(r*0xFF, g*0xFF, b*0xFF); 00416 } 00417 00418 void Smoothiepanel::setEncoderLED(uint8_t r, uint8_t g, uint8_t b) { 00419 const int leds = PCA9634_ADDRESS | this->i2c_address; 00420 char cmd[2]; 00421 00422 cmd[0] = 0x04; // encoder red 00423 cmd[1] = r; 00424 this->i2c->write(leds, cmd, 2); 00425 cmd[0] = 0x05; // encoder green 00426 cmd[1] = g; 00427 this->i2c->write(leds, cmd, 2); 00428 cmd[0] = 0x06; // encoder blue 00429 cmd[1] = b; 00430 this->i2c->write(leds, cmd, 2); 00431 } 00432 00433 void Smoothiepanel::setEncoderByHue(int h) { 00434 float r, g, b; 00435 HSVtoRGB(&r, &g, &b, h, 1.0, 1.0); 00436 setEncoderLED(r*0xFF, g*0xFF, b*0xFF); 00437 } 00438 00439 void Smoothiepanel::setPlayLED(uint8_t v) { 00440 const int leds = PCA9634_ADDRESS | this->i2c_address; 00441 char cmd[2]; 00442 00443 cmd[0] = 0x02; // play 00444 cmd[1] = v; 00445 this->i2c->write(leds, cmd, 2); 00446 } 00447 00448 void Smoothiepanel::setBackLED(uint8_t v) { 00449 const int leds = PCA9634_ADDRESS | this->i2c_address; 00450 char cmd[2]; 00451 00452 cmd[0] = 0x03; // back 00453 cmd[1] = v; 00454 this->i2c->write(leds, cmd, 2); 00455 } 00456 00457 /* 00458 // write either command or data, burst it to the expander over I2C. 00459 void Smoothiepanel::send(uint8_t value, uint8_t mode) { 00460 #ifdef USE_FASTMODE 00461 // polls for ready. not sure on I2C this is any faster 00462 00463 // set Data pins as input 00464 char data[2]; 00465 data[0]= MCP23017_IODIRB; 00466 data[1]= 0x1E; 00467 i2c->write(this->i2c_address, data, 2); 00468 uint8_t b= _backlightBits >> 8; 00469 burstBits8b((M17_BIT_RW>>8)|b); // RW hi,RS lo 00470 char busy; 00471 data[0] = MCP23017_GPIOB; 00472 do { 00473 burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi 00474 i2c->write(this->i2c_address, data, 1); 00475 i2c->read(this->i2c_address, &busy, 1); // Read D7 00476 burstBits8b((M17_BIT_RW>>8)|b); // EN lo 00477 burstBits8b(((M17_BIT_RW|M17_BIT_EN)>>8)|b); // EN hi 00478 burstBits8b((M17_BIT_RW>>8)|b); // EN lo 00479 } while ((busy&(M17_BIT_D7>>8)) != 0); 00480 00481 // reset data bits as output 00482 data[0]= MCP23017_IODIRB; 00483 data[1]= 0x00; 00484 i2c->write(this->i2c_address, data, 2); 00485 burstBits8b(b); // RW lo 00486 00487 #else 00488 // wait_us(320); 00489 #endif 00490 00491 // BURST SPEED, OH MY GOD 00492 // the (now High Speed!) I/O expander pinout 00493 // B7 B6 B5 B4 B3 B2 B1 B0 A7 A6 A5 A4 A3 A2 A1 A0 - MCP23017 00494 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 00495 // RS RW EN D4 D5 D6 D7 B G R B4 B3 B2 B1 B0 00496 00497 // n.b. RW bit stays LOW to write 00498 uint8_t buf = _backlightBits >> 8; 00499 // send high 4 bits 00500 if (value & 0x10) buf |= M17_BIT_D4 >> 8; 00501 if (value & 0x20) buf |= M17_BIT_D5 >> 8; 00502 if (value & 0x40) buf |= M17_BIT_D6 >> 8; 00503 if (value & 0x80) buf |= M17_BIT_D7 >> 8; 00504 00505 if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN 00506 else buf |= M17_BIT_EN >> 8; // EN 00507 00508 burstBits8b(buf); 00509 00510 // resend w/ EN turned off 00511 buf &= ~(M17_BIT_EN >> 8); 00512 burstBits8b(buf); 00513 00514 // send low 4 bits 00515 buf = _backlightBits >> 8; 00516 // send high 4 bits 00517 if (value & 0x01) buf |= M17_BIT_D4 >> 8; 00518 if (value & 0x02) buf |= M17_BIT_D5 >> 8; 00519 if (value & 0x04) buf |= M17_BIT_D6 >> 8; 00520 if (value & 0x08) buf |= M17_BIT_D7 >> 8; 00521 00522 if (mode) buf |= (M17_BIT_RS|M17_BIT_EN) >> 8; // RS+EN 00523 else buf |= M17_BIT_EN >> 8; // EN 00524 00525 burstBits8b(buf); 00526 00527 // resend w/ EN turned off 00528 buf &= ~(M17_BIT_EN >> 8); 00529 burstBits8b(buf); 00530 } 00531 00532 // We pause the system 00533 uint32_t Smoothiepanel::on_pause_release(uint32_t dummy){ 00534 if(!paused) { 00535 THEKERNEL->pauser->take(); 00536 paused= true; 00537 }else{ 00538 THEKERNEL->pauser->release(); 00539 paused= false; 00540 } 00541 return 0; 00542 } 00543 */ 00544
Generated on Tue Jul 12 2022 20:09:02 by 1.7.2