4747//| objects in CircuitPython, Display objects live until `displayio.release_displays()`
4848//| is called. This is done so that CircuitPython can use the display itself.
4949//|
50+ //| Most people should not use this class directly. Use a specific display driver instead that will
51+ //| contain the initialization sequence at minimum.
52+ //|
5053//| .. warning:: This will be changed before 4.0.0. Consider it very experimental.
5154//|
52- //| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c)
55+ //| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None )
5356//|
5457//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
5558//|
56- //| The ``init_sequence`` is bitbacked to minimize the ram impact. Every command begins with a
59+ //| The ``init_sequence`` is bitpacked to minimize the ram impact. Every command begins with a
5760//| command byte followed by a byte to determine the parameter count and if a delay is need after.
5861//| When the top bit of the second byte is 1, the next byte will be the delay time in milliseconds.
5962//| The remaining 7 bits are the parameter count excluding any delay byte. The third through final
7376//| (b"") are merged together on load. The parens are needed to allow byte literals on subsequent
7477//| lines.
7578//|
79+ //| The initialization sequence should always leave the display memory access inline with the scan
80+ //| of the display to minimize tearing artifacts.
81+ //|
7682//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to
7783//| :param buffer init_sequence: Byte-packed initialization sequence.
7884//| :param int width: Width in pixels
7985//| :param int height: Height in pixels
8086//| :param int colstart: The index if the first visible column
8187//| :param int rowstart: The index if the first visible row
88+ //| :param int rotation: The rotation of the display in 90 degree increments
8289//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays
8390//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
8491//| :param int set_column_command: Command used to set the start and end columns to update
8592//| :param int set_row_command: Command used so set the start and end rows to update
8693//| :param int write_ram_command: Command used to write pixels values into the update region
94+ //| :param int set_vertical_scroll: Command used to set the first row to show
8795//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight
8896//|
8997STATIC mp_obj_t displayio_display_make_new (const mp_obj_type_t * type , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
90- enum { ARG_display_bus , ARG_init_sequence , ARG_width , ARG_height , ARG_colstart , ARG_rowstart , ARG_color_depth , ARG_set_column_command , ARG_set_row_command , ARG_write_ram_command , ARG_backlight_pin };
98+ enum { ARG_display_bus , ARG_init_sequence , ARG_width , ARG_height , ARG_colstart , ARG_rowstart , ARG_rotation , ARG_color_depth , ARG_set_column_command , ARG_set_row_command , ARG_write_ram_command , ARG_set_vertical_scroll , ARG_backlight_pin };
9199 static const mp_arg_t allowed_args [] = {
92100 { MP_QSTR_display_bus , MP_ARG_REQUIRED | MP_ARG_OBJ },
93101 { MP_QSTR_init_sequence , MP_ARG_REQUIRED | MP_ARG_OBJ },
94102 { MP_QSTR_width , MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED , },
95103 { MP_QSTR_height , MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED , },
96104 { MP_QSTR_colstart , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
97105 { MP_QSTR_rowstart , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
106+ { MP_QSTR_rotation , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0 } },
98107 { MP_QSTR_color_depth , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 16 } },
99108 { MP_QSTR_set_column_command , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0x2a } },
100109 { MP_QSTR_set_row_command , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0x2b } },
101110 { MP_QSTR_write_ram_command , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0x2c } },
111+ { MP_QSTR_set_vertical_scroll , MP_ARG_INT | MP_ARG_KW_ONLY , {.u_int = 0x0 } },
102112 { MP_QSTR_backlight_pin , MP_ARG_OBJ | MP_ARG_KW_ONLY , {.u_obj = mp_const_none } },
103113 };
104114 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
@@ -116,6 +126,10 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
116126 backlight_pin = MP_OBJ_TO_PTR (backlight_pin_obj );
117127 assert_pin_free (backlight_pin );
118128 }
129+ mp_int_t rotation = args [ARG_rotation ].u_int ;
130+ if (rotation % 90 != 0 ) {
131+ mp_raise_ValueError (translate ("Display rotation must be in 90 degree increments" ));
132+ }
119133
120134 displayio_display_obj_t * self = NULL ;
121135 for (uint8_t i = 0 ; i < CIRCUITPY_DISPLAY_LIMIT ; i ++ ) {
@@ -130,9 +144,11 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
130144 }
131145 self -> base .type = & displayio_display_type ;
132146 common_hal_displayio_display_construct (self ,
133- display_bus , args [ARG_width ].u_int , args [ARG_height ].u_int , args [ARG_colstart ].u_int , args [ARG_rowstart ].u_int ,
147+ display_bus , args [ARG_width ].u_int , args [ARG_height ].u_int , args [ARG_colstart ].u_int , args [ARG_rowstart ].u_int , rotation ,
134148 args [ARG_color_depth ].u_int , args [ARG_set_column_command ].u_int , args [ARG_set_row_command ].u_int ,
135- args [ARG_write_ram_command ].u_int , bufinfo .buf , bufinfo .len , MP_OBJ_TO_PTR (backlight_pin ));
149+ args [ARG_write_ram_command ].u_int ,
150+ args [ARG_set_vertical_scroll ].u_int ,
151+ bufinfo .buf , bufinfo .len , MP_OBJ_TO_PTR (backlight_pin ));
136152
137153 return self ;
138154}
0 commit comments