Skip to content

Commit

Permalink
Add commands to read fuse settings, for SMC diagnostics (14 bytes), v…
Browse files Browse the repository at this point in the history
…ersion 47.2.4 (#50)

* Add commands to read fuse settings, for SMC diagnostics (14 bytes)

New size: 7028 (max size 7680)

Reading fuse bits (and lock bits) is a hardware feature where you set
SPMCSR to (1 << RFLB) | (1 << SELFPRGEN), and then LPM within 4 clock
cycles.

The feature you read with LPM is decided by Z:
0: Low fuse
1: Lock bits
2: Extended fuse
3: High fuse

To keep firmware use at a minimum, assume that the numeric values of the
I2C commands are in the same order as the hardware feature, so that they
can share the code, and only do a simple subtract to separate between them.

X16 need to know which fuse settings to expect, and which fuse settings are
incorrect.

* Bump version to 47.2.4
  • Loading branch information
stople authored Oct 13, 2024
1 parent 211cd33 commit bb054d6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ If you want to update the SMC firmware, please read this [guide](doc/update-guid
| 0x07 | Master read | 1 byte | Get keyboard keycode |
| 0x08 | Master write | 1 byte | Echo |
| 0x09 | Master write | 1 byte | Debug output |
| 0x0a | Master read | 1 byte | Get low fuse setting |
| 0x0b | Master read | 1 byte | Get lock bits |
| 0x0c | Master read | 1 byte | Get extended fuse setting |
| 0x0d | Master read | 1 byte | Get high fuse setting |
| 0x18 | Master read | 1 byte | Get keyboard command status |
| 0x19 | Master write | 1 byte | Send keyboard command |
| 0x1a | Master write | 2 bytes | Send keyboard command |
Expand Down Expand Up @@ -79,6 +83,18 @@ Key codes are one byte. Bit 7 indicates if the key was pressed (0) or released (

This command gets one keycode from the buffer. If the buffer is empty, it returns 0.

## Get fuses and lock bits (0x0a..0x0d)

These offsets returns the fuse settings and lock bits (low-lock-extended-high).

Expected value:
- Low: $F1
- Lock: $FF
- Extended: $FE
- High: $D4

The reason for this particular order, is size optimization in SMC FW.

## Get keyboard command status (0x18)

This offset returns the status of the last host to keyboard command.
Expand Down
2 changes: 1 addition & 1 deletion version.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#define version_major 47
#define version_minor 2
#define version_patch 3
#define version_patch 4
27 changes: 26 additions & 1 deletion x16-smc.ino
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@
#define I2C_CMD_ECHO 0x08
#define I2C_CMD_DBG_OUT 0x09
#define I2C_CMD_GET_LONGPRESS 0x09
#define I2C_CMD_GET_FUSE_LOW 0x0a
#define I2C_CMD_GET_FUSE_LOCK 0x0b
#define I2C_CMD_GET_FUSE_EXT 0x0c
#define I2C_CMD_GET_FUSE_HIGH 0x0d
#define I2C_CMD_GET_KBD_STATUS 0x18
#define I2C_CMD_KBD_CMD1 0x19
#define I2C_CMD_KBD_CMD2 0x1a
Expand Down Expand Up @@ -532,8 +536,21 @@ void I2C_Receive(int) {
I2C_Data[0] = defaultRequest;
}

// readFuse:
// Function must be called with interrupts disabled.
// 0: Low
// 1: Lock
// 2: Extended
// 3: High
uint8_t readFuse(uint8_t address)
{
eeprom_busy_wait();
return boot_lock_fuse_bits_get(address);
}

void I2C_Send() {
switch (I2C_Data[0]) {
uint8_t request = I2C_Data[0];
switch (request) {
case I2C_CMD_GET_KEYCODE_FAST:
if (!sendKeyCode()) smcWire.clearBuffer();
break;
Expand Down Expand Up @@ -602,6 +619,14 @@ void I2C_Send() {
case I2C_CMD_SELF_PROGRAMMING_MODE: // Check if self programming mode is activated
smcWire.write(selfProgrammingModeActive);
break;

case I2C_CMD_GET_FUSE_LOW:
case I2C_CMD_GET_FUSE_LOCK:
case I2C_CMD_GET_FUSE_EXT:
case I2C_CMD_GET_FUSE_HIGH: // Read fuses
// Size optimization: Assume that numeric values of these commands are in this order, to fit with hardware
smcWire.write(readFuse(request - I2C_CMD_GET_FUSE_LOW));
break;
}

I2C_Data[0] = defaultRequest;
Expand Down

0 comments on commit bb054d6

Please sign in to comment.