Class: Denko::Display::SSD168X

Inherits:
Object
  • Object
show all
Includes:
Behaviors::Lifecycle, SPIEPaperCommon
Defined in:
lib/denko/display/ssd168x.rb

Direct Known Subclasses

SSD1680, SSD1681

Constant Summary collapse

RESET_TIME =

Used by #hw_reset

0.010
SW_RESET =

Typical Commands

0x12
DRIVER_OUTPUT_CTL =

+3 data

0x01
DATA_ENTRY_MODE_SET =

+1 data

0x11
BORDER_WAVEFORM_CTL =

+1 data

0x3C
DISPLAY_UPDATE_CTL1 =

+1 data

0x21
TEMP_SENSOR_SELECT =

+1 data

0x18
RAM_X_RANGE_SET =

+2 data. X address range to stay within.

0x44
RAM_Y_RANGE_SET =

+4 data. Y address range to stay within.

0x45
RAM_X_ADDR_SET =

+1 data. X start address

0x4E
RAM_Y_ADDR_SET =

+2 data. Y start address

0x4F
RAM_WRITE_BW =

write n pixel data bytes after

0x24
RAM_WRITE_RED =

write n pixel data bytes after

0x26
MASTER_ACTIVATION =
0x20
DISPLAY_UPDATE_CTL2 =

+1 data

0x22
DEEP_SLEEP =

+1 data

0x10
BOOSTER_CTL =

+4 data

0x0C
RAM_AUTO_INC_BW =

Other commands taken from data sheet. Not used yet. Maybe for enabling more features in future?

0x46
RAM_AUTO_INC_RED =

+1 data. This sets the auto-increment amount?

0x47
READ_RAM =

+1 data. This sets the auto-increment amount?

0x27
GATE_VOLTAGE_CTL =

read n pixel data bytes after

0x03
SOURCE_VOLTAGE_CTL =

+1 data

0x04
INITIAL_CODE_OTP =

+3 data

0x08
INITIAL_CODE_REG_SET =

???

0x08
INITIAL_CODE_REG_GET =

+3 data

0x0A
HV_READY_DETECTION =

Read 3 bytes back? Datasheet not clear.

0x14
VCI_DETECTION =

+1 data

0x15
TEMP_SENSOR_REG_SET =

+1 data

0x1A
TEMP_SENSOR_REG_GET =

+2 data

0x1B
TEMP_SENSOR_CTL =

+2 data READ

0x1C
VCOM_SENSE =

+3 data

0x28
VCOM_SENS_DURATION =

+1 data

0x29
PROGRAM_VCOM_OTP =

+1 data

0x2A
VCOM_REG_CTL =

+2 data

0x2B
VCOM_REG_WRITE =

+1 data

0x2C
OTP_REG_GET =

+11 data READ

0x2D
USER_ID_GET =

+10 data READ

0x2E
STATUS_BIT_GET =

+1 data READ

0x2F
PROGRAM_WS_OTP =
0x30
LOAD_WS_OTP =
0x31
WRITE_LUT_REGISTER =

+153 data

0x32
CRC_CALCULATION =
0x34
CRC_STATUS_GET =

+2 data READ

0x35
PROGRAM_OTP_SELECTION =
0x36
DISPLAY_OPTION_REG_SET =

+10 data

0x37
USER_ID_REG_SET =

+10 data

0x38
OTP_PROGRAM_MODE =

+1 data

0x39
END_OPTION =

+1 data

0x3F
READ_RAM_OPTION =

+1 data

0x41
NOP =
0x7F

Constants included from SPIEPaperCommon

Denko::Display::SPIEPaperCommon::BUSY_WAIT_TIME

Constants included from Behaviors::Lifecycle

Behaviors::Lifecycle::CALLBACK_METHODS

Instance Attribute Summary

Attributes included from SPI::Peripheral

#spi_bit_order, #spi_frequency, #spi_mode

Attributes included from Behaviors::State

#state

Attributes included from Behaviors::Component

#board, #params

Attributes included from Behaviors::MultiPin

#pin, #pins, #proxies

