Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
