|
@@ -52,10 +52,10 @@ The LCD is detected at boot via the return value of `lcd.begin(20, 4)` (hd44780
|
|
|
|
|
|
|
|
## I²C Addresses
|
|
## I²C Addresses
|
|
|
|
|
|
|
|
-| Device | 8-bit | 7-bit (Wire) |
|
|
|
|
|
-|--------|-------|--------------|
|
|
|
|
|
-| ADAU1401 DSP | 0x68 | 0x34 |
|
|
|
|
|
-| 24C256 EEPROM | 0xA0 | 0x50 |
|
|
|
|
|
|
|
+| Device | 8-bit | 7-bit (Wire) |
|
|
|
|
|
+| --------------- | ----- | ------------ |
|
|
|
|
|
+| ADAU1401 DSP | 0x68 | 0x34 |
|
|
|
|
|
+| 24C256 EEPROM | 0xA0 | 0x50 |
|
|
|
|
|
|
|
|
Both devices share the bus at 400 kHz on SDA=GPIO13, SCL=GPIO12.
|
|
Both devices share the bus at 400 kHz on SDA=GPIO13, SCL=GPIO12.
|
|
|
|
|
|
|
@@ -65,7 +65,7 @@ SigmaStudio sends `chipAddr` as a **chip index** (0x01 = DSP, 0x02 = EEPROM), no
|
|
|
|
|
|
|
|
**WRITE (opcode 0x09) — 10-byte header:**
|
|
**WRITE (opcode 0x09) — 10-byte header:**
|
|
|
|
|
|
|
|
-```
|
|
|
|
|
|
|
+```text
|
|
|
[0] 0x09 command
|
|
[0] 0x09 command
|
|
|
[1] safeload 1 = use safeload registers, 0 = direct write
|
|
[1] safeload 1 = use safeload registers, 0 = direct write
|
|
|
[2] placement reserved
|
|
[2] placement reserved
|
|
@@ -82,7 +82,7 @@ ACK response: `{0x09, 0x00, 0x04, status}` (4 bytes). `status` reflects the actu
|
|
|
|
|
|
|
|
**READ (opcode 0x0A) — 8-byte header:**
|
|
**READ (opcode 0x0A) — 8-byte header:**
|
|
|
|
|
|
|
|
-```
|
|
|
|
|
|
|
+```text
|
|
|
[0] 0x0A
|
|
[0] 0x0A
|
|
|
[1-2] totalLen
|
|
[1-2] totalLen
|
|
|
[3] chipAddr
|
|
[3] chipAddr
|
|
@@ -111,7 +111,7 @@ The DSP has 5 safeload slots. Filling them and writing `0x003C` to the Core Regi
|
|
|
`registerSizeForAddress()` derives the I²C bytes-per-register from the address:
|
|
`registerSizeForAddress()` derives the I²C bytes-per-register from the address:
|
|
|
|
|
|
|
|
| Address range | Register size |
|
|
| Address range | Register size |
|
|
|
-|---------------|--------------|
|
|
|
|
|
|
|
+| ------------- | ------------- |
|
|
|
| 0x0000–0x03FF (Parameter RAM) | 4 bytes |
|
|
| 0x0000–0x03FF (Parameter RAM) | 4 bytes |
|
|
|
| 0x0400–0x07FF (Program RAM) | 5 bytes |
|
|
| 0x0400–0x07FF (Program RAM) | 5 bytes |
|
|
|
| 0x081C (Core Register), dataLen == 2 | 2 bytes (R0 reset) |
|
|
| 0x081C (Core Register), dataLen == 2 | 2 bytes (R0 reset) |
|
|
@@ -134,6 +134,20 @@ When the buffer is fully consumed, all three index variables reset to 0 to preve
|
|
|
- Max I²C bytes per transaction: 28 (Wire buffer limit minus the 2-byte address overhead).
|
|
- Max I²C bytes per transaction: 28 (Wire buffer limit minus the 2-byte address overhead).
|
|
|
- After each chunk, `i2cAckPoll()` polls for ACK up to 120 ms — this is the EEPROM's internal write cycle; do not remove this delay.
|
|
- After each chunk, `i2cAckPoll()` polls for ACK up to 120 ms — this is the EEPROM's internal write cycle; do not remove this delay.
|
|
|
|
|
|
|
|
|
|
+## GPIO Register — `GET /gpio` and `POST /gpio`
|
|
|
|
|
+
|
|
|
|
|
+`handleGpioGet()` reads `GpioAllRegister` (0x0808, 1 byte) and `MpCfg0/1` (0x0820–0x0821, 1 byte each) and returns JSON:
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{"ok":true,"gpio":0,"mpcfg0":0,"mpcfg1":0}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+`handleGpioSet()` accepts a form-encoded `value` parameter (0–255) and writes it to `GpioAllRegister` via `DSPWriter::writeRegister`. Returns 400 if `value` is missing or out of range, 200 on success.
|
|
|
|
|
+
|
|
|
|
|
+The `/ota` page adds a row of four toggle buttons (GP0–GP3). Each click XORs the corresponding bit in the cached `gpioVal` and POSTs the new byte to `/gpio`. The page also polls `GET /gpio` every 5 seconds to stay in sync with any external state changes. Buttons render green (btn-success) when the bit is high, outline-secondary when low.
|
|
|
|
|
+
|
|
|
|
|
+Only output-configured pins respond to writes — which pins are outputs is determined by MpCfg registers (read-only in the UI, visible in the JSON response).
|
|
|
|
|
+
|
|
|
## DSP Soft Reset — `POST /dsp_reset`
|
|
## DSP Soft Reset — `POST /dsp_reset`
|
|
|
|
|
|
|
|
`handleDspReset()` writes `{0x00, 0x00}` (stop) to the Core Register, waits 100 ms, then writes `{0x00, 0x01}` (run). Parameter and program RAM are preserved — the DSP restarts execution without reloading from EEPROM. Returns 200 `"DSP soft reset complete."` on success.
|
|
`handleDspReset()` writes `{0x00, 0x00}` (stop) to the Core Register, waits 100 ms, then writes `{0x00, 0x01}` (run). Parameter and program RAM are preserved — the DSP restarts execution without reloading from EEPROM. Returns 200 `"DSP soft reset complete."` on success.
|
|
@@ -177,7 +191,7 @@ ADAU1401 parameter RAM uses **5.23 fixed-point** (4 bytes per word). `DataConver
|
|
|
## Files
|
|
## Files
|
|
|
|
|
|
|
|
| File | Role |
|
|
| File | Role |
|
|
|
-|------|------|
|
|
|
|
|
|
|
+| ---- | ---- |
|
|
|
| `ModulosDSP_101.ino` | Top-level: WiFi, TCP/HTTP servers, I²C helpers, CRC32, OTA |
|
|
| `ModulosDSP_101.ino` | Top-level: WiFi, TCP/HTTP servers, I²C helpers, CRC32, OTA |
|
|
|
| `DSPWriter.h` | I²C address constants, register enums, `DSPWriter` class declaration |
|
|
| `DSPWriter.h` | I²C address constants, register enums, `DSPWriter` class declaration |
|
|
|
| `DSPWriter.cpp` | `writeRegister`, `writeRegisterBlock` (returns bool), safeload with flush |
|
|
| `DSPWriter.cpp` | `writeRegister`, `writeRegisterBlock` (returns bool), safeload with flush |
|