/********************************************************************* 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 SHARPMEM_BIT_WRITECMD (0x80) #define SHARPMEM_BIT_VCOM (0x40) #define SHARPMEM_BIT_CLEAR (0x20) #define TOGGLE_VCOM do { _sharpmem_vcom = _sharpmem_vcom ? 0x00 : SHARPMEM_BIT_VCOM; } while(0); byte *sharpmem_buffer; /* ************* */ /* CONSTRUCTORS */ /* ************* */ Adafruit_SharpMem::Adafruit_SharpMem(uint8_t clk, uint8_t mosi, uint8_t ss, uint16_t width, uint16_t height) : Adafruit_GFX(width, height) { _clk = clk; _mosi = mosi; _ss = ss; } boolean Adafruit_SharpMem::begin(void) { // Set pin state before direction to make sure they start this way (no glitching) digitalWrite(_ss, HIGH); digitalWrite(_clk, LOW); digitalWrite(_mosi, HIGH); pinMode(_ss, OUTPUT); pinMode(_clk, OUTPUT); pinMode(_mosi, OUTPUT); #if defined(USE_FAST_PINIO) clkport = portOutputRegister(digitalPinToPort(_clk)); clkpinmask = digitalPinToBitMask(_clk); dataport = portOutputRegister(digitalPinToPort(_mosi)); datapinmask = digitalPinToBitMask(_mosi); #endif // Set the vcom bit to a defined state _sharpmem_vcom = SHARPMEM_BIT_VCOM; sharpmem_buffer = (byte *)malloc((WIDTH * HEIGHT) / 8); if (!sharpmem_buffer) return false; setRotation(0); return true; } /* *************** */ /* PRIVATE METHODS */ /* *************** */ /**************************************************************************/ /*! @brief Sends a single byte in pseudo-SPI. */ /**************************************************************************/ void Adafruit_SharpMem::sendbyte(uint8_t data) { uint8_t i = 0; // LCD expects LSB first #if defined(USE_FAST_PINIO) for (i=0; i<8; i++) { // Make sure clock starts low *clkport &= ~clkpinmask; if (data & 0x80) *dataport |= datapinmask; else *dataport &= ~datapinmask; // Clock is active high *clkport |= clkpinmask; data <<= 1; } *clkport &= ~clkpinmask; #else for (i=0; i<8; i++) { // Make sure clock starts low digitalWrite(_clk, LOW); if (data & 0x80) digitalWrite(_mosi, HIGH); else digitalWrite(_mosi, LOW); // Clock is active high digitalWrite(_clk, HIGH); data <<= 1; } // Make sure clock ends low digitalWrite(_clk, LOW); #endif } void Adafruit_SharpMem::sendbyteLSB(uint8_t data) { uint8_t i = 0; // LCD expects LSB first #if defined(USE_FAST_PINIO) for (i=0; i<8; i++) { // Make sure clock starts low *clkport &= ~clkpinmask; if (data & 0x01) *dataport |= datapinmask; else *dataport &= ~datapinmask; // Clock is active high *clkport |= clkpinmask; data >>= 1; } // Make sure clock ends low *clkport &= ~clkpinmask; #else for (i=0; i<8; i++) { // Make sure clock starts low digitalWrite(_clk, LOW); if (data & 0x01) digitalWrite(_mosi, HIGH); else digitalWrite(_mosi, LOW); // Clock is active high digitalWrite(_clk, HIGH); data >>= 1; } // Make sure clock ends low digitalWrite(_clk, LOW); #endif } /* ************** */ /* PUBLIC METHODS */ /* ************** */ // 1<= _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); // Send the clear screen command rather than doing a HW refresh (quicker) digitalWrite(_ss, HIGH); sendbyte(_sharpmem_vcom | SHARPMEM_BIT_CLEAR); sendbyteLSB(0x00); TOGGLE_VCOM; digitalWrite(_ss, LOW); } /**************************************************************************/ /*! @brief Renders the contents of the pixel buffer on the LCD */ /**************************************************************************/ void Adafruit_SharpMem::refresh(void) { uint16_t i, totalbytes, currentline, oldline; totalbytes = (WIDTH * HEIGHT) / 8; // Send the write command digitalWrite(_ss, HIGH); sendbyte(SHARPMEM_BIT_WRITECMD | _sharpmem_vcom); TOGGLE_VCOM; // Send the address for line 1 oldline = currentline = 1; sendbyteLSB(currentline); // Send image buffer for (i=0; i