Where "rotation" is modified in Adafuit_GFX library ?

Hi,

I'm trying to write my own ssd1306 library using stm32 maple mini board.

So the stm32_ssd1306 library is using some functions of Arduino Adafuit_GFX master library using C++ public inheritance.

And I want to run my library without Adafuit_GFX master library support.

But as I'm copying the functions to my library, I noticed the protected "rotation" variable is used to determine the rotation of the display and used in different other functions. But what I don't understand and couldn't find is where this variable is modified ?


Edit:
I want to add that the reason that I'm searching for this variable is that I want to know how it's manipulated and try to copy the function that modify/manipulate this variable.

OK, got one part of the problem:

void Adafruit_GFX::setRotation(uint8_t x) {
    rotation = (x & 3);

This is how, but now I should check where setRotation() is used.

God gave you grep.

The Arduino IDE editor gave you ctrl-F

I couldn't find setRotation()

anywhere, whether in example code or in the libraries.

lines 1310-1330

/**************************************************************************/
/*!
    @brief      Set rotation setting for display
    @param  x   0 thru 3 corresponding to 4 cardinal rotations
*/
/**************************************************************************/
void Adafruit_GFX::setRotation(uint8_t x) {
  rotation = (x & 3);
  switch (rotation) {
  case 0:
  case 2:
    _width = WIDTH;
    _height = HEIGHT;
    break;
  case 1:
  case 3:
    _width = HEIGHT;
    _height = WIDTH;
    break;
  }
}

A hardware class that inherits from Adafruit_GFX will implement the hardware specific rotation code and update its parent Adafruit_GFX::setRotation()

The real mystery is: Why do you want to avoid Adafruit_GFX?

David.

david_prentice:
lines 1310-1330

A hardware class that inherits from Adafruit_GFX will implement the hardware specific rotation code and update its parent Adafruit_GFX::setRotation()

Yeah that's the function definition.

I want to know where it's used in the code whether in example of library code ?

The real mystery is: Why do you want to avoid Adafruit_GFX?

I want to teach myself how to write this library in C, then I do my own version of C++.

That way I learn how to run something and also learn something about how a complete library with the necessary functions is written. Otherwise no one would teach me, I better teach myself and a get a fortune in my country.

Programming would be something shiny especially in embedded systems, I've done simple courses in PIC micrcontrollers, I learned about my abilities and what I need for the next level.

I wanna be a professional trainer and buy myself a BMW M5 sport :slight_smile:

Yeah I'm so happy I was able to copy the stm32 ssd1306 library written in C++ and convert it to a C version without Adafruit support and it worked :slight_smile:

#include <avr/pgmspace.h>
#include <stdlib.h>
#include <Wire.h>
#include "ssd1306_stm32.h"

#ifndef swap
#define swap(a, b) { int16_t t = a; a = b; b = t; }
#endif

uint8_t rotation, width = 128, height = 64, _i2caddr, _vccstate;

static uint8_t buffer[1024] = {0};
void ssd1306_start(uint8_t vccstate, uint8_t i2caddr) {
  _vccstate = vccstate;
  _i2caddr = i2caddr;

    // I2C Init
    Wire.begin();

 /*if (reset) {
 // Setup reset pin direction (used by both SPI and I2C)  
 pinMode(rst, OUTPUT); digitalWrite(rst, HIGH);    
 delay(1); // VDD rise at start, wait 1ms
 digitalWrite(rst, LOW); // bring reset low
 delay(10); // wait 10ms
 digitalWrite(rst, HIGH); // bring out of reset
 }*/

 // Init sequence for 128x64 OLED module
 ssd1306_cmd(SSD1306_DISPLAYOFF);                    // 0xAE
 ssd1306_cmd(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
 ssd1306_cmd(0x80);                                  // the suggested ratio 0x80
 ssd1306_cmd(SSD1306_SETMULTIPLEX);                  // 0xA8
 ssd1306_cmd(0x3F);
 ssd1306_cmd(SSD1306_SETDISPLAYOFFSET);              // 0xD3
 ssd1306_cmd(0x0);                                   // no offset
 ssd1306_cmd(SSD1306_SETSTARTLINE | 0x0);            // line #0
 ssd1306_cmd(SSD1306_CHARGEPUMP);                    // 0x8D
 if (vccstate == SSD1306_EXTERNALVCC) 
  { ssd1306_cmd(0x10); }
 else 
  { ssd1306_cmd(0x14); }
 ssd1306_cmd(SSD1306_MEMORYMODE);                    // 0x20
 ssd1306_cmd(0x00);                                  // 0x0 act like ks0108
 ssd1306_cmd(SSD1306_SEGREMAP | 0x1);
 ssd1306_cmd(SSD1306_COMSCANDEC);
 ssd1306_cmd(SSD1306_SETCOMPINS);                    // 0xDA
 ssd1306_cmd(0x12);
 ssd1306_cmd(SSD1306_SETCONTRAST);                   // 0x81
 if (vccstate == SSD1306_EXTERNALVCC) 
  { ssd1306_cmd(0x9F); }
 else 
  { ssd1306_cmd(0xCF); }
 ssd1306_cmd(SSD1306_SETPRECHARGE);                  // 0xd9
 if (vccstate == SSD1306_EXTERNALVCC) 
  { ssd1306_cmd(0x22); }
 else 
  { ssd1306_cmd(0xF1); }
 ssd1306_cmd(SSD1306_SETVCOMDETECT);                 // 0xDB
 ssd1306_cmd(0x40);
 ssd1306_cmd(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
 ssd1306_cmd(SSD1306_NORMALDISPLAY);                 // 0xA6

 ssd1306_cmd(SSD1306_DISPLAYON);//--turn on oled panel
}

void ssd1306_cmd(uint8_t c){
    uint8_t control = 0x00;   // Co = 0, D/C = 0
    Wire.beginTransmission(_i2caddr);
    WIRE_WRITE(control);
    WIRE_WRITE(c);
    Wire.endTransmission(); 
}
void ssd1306_data(uint8_t c){
    uint8_t control = 0x40;   // Co = 0, D/C = 1
    Wire.beginTransmission(_i2caddr);
    WIRE_WRITE(control);
    WIRE_WRITE(c);
    Wire.endTransmission(); 
}
void ssd1306_clearDisplay(void){
 memset(buffer, 0, 1024); 
}
void ssd1306_invertDisplay(uint8_t i){
 if (i) {
 ssd1306_cmd(SSD1306_INVERTDISPLAY);
 } else {
 ssd1306_cmd(SSD1306_NORMALDISPLAY);
 } 
}
void ssd1306_display(void){
 ssd1306_cmd(SSD1306_COLUMNADDR);
 ssd1306_cmd(0);   // Column start address (0 = reset)
 ssd1306_cmd(SSD1306_WIDTH-1); // Column end address (127 = reset)

 ssd1306_cmd(SSD1306_PAGEADDR);
 ssd1306_cmd(0); // Page start address (0 = reset)
 ssd1306_cmd(7); // Page end address

 // I2C
 for (uint16_t i=0; i<1024; i++) {
 // send a bunch of data in one xmission
 Wire.beginTransmission(_i2caddr);
 WIRE_WRITE(0x40);
 for (uint8_t x=0; x<16; x++) {
 WIRE_WRITE(buffer[i]);
 i++;
 }
 i--;
 Wire.endTransmission();
 }
}

// lcd control functions
void ssd1306_scrl_right(uint8_t start, uint8_t stop){
 ssd1306_cmd(SSD1306_RIGHT_HORIZONTAL_SCROLL);
 ssd1306_cmd(0X00);
 ssd1306_cmd(start);
 ssd1306_cmd(0X0F);
 ssd1306_cmd(stop);
 ssd1306_cmd(0X00);
 ssd1306_cmd(0XFF);
 ssd1306_cmd(SSD1306_ACTIVATE_SCROLL); 
}
void ssd1306_scrl_left(uint8_t start, uint8_t stop){
 ssd1306_cmd(SSD1306_LEFT_HORIZONTAL_SCROLL);
 ssd1306_cmd(0X00);
 ssd1306_cmd(start);
 ssd1306_cmd(7);
 ssd1306_cmd(stop);
 ssd1306_cmd(0X00);
 ssd1306_cmd(0XFF);
 ssd1306_cmd(SSD1306_ACTIVATE_SCROLL); 
}
void ssd1306_scrl_d_right(uint8_t start, uint8_t stop){
 ssd1306_cmd(SSD1306_SET_VERTICAL_SCROLL_AREA);  
 ssd1306_cmd(0X00);
 ssd1306_cmd(SSD1306_HEIGHT);
 ssd1306_cmd(SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL);
 ssd1306_cmd(0X00);
 ssd1306_cmd(start);
 ssd1306_cmd(0X00);
 ssd1306_cmd(stop);
 ssd1306_cmd(0X01);
 ssd1306_cmd(SSD1306_ACTIVATE_SCROLL); 
}
void ssd1306_scrl_d_left(uint8_t start, uint8_t stop){
 ssd1306_cmd(SSD1306_SET_VERTICAL_SCROLL_AREA);  
 ssd1306_cmd(0X00);
 ssd1306_cmd(SSD1306_HEIGHT);
 ssd1306_cmd(SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL);
 ssd1306_cmd(0X00);
 ssd1306_cmd(start);
 ssd1306_cmd(0X00);
 ssd1306_cmd(stop);
 ssd1306_cmd(0X01);
 ssd1306_cmd(SSD1306_ACTIVATE_SCROLL); 
}
void ssd1306_stop_scrl(void){
 ssd1306_cmd(SSD1306_DEACTIVATE_SCROLL); 
}
void ssd1306_dim(boolean dim){
 uint8_t contrast;

 if (dim) {
 contrast = 0; // Dimmed display
 } else {
 if (_vccstate == SSD1306_EXTERNALVCC) {
 contrast = 0x9F;
 } else {
 contrast = 0xCF;
 }
 }
 // the range of contrast to too small to be really useful
 // it is useful to dim the display
 ssd1306_cmd(SSD1306_SETCONTRAST);
 ssd1306_cmd(contrast); 
}

void ssd1306_set_rotation(uint8_t x) {
    rotation = (x & 3);
    switch(rotation) {
        case 0:
        case 2:
            width  = SSD1306_WIDTH;
            height = SSD1306_HEIGHT;
            break;
        case 1:
        case 3:
            width  = SSD1306_HEIGHT;
            height = SSD1306_WIDTH;
            break;
    }
}

void ssd1306_drawPixel(int16_t x, int16_t y, uint16_t color){
 
  if ((x < 0) || (x >= width) || (y < 0) || (y >= height))
    return;

  // check rotation, move pixel around if necessary
  switch (rotation) {
  case 1:
    swap(x, y);
    x = width - x - 1;
    break;
  case 2:
    x = width - x - 1;
    y = height - y - 1;
    break;
  case 3:
    swap(x, y);
    y = height - y - 1;
    break;
  }  

  // x is which column
    switch (color) 
    {
      case WHITE:   buffer[x+ (y/8)*SSD1306_WIDTH] |=  (1 << (y&7)); break;
      case BLACK:   buffer[x+ (y/8)*SSD1306_WIDTH] &= ~(1 << (y&7)); break; 
      case INVERSE: buffer[x+ (y/8)*SSD1306_WIDTH] ^=  (1 << (y&7)); break; 
    }
    
}

Now I can investigate the code parts more and then I would consider doing a C++ version of my own.

But I still need to know where

setRotation()

is used.

Because I want to know the parts of code that modify the rotation of the display.