summaryrefslogtreecommitdiff
path: root/code_refs/Adafruit_SharpMem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'code_refs/Adafruit_SharpMem.cpp')
-rw-r--r--code_refs/Adafruit_SharpMem.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/code_refs/Adafruit_SharpMem.cpp b/code_refs/Adafruit_SharpMem.cpp
new file mode 100644
index 0000000..27b24c2
--- /dev/null
+++ b/code_refs/Adafruit_SharpMem.cpp
@@ -0,0 +1,277 @@
+/*********************************************************************
+This is an Arduino library for our Monochrome SHARP Memory Displays
+
+ Pick one up today in the adafruit shop!
+ ------> http://www.adafruit.com/products/1393
+
+These displays use SPI to communicate, 3 pins are required to
+interface
+
+Adafruit invests time and resources providing this open source code,
+please support Adafruit and open-source hardware by purchasing
+products from Adafruit!
+
+Written by Limor Fried/Ladyada for Adafruit Industries.
+BSD license, check license.txt for more information
+All text above, and the splash screen must be included in any redistribution
+*********************************************************************/
+
+#include "Adafruit_SharpMem.h"
+
+#ifndef _swap_int16_t
+#define _swap_int16_t(a, b) \
+ { \
+ int16_t t = a; \
+ a = b; \
+ b = t; \
+ }
+#endif
+#ifndef _swap_uint16_t
+#define _swap_uint16_t(a, b) \
+ { \
+ uint16_t t = a; \
+ a = b; \
+ b = t; \
+ }
+#endif
+
+/**************************************************************************
+ Sharp Memory Display Connector
+ -----------------------------------------------------------------------
+ Pin Function Notes
+ === ============== ===============================
+ 1 VIN 3.3-5.0V (into LDO supply)
+ 2 3V3 3.3V out
+ 3 GND
+ 4 SCLK Serial Clock
+ 5 MOSI Serial Data Input
+ 6 CS Serial Chip Select
+ 9 EXTMODE COM Inversion Select (Low = SW clock/serial)
+ 7 EXTCOMIN External COM Inversion Signal
+ 8 DISP Display On(High)/Off(Low)
+
+ **************************************************************************/
+
+#define TOGGLE_VCOM \
+ do { \
+ _sharpmem_vcom = _sharpmem_vcom ? 0x00 : SHARPMEM_BIT_VCOM; \
+ } while (0);
+
+/**
+ * @brief Construct a new Adafruit_SharpMem object with software SPI
+ *
+ * @param clk The clock pin
+ * @param mosi The MOSI pin
+ * @param cs The display chip select pin - **NOTE** this is ACTIVE HIGH!
+ * @param width The display width
+ * @param height The display height
+ * @param freq The SPI clock frequency desired (unlikely to be that fast in soft
+ * spi mode!)
+ */
+Adafruit_SharpMem::Adafruit_SharpMem(uint8_t clk, uint8_t mosi, uint8_t cs,
+ uint16_t width, uint16_t height,
+ uint32_t freq)
+ : Adafruit_GFX(width, height) {
+ _cs = cs;
+ if (spidev) {
+ delete spidev;
+ }
+ spidev =
+ new Adafruit_SPIDevice(cs, clk, -1, mosi, freq, SPI_BITORDER_LSBFIRST);
+}
+
+/**
+ * @brief Construct a new Adafruit_SharpMem object with hardware SPI
+ *
+ * @param theSPI Pointer to hardware SPI device you want to use
+ * @param cs The display chip select pin - **NOTE** this is ACTIVE HIGH!
+ * @param width The display width
+ * @param height The display height
+ * @param freq The SPI clock frequency desired
+ */
+Adafruit_SharpMem::Adafruit_SharpMem(SPIClass *theSPI, uint8_t cs,
+ uint16_t width, uint16_t height,
+ uint32_t freq)
+ : Adafruit_GFX(width, height) {
+ _cs = cs;
+ if (spidev) {
+ delete spidev;
+ }
+ spidev = new Adafruit_SPIDevice(cs, freq, SPI_BITORDER_LSBFIRST, SPI_MODE0,
+ theSPI);
+}
+
+/**
+ * @brief Start the driver object, setting up pins and configuring a buffer for
+ * the screen contents
+ *
+ * @return boolean true: success false: failure
+ */
+boolean Adafruit_SharpMem::begin(void) {
+ if (!spidev->begin()) {
+ return false;
+ }
+ // this display is weird in that _cs is active HIGH not LOW like every other
+ // SPI device
+ digitalWrite(_cs, LOW);
+
+ // Set the vcom bit to a defined state
+ _sharpmem_vcom = SHARPMEM_BIT_VCOM;
+
+ sharpmem_buffer = (uint8_t *)malloc((WIDTH * HEIGHT) / 8);
+
+ if (!sharpmem_buffer)
+ return false;
+
+ setRotation(0);
+
+ return true;
+}
+
+// 1<<n is a costly operation on AVR -- table usu. smaller & faster
+static const uint8_t PROGMEM set[] = {1, 2, 4, 8, 16, 32, 64, 128},
+ clr[] = {(uint8_t)~1, (uint8_t)~2, (uint8_t)~4,
+ (uint8_t)~8, (uint8_t)~16, (uint8_t)~32,
+ (uint8_t)~64, (uint8_t)~128};
+
+/**************************************************************************/
+/*!
+ @brief Draws a single pixel in image buffer
+
+ @param[in] x
+ The x position (0 based)
+ @param[in] y
+ The y position (0 based)
+ @param color The color to set:
+ * **0**: Black
+ * **1**: White
+*/
+/**************************************************************************/
+void Adafruit_SharpMem::drawPixel(int16_t x, int16_t y, uint16_t color) {
+ if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height))
+ return;
+
+ switch (rotation) {
+ case 1:
+ _swap_int16_t(x, y);
+ x = WIDTH - 1 - x;
+ break;
+ case 2:
+ x = WIDTH - 1 - x;
+ y = HEIGHT - 1 - y;
+ break;
+ case 3:
+ _swap_int16_t(x, y);
+ y = HEIGHT - 1 - y;
+ break;
+ }
+
+ if (color) {
+ sharpmem_buffer[(y * WIDTH + x) / 8] |= pgm_read_byte(&set[x & 7]);
+ } else {
+ sharpmem_buffer[(y * WIDTH + x) / 8] &= pgm_read_byte(&clr[x & 7]);
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the value (1 or 0) of the specified pixel from the buffer
+
+ @param[in] x
+ The x position (0 based)
+ @param[in] y
+ The y position (0 based)
+
+ @return 1 if the pixel is enabled, 0 if disabled
+*/
+/**************************************************************************/
+uint8_t Adafruit_SharpMem::getPixel(uint16_t x, uint16_t y) {
+ if ((x >= _width) || (y >= _height))
+ return 0; // <0 test not needed, unsigned
+
+ switch (rotation) {
+ case 1:
+ _swap_uint16_t(x, y);
+ x = WIDTH - 1 - x;
+ break;
+ case 2:
+ x = WIDTH - 1 - x;
+ y = HEIGHT - 1 - y;
+ break;
+ case 3:
+ _swap_uint16_t(x, y);
+ y = HEIGHT - 1 - y;
+ break;
+ }
+
+ return sharpmem_buffer[(y * WIDTH + x) / 8] & pgm_read_byte(&set[x & 7]) ? 1
+ : 0;
+}
+
+/**************************************************************************/
+/*!
+ @brief Clears the screen
+*/
+/**************************************************************************/
+void Adafruit_SharpMem::clearDisplay() {
+ memset(sharpmem_buffer, 0xff, (WIDTH * HEIGHT) / 8);
+
+ spidev->beginTransaction();
+ // Send the clear screen command rather than doing a HW refresh (quicker)
+ digitalWrite(_cs, HIGH);
+
+ uint8_t clear_data[2] = {(uint8_t)(_sharpmem_vcom | SHARPMEM_BIT_CLEAR),
+ 0x00};
+ spidev->transfer(clear_data, 2);
+
+ TOGGLE_VCOM;
+ digitalWrite(_cs, LOW);
+ spidev->endTransaction();
+}
+
+/**************************************************************************/
+/*!
+ @brief Renders the contents of the pixel buffer on the LCD
+*/
+/**************************************************************************/
+void Adafruit_SharpMem::refresh(void) {
+ uint16_t i, currentline;
+
+ spidev->beginTransaction();
+ // Send the write command
+ digitalWrite(_cs, HIGH);
+
+ spidev->transfer(_sharpmem_vcom | SHARPMEM_BIT_WRITECMD);
+ TOGGLE_VCOM;
+
+ uint8_t bytes_per_line = WIDTH / 8;
+ uint16_t totalbytes = (WIDTH * HEIGHT) / 8;
+
+ for (i = 0; i < totalbytes; i += bytes_per_line) {
+ uint8_t line[bytes_per_line + 2];
+
+ // Send address byte
+ currentline = ((i + 1) / (WIDTH / 8)) + 1;
+ line[0] = currentline;
+ // copy over this line
+ memcpy(line + 1, sharpmem_buffer + i, bytes_per_line);
+ // Send end of line
+ line[bytes_per_line + 1] = 0x00;
+ // send it!
+ spidev->transfer(line, bytes_per_line + 2);
+ }
+
+ // Send another trailing 8 bits for the last line
+ spidev->transfer(0x00);
+ digitalWrite(_cs, LOW);
+ spidev->endTransaction();
+}
+
+/**************************************************************************/
+/*!
+ @brief Clears the display buffer without outputting to the display
+*/
+/**************************************************************************/
+void Adafruit_SharpMem::clearDisplayBuffer() {
+ memset(sharpmem_buffer, 0xff, (WIDTH * HEIGHT) / 8);
+}