Instance Method Summary collapse

Methods included from SPIEPaperCommon

#busy_wait, #hw_reset, #initialize_pins

Methods included from SPICommon

#command, #data, #initialize_pins, #transfer_limit

Methods included from PixelCommon

#canvas, #colors, #columns, #draw, #get_partial_buffer, #p_max, #p_min, #rows, #x_max, #x_min, #y_max, #y_min

Methods included from SPI::Peripheral

#ensure_byte_array, #initialize_pins, #proxy_pin, #spi_listen, #spi_read, #spi_stop, #spi_transfer, #spi_write, #update

Methods included from Behaviors::Lifecycle

included

Methods included from Behaviors::Callbacks

#add_callback, #callbacks, #pre_callback_filter, #remove_callback, #update

Methods included from Behaviors::State

#update_state

Methods included from Behaviors::BusPeripheral

#atomically

Methods included from Behaviors::Component

#initialize, #micro_delay

Methods included from Behaviors::MultiPin

#convert_pins, #proxy_pin, #proxy_states, #require_pin, #require_pins

Instance Method Details

#booster_soft_startObject



152
153
154
155
156
157
158
159
160
# File 'lib/denko/display/ssd168x.rb', line 152

def booster_soft_start
  command [BOOSTER_CTL]
  data [
    0b1010_0011, # phase 1
    0b1100_0111, # phase 2
    0b1100_0011, # phase 3
    0b0000_0001, # duration
  ]
end

#deep_sleep(sleep_mode = 0b11) ⇒ Object



166
167
168
169
170
171
172
# File 'lib/denko/display/ssd168x.rb', line 166

def deep_sleep(sleep_mode=0b11)
  # 0b00 = Normal Mode
  # 0b01 = Deep Sleep Mode 1
  # 0b11 = Deep Sleep Mode 2
  command [DEEP_SLEEP]
  data    [sleep_mode]
end

#draw_partial(buffer, x_start, x_finish, p_start, p_finish, color = 1) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/denko/display/ssd168x.rb', line 194

def draw_partial(buffer, x_start, x_finish, p_start, p_finish, color=1)
  partial_buffer = get_partial_buffer(buffer, x_start, x_finish, p_start, p_finish)

  # These displays treat bit 7 of a byte as the top pixel, but canvas uses bit 0 as top.
  # Bytes are sent reversed to fix this, essentially rotating the image by 180 degrees byte-wise.
  # Transform framebuffer coordinates to rotated hardware coordinates before sending.
  x1 = x_max - x_finish
  x2 = x_max - x_start
  p1 = p_max - p_finish
  p2 = p_max - p_start

  # Set hardware addresses
  set_range_x x1, x2
  set_range_p p1, p2
  set_address_x x1
  set_address_p p1

  # Send as black by default, or red if specified
  ram_select = (color == 2) ? RAM_WRITE_RED : RAM_WRITE_BW
  command [ram_select]
  partial_buffer.reverse.each_slice(transfer_limit) { |slice| data(slice) }
end

#invert_blackObject



141
142
143
# File 'lib/denko/display/ssd168x.rb', line 141

def invert_black
  @invert_black = !@invert_black
end

#master_activateObject



162
163
164
# File 'lib/denko/display/ssd168x.rb', line 162

def master_activate
  command [MASTER_ACTIVATION]
end

#reflect_xObject



81
82
83
# File 'lib/denko/display/ssd168x.rb', line 81

def reflect_x
  @reflect_x = !@reflect_x
end

#refreshObject



217
218
219
220
221
222
223
224
# File 'lib/denko/display/ssd168x.rb', line 217

def refresh
  booster_soft_start
  set_driver_output_control
  set_display_update_control
  set_display_update_sequence(0xF7)
  master_activate
  busy_wait
end

#set_address_p(addr = p_min) ⇒ Object



110
111
112
113
# File 'lib/denko/display/ssd168x.rb', line 110

def set_address_p(addr=p_min)
  command [RAM_X_ADDR_SET]
  data    [addr]
end

#set_address_x(addr = x_min) ⇒ Object



