Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2018-02-06 02:38:47 +0300
committerDavid Crocker <dcrocker@eschertech.com>2018-02-06 02:38:47 +0300
commitc5a8315c2d0ab6eb6a7c961e0f44cea198bee38d (patch)
treec15f0b8d3d7eb6a378992816a4b4223f56d858ef /src/Display
parent1448121041393c9a878c3dd84ddd97dff2a4687f (diff)
More work on SAM4S port
Renamed IoPort{.cpp,.h} to avoid name clash with ASF Fixes to 12864 display Support beeper on 12864 display Encoder parameters are now configurable (M918)
Diffstat (limited to 'src/Display')
-rw-r--r--src/Display/Display.cpp52
-rw-r--r--src/Display/Display.h9
-rw-r--r--src/Display/RotaryEncoder.cpp18
-rw-r--r--src/Display/RotaryEncoder.h7
-rw-r--r--src/Display/ST7920/lcd7920.cpp35
5 files changed, 95 insertions, 26 deletions
diff --git a/src/Display/Display.cpp b/src/Display/Display.cpp
index aa8fcba6..264978ce 100644
--- a/src/Display/Display.cpp
+++ b/src/Display/Display.cpp
@@ -7,14 +7,18 @@
#include "Display.h"
#include "GCodes/GCodes.h"
+#include "IoPort.h"
+#include "Pins.h"
+
+constexpr int DefaultPulsesPerClick = -4; // values that work with displays I have are 2 and -4
extern const LcdFont font16x16;
-//extern const LcdFont font10x10;
+extern const LcdFont font10x10;
static int val = 0;
Display::Display()
- : lcd(LcdCSPin), encoder(EncoderPinA, EncoderPinB, EncoderPinSw, 4)
+ : lcd(LcdCSPin), encoder(EncoderPinA, EncoderPinB, EncoderPinSw), present(false)
{
//TODO init menus here
}
@@ -22,7 +26,7 @@ Display::Display()
void Display::Init()
{
lcd.Init();
- encoder.Init();
+ encoder.Init(DefaultPulsesPerClick);
//TODO display top menu here
// For now we just print some text to test the display
@@ -35,6 +39,9 @@ void Display::Init()
lcd.SetCursor(20, 5);
lcd.SetRightMargin(50);
lcd.print(val);
+
+ IoPort::SetPinMode(LcdBeepPin, OUTPUT_PWM_LOW);
+ beepActive = false;
}
void Display::Spin(bool full)
@@ -67,6 +74,11 @@ void Display::Spin(bool full)
lcd.FlushSome();
}
+
+ if (beepActive && millis() - whenBeepStarted > beepLength)
+ {
+ IoPort::WriteAnalog(LcdBeepPin, 0.0, 0);
+ }
}
void Display::Exit()
@@ -74,4 +86,38 @@ void Display::Exit()
// TODO display a "shutdown" message, or turn the display off?
}
+void Display::Beep(unsigned int frequency, unsigned int milliseconds)
+{
+ whenBeepStarted = millis();
+ beepLength = milliseconds;
+ beepActive = true;
+ IoPort::WriteAnalog(LcdBeepPin, 0.5, (uint16_t)frequency);
+}
+
+GCodeResult Display::Configure(GCodeBuffer& gb, const StringRef& reply)
+{
+ if (gb.Seen('P') && gb.GetUIValue() == 1)
+ {
+ // 12864 display configuration
+ present = true;
+ if (gb.Seen('E'))
+ {
+ encoder.Init(gb.GetIValue()); // configure encoder pulses per click and direction
+ }
+ }
+ return GCodeResult::ok;
+}
+
+// Suspend normal operation and display an "Updating firmware" message
+void Display::UpdatingFirmware()
+{
+ IoPort::WriteAnalog(LcdBeepPin, 0.0, 0); // stop any beep
+ lcd.TextInvert(false);
+ lcd.Clear();
+ lcd.SetFont(&font10x10);
+ lcd.SetCursor(20, 0);
+ lcd.print("Updating firmware...");
+ lcd.FlushAll();
+}
+
// End
diff --git a/src/Display/Display.h b/src/Display/Display.h
index fa321a1c..b7c90322 100644
--- a/src/Display/Display.h
+++ b/src/Display/Display.h
@@ -11,6 +11,7 @@
#include "RotaryEncoder.h"
#include "ST7920/lcd7920.h"
#include "Menu.h"
+#include "GCodes/GCodeResult.h"
class Display
{
@@ -18,13 +19,21 @@ public:
Display();
void Init();
+ GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply);
void Spin(bool full);
void Exit();
+ void Beep(unsigned int frequency, unsigned int milliseconds);
+ bool IsPresent() const { return present; }
+ void UpdatingFirmware();
private:
Lcd7920 lcd;
RotaryEncoder encoder;
Menu *mainMenu;
+ uint32_t whenBeepStarted;
+ uint32_t beepLength;
+ bool present;
+ bool beepActive;
};
#endif /* SRC_DISPLAY_DISPLAY_H_ */
diff --git a/src/Display/RotaryEncoder.cpp b/src/Display/RotaryEncoder.cpp
index a862591b..33e9d702 100644
--- a/src/Display/RotaryEncoder.cpp
+++ b/src/Display/RotaryEncoder.cpp
@@ -4,21 +4,25 @@
#if SUPPORT_12864_LCD
#include "RotaryEncoder.h"
+#include "IoPorts.h"
-RotaryEncoder::RotaryEncoder(Pin p0, Pin p1, Pin pb, int pulsesPerClick)
- : pin0(p0), pin1(p1), pinButton(pb), ppc(pulsesPerClick), encoderChange(0), encoderState(0), newPress(false) {}
+RotaryEncoder::RotaryEncoder(Pin p0, Pin p1, Pin pb)
+ : pin0(p0), pin1(p1), pinButton(pb), ppc(1), encoderChange(0), encoderState(0), newPress(false), reverseDirection(false) {}
inline unsigned int RotaryEncoder::ReadEncoderState() const
{
return (digitalRead(pin0) ? 1u : 0u) | (digitalRead(pin1) ? 2u : 0u);
}
-void RotaryEncoder::Init()
+void RotaryEncoder::Init(int pulsesPerClick)
{
+ ppc = max<unsigned int>(abs(pulsesPerClick), 1);
+ reverseDirection = (pulsesPerClick < 0);
+
// Set up pins
- pinMode(pin0, INPUT_PULLUP);
- pinMode(pin1, INPUT_PULLUP);
- pinMode(pinButton, INPUT_PULLUP);
+ IoPort::SetPinMode(pin0, INPUT_PULLUP);
+ IoPort::SetPinMode(pin1, INPUT_PULLUP);
+ IoPort::SetPinMode(pinButton, INPUT_PULLUP);
delay(2); // ensure we read the initial state correctly
// Initialise encoder variables
@@ -88,7 +92,7 @@ int RotaryEncoder::GetChange()
r = 0;
}
encoderChange -= (r * ppc);
- return r;
+ return (reverseDirection) ? -r : r;
}
bool RotaryEncoder::GetButtonPress()
diff --git a/src/Display/RotaryEncoder.h b/src/Display/RotaryEncoder.h
index 79eac3db..972e7d93 100644
--- a/src/Display/RotaryEncoder.h
+++ b/src/Display/RotaryEncoder.h
@@ -7,11 +7,12 @@
class RotaryEncoder
{
const Pin pin0, pin1, pinButton;
- const int ppc;
+ int ppc;
int encoderChange;
unsigned int encoderState;
bool buttonState;
bool newPress;
+ bool reverseDirection;
uint32_t whenSame;
unsigned int ReadEncoderState() const;
@@ -19,9 +20,9 @@ class RotaryEncoder
static constexpr uint32_t DebounceMillis = 5;
public:
- RotaryEncoder(Pin p0, Pin p1, Pin pb, int pulsesPerClick);
+ RotaryEncoder(Pin p0, Pin p1, Pin pb);
- void Init();
+ void Init(int pulsesPerClick);
void Poll();
int GetChange();
bool GetButtonPress();
diff --git a/src/Display/ST7920/lcd7920.cpp b/src/Display/ST7920/lcd7920.cpp
index e5b336aa..fd9a9665 100644
--- a/src/Display/ST7920/lcd7920.cpp
+++ b/src/Display/ST7920/lcd7920.cpp
@@ -153,7 +153,7 @@ size_t Lcd7920::writeNative(uint16_t ch)
const uint8_t bytesPerColumn = (fontHeight + 7)/8;
const uint8_t bytesPerChar = (bytesPerColumn * fontWidth) + 1;
const uint8_t *fontPtr = currentFont->ptr + (bytesPerChar * (ch - startChar));
- uint16_t cmask = (1 << fontHeight) - 1;
+ const uint16_t cmask = (1u << fontHeight) - 1;
uint8_t nCols = *fontPtr++;
@@ -171,10 +171,10 @@ size_t Lcd7920::writeNative(uint16_t ch)
// We add a space column after a space character if we would have added one between the preceding and following characters.
if (column < rightMargin)
{
- uint16_t thisCharColData = *fontPtr & cmask;
- if (thisCharColData == 0) // for characters with deliberate space row at the start, e.g. decimal point
+ uint16_t thisCharColData = *reinterpret_cast<const uint16_t*>(fontPtr) & cmask;
+ if (thisCharColData == 0) // for characters with deliberate space column at the start, e.g. decimal point
{
- thisCharColData = *(fontPtr + 2) & cmask;
+ thisCharColData = *reinterpret_cast<const uint16_t*>(fontPtr + 2) & cmask;
}
const bool wantSpace = ((thisCharColData | (thisCharColData << 1)) & (lastCharColData | (lastCharColData << 1))) != 0;
if (wantSpace)
@@ -200,7 +200,7 @@ size_t Lcd7920::writeNative(uint16_t ch)
while (nCols != 0 && column < rightMargin)
{
- uint16_t colData = *fontPtr;
+ uint16_t colData = *reinterpret_cast<const uint16_t*>(fontPtr);
fontPtr += bytesPerColumn;
if (colData != 0)
{
@@ -212,7 +212,7 @@ size_t Lcd7920::writeNative(uint16_t ch)
const uint16_t setPixelVal = (textInverted) ? 0 : 1;
for (uint8_t i = 0; i < fontHeight && p < (image + sizeof(image)); ++i)
{
- if ((colData & 1) == setPixelVal)
+ if ((colData & 1u) == setPixelVal)
{
*p |= mask1; // set pixel
}
@@ -240,10 +240,10 @@ void Lcd7920::SetRightMargin(uint8_t r)
rightMargin = (r > numCols) ? numCols : r;
}
-// Clear a rectangle from the current position to the right margin (graphics mode only). The height of the rectangle is the height of the current font.
+// Clear a rectangle from the current position to the right margin. The height of the rectangle is the height of the current font.
void Lcd7920::ClearToMargin()
{
- if (currentFont != 0)
+ if (currentFont != nullptr)
{
if (column < rightMargin)
{
@@ -257,11 +257,20 @@ void Lcd7920::ClearToMargin()
if (endRow < nextRow) { endRow = nextRow; }
if (endCol < rightMargin) { endCol = rightMargin; }
}
+
while (column < rightMargin)
{
- // Add space after character
- uint8_t mask = 0x80 >> (column & 7);
uint8_t *p = image + ((row * (numCols/8)) + (column/8));
+ uint8_t mask = 0xFF >> (column & 7);
+ if ((column & (~7)) < (rightMargin & (~7)))
+ {
+ column = (column & (~7)) + 8;
+ }
+ else
+ {
+ mask ^= 0xFF >> (rightMargin & 7);
+ column = rightMargin;;
+ }
for (uint8_t i = 0; i < fontHeight && p < (image + sizeof(image)); ++i)
{
if (textInverted)
@@ -274,7 +283,6 @@ void Lcd7920::ClearToMargin()
}
p += (numCols/8);
}
- ++column;
}
}
}
@@ -370,7 +378,7 @@ void Lcd7920::Circle(uint8_t x0, uint8_t y0, uint8_t radius, PixelMode mode)
}
}
-// Draw a bitmap
+// Draw a bitmap. x0 and numCols must be divisible by 8.
void Lcd7920::Bitmap(uint8_t x0, uint8_t y0, uint8_t width, uint8_t height, const uint8_t data[])
{
for (uint8_t r = 0; r < height && r + y0 < numRows; ++r)
@@ -434,7 +442,7 @@ bool Lcd7920::FlushSome()
return false;
}
-// Set the cursor position. We can only set alternate columns. The row addressing is rather odd.
+// Set the cursor position
void Lcd7920::SetCursor(uint8_t r, uint8_t c)
{
row = r % numRows;
@@ -479,6 +487,7 @@ bool Lcd7920::ReadPixel(uint8_t x, uint8_t y) const
return false;
}
+// Set the address to write to. The column address is in 16-bit words, so it ranges from 0 to 7.
void Lcd7920::setGraphicsAddress(unsigned int r, unsigned int c)
{
ensureExtendedMode();