From 75273770000cc41c22a04983f5da0f8de4b74220 Mon Sep 17 00:00:00 2001
From: Christos Gentsos <christos.gentsos@cern.ch>
Date: Thu, 14 Oct 2021 12:12:17 +0200
Subject: [PATCH] I2C: Merge "standard" and "extended" PMBus command structures

---
 bootloader/src/i2c_impl.c  |  67 ++++++-------
 bootloader/src/main.c      |   4 +-
 common/include/i2c_slave.h |  14 +--
 common/src/i2c_slave.c     | 201 +++++++++++--------------------------
 main_fw/src/i2c_impl.c     |  85 +++++++---------
 main_fw/src/main.c         |   4 +-
 6 files changed, 135 insertions(+), 240 deletions(-)

diff --git a/bootloader/src/i2c_impl.c b/bootloader/src/i2c_impl.c
index 8bf0d2c..b5037de 100644
--- a/bootloader/src/i2c_impl.c
+++ b/bootloader/src/i2c_impl.c
@@ -17,32 +17,6 @@ const char MFR_SER[] = "123456789";
 void query_prp();
 uint8_t query_r;
 
-static const int8_t cmd_data_lengths[] = {
-        -1,                        // 0x1A
-        -(int8_t)sizeof(MFR_ID),   // 0x99
-        -(int8_t)sizeof(MFR_MDL),  // 0x9A
-        -(int8_t)sizeof(MFR_REV),  // 0x9B
-        -(int8_t)sizeof(MFR_LOC),  // 0x9C
-        -(int8_t)sizeof(MFR_DAT),  // 0x9D
-        -(int8_t)sizeof(MFR_SER)}; // 0x9E
-
-// for block write-block read process calls, which modify the length
-static int8_t cmd_data_length_query = -1;
-
-static cmd_t cmds_cmds[] = (cmd_t[]){
-        {0x1A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r,  (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_SUP, 1},
-        {0x99, (int8_t *)&cmd_data_lengths[1], (uint8_t *)&MFR_ID,   (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9A, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&MFR_MDL,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9B, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&MFR_REV,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9C, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&MFR_LOC,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9D, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&MFR_DAT,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9E, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&MFR_SER,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0}};
-
-cmd_space_t cmds = {
-        sizeof(cmds_cmds)/sizeof(cmd_t),
-        cmds_cmds
-};
-
 void written_fw_block();
 void written_fw_checksum();
 void uc_reset();
@@ -55,6 +29,18 @@ static uint8_t fw_block[8];
 
 static uint8_t dummy_byte;
 
+static const int8_t cmd_data_lengths[] = {
+        -1,                        // 0x1A
+        -(int8_t)sizeof(MFR_ID),   // 0x99
+        -(int8_t)sizeof(MFR_MDL),  // 0x9A
+        -(int8_t)sizeof(MFR_REV),  // 0x9B
+        -(int8_t)sizeof(MFR_LOC),  // 0x9C
+        -(int8_t)sizeof(MFR_DAT),  // 0x9D
+        -(int8_t)sizeof(MFR_SER)}; // 0x9E
+
+// for block write-block read process calls, which modify the length
+static int8_t cmd_data_length_query = -1;
+
 static const int8_t ext_cmd_data_lengths[] = {
         2,  // 0x05
         8,  // 0x06
@@ -63,17 +49,24 @@ static const int8_t ext_cmd_data_lengths[] = {
         1,  // 0xC0
         1}; // 0xC4
 
-static cmd_t ext_cmds_cmds[] = (cmd_t[]){
-        {0x01, (int8_t *)&ext_cmd_data_lengths[0], (uint8_t *)&fw_len,      (fp_t)NULL, (fp_t)NULL,                 (fp_t)NULL, 0, 0},
-        {0x02, (int8_t *)&ext_cmd_data_lengths[1], (uint8_t *)fw_block,     (fp_t)NULL, (fp_t)&written_fw_block,    (fp_t)NULL, 0, 1},
-        {0x03, (int8_t *)&ext_cmd_data_lengths[2], (uint8_t *)&fw_checksum, (fp_t)NULL, (fp_t)&written_fw_checksum, (fp_t)NULL, 0, 0},
-        {0x04, (int8_t *)&ext_cmd_data_lengths[3], (uint8_t *)&fw_local_checksum, (fp_t)NULL, (fp_t)NULL,           (fp_t)NULL, 0, 0},
-        {0x05, (int8_t *)&ext_cmd_data_lengths[4], (uint8_t *)&dummy_byte,  (fp_t)NULL, (fp_t)&boot_new_fw,         (fp_t)NULL, 0, 0},
-        {0x06, (int8_t *)&ext_cmd_data_lengths[5], (uint8_t *)&dummy_byte,  (fp_t)NULL, (fp_t)&uc_reset,            (fp_t)NULL, 0, 0}};
-
-cmd_space_t ext_cmds = {
-        sizeof(ext_cmds_cmds)/sizeof(cmd_t),
-        ext_cmds_cmds
+static cmd_t cmds_cmds[] = (cmd_t[]){
+        {0x001A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r,  (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_SUP, 1},
+        {0x0099, (int8_t *)&cmd_data_lengths[1], (uint8_t *)&MFR_ID,   (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009A, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&MFR_MDL,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009B, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&MFR_REV,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009C, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&MFR_LOC,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009D, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&MFR_DAT,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009E, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&MFR_SER,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0xFF01, (int8_t *)&ext_cmd_data_lengths[0], (uint8_t *)&fw_len,      (fp_t)NULL, (fp_t)NULL,                 (fp_t)NULL, 0, 0},
+        {0xFF02, (int8_t *)&ext_cmd_data_lengths[1], (uint8_t *)fw_block,     (fp_t)NULL, (fp_t)&written_fw_block,    (fp_t)NULL, 0, 1},
+        {0xFF03, (int8_t *)&ext_cmd_data_lengths[2], (uint8_t *)&fw_checksum, (fp_t)NULL, (fp_t)&written_fw_checksum, (fp_t)NULL, 0, 0},
+        {0xFF04, (int8_t *)&ext_cmd_data_lengths[3], (uint8_t *)&fw_local_checksum, (fp_t)NULL, (fp_t)NULL,           (fp_t)NULL, 0, 0},
+        {0xFF05, (int8_t *)&ext_cmd_data_lengths[4], (uint8_t *)&dummy_byte,  (fp_t)NULL, (fp_t)&boot_new_fw,         (fp_t)NULL, 0, 0},
+        {0xFF06, (int8_t *)&ext_cmd_data_lengths[5], (uint8_t *)&dummy_byte,  (fp_t)NULL, (fp_t)&uc_reset,            (fp_t)NULL, 0, 0}};
+
+cmd_space_t cmds = {
+        sizeof(cmds_cmds)/sizeof(cmd_t),
+        cmds_cmds
 };
 
 static uint8_t fw_write_buf[FLASH_ROW_SIZE] __attribute__((__aligned__(4)));
diff --git a/bootloader/src/main.c b/bootloader/src/main.c
index 253e0f9..cfa660d 100644
--- a/bootloader/src/main.c
+++ b/bootloader/src/main.c
@@ -9,8 +9,6 @@ __DEFAULT_NO_xMR
 
 //! PMBus commmands structure
 extern cmd_space_t cmds;
-//! Our custom commmands structure
-extern cmd_space_t ext_cmds;
 
 uint8_t status_b;
 
@@ -19,7 +17,7 @@ int main(void)
         system_init();
 
         if (user_flash.copy_fw == 0xBEC0ABCD) {
-                setup_I2C_slave(&cmds, &ext_cmds);
+                setup_I2C_slave(&cmds);
 
                 while (1)
                         ;
diff --git a/common/include/i2c_slave.h b/common/include/i2c_slave.h
index df9dcde..9b13828 100644
--- a/common/include/i2c_slave.h
+++ b/common/include/i2c_slave.h
@@ -5,12 +5,8 @@
 
 #define CMD 0x01
 #define DATA 0x02
-#define EXT_CMD 0x04
-#define EXT_DATA 0x08
-#define BLK_GET_LEN 0x10
-#define EXT_BLK_GET_LEN 0x20
-#define GET_CHECKSUM 0x40
-#define EXT_GET_CHECKSUM 0x80
+#define BLK_GET_LEN 0x04
+#define GET_CHECKSUM 0x08
 
 typedef void(*fp_t)(void);
 
@@ -29,7 +25,7 @@ enum QUERY_RET_VALS {
 
 typedef const struct {
         //! CMD code
-        const uint8_t addr;
+        const uint16_t addr;
         //! transaction length for this command
         int8_t *const data_len;
         //! pointer to data
@@ -53,7 +49,7 @@ typedef const struct {
         cmd_t *const cmds;
 } cmd_space_t;
 
-int16_t in_addr_space(cmd_space_t *addr_space, uint8_t addr);
-void setup_I2C_slave(cmd_space_t *impl_cmds, cmd_space_t *impl_ext_cmds);
+int16_t in_addr_space(cmd_space_t *addr_space, uint16_t addr);
+void setup_I2C_slave(cmd_space_t *impl_cmds);
 
 #endif
diff --git a/common/src/i2c_slave.c b/common/src/i2c_slave.c
index 16c75c9..e6fc259 100644
--- a/common/src/i2c_slave.c
+++ b/common/src/i2c_slave.c
@@ -16,17 +16,15 @@ static struct io_descriptor *io;
 
 static uint16_t dev_addr __xMR;
 static uint16_t rx_state __xMR = CMD;
-static uint8_t tmp_std_cmd_addr;
-static uint16_t std_cmd_addr __xMR = 0xFF;
+static uint8_t tmp_cmd_addr;
+static uint16_t cmd_addr __xMR;
+static uint16_t got_ff __xMR;
 static int16_t cmd_index __xMR;
 static int16_t cmd_len __xMR;
-static uint8_t tmp_ext_cmd_addr;
-static uint16_t ext_cmd_addr __xMR;
 static uint16_t blk_wrote_len_byte __xMR;
 static uint16_t last_byte_read_got_nack __xMR;
 
 static cmd_space_t *cmds;
-static cmd_space_t *ext_cmds;
 
 uint16_t use_pec __xMR = 0;
 static uint16_t pec_checksum __xMR;
@@ -41,7 +39,7 @@ uint8_t status_cml;
 
 /*! This function checks the command array for a specific command. Returns its
  *  index if it finds it, and -1 if it doesn't. */
-int16_t in_addr_space(cmd_space_t *addr_space, uint8_t addr)
+int16_t in_addr_space(cmd_space_t *addr_space, uint16_t addr)
 {
         for (uint8_t i = 0; i < addr_space->n_cmds; ++i)
                 if (addr == addr_space->cmds[i].addr)
@@ -74,17 +72,28 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
         case CMD:
                 // first state after getting the address + write bit,
                 // set the PEC checksum
-                if (use_pec)
+                if (use_pec && got_ff == 0)
                         pec_checksum = crc8_byte(dev_addr << 1);
-                io_read(io, &tmp_std_cmd_addr, 1);
-                std_cmd_addr = tmp_std_cmd_addr;
+
+                io_read(io, &tmp_cmd_addr, 1);
+                cmd_addr = tmp_cmd_addr;
+
                 if (use_pec)
-                        pec_checksum = crc8_byte(pec_checksum ^ std_cmd_addr);
-                if (std_cmd_addr == 0xFF) {
-                        rx_state = EXT_CMD;
+                        pec_checksum = crc8_byte(pec_checksum ^ cmd_addr);
+
+                if (got_ff) {
+                        got_ff = 0;
+                        cmd_index = in_addr_space(cmds, 0xFF00 | cmd_addr);
+                } else if (cmd_addr == 0xFF) {
+                        got_ff = 1;
                         send_ack(descr);
                         set_cmd(descr, 3);
-                } else if ((cmd_index = in_addr_space(cmds, std_cmd_addr)) != -1) {
+                        break;
+                } else {
+                        cmd_index = in_addr_space(cmds, cmd_addr);
+                }
+
+                if (cmd_index != -1) {
                         cmd_len = 0;
                         if (*cmds->cmds[cmd_index].data_len < 0)
                                 rx_state = BLK_GET_LEN;
@@ -100,28 +109,7 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
                         set_cmd(descr, 2);
                 }
                 break;
-        case DATA:
-                io_read(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
-                if (use_pec)
-                        pec_checksum = crc8_byte(pec_checksum ^ cmds->cmds[cmd_index].data_pnt[cmd_len]);
-                ++cmd_len;
-                if (cmd_len < abs(*cmds->cmds[cmd_index].data_len)) {
-                        send_ack(descr);
-                        set_cmd(descr, 3);
-                } else {
-                        if (use_pec && !cmds->cmds[cmd_index].wr_pec_disabled) {
-                                send_ack(descr);
-                                set_cmd(descr, 3);
-                                rx_state = GET_CHECKSUM;
-                        } else {
-                                send_ack(descr);
-                                set_cmd(descr, 2);
-                                rx_state = CMD;
-                                if (cmds->cmds[cmd_index].w_callback)
-                                        notmr_call_helper(cmds->cmds[cmd_index].w_callback);
-                        }
-                }
-                break;
+
         case BLK_GET_LEN:
                 io_read(io, (uint8_t *)cmds->cmds[cmd_index].data_len, 1);
                 if (use_pec)
@@ -131,59 +119,30 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
                 set_cmd(descr, 3);
                 rx_state = DATA;
                 break;
-        case EXT_CMD:
-                io_read(io, &tmp_ext_cmd_addr, 1);
-                ext_cmd_addr = tmp_ext_cmd_addr;
-                if (use_pec)
-                        pec_checksum = crc8_byte(pec_checksum ^ ext_cmd_addr);
-                if ((cmd_index = in_addr_space(ext_cmds, ext_cmd_addr)) != -1) {
-                        cmd_len = 0;
-                        if (*ext_cmds->cmds[cmd_index].data_len < 0)
-                                rx_state = EXT_BLK_GET_LEN;
-                        else
-                                rx_state = EXT_DATA;
-                        send_ack(descr);
-                        set_cmd(descr, 3);
-                        if (ext_cmds->cmds[cmd_index].a_callback)
-                                notmr_call_helper(ext_cmds->cmds[cmd_index].a_callback);
-                } else {
-                        // invalid EXT_CMD, return NACK and terminate transaction
-                        send_nack(descr);
-                        set_cmd(descr, 2);
-                        rx_state = CMD;
-                }
-                break;
-        case EXT_DATA:
-                io_read(io, &ext_cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
+
+        case DATA:
+                io_read(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
                 if (use_pec)
-                        pec_checksum = crc8_byte(pec_checksum ^ ext_cmds->cmds[cmd_index].data_pnt[cmd_len]);
+                        pec_checksum = crc8_byte(pec_checksum ^ cmds->cmds[cmd_index].data_pnt[cmd_len]);
                 ++cmd_len;
-                if (cmd_len < abs(*ext_cmds->cmds[cmd_index].data_len)) {
+                if (cmd_len < abs(*cmds->cmds[cmd_index].data_len)) {
                         send_ack(descr);
                         set_cmd(descr, 3);
                 } else {
-                        if (use_pec && !ext_cmds->cmds[cmd_index].wr_pec_disabled) {
+                        if (use_pec && !cmds->cmds[cmd_index].wr_pec_disabled) {
                                 send_ack(descr);
                                 set_cmd(descr, 3);
-                                rx_state = EXT_GET_CHECKSUM;
+                                rx_state = GET_CHECKSUM;
                         } else {
                                 send_ack(descr);
                                 set_cmd(descr, 2);
                                 rx_state = CMD;
-                                if (ext_cmds->cmds[cmd_index].w_callback)
-                                        notmr_call_helper(ext_cmds->cmds[cmd_index].w_callback);
+                                if (cmds->cmds[cmd_index].w_callback)
+                                        notmr_call_helper(cmds->cmds[cmd_index].w_callback);
                         }
                 }
                 break;
-        case EXT_BLK_GET_LEN:
-                io_read(io, (uint8_t *)ext_cmds->cmds[cmd_index].data_len, 1);
-                if (use_pec)
-                        pec_checksum = crc8_byte(pec_checksum ^ *ext_cmds->cmds[cmd_index].data_len);
-                *ext_cmds->cmds[cmd_index].data_len = -(*ext_cmds->cmds[cmd_index].data_len);
-                send_ack(descr);
-                set_cmd(descr, 3);
-                rx_state = EXT_DATA;
-                break;
+
         case GET_CHECKSUM:
                 io_read(io, &checksum_from_m, 1);
                 if (checksum_from_m == pec_checksum) {
@@ -198,20 +157,7 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
                 set_cmd(descr, 2);
                 rx_state = CMD;
                 break;
-        case EXT_GET_CHECKSUM:
-                io_read(io, &checksum_from_m, 1);
-                if (checksum_from_m == pec_checksum) {
-                        send_ack(descr);
-                        if (ext_cmds->cmds[cmd_index].w_callback)
-                                notmr_call_helper(ext_cmds->cmds[cmd_index].w_callback);
-                } else {
-                        status_b |= 0x01;
-                        status_cml = 0x20; // PEC error
-                        send_nack(descr);
-                }
-                set_cmd(descr, 2);
-                rx_state = CMD;
-                break;
+
         default:
                 break;
         }
@@ -231,58 +177,30 @@ static void __xMR I2C_tx_pending(const struct i2c_s_async_descriptor *const desc
                 added_tx_pec = 1;
                 sent_checksum = 0;
         }
-        if (std_cmd_addr != 0xFF) {
-                if ((*cmds->cmds[cmd_index].data_len < 0) && (!blk_wrote_len_byte)) {
-                        cmd_len = 0;
-                        tx_tmp = -*cmds->cmds[cmd_index].data_len;
-                        if (use_pec)
-                                pec_checksum = crc8_byte(pec_checksum ^ tx_tmp);
-                        io_write(io, (uint8_t *)&tx_tmp, 1);
-                        set_cmd(descr, 3);
-                        blk_wrote_len_byte = 1;
-                } else if (cmd_len < abs(*cmds->cmds[cmd_index].data_len)) {
-                        if (use_pec)
-                                pec_checksum = crc8_byte(pec_checksum ^ cmds->cmds[cmd_index].data_pnt[cmd_len]);
-                        io_write(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
-                        set_cmd(descr, 3);
-                        ++cmd_len;
-                } else if (use_pec && !sent_checksum) {
-                        tmp_pec_checksum = pec_checksum;
-                        io_write(io, (uint8_t *)&tmp_pec_checksum, 1);
-                        set_cmd(descr, 3);
-                        sent_checksum = 1;
-                } else {
-                        set_cmd(descr, 2);
-                        rx_state = CMD;
-                        if (cmds->cmds[cmd_index].r_callback)
-                                notmr_call_helper(cmds->cmds[cmd_index].r_callback);
-                }
-        } else {                /* extended command space */
-                if ((*ext_cmds->cmds[cmd_index].data_len < 0) && (!blk_wrote_len_byte)) {
-                        cmd_len = 0;
-                        tx_tmp = -*ext_cmds->cmds[cmd_index].data_len;
-                        if (use_pec)
-                                pec_checksum = crc8_byte(pec_checksum ^ tx_tmp);
-                        io_write(io, (uint8_t *)&tx_tmp, 1);
-                        set_cmd(descr, 3);
-                        blk_wrote_len_byte = 1;
-                } else if (cmd_len < abs(*ext_cmds->cmds[cmd_index].data_len)) {
-                        if (use_pec)
-                                pec_checksum = crc8_byte(pec_checksum ^ ext_cmds->cmds[cmd_index].data_pnt[cmd_len]);
-                        io_write(io, &ext_cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
-                        set_cmd(descr, 3);
-                        ++cmd_len;
-                } else if (use_pec && !sent_checksum) {
-                        tmp_pec_checksum = pec_checksum;
-                        io_write(io, (uint8_t *)&tmp_pec_checksum, 1);
-                        set_cmd(descr, 3);
-                        sent_checksum = 1;
-                } else {
-                        set_cmd(descr, 2);
-                        rx_state = CMD;
-                        if (ext_cmds->cmds[cmd_index].r_callback)
-                                notmr_call_helper(ext_cmds->cmds[cmd_index].r_callback);
-                }
+        if ((*cmds->cmds[cmd_index].data_len < 0) && (!blk_wrote_len_byte)) {
+                cmd_len = 0;
+                tx_tmp = -*cmds->cmds[cmd_index].data_len;
+                if (use_pec)
+                        pec_checksum = crc8_byte(pec_checksum ^ tx_tmp);
+                io_write(io, (uint8_t *)&tx_tmp, 1);
+                set_cmd(descr, 3);
+                blk_wrote_len_byte = 1;
+        } else if (cmd_len < abs(*cmds->cmds[cmd_index].data_len)) {
+                if (use_pec)
+                        pec_checksum = crc8_byte(pec_checksum ^ cmds->cmds[cmd_index].data_pnt[cmd_len]);
+                io_write(io, &cmds->cmds[cmd_index].data_pnt[cmd_len], 1);
+                set_cmd(descr, 3);
+                ++cmd_len;
+        } else if (use_pec && !sent_checksum) {
+                tmp_pec_checksum = pec_checksum;
+                io_write(io, (uint8_t *)&tmp_pec_checksum, 1);
+                set_cmd(descr, 3);
+                sent_checksum = 1;
+        } else {
+                set_cmd(descr, 2);
+                rx_state = CMD;
+                if (cmds->cmds[cmd_index].r_callback)
+                        notmr_call_helper(cmds->cmds[cmd_index].r_callback);
         }
 }
 
@@ -313,12 +231,11 @@ static void  __attribute__((noinline)) __xMR set_dev_addr(uint8_t dev_addr_notmr
 
 /*! this configures the I2C interrupt handlers with the PMBus and
     extended command structures */
-void setup_I2C_slave(cmd_space_t *impl_cmds, cmd_space_t *impl_ext_cmds)
+void setup_I2C_slave(cmd_space_t *impl_cmds)
 {
         uint8_t dev_addr_notmr = 0x12 + 4*(!gpio_get_pin_level(ADDR2)) + 2*(!gpio_get_pin_level(ADDR1)) + (!gpio_get_pin_level(ADDR0));
 
         cmds = impl_cmds;
-        ext_cmds = impl_ext_cmds;
         hri_sercomi2cs_clear_CTRLB_SMEN_bit(SERCOM2);
 	i2c_s_async_get_io_descriptor(&I2C_0, &io);
 	i2c_s_async_register_callback(&I2C_0, I2C_S_RX_COMPLETE, I2C_rx_complete);
diff --git a/main_fw/src/i2c_impl.c b/main_fw/src/i2c_impl.c
index f7a2300..d53793b 100644
--- a/main_fw/src/i2c_impl.c
+++ b/main_fw/src/i2c_impl.c
@@ -88,6 +88,9 @@ extern uint16_t fan_installed[3] __xMR;
 extern uint16_t fan_cmdrpm[3] __xMR;
 extern uint16_t fan_ppr[3] __xMR;
 
+void uc_reset();
+void boot_new_fw();
+
 static const int8_t cmd_data_lengths[] = {
         1,                         // 0x00
         -1,                        // 0x1A
@@ -117,40 +120,6 @@ static const int8_t cmd_data_lengths[] = {
 // only block write-block read process calls modify the length
 static int8_t cmd_data_length_query = -1;
 
-static const cmd_t cmds_cmds[] = (cmd_t[]){
-        {0x00, (int8_t *)&cmd_data_lengths[0], (uint8_t *)&page_tmp,     (fp_t)NULL, &page_chk,  (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_8B, 0},
-        {0x1A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r,  (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_SUP, 1},
-        {0x78, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&status_b, (fp_t)NULL, (fp_t)NULL, &read_status_b, QUERY_RD, 0},
-        {0x7E, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&status_cml, (fp_t)NULL, (fp_t)NULL, &read_status_cml, QUERY_RD, 0},
-        {0x8B, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&curpage_volt, &accvolt, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x8C, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&curpage_curr, &acccurr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x8D, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&temps_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x8E, (int8_t *)&cmd_data_lengths[7], (uint8_t *)&temps_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x8F, (int8_t *)&cmd_data_lengths[8], (uint8_t *)&temps_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x90, (int8_t *)&cmd_data_lengths[9], (uint8_t *)&frpms_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x91, (int8_t *)&cmd_data_lengths[10], (uint8_t *)&frpms_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x92, (int8_t *)&cmd_data_lengths[11], (uint8_t *)&frpms_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x96, (int8_t *)&cmd_data_lengths[12], (uint8_t *)&curpage_powr, &accpowr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
-        {0x99, (int8_t *)&cmd_data_lengths[13], (uint8_t *)&MFR_ID,   (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9A, (int8_t *)&cmd_data_lengths[14], (uint8_t *)&MFR_MDL,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9B, (int8_t *)&cmd_data_lengths[15], (uint8_t *)&MFR_REV,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9C, (int8_t *)&cmd_data_lengths[16], (uint8_t *)&MFR_LOC,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9D, (int8_t *)&cmd_data_lengths[17], (uint8_t *)&MFR_DAT,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x9E, (int8_t *)&cmd_data_lengths[18], (uint8_t *)&MFR_SER,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
-        {0x3A, (int8_t *)&cmd_data_lengths[19], (uint8_t *)&fan_config_1_2, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
-        {0x3B, (int8_t *)&cmd_data_lengths[20], (uint8_t *)&setfrpms_lin[0], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
-        {0x3C, (int8_t *)&cmd_data_lengths[21], (uint8_t *)&setfrpms_lin[1], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
-        {0x3D, (int8_t *)&cmd_data_lengths[22], (uint8_t *)&fan_config_3_4, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
-        {0x3E, (int8_t *)&cmd_data_lengths[23], (uint8_t *)&setfrpms_lin[2], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0}};
-
-cmd_space_t cmds = {
-        sizeof(cmds_cmds)/sizeof(cmd_t),
-        cmds_cmds
-};
-
-void uc_reset();
-void boot_new_fw();
-
 static const int8_t ext_cmd_data_lengths[] = {
         1,  // 0x05
         1,  // 0x06
@@ -160,18 +129,42 @@ static const int8_t ext_cmd_data_lengths[] = {
         7,  // 0xC1
         1}; // 0xC4
 
-static cmd_t ext_cmds_cmds[] = (cmd_t[]){
-        {0x05, (int8_t *)&ext_cmd_data_lengths[0], (uint8_t *)&dummy_byte, (fp_t)NULL, &boot_new_fw, (fp_t)NULL, 0, 0},
-        {0x06, (int8_t *)&ext_cmd_data_lengths[1], (uint8_t *)&dummy_byte, (fp_t)NULL, &uc_reset, (fp_t)NULL, 0, 0},
-        {0xA0, (int8_t *)&ext_cmd_data_lengths[2], (uint8_t *)&TMR_ERROR_CNT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, 0, 0},
-        {0xB0, (int8_t *)&ext_cmd_data_lengths[3], (uint8_t *)&use_pec_tmp, (fp_t)NULL, &set_pec, (fp_t)NULL, 0, 1},
-        {0xC0, (int8_t *)&ext_cmd_data_lengths[4], (uint8_t *)&temp_curve_points_data, (fp_t)NULL, &set_tc_curve, (fp_t)NULL, 0, 0},
-        {0xC1, (int8_t *)&ext_cmd_data_lengths[5], (uint8_t *)&temp_matrix_row, (fp_t)NULL, &set_tc_matrix, (fp_t)NULL, 0, 0},
-        {0xC4, (int8_t *)&ext_cmd_data_lengths[6], (uint8_t *)&tc_on, (fp_t)NULL, &set_tc_onoff, (fp_t)NULL, 0, 0}};
-
-cmd_space_t ext_cmds = {
-        sizeof(ext_cmds_cmds)/sizeof(cmd_t),
-        ext_cmds_cmds
+static const cmd_t cmds_cmds[] = (cmd_t[]){
+        {0x0000, (int8_t *)&cmd_data_lengths[0], (uint8_t *)&page_tmp,     (fp_t)NULL, &page_chk,  (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_8B, 0},
+        {0x001A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r,  (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_SUP, 1},
+        {0x0078, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&status_b, (fp_t)NULL, (fp_t)NULL, &read_status_b, QUERY_RD, 0},
+        {0x007E, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&status_cml, (fp_t)NULL, (fp_t)NULL, &read_status_cml, QUERY_RD, 0},
+        {0x008B, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&curpage_volt, &accvolt, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x008C, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&curpage_curr, &acccurr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x008D, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&temps_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x008E, (int8_t *)&cmd_data_lengths[7], (uint8_t *)&temps_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x008F, (int8_t *)&cmd_data_lengths[8], (uint8_t *)&temps_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x0090, (int8_t *)&cmd_data_lengths[9], (uint8_t *)&frpms_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x0091, (int8_t *)&cmd_data_lengths[10], (uint8_t *)&frpms_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x0092, (int8_t *)&cmd_data_lengths[11], (uint8_t *)&frpms_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x0096, (int8_t *)&cmd_data_lengths[12], (uint8_t *)&curpage_powr, &accpowr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
+        {0x0099, (int8_t *)&cmd_data_lengths[13], (uint8_t *)&MFR_ID,   (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009A, (int8_t *)&cmd_data_lengths[14], (uint8_t *)&MFR_MDL,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009B, (int8_t *)&cmd_data_lengths[15], (uint8_t *)&MFR_REV,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009C, (int8_t *)&cmd_data_lengths[16], (uint8_t *)&MFR_LOC,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009D, (int8_t *)&cmd_data_lengths[17], (uint8_t *)&MFR_DAT,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x009E, (int8_t *)&cmd_data_lengths[18], (uint8_t *)&MFR_SER,  (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
+        {0x003A, (int8_t *)&cmd_data_lengths[19], (uint8_t *)&fan_config_1_2, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
+        {0x003B, (int8_t *)&cmd_data_lengths[20], (uint8_t *)&setfrpms_lin[0], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
+        {0x003C, (int8_t *)&cmd_data_lengths[21], (uint8_t *)&setfrpms_lin[1], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
+        {0x003D, (int8_t *)&cmd_data_lengths[22], (uint8_t *)&fan_config_3_4, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
+        {0x003E, (int8_t *)&cmd_data_lengths[23], (uint8_t *)&setfrpms_lin[2], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
+        {0xFF05, (int8_t *)&ext_cmd_data_lengths[0], (uint8_t *)&dummy_byte, (fp_t)NULL, &boot_new_fw, (fp_t)NULL, 0, 0},
+        {0xFF06, (int8_t *)&ext_cmd_data_lengths[1], (uint8_t *)&dummy_byte, (fp_t)NULL, &uc_reset, (fp_t)NULL, 0, 0},
+        {0xFFA0, (int8_t *)&ext_cmd_data_lengths[2], (uint8_t *)&TMR_ERROR_CNT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, 0, 0},
+        {0xFFB0, (int8_t *)&ext_cmd_data_lengths[3], (uint8_t *)&use_pec_tmp, (fp_t)NULL, &set_pec, (fp_t)NULL, 0, 1},
+        {0xFFC0, (int8_t *)&ext_cmd_data_lengths[4], (uint8_t *)&temp_curve_points_data, (fp_t)NULL, &set_tc_curve, (fp_t)NULL, 0, 0},
+        {0xFFC1, (int8_t *)&ext_cmd_data_lengths[5], (uint8_t *)&temp_matrix_row, (fp_t)NULL, &set_tc_matrix, (fp_t)NULL, 0, 0},
+        {0xFFC4, (int8_t *)&ext_cmd_data_lengths[6], (uint8_t *)&tc_on, (fp_t)NULL, &set_tc_onoff, (fp_t)NULL, 0, 0}};
+
+cmd_space_t cmds = {
+        sizeof(cmds_cmds)/sizeof(cmd_t),
+        cmds_cmds
 };
 
 static uint32_t fw_write_buf[FLASH_ROW_SIZE/4];
diff --git a/main_fw/src/main.c b/main_fw/src/main.c
index d433c79..8e7e40a 100644
--- a/main_fw/src/main.c
+++ b/main_fw/src/main.c
@@ -16,8 +16,6 @@ __DEFAULT_NO_xMR
 
 //! PMBus commmands structure
 extern cmd_space_t cmds;
-//! Our custom commmands structure
-extern cmd_space_t ext_cmds;
 
 #ifdef MMRTSB
 #define MAX_PAGE 3
@@ -478,7 +476,7 @@ int main(void)
 	adc_async_enable_channel(&ADC_0, 0);
         adc_async_start_conversion(&ADC_0);
 
-        setup_I2C_slave(&cmds, &ext_cmds);
+        setup_I2C_slave(&cmds);
 
         // set the timer interrupt to a lower priority otherwise i2c won't work
         NVIC_SetPriority(RTC_IRQn, 1);
-- 
GitLab