105
106
107
108
# File 'lib/denko/display/ssd168x.rb', line 105

def set_address_x(addr=x_min)
  command [RAM_Y_ADDR_SET]
  data    [addr & 0xFF, (addr >> 8) & 0b1]
end

#set_data_entry_modeObject



85
86
87
88
89
90
91
92
# File 'lib/denko/display/ssd168x.rb', line 85

def set_data_entry_mode
  # Bit 2 = 1 : update hardware Y (software X) address first (after each byte),
  # then update hardware X (software P) on overflow. (0 would update hardware X / software P first)
  # Bit 1 = 1 : increment hardware Y (0 would decrement)
  # Bit 0 = 1 : increment hardware X (0 would decrement)
  command [DATA_ENTRY_MODE_SET]
  data    [0b111]
end

#set_display_update_controlObject



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/denko/display/ssd168x.rb', line 127

def set_display_update_control
  # In hardware:
  #   0b1000: display inverted
  #   0b0100: bypass
  #   0b0000: display normally
  #
  # For black only, hardware treats 1 as blank, 0 as filled. Opposite of Canvas.
  black = @invert_black ? 0b0000 : 0b1000
  red   = (colors == 1) ? 0b0100 : 0b0000

  command [DISPLAY_UPDATE_CTL1]
  data    [red << 4 | black]
end

#set_display_update_sequence(value = 0x80) ⇒ Object



145
146
147
148
149
150
# File 'lib/denko/display/ssd168x.rb', line 145

def set_display_update_sequence(value=0x80)
  # 0x80 enables clock signal without loading pixels from RAM
  # 0xF7 refreshes all pixels from RAM
  command [DISPLAY_UPDATE_CTL2]
  data    [value]
end

#set_driver_output_control(gate_lines = columns) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/denko/display/ssd168x.rb', line 66

def set_driver_output_control(gate_lines=columns)
  # First data byte is lowest 8 bits of MUX value.
  # Second data byte is 9th bit.
  mux = gate_lines - 1

  # Third byte:
  #   Bit 2: toggles gate scan interleave order
  #   Bit 1: enables gate scan interleaving
  #   Bit 0: flips gate scan direction, mirroring display in 1 axis
  third_byte = @reflect_x ? 0b000 : 0b001

  command [DRIVER_OUTPUT_CTL]
  data    [mux & 0xFF, (mux >> 8) & 0b1, third_byte]
end

#set_panel_borderObject



115
116
117
118
119
# File 'lib/denko/display/ssd168x.rb', line 115

def set_panel_border
  # Default to GS Transition: Follow LUT and LUT1, and VBD fix level: VSS.
  command [BORDER_WAVEFORM_CTL]
  data    [0b00_00_00_01]
end

#set_range_p(start = p_min, finish = p_max) ⇒ Object



100
101
102
103
# File 'lib/denko/display/ssd168x.rb', line 100

def set_range_p(start=p_min, finish=p_max)
  command [RAM_X_RANGE_SET]
  data    [start, finish]
end

#set_range_x(start = x_min, finish = x_max) ⇒ Object

Treating hardware X axis as page (P) axis, and hardware Y axis as X axis to match framebuffer.



95
96
97
98
# File 'lib/denko/display/ssd168x.rb', line 95

def set_range_x(start=x_min, finish=x_max)
  command [RAM_Y_RANGE_SET]
  data    [start & 0xFF, (start >> 8) & 0b1, finish & 0xFF, (finish >> 8) & 0b1]
end

#set_temperature_sensorObject



121
122
123
124
125
# File 'lib/denko/display/ssd168x.rb', line 121

def set_temperature_sensor
  # Use internal temperature sensor
  command [TEMP_SENSOR_SELECT]
  data [0x80]
end

#wakeObject



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/denko/display/ssd168x.rb', line 174

def wake
  hw_reset
  command [SW_RESET]
  sleep 0.020

  set_driver_output_control
  set_data_entry_mode
  set_temperature_sensor
  set_panel_border

  set_display_update_control
  set_display_update_sequence
  master_activate
  busy_wait
end