From 65ae4f82791f5d9e05002793b4610051382c368e Mon Sep 17 00:00:00 2001
From: Federico Terraneo <fede.tft@miosix.org>
Date: Tue, 7 Dec 2021 00:29:23 +0100
Subject: [PATCH] Added er_oledm024 driver

---
 .../display_er_oledm024.cpp                   | 147 ++++++++++++++++++
 .../display_er_oledm024/display_er_oledm024.h |  67 ++++++++
 _examples/display_er_oledm024/main.cpp        |  44 ++++++
 3 files changed, 258 insertions(+)
 create mode 100644 _examples/display_er_oledm024/display_er_oledm024.cpp
 create mode 100644 _examples/display_er_oledm024/display_er_oledm024.h
 create mode 100644 _examples/display_er_oledm024/main.cpp

diff --git a/_examples/display_er_oledm024/display_er_oledm024.cpp b/_examples/display_er_oledm024/display_er_oledm024.cpp
new file mode 100644
index 0000000..d346a3c
--- /dev/null
+++ b/_examples/display_er_oledm024/display_er_oledm024.cpp
@@ -0,0 +1,147 @@
+/***************************************************************************
+ *   Copyright (C) 2021 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program 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 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#include "display_er_oledm024.h"
+#include <miosix.h>
+#include <algorithm>
+
+using namespace std;
+using namespace miosix;
+
+#ifndef _BOARD_STM32F411CE_BLACKPILL
+#warning "The SPI driver has only been tested on an STM32F411CE_BLACKPILL"
+#endif
+
+//Display connection
+
+using cs   = Gpio<GPIOB_BASE,7>;
+using sck  = Gpio<GPIOB_BASE,3>; //Used as HW SPI
+using mosi = Gpio<GPIOB_BASE,5>; //Used as HW SPI
+using dc   = Gpio<GPIOB_BASE,6>;
+using res  = Gpio<GPIOB_BASE,4>;
+
+static unsigned char spi1sendRecv(unsigned char x=0)
+{
+    SPI1->DR=x;
+    while((SPI1->SR & SPI_SR_RXNE)==0) ;
+    return SPI1->DR;
+}
+
+static void cmd(unsigned char c)
+{
+    dc::low();
+    cs::low();
+    delayUs(1);
+    spi1sendRecv(c);
+    cs::high();
+    delayUs(1);
+}
+
+//
+// class DisplayErOledm024
+//
+
+namespace mxgui {
+
+DisplayErOledm024::DisplayErOledm024() : DisplayGeneric1BPP(128,64)
+{
+    {
+        FastInterruptDisableLock dLock;
+        cs::mode(Mode::OUTPUT);      cs::high();
+        sck::mode(Mode::ALTERNATE);  sck::alternateFunction(5);
+        mosi::mode(Mode::ALTERNATE); mosi::alternateFunction(5);
+        dc::mode(Mode::OUTPUT);
+        res::mode(Mode::OUTPUT);
+
+        RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
+        RCC_SYNC();
+    }
+
+    SPI1->CR1=SPI_CR1_SSM  //No HW cs
+            | SPI_CR1_SSI
+            | SPI_CR1_SPE  //SPI enabled
+            | SPI_CR1_BR_1 //SPI clock 50/8=6.25 MHz
+            | SPI_CR1_MSTR;//Master mode
+
+    res::high();
+    Thread::sleep(1);
+    res::low();
+    delayUs(100);
+    res::high();
+    delayUs(100);
+
+    //VCC=13.4V VCOMH=10.4V IREF~11uA SPI_fmax=10MHz
+    cmd(0xfd); cmd(0x12);     // Disable command lock
+    cmd(0xae);                // Display OFF
+    cmd(0xd5); cmd(0xa0);     // Oscillator 0xa no divider
+    cmd(0xa8); cmd(height-1); // Number of rows 64
+    cmd(0xd3); cmd(0x00);     // Display offset 0
+    cmd(0x40);                // Display start line 0
+    cmd(0x20); cmd(0x00);     // Memory addrressing horizontal
+    cmd(0xa1);
+    cmd(0xc8);                // Scan direction 64 to 1
+    cmd(0xda); cmd(0x12);     // Alternate COM, no COM left/right
+    cmd(0x81); cmd(0x32);     // Brightness 1.1uA/pixel
+    cmd(0xd9); cmd(0x25);     // Precharge phase2=2 phase1=5
+    cmd(0xdb); cmd(0x34);     // VCOMH=.78*VCC 
+    cmd(0xa6);                // Normal display mode
+    cmd(0xa4);                // Disable test mode
+    clear(0);
+    update();
+    cmd(0xaf);                // Display ON
+    setTextColor(std::make_pair(Color(0xf),Color(0x0)));
+}
+
+void DisplayErOledm024::doTurnOn()
+{
+    cmd(0xaf);
+}
+
+void DisplayErOledm024::doTurnOff()
+{
+    cmd(0xae);
+}
+
+void DisplayErOledm024::doSetBrightness(int brt)
+{
+    int brightness=max(0,min(50,brt/2));
+    cmd(0x81); cmd(brightness);
+}
+
+void DisplayErOledm024::update()
+{
+    cmd(0x21); cmd(0); cmd(127);
+    cmd(0x22); cmd(0); cmd(7);
+    dc::high();
+    cs::low();
+    delayUs(1);
+    for(int i=0;i<fbSize;i++) spi1sendRecv(backbuffer[i]);
+    cs::high();
+    delayUs(1);
+}
+
+} //namespace mxgui
diff --git a/_examples/display_er_oledm024/display_er_oledm024.h b/_examples/display_er_oledm024/display_er_oledm024.h
new file mode 100644
index 0000000..ccad313
--- /dev/null
+++ b/_examples/display_er_oledm024/display_er_oledm024.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *   Copyright (C) 2021 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program 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 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program 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.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#pragma once
+
+#include <mxgui/drivers/display_generic_1bpp.h>
+
+namespace mxgui {
+
+class DisplayErOledm024 : public DisplayGeneric1BPP
+{
+public:
+    /*
+     * Constructor
+     */
+    DisplayErOledm024();
+        
+    /**
+     * Turn the display On after it has been turned Off.
+     * Display initial state is On.
+     */
+    void doTurnOn() override;
+
+    /**
+     * Turn the display Off. It can be later turned back On.
+     */
+    void doTurnOff() override;
+    
+    /**
+     * Set display brightness. Depending on the underlying driver,
+     * may do nothing.
+     * \param brt from 0 to 100
+     */
+    void doSetBrightness(int brt) override;
+    
+    /**
+     * Make all changes done to the display since the last call to update()
+     * visible. Backends that require it may override this.
+     */
+    void update() override;
+};
+
+} //namespace mxgui
diff --git a/_examples/display_er_oledm024/main.cpp b/_examples/display_er_oledm024/main.cpp
new file mode 100644
index 0000000..9a36eec
--- /dev/null
+++ b/_examples/display_er_oledm024/main.cpp
@@ -0,0 +1,44 @@
+
+#include <cstdio>
+#include "miosix.h"
+#include "mxgui/display.h"
+#include "mxgui/misc_inst.h"
+#include "display_er_oledm024.h"
+
+using namespace std;
+using namespace miosix;
+using namespace mxgui;
+
+//NOTE: to try this example, you have to connect the display to the board as
+//written in display_er_oledm024.cpp
+
+/*
+ * On boards which do not have a built-in display, MXGUI requires you to
+ * implement the registerDisplayHook callback to tell MXGUI which display to
+ * use. If you want to adapt this example for a board that already has a
+ * display, you can register a secondary display in the main with the following
+ * line
+ * \code
+ * DisplayManager::instance().registerDisplay(new DisplayLy091wg14<sda,scl,reset>);
+ * \endcode
+ * And then get the display with DisplayManager::instance().getDisplay(1).
+ * Note that 0 is the default display, 1 would be the secondary one.
+ */
+namespace mxgui {
+void registerDisplayHook(DisplayManager& dm)
+{
+    dm.registerDisplay(new DisplayErOledm024);
+}
+} //namespace mxgui
+
+int main()
+{
+    auto& display=DisplayManager::instance().getDisplay();
+    {
+        DrawingContext dc(display);
+        dc.setFont(tahoma);
+        dc.write(Point(0,0),"Miosix OS");
+        dc.write(Point(0,tahoma.getHeight()),"MXGUI graphics library");
+    }
+   for(;;) Thread::sleep(100);
+}
-- 
GitLab