Skip to content

internal

kraus edited this page Oct 6, 2021 · 59 revisions

Rebuild Fonts

Rebuilding a all font c code, font pictures and all font related md (Github markdown) files:

tools/font/build$ make clean
tools/font/build$ make build1
tools/font/build$ ./build1
tools/font/build$ make clean
tools/font/build$ make build2
tools/font/build$ ./build2

The font pictures must be copied manually to the wiki:

tools/font/build$ cp *.png ~/git/u8g2.wiki/fntpic/.

Some pictures are too large for the build processor. These pictures have to be generated with bdfconv. After this, overwrite the incomplete pictures.

tools/font/bdfconv$ make chinese
tools/font/bdfconv$ cp u8g2_font_*.png ~/git/u8g2.wiki/fntpic/.

The updated font md files will clear the TOC. This has to be rebuild also:

tools/mdtoc$ make wiki

The makefile target "wiki" will update all markdown files in the wiki. All modified markdown files will get a generated table of content. Labels are inserted before and after the TOC. Do not delete these labels.

To update the examples, call the .ino updater:

tools/inoupdate$ make ino

This will the constructor list for the examples.

LCD and ePaper

Powersave Mode

LCD: Powersave mode will make the content of the display invisible.

e-Paper: Powersave mode will try to lower the power consumption, however the display content will not be affected.

In both cases the RAM content is not affected and can still be written. This means, that the RAM can be written during power down mode. After enabling power up, the new display content will be visible (for e-Paper devices an additional refresh is required).

Refresh

E-Paper devices have to handle the U8X8_MSG_DISPLAY_REFRESH message. LCDs must ignore this message. U8X8_MSG_DISPLAY_REFRESH is sent to the device via call to refreshDisplay. For the u8x8-API this call must be done by the user. For the u8g2-API this call is automatically performed by the sendBuffer and nextPage calls.

The refresh message must be sent only during power up mode of the e-Paper/e-Ink device. This leads to the following problem: The C++ begin() sequence looks like this:

  1. initDisplay
  2. clearDisplay
  3. setPowerSave(0)

While this is fine for LCDs, the problem for e-Paper/e-Ink is, that a refresh message is sent during step 2, but the power save might still be enabled. To solve this, the procedures above behave differently for LCDs and e-Paper/e-Ink devices:

Procedure Result for LCD Result for e-Paper/e-Ink
initDisplay Power Save enabled, display RAM undefined, empty display screen Power Save disabled, display RAM cleared, empty display screen
clearDisplay Display RAM cleared Display RAM cleared (redundant, because it is already empty)
setPowerSave(0) Display RAM is visible on the screen Disable Power Save (redundant, because it is already disabled)

New Displays

Display Procedure

Every display has its own display procedure. All display specific communication happens through this procedure. The procedure should be located in a c file with the prefix u8x8_d_ and the function name must have the following form: u8x8_d_<controller>_<display>()

Example:

uint8_t u8x8_d_<controller>_<display>(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
  uint8_t x, c;
  uint8_t *ptr;
  switch(msg)
  {
    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
      // make a call to u8x8_d_helper_display_setup_memory 
      // do NOT communicate with the display 
      u8x8_d_helper_display_setup_memory(u8x8, <adr of display info struct>);
      break;
    case U8X8_MSG_DISPLAY_INIT:
      // setup the communication interface
      // init the display by sending an init sequence
      u8x8_d_helper_display_init(u8x8);  
      u8x8_cad_SendSequence(u8x8, <adr of the init sequence>);
      // LCD: Put controller in power safe mode and do not clear  
      //     the controller RAM (will be done later)
      // e-paper/e-Ink: Leave the controller in normal mode (activated charge pump, etc)
      //     ensure, that the controller RAM and the display content are cleared
      break;
    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
      // arg_int == 0: wakeup, normal mode
      // arg_int == 1: power safe 
      // Power save mode means, that power is reduced, but still the controller RAM
      // is valid. Sometimes a controller might have several power modes (normal,
      // sleep, deep sleep, etc). As long as the RAM can be written, any power down 
      // mode is fine. Do not switch to a power down mode, where the controller RAM
      // gets invalid.
      ...
      break;
#ifdef U8X8_WITH_SET_FLIP_MODE
    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
      // This case should be compiled only with U8X8_WITH_SET_FLIP_MODE
      // arg_int == 0: normal, native orientation
      // arg_int == 1: 180 degree rotation
      ...
      break;
#endif
#ifdef U8X8_WITH_SET_CONTRAST
    case U8X8_MSG_DISPLAY_SET_CONTRAST:
      // This case should be compiled only with U8X8_WITH_SET_CONTRAST
      // arg_int: 0 (no contrast/brightness) to 255 (max contrast/brightness)
      ...
      break;
#endif
    case U8X8_MSG_DISPLAY_DRAW_TILE:
      /* arg_ptr: (u8x8_tile_t *) */
      /* arg_int: How often u8x8_tile_t should be repeated */
      ...
      break;
    case U8X8_MSG_DISPLAY_REFRESH:
      // LCD: Do nothing
      // e-Paper/e-Ink: Make controller RAM visible on the display.
      //    It can be assumed, that the controler is NOT in power save mode.
      break;
    default:
      return 0;
  }
  return 1;
}

