71 template<board::DigitalPin, board::DigitalPin, board::DigitalPin>
class LCD5110;
73 template<board::DigitalPin SCE, board::DigitalPin DC, board::DigitalPin RST>
74 struct DisplayDeviceTrait<LCD5110<SCE, DC, RST>> :
75 DisplayDeviceTrait_impl<bool, 84, 48, true, true> {};
115 template<board::DigitalPin SCE, board::DigitalPin DC, board::DigitalPin RST>
class LCD5110 :
116 public spi::SPIDevice<SCE, spi::ChipSelect::ACTIVE_LOW, spi::compute_clockrate(4'000'000UL)>
145 if (bias > MAX_BIAS) bias = MAX_BIAS;
147 send_command_(FUNCTION_SET_MASK | FUNCTION_SET_EXTENDED);
148 send_command_(EXTENDED_SET_BIAS | bias);
149 send_command_(FUNCTION_SET_MASK);
161 if (contrast > MAX_VOP) contrast = MAX_VOP;
163 send_command_(FUNCTION_SET_MASK | FUNCTION_SET_EXTENDED);
164 send_command_(EXTENDED_SET_VOP | contrast);
165 send_command_(FUNCTION_SET_MASK);
179 send_command_(FUNCTION_SET_MASK | FUNCTION_SET_EXTENDED);
180 send_command_(EXTENDED_SET_BIAS | uint8_t(coef));
181 send_command_(FUNCTION_SET_MASK);
190 send_command(FUNCTION_SET_MASK | FUNCTION_SET_POWER_DOWN);
199 send_command(FUNCTION_SET_MASK);
209 send_command(DISPLAY_CONTROL_MASK | DISPLAY_CONTROL_BLANK);
219 send_command(DISPLAY_CONTROL_MASK | DISPLAY_CONTROL_FULL);
228 send_command(DISPLAY_CONTROL_MASK | DISPLAY_CONTROL_INVERSE);
238 send_command(DISPLAY_CONTROL_MASK | DISPLAY_CONTROL_NORMAL);
250 memset(display_, 0,
sizeof(display_));
254 bool set_pixel(uint8_t x, uint8_t y,
const DRAW_CONTEXT& context)
258 const uint8_t r = y / ROW_HEIGHT;
259 const uint8_t offset = y % ROW_HEIGHT;
262 uint8_t* pix_column = get_display(r, c);
264 const bool current = (*pix_column & mask);
265 const bool dest = context.draw_mode().pixel_op(current);
270 if (current)
return false;
275 if (!current)
return false;
276 *pix_column &= uint8_t(~mask);
281 bool is_valid_char_xy(
UNUSED uint8_t x, uint8_t y)
283 return (y % ROW_HEIGHT) == 0;
287 uint8_t write_char(uint8_t x, uint8_t y, uint16_t glyph_ref,
const DRAW_CONTEXT& context)
290 const uint8_t width = context.font().width();
291 uint8_t row = y / ROW_HEIGHT;
292 const uint8_t col = x;
293 bool add_interchar_space = ((col + width + 1) < WIDTH);
295 uint8_t glyph_index = 0;
296 for (uint8_t glyph_row = 0; glyph_row < context.font().glyph_rows(); ++glyph_row)
299 uint8_t* display_ptr = get_display(row, col);
301 for (uint8_t i = 0; i <= width; ++i)
303 const bool space_column = (i == width);
304 uint8_t pixel_bar = 0x00;
306 pixel_bar = context.font().get_char_glyph_byte(glyph_ref, glyph_index);
307 if ((!space_column) || add_interchar_space)
308 *display_ptr = context.draw_mode().bw_pixels_op(pixel_bar, *display_ptr);
316 return width + (add_interchar_space ? 1 : 0);
320 void update(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
322 const uint8_t size = (x2 - x1 + 1);
323 const uint8_t xmin = x1;
324 const uint8_t ymin = y1 / ROW_HEIGHT;
325 const uint8_t ymax = y2 / ROW_HEIGHT;
327 for (uint8_t y = ymin; y <= ymax; ++y)
331 const uint8_t* display = get_display(y, xmin);
340 static constexpr uint8_t ROW_HEIGHT = 8;
343 static constexpr uint8_t FUNCTION_SET_MASK =
bits::BV8(5);
344 static constexpr uint8_t FUNCTION_SET_POWER_DOWN =
bits::BV8(2);
345 static constexpr uint8_t FUNCTION_SET_EXTENDED =
bits::BV8(0);
347 static constexpr uint8_t EXTENDED_SET_BIAS =
bits::BV8(4);
348 static constexpr uint8_t EXTENDED_SET_VOP =
bits::BV8(7);
350 static constexpr uint8_t DISPLAY_CONTROL_MASK =
bits::BV8(3);
351 static constexpr uint8_t DISPLAY_CONTROL_BLANK = 0;
352 static constexpr uint8_t DISPLAY_CONTROL_NORMAL =
bits::BV8(2);
353 static constexpr uint8_t DISPLAY_CONTROL_FULL =
bits::BV8(0);
354 static constexpr uint8_t DISPLAY_CONTROL_INVERSE =
bits::BV8(0, 2);
356 static constexpr uint8_t SET_ROW_ADDRESS =
bits::BV8(6);
357 static constexpr uint8_t SET_COL_ADDRESS =
bits::BV8(7);
360 static constexpr uint8_t MAX_BIAS = 0x07;
361 static constexpr uint8_t DEFAULT_BIAS = 0x04;
362 static constexpr uint8_t MAX_VOP = 0x7F;
363 static constexpr uint8_t DEFAULT_VOP = 40;
365 void send_command_(uint8_t command)
371 void send_command(uint8_t command)
374 send_command_(command);
378 void set_rc_(uint8_t r, uint8_t c)
381 this->
transfer(r | SET_ROW_ADDRESS);
382 this->
transfer(c | SET_COL_ADDRESS);
387 uint8_t* get_display(uint8_t r, uint8_t c)
389 return &display_[r * WIDTH + c];
391 const uint8_t* get_display(uint8_t r, uint8_t c)
const
393 return &display_[r * WIDTH + c];
401 uint8_t display_[HEIGHT * WIDTH / ROW_HEIGHT];
Drawing Context passed to display devices low-level primitives set_pixel() and write_char().
SPI device driver for Nokia 5110 display chip.
void reset()
Reset PCD8544 chip and Nokia 5110 display.
void set_temperature_control(TemperatureCoefficient coef)
Set temperature coefficient for Nokia5110 display.
void invert()
Invert Nokia5110 LCD display.
void full()
Blacken Nokia5110 LCD display.
void power_down()
Set Nokia5110 display to power down mode.
void normal()
Set Nokia5110 LCD display to normal mode.
void blank()
Blank Nokia5110 LCD display.
void set_display_bias(uint8_t bias=DEFAULT_BIAS)
Set bias for Nokia5110 LCD display.
void power_up()
Set Nokia5110 display to power up mode.
void set_display_contrast(uint8_t contrast=DEFAULT_VOP)
Set contrast for Nokia5110 LCD display.
static void set()
Set pin level to HIGH (i.e.
static void set_mode(PinMode mode, bool value=false)
Set mode (direction) and value (if output) of DPIN.
uint8_t transfer(uint8_t data)
Transfer one byte to the currently selected SPI slave device through MOSI pin, and get the byte retur...
Base class for any SPI slave device.
void start_transfer()
Start an SPI transfer to this device.
void end_transfer() INLINE
End the current SPI ransfer tot hsi device.
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Generic API to handle any display device (e.g.
Generic API to handle Character Fonts for any display device.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Defines generic API for all display devices.
TemperatureCoefficient
Possible temperature coeeficient that can be set on Nokia5110 display.
@ TC0_1mV_K
TC0 Temperature coefficient 1mV/K
@ TC2_17mV_K
TC0 Temperature coefficient 17mV/K
@ TC1_9mV_K
TC0 Temperature coefficient 9mV/K
@ TC3_24mV_K
TC0 Temperature coefficient 24mV/K
typename FastPinType< DPIN_ >::TYPE FAST_PIN
Useful alias type to the FastPin type matching a given board::DigitalPin.
@ OUTPUT
Digital pin is configured as output.
void delay_us(uint16_t us) INLINE
Delay program execution for the given amount of microseconds.
Traits for display devices.
static constexpr uint8_t WIDTH
The width in pixels of DEVICE.
static constexpr uint8_t HEIGHT
The height in pixels of DEVICE.