2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 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.
4 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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
7 #include "ReprapDiscountGLCD.h"
9 ReprapDiscountGLCD::ReprapDiscountGLCD() {
10 // configure the pins to use
11 this->encoder_a_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, encoder_a_pin_checksum
)->by_default("nc")->as_string())->as_input();
12 this->encoder_b_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, encoder_b_pin_checksum
)->by_default("nc")->as_string())->as_input();
13 this->click_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, click_button_pin_checksum
)->by_default("nc")->as_string())->as_input();
14 this->pause_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, pause_button_pin_checksum
)->by_default("nc")->as_string())->as_input();
15 this->buzz_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, buzz_pin_checksum
)->by_default("nc")->as_string())->as_output();
16 this->spi_cs_pin
.from_string(THEKERNEL
->config
->value( panel_checksum
, spi_cs_pin_checksum
)->by_default("nc")->as_string())->as_output();
18 // select which SPI channel to use
19 int spi_channel
= THEKERNEL
->config
->value(panel_checksum
, spi_channel_checksum
)->by_default(0)->as_number();
23 mosi
= P0_18
; sclk
= P0_15
;
24 }else if(spi_channel
== 1){
25 mosi
= P0_9
; sclk
= P0_7
;
27 mosi
= P0_18
; sclk
= P0_15
;
30 this->glcd
= new RrdGlcd(mosi
, sclk
, this->spi_cs_pin
);
32 int spi_frequency
= THEKERNEL
->config
->value(panel_checksum
, spi_frequency_checksum
)->by_default(1000000)->as_number();
33 this->glcd
->setFrequency(spi_frequency
);
36 ReprapDiscountGLCD::~ReprapDiscountGLCD() {
40 uint8_t ReprapDiscountGLCD::readButtons() {
42 state
|= (this->click_pin
.get() ? BUTTON_SELECT
: 0);
43 // check the pause button
44 if(this->pause_pin
.connected() && this->pause_pin
.get()) state
|= BUTTON_PAUSE
;
48 int ReprapDiscountGLCD::readEncoderDelta() {
49 static int8_t enc_states
[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
50 static uint8_t old_AB
= 0;
51 old_AB
<<= 2; //remember previous state
52 old_AB
|= ( this->encoder_a_pin
.get() + ( this->encoder_b_pin
.get() * 2 ) ); //add current state
53 return enc_states
[(old_AB
&0x0f)];
56 // cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
57 void ReprapDiscountGLCD::buzz(long duration
, uint16_t freq
) {
58 if(!this->buzz_pin
.connected()) return;
60 duration
*=1000; //convert from ms to us
61 long period
= 1000000 / freq
; // period in us
62 long elapsed_time
= 0;
63 while (elapsed_time
< duration
) {
64 this->buzz_pin
.set(1);
66 this->buzz_pin
.set(0);
68 elapsed_time
+= (period
);
72 void ReprapDiscountGLCD::write(const char* line
, int len
) {
73 for (int i
= 0; i
< len
; ++i
) {
74 this->glcd
->displayString(this->row
, this->col
, line
, len
);
79 void ReprapDiscountGLCD::home(){
84 void ReprapDiscountGLCD::clear(){
85 this->glcd
->clearScreen();
90 void ReprapDiscountGLCD::display() {
94 void ReprapDiscountGLCD::setCursor(uint8_t col
, uint8_t row
){
99 void ReprapDiscountGLCD::init(){
100 this->glcd
->initDisplay();
103 // displays a selectable rectangle from the glyph
104 void ReprapDiscountGLCD::bltGlyph(int x
, int y
, int w
, int h
, const uint8_t *glyph
, int span
, int x_offset
, int y_offset
) {
105 if(x_offset
== 0 && y_offset
== 0 && span
== 0) {
106 // blt the whole thing
107 this->glcd
->renderGlyph(x
, y
, glyph
, w
, h
);
110 // copy portion of glyph into g where x_offset is left byte aligned
111 // Note currently thw x_offset must be byte aligned
112 int n
= w
/8; // bytes per line to copy
113 if(w
%8 != 0) n
++; // round up to next byte
116 for (int i
= 0; i
< h
; ++i
) {
117 memcpy(&g
[i
*n
], &glyph
[(i
+y_offset
)*span
+x_offset
/8], n
);
119 this->glcd
->renderGlyph(x
, y
, g
, w
, h
);
123 void ReprapDiscountGLCD::on_refresh(bool now
){
124 static int refresh_counts
= 0;
127 if(now
|| refresh_counts
% 4 == 0 ) this->glcd
->refresh();