In most cases each display includes a display-informations stucture (which must be set if U8X8_MSG_DISPLAY_SETUP_MEMORY is received) and a display init sequence (which must be set if U8X8_MSG_DISPLAY_INIT) is received.

Update u8x8.h

The prototype of the display procedure

uint8_t u8x8_d_<controller>_<display>(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)

has to be added to u8x8.h

Rebuild Code

Locate

tools/codebuild$ 

Update codebuild.c file with the new controller/display: Usually this is done by copying an existing display structure. The structure usually looks like this:

   {
    "sh1106", 	8, 	4, 	"u8g2_ll_hvline_vertical_top_lsb", "u8x8_cad_001", "", COM_4WSPI|COM_3WSPI|COM_6800|COM_8080,
    "Not tested", /* is_generate_u8g2_class= */ 1,
    {
      { "64x32" },
      { NULL }
    }
  },
  {
    "sh1106", 	8, 	4, 	"u8g2_ll_hvline_vertical_top_lsb", "u8x8_cad_ssd13xx_i2c", "i2c", COM_I2C,
    "Not tested", /* is_generate_u8g2_class= */ 1,
    {
      { "64x32" },
      { NULL }
    }
  },

From left to right:

Example Description
"sh1106" The name of the controller in your procedure:
8 The tile width (=8 pixel) of the display: In this case 8x8 = 64 pixel width
4 The tile height (=8 pixel) of the display: Here: 4*8 = 32 pixel height
"u8g2_ll_hvline_vertical_top_lsb" The U8g2 memory vs display memory mapping procedure (see also u8g2.h)
"u8x8_cad_001" The command Argument Data mapping procedure. This might depend on the COM procedure.
COM_4WSPI The communication protocols, supported by the display. Can be or'ed
"Not tested" Unused comment
/* is_generate_u8g2_class= */ 1 Whether the u8g2 Arduino class should be generated (usually 1)
display list At the end there must be a NULL terminated list of display names. This must match the part of the function name

Then rebuild the code with

tools/codebuild$ make build

Finally execute codebuild:

tools/codebuild$ ./codebuild

This will update U8g2 and add the new constructors for the display

Release

PDF Generation

pandoc -f gfm fntlistall.md -t latex -o /data/kraus/git/u8g2/doc/u8g2fntlistall.pdf

Arduino IDE

Library

A library, which has been installed via local zip file, is located in the "Arduino/libraries" folder.

Test Devices

Digispark ATTiny Model A (LED at Pin 1)

Images

  • LED light, white background
  • ISO 200, Cloud, 1/60 (A), +3/10 EV, S-Prog

Defines

GCC

  • Show gcc buildin macros: gcc -dM -E - < /dev/null

F_CPU

  • F_CPU must be defined and must expand to the CPU frequency in hertz (e.g. -DF_CPU=16000000L)

Identify Environment

  • ARDUINO: Version number of the Arduino Environment. 100 for 1.00, 10600 for 1.6.0, 10800 for 1.8.0

  • __AVR__: Atmel AVR

  • __18CXX: MPLAB C18 (PIC)

  • __PIC32MX: PIC32

  • __XC8 MPLAB XC8 Compiler (Microchip)

  • __PIC18 MPLAB XC8 Compiler with selected PIC18 device

  • __arm__: GCC ARM (Arduino Due)

  • __SAM3X8E__: Arduino Due

  • __AVR_ARCH__: Values 2 and 25 are ATTiny

  • __XTENSA__, __xtensa__: gcc predefined for xtensa architecture (ESP8266)

  • XTENSA_EL, XTENSA, xtensa: gcc predefined for ESP32

  • ARDUINO_ARCH_ESP8266, ESP8266: Defined by the esp8266 Arduino board file

  • ARDUINO_ARCH_ESP32, ESP_PLATFORM: Defined by Arduino IDE for ESP32 boards

  • __AVR_ARCH__: Build-in macro that resolves to a decimal number that identifies the architecture. Possible values are:

    • 2: avr2, ATTiny
    • 25: avr25, ATTiny with MOVW instruction
    • 3: avr3
    • 31: avr31
    • 35: avr35 (ata5505, ata6617c, ata664251, atmega16u2, atmega32u2, atmega8u2, attiny1634, attiny167, at90usb162, at90usb82)
    • 4: avr4 (ATMega with 8KB)
    • 5: avr5 (ATMega with 16KB to 64KB)
    • 51: avr51 (ATMega with 128KB)
    • 6: avr6 (ATMega with > 128KB)

    for mcu=avr2, avr25, avr3, avr31, avr35, avr4, avr5, avr51, avr6,

Upload to Arduino Due on Linux

Often the following code seems to be required (enter on terminal):

stty -F /dev/ttyACM0 speed 1200 cs8 -cstopb -parenb

The following code will reset and wait for the board:

# reset arduino board
stty -F /dev/ttyACM0 speed 1200 cs8 

# wait for it...
# https://stackoverflow.com/questions/43016993/how-can-i-force-a-leonardo-to-reset-with-avrdude
while :; do
  sleep 0.5
  [ -c /dev/ttyACM0 ] && break
done

TTF to BDF

Usually, the following options should be used

8x8 Fonts:

otf2bdf -r 72 -p 8 <ttf-file> -o <bdf-file>

16x16 Fonts:

otf2bdf -r 72 -p 16 <ttf-file> -o <bdf-file>

External Lib Refs

Clone this wiki locally