Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DMA engine to write the display buffer into the Display #20

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
build/
.cache/
13 changes: 13 additions & 0 deletions basic_font.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef _basic_font_h
#define _basic_font_h
#include "font.h"
#include "font_struct.h"

const font basic_font = {
.bytes_per_char = 5,
.char_width = 5,
.first_char_in_font = 32,
.char_height = 8,
.bitmap_buffer = (char *)&font_8x5[5],
};
#endif
14 changes: 14 additions & 0 deletions example/BMSPA_font.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#ifndef _bmspa_font_h
#define _bmspa_font_h
#include <stdint.h>
#include "font_struct.h"

const uint8_t BMSPA_font[] = {
8, 8, 0, 32, 126,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
Expand Down Expand Up @@ -97,3 +102,12 @@ const uint8_t BMSPA_font[] = {
0x02,0x01,0x01,0x02,0x02,0x01,0x00,0x00, // ~
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const font bmspa = {
.bitmap_buffer = (const char *)&BMSPA_font[5] ,
.first_char_in_font = 32,
.bytes_per_char = 8,
.char_width = 8,
.char_height = 8,
};
#endif
13 changes: 13 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ include(pico_sdk_import.cmake)
project(ssd1306-example)

set(CMAKE_C_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(USE_DMA_FOR_DISPLAY "Use the DMA engine to move the display buffer to the display" OFF)

# initialize the Raspberry Pi Pico SDK
pico_sdk_init()
Expand All @@ -22,6 +24,17 @@ target_include_directories(ssd1306-example
${CMAKE_CURRENT_LIST_DIR}/../
)

if(USE_DMA_FOR_DISPLAY)
message(STATUS "Using DMA")
target_compile_definitions(ssd1306-example
PUBLIC SSD1306_USE_DMA
)
target_link_libraries(ssd1306-example
hardware_dma
)
endif(USE_DMA_FOR_DISPLAY)


target_link_libraries(ssd1306-example pico_stdlib hardware_i2c)

pico_enable_stdio_usb(ssd1306-example 1)
Expand Down
14 changes: 14 additions & 0 deletions example/acme_5_outlines_font.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#ifndef _acme_font_h
#define _acme_font_h
#include <stdint.h>
#include "font_struct.h"

const uint8_t acme_font[] = {
8, 6, 1, 32, 126,
0x00,0x00,0x00,0x00,0x00,0x00, //
Expand Down Expand Up @@ -97,3 +102,12 @@ const uint8_t acme_font[] = {
0x0f,0x09,0x0d,0x09,0x0b,0x09, // ~
0x00,0x00,0x00,0x00,0x00,0x00
};

const font acme = {
.bitmap_buffer = (const char *)&acme_font[5] ,
.first_char_in_font = 32,
.bytes_per_char = 6,
.char_width = 6,
.char_height = 8,
};
#endif
14 changes: 14 additions & 0 deletions example/bubblesstandard_font.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#ifndef _bubblesstandard_font_h
#define _bubblesstandard_font_h
#include <stdint.h>
#include "font_struct.h"

const uint8_t bubblesstandard_font[] = {
8, 7, 0, 32, 126,
0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
Expand Down Expand Up @@ -97,3 +102,12 @@ const uint8_t bubblesstandard_font[] = {
0x10,0x08,0x08,0x10,0x10,0x08,0x00, // ~
0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

const font bubblesstandard = {
.bitmap_buffer = (const char *)&bubblesstandard_font[5] ,
.first_char_in_font = 32,
.bytes_per_char = 7,
.char_width = 7,
.char_height = 8,
};
#endif
14 changes: 14 additions & 0 deletions example/crackers_font.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#ifndef _crackers_font_h
#define _crackers_font_h
#include <stdint.h>
#include "font_struct.h"

const unsigned char crackers_font[] = {
8, 6, 2, 32, 126,
0x00,0x00,0x00,0x00,0x00,0x00, //
Expand Down Expand Up @@ -97,3 +102,12 @@ const unsigned char crackers_font[] = {
0x04,0x06,0x06,0x02,0x04,0x06, // ~
0x00,0x00,0x00,0x00,0x00,0x00
};

const font crackers = {
.bitmap_buffer = (const char *)&crackers_font[5] ,
.first_char_in_font = 32,
.bytes_per_char = 6,
.char_width = 6,
.char_height = 8,
};
#endif
61 changes: 37 additions & 24 deletions example/example.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
#include "bubblesstandard_font.h"
#include "crackers_font.h"
#include "BMSPA_font.h"
#include "font.h"

const uint8_t num_chars_per_disp[]={7,7,7,5};
const uint8_t *fonts[4]= {acme_font, bubblesstandard_font, crackers_font, BMSPA_font};
const uint8_t *fonts[] = {acme_font, bubblesstandard_font, crackers_font, BMSPA_font};

#define SLEEPTIME 30
#ifdef SSD1306_USE_DMA
CREATE_DISPLAY(128, 64, i2c1, 0x3C, 0, 0, 01) ;
#endif

#define SLEEPTIME 25

void setup_gpios(void);
void animation(void);
Expand All @@ -40,48 +45,56 @@ void setup_gpios(void) {
gpio_pull_up(3);
}

void ssd1306_draw_string(ssd1306_t *disp, uint32_t x, uint32_t y, uint32_t scale, const char *s) {
ssd1306_draw_string_with_font(disp, x, y, scale, font_8x5, s);
}


void animation(void) {
const char *words[]= {"SSD1306", "DISPLAY", "DRIVER"};

ssd1306_t disp;
disp.external_vcc=false;
ssd1306_init(&disp, 128, 64, 0x3C, i2c1);
ssd1306_clear(&disp);
#ifdef SSD1306_USE_DMA
ssd1306_init(&display_01);
#else
ssd1306_t display_01;
display_01.external_vcc=false;
ssd1306_init(&display_01, 128, 64, 0x3C, i2c1);
#endif
ssd1306_clear(&display_01);

printf("ANIMATION!\n");

char buf[8];

for(;;) {
for(int y=0; y<31; ++y) {
ssd1306_draw_line(&disp, 0, y, 127, y);
ssd1306_show(&disp);
ssd1306_draw_line(&display_01, 0, y, 127, y);
ssd1306_show(&display_01);
sleep_ms(SLEEPTIME);
ssd1306_clear(&disp);
ssd1306_clear(&display_01);
}

for(int y=0, i=1; y>=0; y+=i) {
ssd1306_draw_line(&disp, 0, 31-y, 127, 31+y);
ssd1306_draw_line(&disp, 0, 31+y, 127, 31-y);
ssd1306_show(&disp);
ssd1306_draw_line(&display_01, 0, 31-y, 127, 31+y);
ssd1306_draw_line(&display_01, 0, 31+y, 127, 31-y);
ssd1306_show(&display_01);
sleep_ms(SLEEPTIME);
ssd1306_clear(&disp);
ssd1306_clear(&display_01);
if(y==32) i=-1;
}

for(int i=0; i<sizeof(words)/sizeof(char *); ++i) {
ssd1306_draw_string(&disp, 8, 24, 2, words[i]);
ssd1306_show(&disp);
ssd1306_draw_string(&display_01, 8, 24, 2, words[i]);
ssd1306_show(&display_01);
sleep_ms(800);
ssd1306_clear(&disp);
ssd1306_clear(&display_01);
}

for(int y=31; y<63; ++y) {
ssd1306_draw_line(&disp, 0, y, 127, y);
ssd1306_show(&disp);
ssd1306_draw_line(&display_01, 0, y, 127, y);
ssd1306_show(&display_01);
sleep_ms(SLEEPTIME);
ssd1306_clear(&disp);
ssd1306_clear(&display_01);
}

for(size_t font_i=0; font_i<sizeof(fonts)/sizeof(fonts[0]); ++font_i) {
Expand All @@ -95,15 +108,15 @@ void animation(void) {
}
buf[i]=0;

ssd1306_draw_string_with_font(&disp, 8, 24, 2, fonts[font_i], buf);
ssd1306_show(&disp);
ssd1306_draw_string_with_font(&display_01, 8, 24, 2, fonts[font_i], buf);
ssd1306_show(&display_01);
sleep_ms(800);
ssd1306_clear(&disp);
ssd1306_clear(&display_01);
}
}

ssd1306_bmp_show_image(&disp, image_data, image_size);
ssd1306_show(&disp);
ssd1306_bmp_show_image(&display_01, image_data, image_size);
ssd1306_show(&display_01);
sleep_ms(2000);
}
}
1 change: 1 addition & 0 deletions font.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef _inc_font
#define _inc_font
#include <stdint.h>

/*
* Format
Expand Down
14 changes: 14 additions & 0 deletions font_struct.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _font_struct_h
#define _font_struct_h
#include <stdint.h>
/**
* Struct that holds a font and all relevant information
*/
typedef struct {
uint16_t bytes_per_char; // the size of the char sprite in bytes (including padding)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these 16-bit vs the uint8_t they were before? A character greater than 255 doesn't seem likely / useful. Granted the sprite size would be limited to ~45x45 but that doesn't feel very limiting.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the size of the character sprite, so the memory used to store the bitmap of the character. If a font is large, it very well might take more than 255 bytes to store the sprite in. (The display is 128x64 -> 128 x 8 bytes -> 1024 bytes large (which may all be a single char sprite) this means we need more than 255 bytes in extreme cases. Given that the pico can do 32bit load and store and we have plenty of ram i dont think a single byte per font element would matter much.

uint16_t char_width; // width of the caracter in pixels (how many columns the sprite spans)
char first_char_in_font; // the first char that is included in the font
uint16_t char_height; // height of the character in pixels (how many rows the sprite spans)
const char *bitmap_buffer;
} font;
#endif
Loading