Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ReprapDiscountGLCD.cpp Source File

ReprapDiscountGLCD.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 "ReprapDiscountGLCD.h"
00008 
00009 #include "Kernel.h"
00010 
00011 // config settings
00012 #define panel_checksum             CHECKSUM("panel")
00013 #define encoder_a_pin_checksum     CHECKSUM("encoder_a_pin")
00014 #define encoder_b_pin_checksum     CHECKSUM("encoder_b_pin")
00015 #define click_button_pin_checksum  CHECKSUM("click_button_pin")
00016 #define pause_button_pin_checksum  CHECKSUM("pause_button_pin")
00017 #define buzz_pin_checksum          CHECKSUM("buzz_pin")
00018 #define spi_channel_checksum       CHECKSUM("spi_channel")
00019 #define spi_cs_pin_checksum        CHECKSUM("spi_cs_pin")
00020 #define spi_frequency_checksum     CHECKSUM("spi_frequency")
00021 
00022 ReprapDiscountGLCD::ReprapDiscountGLCD() {
00023     // configure the pins to use
00024     this->encoder_a_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_a_pin_checksum)->by_default("nc")->as_string())->as_input();
00025     this->encoder_b_pin.from_string(THEKERNEL->config->value( panel_checksum, encoder_b_pin_checksum)->by_default("nc")->as_string())->as_input();
00026     this->click_pin.from_string(THEKERNEL->config->value( panel_checksum, click_button_pin_checksum )->by_default("nc")->as_string())->as_input();
00027     this->pause_pin.from_string(THEKERNEL->config->value( panel_checksum, pause_button_pin_checksum)->by_default("nc")->as_string())->as_input();
00028     this->buzz_pin.from_string(THEKERNEL->config->value( panel_checksum, buzz_pin_checksum)->by_default("nc")->as_string())->as_output();
00029     this->spi_cs_pin.from_string(THEKERNEL->config->value( panel_checksum, spi_cs_pin_checksum)->by_default("nc")->as_string())->as_output();
00030 
00031     // select which SPI channel to use
00032     int spi_channel = THEKERNEL->config->value(panel_checksum, spi_channel_checksum)->by_default(0)->as_number();
00033     PinName mosi;
00034     PinName sclk;
00035     if(spi_channel == 0){
00036         mosi= P0_18; sclk= P0_15;
00037     }else if(spi_channel == 1){
00038         mosi= P0_9; sclk= P0_7;
00039     }else{
00040         mosi= P0_18; sclk= P0_15;
00041     }
00042 
00043     this->glcd= new RrdGlcd(mosi, sclk, this->spi_cs_pin);
00044 
00045     int spi_frequency = THEKERNEL->config->value(panel_checksum, spi_frequency_checksum)->by_default(1000000)->as_number();
00046     this->glcd->setFrequency(spi_frequency);
00047 }
00048 
00049 ReprapDiscountGLCD::~ReprapDiscountGLCD() {
00050     delete this->glcd;
00051 }
00052 
00053 uint8_t ReprapDiscountGLCD::readButtons() {
00054     uint8_t state= 0;
00055     state |= (this->click_pin.get() ? BUTTON_SELECT : 0);
00056     // check the pause button
00057     if(this->pause_pin.connected() && this->pause_pin.get()) state |= BUTTON_PAUSE;
00058     return state;
00059 }
00060 
00061 int ReprapDiscountGLCD::readEncoderDelta() {
00062     static const int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
00063     static uint8_t old_AB = 0;
00064     old_AB <<= 2;                   //remember previous state
00065     old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) );  //add current state
00066     return  enc_states[(old_AB&0x0f)];
00067 }
00068 
00069 // cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
00070 void ReprapDiscountGLCD::buzz(long duration, uint16_t freq) {
00071     if(!this->buzz_pin.connected()) return;
00072 
00073     duration *=1000; //convert from ms to us
00074     long period = 1000000 / freq; // period in us
00075     long elapsed_time = 0;
00076     while (elapsed_time < duration) {
00077         this->buzz_pin.set(1);
00078         wait_us(period / 2);
00079         this->buzz_pin.set(0);
00080         wait_us(period / 2);
00081         elapsed_time += (period);
00082     }
00083 }
00084 
00085 void ReprapDiscountGLCD::write(const char* line, int len) {
00086     this->glcd->displayString(this->row, this->col, line, len);
00087     this->col+=len;
00088 }
00089 
00090 void ReprapDiscountGLCD::home(){
00091     this->col= 0;
00092     this->row= 0;
00093 }
00094 
00095 void ReprapDiscountGLCD::clear(){
00096     this->glcd->clearScreen();
00097     this->col= 0;
00098     this->row= 0;
00099 }
00100 
00101 void ReprapDiscountGLCD::display() {
00102     // it is always on
00103 }
00104 
00105 void ReprapDiscountGLCD::setCursor(uint8_t col, uint8_t row){
00106     this->col= col;
00107     this->row= row;
00108 }
00109 
00110 void ReprapDiscountGLCD::init(){
00111     this->glcd->initDisplay();
00112 }
00113 
00114 // displays a selectable rectangle from the glyph
00115 void ReprapDiscountGLCD::bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span, int x_offset, int y_offset) {
00116     if(x_offset == 0 && y_offset == 0 && span == 0) {
00117         // blt the whole thing
00118         this->glcd->renderGlyph(x, y, glyph, w, h);
00119 
00120     }else{
00121         // copy portion of glyph into g where x_offset is left byte aligned
00122         // Note currently the x_offset must be byte aligned
00123         int n= w/8; // bytes per line to copy
00124         if(w%8 != 0) n++; // round up to next byte
00125         uint8_t g[n*h];
00126         uint8_t *dst= g;
00127         const uint8_t *src= &glyph[y_offset*span + x_offset/8];
00128         for (int i = 0; i < h; ++i) {
00129             memcpy(dst, src, n);
00130             dst+=n;
00131             src+= span;
00132         }
00133         this->glcd->renderGlyph(x, y, g, w, h);
00134     }
00135 }
00136 
00137 void ReprapDiscountGLCD::on_refresh(bool now){
00138     static int refresh_counts = 0;
00139     refresh_counts++;
00140     // 10Hz refresh rate
00141     if(now || refresh_counts % 2 == 0 ) this->glcd->refresh();
00142 }