diff --git a/README.md b/README.md index 101ff21..ac57f1f 100644 --- a/README.md +++ b/README.md @@ -71,4 +71,5 @@ then take a look at the [known issues document](doc/known_issues.md). * [Configuration_guide](doc/configuration.md) * [Flashing guide](doc/flashing.md) * [Known issues](doc/known_issues.md) +* [Hardware information](doc/hardware.md) * [Sponsoring](doc/sponsoring.md) diff --git a/doc/hardware.md b/doc/hardware.md new file mode 100644 index 0000000..10eddda --- /dev/null +++ b/doc/hardware.md @@ -0,0 +1,244 @@ +< [Known issues](known_issues.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) > + +# Hardware information + +In this section, you can find some of the information that was gathered +during the reverse engineering of the Bedside Lamp 2 hardware. + +Table of contents: + +* [High level overview](#high-level-overview) +* [ESP32 pinout](#esp32-pinout) +* [Front panel](#front-panel) + + +## High level overview + +No documentation is complete without some ASCII art schematics. + +``` + RX/TX/GND for + 12V power supply flashing and logs + | | + v | Front panel + +---------------+ +---------------+ .---. + | Power supply |---- 3.3V -.----->| ESP-WROOM-32D | | O | -- color + +---------------+ \ | single core | | | button + | \ | 4 MB flash | | | | + 12V \ +---------------+ | | | + | \ | ^ | | | | -- slider + | `------|--|--|--- 3.3V ---->| | | + | | | | | | | + v | | +--- I2C ------| | | + +---------------+ | | | | | + | RGB and white |<---- RGBW + master ---+ +------ IRQ ------| | power + | LED circuitry | PWM on/off | O | -- button + +---------------+ `---` +``` + +The LED circuitry provides two light modes: + +* Colored RGB light; +* Warm to cool white light. + +The front panel of the device contains a two touch buttons (power on/off and +color selection) and a touch slider (for setting the brightness level). This +panel is lit when the device is turned on. The light behind the slider will +represent the actual brightness setting of the device. + + +## ESP32 pinout + +In the following image, you can find the pinout as used for the ESP32: + + + +Here's an overview of all exposed pins of the chip, starting at the GND + +3.3V pins, and going anti-clockwise. The table shows not only the functions +of the pins that are actually in use by the lamp's circuitry, but also the +pins that are not in use and their possible applications. + +| PIN | GPIO# | Function | Description | Possible use | +|------|--------|-----------|--------------------------------|--------------| +| GND | | Ground | Connected to ground | - | +| 3.3V | | Power | Power supply input | - | +| 9 | | Reset | Can be pulled to GND to reset | - | +| 5 | GPIO36 | - | | I | +| 8 | GPIO39 | - | | I | +| 10 | GPIO34 | - | | I | +| 11 | GPIO35 | - | | I | +| 12 | GPIO32 | - | | I/O | +| 13 | GPIO33 | LEDs | LEDs, master switch 1 | - | +| 14 | GPIO25 | ??? | 10k pull up, unknown function | I/O (1) | +| 15 | GPIO26 | - | | I/O | +| 16 | GPIO27 | - | | I/O | +| 17 | GPIO14 | LEDs | LEDs, green PWM channel | - | +| 18 | GPIO12 | LEDs | LEDs, white PWM channel | - | +| GND | | Ground | Connected to ground | - | +| 20 | GPIO13 | LEDs | LEDs, red PWM channel | - | +| 28 | GPIO9 | SPI | SPI flash memory | - | +| 29 | GPIO10 | SPI | SPI flash memory | - | +| 30 | GPIO11 | SPI | SPI flash memory | - | +| 31 | GPIO6 | SPI | SPI flash memory | - | +| 32 | GPIO7 | SPI | SPI flash memory | - | +| 33 | GPIO8 | SPI | SPI flash memory | - | +| 21 | GPIO15 | - | | I/O (2) | +| 22 | GPIO2 | ??? | Debug pad, unknown function | I/O (3) | +| 23 | GPIO0 | Boot mode | Pull to GND for flashing mode | - | +| 24 | GPIO4 | LEDs | LEDs, master switch 2 | - | +| 25 | GPIO16 | Front pnl | Front panel interrupt | - | +| 27 | GPIO17 | EEPROM | EEPROM I2C SDA (4) | - | +| 34 | GPIO5 | LEDs | LEDs, blue PWM channel | - | +| 35 | GPIO18 | EEPROM | EEPROM I2C CLK (4) | - | +| 38 | GPIO19 | Front pnl | Front panel I2C SCL | - | +| N/C | | | | | +| 42 | GPIO21 | Front pnl | Front panel I2C SDA | - | +| 40 | GPIO3 | Serial | Debug pad, RX (flashing, logs) | - | +| 41 | GPIO1 | Serial | Debug pad, TX (flashing, logs) | - | +| 39 | GPIO22 | - | | I/O | +| 36 | GPIO23 | - | | I/O | +| GND | | Ground | Connected to ground | - | + +1. GPIO25 is connected to a 10k pull up resistor. This suggests that it + might have some function in the lamp, but I have not found that function + yet. If you find the actual use for this pin, or find that you can indeed + repurpose it, then please let me know. +1. Beware that GPIO15 outputs a PWM signal at boot. This might make the pin + less useful for your use case. +1. Often, GPIO2 is used for an on-board LED, but it looks like it is only + connected to the debug pad here. I think the pin is usable, and that it + might only be used for testing purposes in the original firmware. +1. The connected IC, using I2C address 0x10, looks a lot like an EEPROM, + but this has yet to be confirmed. It uses a decicated I2C bus, separate + from the I2C bus of the front panel. + [This picture](images/hardware/IC_on_I2C_GPIO1718.jpg) shows the IC. + +For more information on the use of pins on the ESP32 chip, please check out +this [ESP32 pinout reference information](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/). + + +## Front panel + + + +The front panel is a stand-alone component, with its own control chip +(KungFu KF8TS2716). Communication between the ESP32 and the front panel +is done using: + +- **An I2C bus** + - the front panel is the I2C slave, the ESP32 is the I2C master + (pardon the standard terminology, I am aware of the controversy) + - the front panel device ID is 0x2C + - SDA is connected to ESP32 pin GPIO21 + - SCL is connected to ESP32 pin GPIO19 +- **An interrupt data line to signal the ESP32 about new events** + - this line is connected to ESP32 pin GPIO16 + - the default state is HIGH + - line is pulled LOW for at least 6 ms when a new event is available + +Commands can be written to and data can be read from the front panel +component using I2C. The I2C protocol is fairly simple. All read and write +operations uses 6 bytes of data. No register selection is done before +reading or writing. + +The interrupt data line is used by the front panel, to signal the ESP32 that +a new button or slider event is available. Further details on this can be +found below. + +**Connection to the main board** + +The front panel is connected to the main board using a flat cable. +The picture below shows the connector on the main board, including the +functions of the cable pins: + + + +**Writing commands to the front panel** + +Commands can be written to the front panel at any time. + +The available commands are: + +| Command | Byte sequence to send | +|-------------------|-----------------------| +| `TURN PANEL ON` | 02 03 5E 00 64 00 00 | +| `TURN PANEL OFF` | 02 03 0C 00 64 00 00 | +| `SET LEVEL 1` | 02 03 5E 00 64 00 00 | +| `SET LEVEL 2` | 02 03 5F 00 64 00 00 | +| `SET LEVEL 3` | 02 03 5F 80 64 00 00 | +| `SET LEVEL 4` | 02 03 5F C0 64 00 00 | +| `SET LEVEL 5` | 02 03 5F E0 64 00 00 | +| `SET LEVEL 6` | 02 03 5F F0 64 00 00 | +| `SET LEVEL 7` | 02 03 5F F8 64 00 00 | +| `SET LEVEL 8` | 02 03 5F FC 64 00 00 | +| `SET LEVEL 9` | 02 03 5F FE 64 00 00 | +| `SET LEVEL 10` | 02 03 5F FF 64 00 00 | +| `READY FOR EVENT` | 01 00 00 00 00 00 01 | + +*Note: The `READY FOR EVENT` command is only used when a new event is provided +by the front panel. Information about this command can be found in the next +section.* + +**Reading events from the front panel** + +The types of events that can occur can be summarized as: + +- Touch or release the power button +- Touch or release the color button +- Touch or release the slider at a certain level + +Because the front panel is an I2C slave device, it cannot contact the ESP32 via +I2C. Only an I2C master device can initiate communication. Therefore, when the +front panel has a new event available, it will pull down the interrupt line for +a short period of time, to signal the ESP32 about this new event. + +*Note that the ESP32 needs to poll the interrupt line at least at 667 Hz to be +able to trustworthy detect the 6 ms signal. Unfortunately, the interrupt line +does not wait for the ESP32 to respond to its signalling. The best way to +handle signals from this line, is to use an actual interrupt handler.* + +After detecting this signal, the ESP32 must first write the "READY FOR EVENT" +command (`01 00 00 00 00 00 01`) via I2C to the front panel. + +After the front panel has ACK'ed this command, the ESP32 can read 6 bytes, +which will represent the event that occurred. + +Here's the mapping for the events and their corresponding byte sequences: + +| | Touch event | Release event | +|-----------------|----------------------|----------------------| +| POWER BUTTON | 04 04 01 00 01 01 03 | 04 04 01 00 01 02 04 | +| COLOR BUTTON | 04 04 01 00 02 01 04 | 04 04 01 00 02 02 05 | +| SLIDER LEVEL 1 | 04 04 01 00 03 16 1A | 04 04 01 00 04 16 1B | +| SLIDER LEVEL 2 | 04 04 01 00 03 15 19 | 04 04 01 00 04 15 1A | +| SLIDER LEVEL 3 | 04 04 01 00 03 14 18 | 04 04 01 00 04 14 19 | +| SLIDER LEVEL 4 | 04 04 01 00 03 13 17 | 04 04 01 00 04 13 18 | +| SLIDER LEVEL 5 | 04 04 01 00 03 12 16 | 04 04 01 00 04 12 17 | +| SLIDER LEVEL 6 | 04 04 01 00 03 11 15 | 04 04 01 00 04 11 16 | +| SLIDER LEVEL 7 | 04 04 01 00 03 10 14 | 04 04 01 00 04 10 15 | +| SLIDER LEVEL 8 | 04 04 01 00 03 0F 13 | 04 04 01 00 04 0F 14 | +| SLIDER LEVEL 9 | 04 04 01 00 03 0E 12 | 04 04 01 00 04 0E 13 | +| SLIDER LEVEL 10 | 04 04 01 00 03 0D 11 | 04 04 01 00 04 0D 12 | +| SLIDER LEVEL 11 | 04 04 01 00 03 0C 10 | 04 04 01 00 04 0C 11 | +| SLIDER LEVEL 12 | 04 04 01 00 03 0B 0F | 04 04 01 00 04 0B 10 | +| SLIDER LEVEL 13 | 04 04 01 00 03 0A 0E | 04 04 01 00 04 0A 0F | +| SLIDER LEVEL 14 | 04 04 01 00 03 09 0D | 04 04 01 00 04 09 0E | +| SLIDER LEVEL 15 | 04 04 01 00 03 08 0C | 04 04 01 00 04 08 0D | +| SLIDER LEVEL 16 | 04 04 01 00 03 07 0B | 04 04 01 00 04 07 0C | +| SLIDER LEVEL 17 | 04 04 01 00 03 06 0A | 04 04 01 00 04 06 0B | +| SLIDER LEVEL 18 | 04 04 01 00 03 05 09 | 04 04 01 00 04 05 0A | +| SLIDER LEVEL 19 | 04 04 01 00 03 04 08 | 04 04 01 00 04 04 09 | +| SLIDER LEVEL 20 | 04 04 01 00 03 03 07 | 04 04 01 00 04 03 08 | +| SLIDER LEVEL 21 | 04 04 01 00 03 02 06 | 04 04 01 00 04 02 07 | +| SLIDER LEVEL 22 | 04 04 01 00 03 01 05 | 04 04 01 00 04 01 06 | + +**Behavior when more events come in than can be handled** + +The front panel does not queue events. When a new event occurs, before the +previous event has be read by the ESP32, the new event will replace the old +event and a new signal is sent over the interrupt line. + +The ESP32 can read the last event multiple times. It will not be cleared +by the front panel after reading it. + +< [Known issues](known_issues.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) > diff --git a/doc/images/hardware/ESP32_pinout.jpg b/doc/images/hardware/ESP32_pinout.jpg new file mode 100755 index 0000000..131ab01 Binary files /dev/null and b/doc/images/hardware/ESP32_pinout.jpg differ diff --git a/doc/images/hardware/IC_on_I2C_GPIO1718.jpg b/doc/images/hardware/IC_on_I2C_GPIO1718.jpg new file mode 100755 index 0000000..2151a7b Binary files /dev/null and b/doc/images/hardware/IC_on_I2C_GPIO1718.jpg differ diff --git a/doc/images/hardware/esp-wroom-32d.jpg b/doc/images/hardware/esp-wroom-32d.jpg new file mode 100755 index 0000000..2da5af1 Binary files /dev/null and b/doc/images/hardware/esp-wroom-32d.jpg differ diff --git a/doc/images/hardware/front_panel.jpg b/doc/images/hardware/front_panel.jpg new file mode 100755 index 0000000..de7589f Binary files /dev/null and b/doc/images/hardware/front_panel.jpg differ diff --git a/doc/images/hardware/front_panel_flat_cable_connection.jpg b/doc/images/hardware/front_panel_flat_cable_connection.jpg new file mode 100755 index 0000000..1e7aabe Binary files /dev/null and b/doc/images/hardware/front_panel_flat_cable_connection.jpg differ diff --git a/doc/known_issues.md b/doc/known_issues.md index 5e772a5..0c36813 100644 --- a/doc/known_issues.md +++ b/doc/known_issues.md @@ -1,4 +1,4 @@ -< [Flashing guide](flashing.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) > +< [Flashing guide](flashing.md) | [Index](../README.md) | [Hardware information](hardware.md) > # Known issues @@ -83,4 +83,4 @@ the ESP32. For this reason, I advise to completely omit logging or use a very low log level for production purposes. -< [Flashing guide](flashing.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) > +< [Flashing guide](flashing.md) | [Index](../README.md) | [Hardware information](hardware.md) > diff --git a/doc/sponsoring.md b/doc/sponsoring.md index 86d9889..a11cf43 100644 --- a/doc/sponsoring.md +++ b/doc/sponsoring.md @@ -1,4 +1,4 @@ -< [Known issues](known_issues.md) | [Index](../README.md) +< [Hardware information](hardware.md) | [Index](../README.md) # Sponsoring the project @@ -18,4 +18,4 @@ this project were: the I2C protocol of the front panel. * Various wires and buttons. -< [Known issues](known_issues.md) | [Index](../README.md) +< [Hardware information](hardware.md) | [Index](../README.md)