diff --git a/_examples/display_er_oledm015/main.cpp b/_examples/display_er_oledm015/main.cpp index 33806c903bb83949553dcfffd9c44775b8a84e99..d399875274f486801a57add46226c3bee071ff8d 100644 --- a/_examples/display_er_oledm015/main.cpp +++ b/_examples/display_er_oledm015/main.cpp @@ -40,14 +40,14 @@ int main() dc.write(Point(0,0),"Miosix OS"); dc.write(Point(0,tahoma.getHeight()),"MXGUI graphics library"); } - for(int i=0;;i++) - { - { - DrawingContext dc(display); - char s[16]; - sniprintf(s,15,"%02d:%02d",i/60,i%60); - dc.write(Point(0,2*tahoma.getHeight()),s); - } - Thread::sleep(1000); - } + for(int i=0;;i++) + { + { + DrawingContext dc(display); + char s[16]; + sniprintf(s,15,"%02d:%02d",i/60,i%60); + dc.write(Point(0,2*tahoma.getHeight()),s); + } + Thread::sleep(1000); + } } diff --git a/_examples/display_er_oledm024/display_er_oledm024.cpp b/_examples/display_er_oledm024/display_er_oledm024.cpp index d346a3c93643e43d1cb7833ee823eb5b17d193f8..f9b22384518b92e600b24ca382293522da6ec28d 100644 --- a/_examples/display_er_oledm024/display_er_oledm024.cpp +++ b/_examples/display_er_oledm024/display_er_oledm024.cpp @@ -44,6 +44,11 @@ using mosi = Gpio<GPIOB_BASE,5>; //Used as HW SPI using dc = Gpio<GPIOB_BASE,6>; using res = Gpio<GPIOB_BASE,4>; +/** + * Send and receive a byte, thus returning only after transmission is complete + * \param x byte to send + * \return the received byte + */ static unsigned char spi1sendRecv(unsigned char x=0) { SPI1->DR=x; @@ -51,11 +56,41 @@ static unsigned char spi1sendRecv(unsigned char x=0) return SPI1->DR; } +/** + * Send a byte only. + * NOTE: this function requires special care to use as + * - it returns before the byte has been transmitted, and if this is the last + * byte, you have to wait with spi1waitCompletion() before deasserting cs + * - as the received byte is ignored, the overrun flag gets set and it must be + * cleared (spi1waitCompletion() does that as well) + */ +static void spi1sendOnly(unsigned char x) +{ + //NOTE: data is sent after the function returns, watch out! + while((SPI1->SR & SPI_SR_TXE)==0) ; + SPI1->DR=x; +} + +/** + * Must be called after using spi1sendOnly(), complete the last byte transmission + */ +static void spi1waitCompletion() +{ + while(SPI1->SR & SPI_SR_BSY) ; + //Reading DR and then SR clears overrun flag + [[gnu::unused]] volatile int unused; + unused=SPI1->DR; + unused=SPI1->SR; +} + +/** + * Send a command to the display + * \param c command + */ static void cmd(unsigned char c) { dc::low(); cs::low(); - delayUs(1); spi1sendRecv(c); cs::high(); delayUs(1); @@ -84,7 +119,7 @@ DisplayErOledm024::DisplayErOledm024() : DisplayGeneric1BPP(128,64) 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_BR_1 //SPI clock 50/8=6.25 MHz (Fmax=10MHz) | SPI_CR1_MSTR;//Master mode res::high(); @@ -138,8 +173,8 @@ void DisplayErOledm024::update() cmd(0x22); cmd(0); cmd(7); dc::high(); cs::low(); - delayUs(1); - for(int i=0;i<fbSize;i++) spi1sendRecv(backbuffer[i]); + for(int i=0;i<fbSize;i++) spi1sendOnly(backbuffer[i]); + spi1waitCompletion(); cs::high(); delayUs(1); } diff --git a/_examples/display_er_oledm024/main.cpp b/_examples/display_er_oledm024/main.cpp index 9a36eecaa9f9f4c638da4e29bc5aab881cd5a58a..5ba9972c3e63d3a4f5e609e6e3939fe50aa6538e 100644 --- a/_examples/display_er_oledm024/main.cpp +++ b/_examples/display_er_oledm024/main.cpp @@ -40,5 +40,14 @@ int main() dc.write(Point(0,0),"Miosix OS"); dc.write(Point(0,tahoma.getHeight()),"MXGUI graphics library"); } - for(;;) Thread::sleep(100); + for(int i=0;;i++) + { + { + DrawingContext dc(display); + char s[16]; + sniprintf(s,15,"%02d:%02d",i/60,i%60); + dc.write(Point(0,2*tahoma.getHeight()),s); + } + Thread::sleep(1000); + } } diff --git a/_examples/display_er_oledm028/display_er_oledm028.cpp b/_examples/display_er_oledm028/display_er_oledm028.cpp index fb0ac0fe85efd1b9296d83878794a9ad78954d59..4ef23b3a2cc21c12aa1d8fe5458abb1913de6205 100644 --- a/_examples/display_er_oledm028/display_er_oledm028.cpp +++ b/_examples/display_er_oledm028/display_er_oledm028.cpp @@ -38,61 +38,74 @@ using namespace miosix; //Display connection -typedef Gpio<GPIOB_BASE,3> sck; -typedef Gpio<GPIOB_BASE,4> miso; //Not used -typedef Gpio<GPIOB_BASE,5> mosi; -typedef Gpio<GPIOB_BASE,7> cs; - -typedef Gpio<GPIOB_BASE,8> dc; -typedef Gpio<GPIOB_BASE,15> reset; - -static void spiInit() +using cs = Gpio<GPIOB_BASE,7>; //Display pin 16 +using sck = Gpio<GPIOB_BASE,3>; //Display pin 4, used as HW SPI +using mosi = Gpio<GPIOB_BASE,5>; //Display pin 5, used as HW SPI +using dc = Gpio<GPIOB_BASE,8>; //Display pin 14 +using res = Gpio<GPIOB_BASE,15>; //Display pin 15 +//Display pin 2 is Vbat (3.3..5V), while display pins 1,7,8,9,10,11,12,13 are GND + +/** + * Send and receive a byte, thus returning only after transmission is complete + * \param x byte to send + * \return the received byte + */ +static unsigned char spi3sendRecv(unsigned char x=0) { - sck::mode(Mode::ALTERNATE); - sck::alternateFunction(6); - mosi::mode(Mode::ALTERNATE); - mosi::alternateFunction(6); - cs::mode(Mode::OUTPUT); - cs::high(); + SPI3->DR=x; + while((SPI3->SR & SPI_SR_RXNE)==0) ; + return SPI3->DR; +} - { - FastInterruptDisableLock dLock; - RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; - RCC_SYNC(); - } - //Master mode no hardware CS pin - //Note: SPI3 is attached on the 42MHz APB2 bus, so the clock is set - //to APB2/2/2=10.5MHz. This overclocking the SSD1332 by 500KHz - SPI3->CR1=SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_MSTR | SPI_CR1_BR_0; - SPI3->CR2=0; - SPI3->CR1 |= SPI_CR1_SPE; //Set enable bit +/** + * Send a byte only. + * NOTE: this function requires special care to use as + * - it returns before the byte has been transmitted, and if this is the last + * byte, you have to wait with spi3waitCompletion() before deasserting cs + * - as the received byte is ignored, the overrun flag gets set and it must be + * cleared (spi1waitCompletion() does that as well) + */ +static void spi3sendOnly(unsigned char x) +{ + //NOTE: data is sent after the function returns, watch out! + while((SPI3->SR & SPI_SR_TXE)==0) ; + SPI3->DR=x; } -static unsigned char spiSendRecv(unsigned char data) +/** + * Must be called after using spi3sendOnly(), complete the last byte transmission + */ +static void spi3waitCompletion() { - SPI3->DR=data; - while((SPI3->SR & SPI_SR_RXNE)==0) ; - return SPI3->DR; + while(SPI3->SR & SPI_SR_BSY) ; + //Reading DR and then SR clears overrun flag + [[gnu::unused]] volatile int unused; + unused=SPI3->DR; + unused=SPI3->SR; } +/** + * Send a command to the display + * \param c command + */ static void cmd(unsigned char c) { dc::low(); - cs::low(); - delayUs(1); - spiSendRecv(c); + spi3sendRecv(c); cs::high(); delayUs(1); } +/** + * Send data to the display + * \param d data + */ static void data(unsigned char d) { dc::high(); - cs::low(); - delayUs(1); - spiSendRecv(d); + spi3sendRecv(d); cs::high(); delayUs(1); } @@ -105,15 +118,29 @@ namespace mxgui { DisplayErOledm028::DisplayErOledm028() : DisplayGeneric4BPP(256,64) { - spiInit(); - dc::mode(Mode::OUTPUT); - reset::mode(Mode::OUTPUT); + { + FastInterruptDisableLock dLock; + cs::mode(Mode::OUTPUT); cs::high(); + sck::mode(Mode::ALTERNATE); sck::alternateFunction(6); + mosi::mode(Mode::ALTERNATE); mosi::alternateFunction(6); + dc::mode(Mode::OUTPUT); + res::mode(Mode::OUTPUT); + + RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; + RCC_SYNC(); + } + + SPI3->CR1=SPI_CR1_SSM //No HW cs + | SPI_CR1_SSI + | SPI_CR1_SPE //SPI enabled + | SPI_CR1_BR_1 //SPI clock 42/8=5.25MHz (Fmax=10MHz) + | SPI_CR1_MSTR;//Master mode - reset::high(); + res::high(); Thread::sleep(1); - reset::low(); + res::low(); delayUs(100); - reset::high(); + res::high(); delayUs(100); cmd(0xfd); data(0x12); // Disable command lock @@ -167,8 +194,8 @@ void DisplayErOledm028::update() dc::high(); cs::low(); - delayUs(1); - for(int i=0;i<fbSize;i++) spiSendRecv(backbuffer[i]); + for(int i=0;i<fbSize;i++) spi3sendOnly(backbuffer[i]); + spi3waitCompletion(); cs::high(); delayUs(1); } diff --git a/_examples/display_er_oledm028/main.cpp b/_examples/display_er_oledm028/main.cpp index 3d56c86f9cef65d347dd42f329f0fea06b03b006..553893b92c90a138c4f1f80b322041523730944b 100644 --- a/_examples/display_er_oledm028/main.cpp +++ b/_examples/display_er_oledm028/main.cpp @@ -41,5 +41,14 @@ int main() dc.setFont(tahoma); dc.write(Point(0,droid21.getHeight()),"MXGUI graphics library"); } - for(;;) Thread::sleep(100); + for(int i=0;;i++) + { + { + DrawingContext dc(display); + char s[16]; + sniprintf(s,15,"%02d:%02d",i/60,i%60); + dc.write(Point(0,droid21.getHeight()+tahoma.getHeight()),s); + } + Thread::sleep(1000); + } }