Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add commands to read fuse settings, for SMC diagnostics (14 bytes), version 47.2.4 #50

Merged
merged 2 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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