.. so they need a correct row count, which could be the "core.width"
of a 90/180 rotated display.
While I discovered this on the very unusual 320x960 display it could have
affected any framebuffer display that was taller than it was wide,
including sharp memory displays and rgbmatrix displays.
* can now send the I2C bus initialization code
* can now reset the display on an I/O expander pin
* parameters re-ordered to enable easy use with **board.TFT_IO_EXPANDER
with the i2c bus operating at 400kHz this achieves a 4.8kHz SPI clock
rate which could be worse.
It accepts the same style of init sequence as displayio.
tested by scoping the pins on the espressif lcd dev kit with a dummy init sequence:
```python
dotclockframebuffer.ioexpander_send_init_sequence(
bus=bus,
i2c_address=expander_addr,
gpio_address=1,
gpio_data_len=1,
gpio_data=0xff,
cs_bit=1,
mosi_bit=3,
clk_bit=2,
init_sequence=init_sequence)
```
We use it to open endpoints as they are used. Fetching the descriptor
as needed can cause issues with devices that we're expecting a control
packet while another transaction was ongoing. Specifically, a usb
thumb drive didn't expect a control transaction while doing a SCSI
transaction.
This PR also aborts transactions on timeout or ctrl-c interrupt. It
doesn't always recover though...
1. Raise an exception when creating a USB device when host isn't
initialized.
2. Mark RP2040 dtcm_bss as NOLOAD since it doesn't need to be
loaded (just zeroed.)
3. Fix submodule location for ulab to Jeff's copy.
This enables the specific use case of checking whether a note's release
phase has ended, but is also potentially useful to implement a sort of
"voice stealing" algorithm in Python code, which can take account of
the note's envelope state as well as other factors specific to the
program.