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