This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new a6b21e07134 libc: Add SMBus PEC helpers and fix BQ769x0 CRC.
a6b21e07134 is described below

commit a6b21e071346a234d8d15d5c3c78a3802e3964e3
Author: jsanchez-2g <[email protected]>
AuthorDate: Fri Oct 9 09:23:09 2026 -0500

    libc: Add SMBus PEC helpers and fix BQ769x0 CRC.
    
    Add crc8smbus() and crc8smbuspart() for polynomial 0x07, initial value
    zero, no reflection and no final XOR. Reuse the existing CCITT table
    while cancelling the shared table helper's entry and exit inversions.
    Preserve existing CRC APIs and results.
    
    Use the new helper in BQ769x0 register read, write and multi-register
    read paths. Its PEC requires uncomplemented CRC state; the existing
    crc8ccittpart() produces different results. For address/data 11 00,
    the required PEC is 42 rather than 6a.
    
    Correct existing driver indentation for full-file style compliance.
    Companion NuttX Apps crctest coverage checks known vectors, incremental
    and empty calculations, all seed values, and legacy API compatibility.
    Integrated builds and user-reported hardware verification passed for
    Conductor, Vacule and Golgi; BMS builds exercise BQ769x0 PEC.
    
    Assisted-by: Codex:GPT-6
    Signed-off-by: jsanchez-2g <[email protected]>
---
 drivers/power/battery/bq769x0.c | 140 ++++++++++++++++++++--------------------
 include/nuttx/crc8.h            |  24 +++++++
 libs/libc/misc/lib_crc8ccitt.c  |  29 +++++++++
 3 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/drivers/power/battery/bq769x0.c b/drivers/power/battery/bq769x0.c
index d14aea8c535..8a8ed30b17d 100644
--- a/drivers/power/battery/bq769x0.c
+++ b/drivers/power/battery/bq769x0.c
@@ -178,7 +178,7 @@ static const uint8_t bq76940_15cell_mapping[] =
 
     {
         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-      };
+    };
 static const uint8_t *bq76940_cell_mapping[] =
     {
         bq76940_9cell_mapping,
@@ -368,8 +368,8 @@ static int bq769x0_getreg8(FAR struct bq769x0_dev_s *priv, 
uint8_t regaddr,
   if (priv->crc)
     {
       sl_addr = RD_ADDR(priv->addr);
-      crc = crc8ccittpart(&sl_addr, 1, 0);
-      crc = crc8ccittpart(val, 1, crc);
+      crc = crc8smbuspart(&sl_addr, 1, 0);
+      crc = crc8smbuspart(val, 1, crc);
       if (crc != val[1])
         {
           baterr("ERROR: CRC mismatch: Got %02x, Expected %02x\n", val[1],
@@ -422,8 +422,8 @@ static int bq769x0_putreg8(FAR struct bq769x0_dev_s *priv, 
uint8_t regaddr,
     {
       datalen = 3;
       sl_addr = WR_ADDR(priv->addr);
-      crc = crc8ccittpart(&sl_addr, 1, 0);
-      crc = crc8ccittpart(buffer, 2, crc);
+      crc = crc8smbuspart(&sl_addr, 1, 0);
+      crc = crc8smbuspart(buffer, 2, crc);
       buffer[2] = crc;
       batinfo("write crc: %02x\n", crc);
     }
@@ -545,10 +545,10 @@ static int bq769x0_getnreg16(FAR struct bq769x0_dev_s 
*priv, uint8_t regaddr,
   if (priv->crc)
     {
       sl_addr = RD_ADDR(priv->addr);
-      crc = crc8ccittpart(&sl_addr, 1, 0);
+      crc = crc8smbuspart(&sl_addr, 1, 0);
       for (i = 0; i < byte_count; i += 2)
         {
-          crc = crc8ccittpart(&tmp_val[i], 1, crc);
+          crc = crc8smbuspart(&tmp_val[i], 1, crc);
           if (crc != tmp_val[i + 1])
             {
               baterr("ERROR: CRC mismatch: Got %02x, Expected %02x\n",
@@ -1340,7 +1340,7 @@ static int bq769x0_health(struct battery_monitor_dev_s 
*dev, int *health)
     }
   else
     {
-     *health = BATTERY_HEALTH_GOOD;
+      *health = BATTERY_HEALTH_GOOD;
     }
 
   return OK;
@@ -1476,16 +1476,16 @@ static int bq769x0_gettemperature(FAR struct 
bq769x0_dev_s *priv,
 
   switch (priv->chip)
     {
-    case CHIP_BQ76920:
-      chip_sensors = BQ76920_TEMP_COUNT;
-      break;
-    case CHIP_BQ76930:
-      chip_sensors = BQ76930_TEMP_COUNT;
-      break;
-    default:
-    case CHIP_BQ76940:
-      chip_sensors = BQ76940_TEMP_COUNT;
-      break;
+      case CHIP_BQ76920:
+        chip_sensors = BQ76920_TEMP_COUNT;
+        break;
+      case CHIP_BQ76930:
+        chip_sensors = BQ76930_TEMP_COUNT;
+        break;
+      default:
+      case CHIP_BQ76940:
+        chip_sensors = BQ76940_TEMP_COUNT;
+        break;
     }
 
   /* Read the number of sensors requested or available, whichever is smaller
@@ -1524,18 +1524,18 @@ static int bq769x0_chip_cellcount(FAR struct 
bq769x0_dev_s *priv)
 {
   switch (priv->chip)
     {
-    case CHIP_BQ76920:
-      return BQ76920_MAX_CELL_COUNT;
-      break;
+      case CHIP_BQ76920:
+        return BQ76920_MAX_CELL_COUNT;
+        break;
 
-    case CHIP_BQ76930:
-      return BQ76930_MAX_CELL_COUNT;
-      break;
+      case CHIP_BQ76930:
+        return BQ76930_MAX_CELL_COUNT;
+        break;
 
-    default:
-    case CHIP_BQ76940:
-      return BQ76940_MAX_CELL_COUNT;
-      break;
+      default:
+      case CHIP_BQ76940:
+        return BQ76940_MAX_CELL_COUNT;
+        break;
     }
 }
 
@@ -2094,59 +2094,59 @@ FAR struct battery_monitor_dev_s *
 
       switch (chip)
         {
-        case CHIP_BQ76920:
-          if (cellcount < BQ76920_MIN_CELL_COUNT ||
+          case CHIP_BQ76920:
+            if (cellcount < BQ76920_MIN_CELL_COUNT ||
               cellcount > BQ76920_MAX_CELL_COUNT)
-            {
-              berr("ERROR: Invalid number of cells (%d) for BQ76920\n",
+              {
+                berr("ERROR: Invalid number of cells (%d) for BQ76920\n",
                    cellcount);
-              kmm_free(priv);
-              return NULL;
-            }
-          else
-            {
-              priv->mapping = bq76920_cell_mapping[cellcount -
+                kmm_free(priv);
+                return NULL;
+              }
+            else
+              {
+                priv->mapping = bq76920_cell_mapping[cellcount -
                                                    BQ76920_MIN_CELL_COUNT];
-            }
-          break;
+              }
+            break;
 
-        case CHIP_BQ76930:
-          if (cellcount < BQ76930_MIN_CELL_COUNT ||
+          case CHIP_BQ76930:
+            if (cellcount < BQ76930_MIN_CELL_COUNT ||
               cellcount > BQ76930_MAX_CELL_COUNT)
-            {
-              berr("ERROR: Invalid number of cells (%d) for BQ76930\n",
+              {
+                berr("ERROR: Invalid number of cells (%d) for BQ76930\n",
                    cellcount);
-              kmm_free(priv);
-              return NULL;
-            }
-          else
-            {
-              priv->mapping = bq76930_cell_mapping[cellcount -
+                kmm_free(priv);
+                return NULL;
+              }
+            else
+              {
+                priv->mapping = bq76930_cell_mapping[cellcount -
                                                    BQ76930_MIN_CELL_COUNT];
-            }
-          break;
+              }
+            break;
 
-        case CHIP_BQ76940:
-          if (cellcount < BQ76940_MIN_CELL_COUNT ||
+          case CHIP_BQ76940:
+            if (cellcount < BQ76940_MIN_CELL_COUNT ||
               cellcount > BQ76940_MAX_CELL_COUNT)
-            {
-              berr("ERROR: Invalid number of cells (%d) for BQ76940\n",
+              {
+                berr("ERROR: Invalid number of cells (%d) for BQ76940\n",
                    cellcount);
-              kmm_free(priv);
-              return NULL;
-            }
-          else
-            {
-              priv->mapping = bq76940_cell_mapping[cellcount -
+                kmm_free(priv);
+                return NULL;
+              }
+            else
+              {
+                priv->mapping = bq76940_cell_mapping[cellcount -
                                                    BQ76940_MIN_CELL_COUNT];
-            }
-          break;
-
-        default:
-          berr("ERROR: Unrecognized chip type: %d\n", chip);
-          kmm_free(priv);
-          return NULL;
-          break;
+              }
+            break;
+
+          default:
+            berr("ERROR: Unrecognized chip type: %d\n", chip);
+            kmm_free(priv);
+            return NULL;
+            break;
         }
 
       /* Configure the BQ769x0
diff --git a/include/nuttx/crc8.h b/include/nuttx/crc8.h
index 07d61fd62df..c5da6f29ed6 100644
--- a/include/nuttx/crc8.h
+++ b/include/nuttx/crc8.h
@@ -106,6 +106,30 @@ uint8_t crc8ccitt(FAR const uint8_t *src, size_t len);
 
 uint8_t crc8ccittpart(FAR const uint8_t *src, size_t len, uint8_t crc8val);
 
+/****************************************************************************
+ * Name: crc8smbuspart
+ *
+ * Description:
+ *   Continue an SMBus packet error code (PEC) calculation with polynomial
+ *   0x07, no reflection and no final XOR.  Pass zero for the first buffer
+ *   and the previous result for subsequent buffers.  An empty buffer returns
+ *   crc8val unchanged.
+ *
+ ****************************************************************************/
+
+uint8_t crc8smbuspart(FAR const uint8_t *src, size_t len, uint8_t crc8val);
+
+/****************************************************************************
+ * Name: crc8smbus
+ *
+ * Description:
+ *   Calculate an SMBus PEC using polynomial 0x07, initial value zero,
+ *   no reflection and no final XOR.  An empty buffer returns zero.
+ *
+ ****************************************************************************/
+
+uint8_t crc8smbus(FAR const uint8_t *src, size_t len);
+
 /****************************************************************************
  * Name: crc8rohcpart
  ****************************************************************************/
diff --git a/libs/libc/misc/lib_crc8ccitt.c b/libs/libc/misc/lib_crc8ccitt.c
index e5081483a04..49c5c3d4973 100644
--- a/libs/libc/misc/lib_crc8ccitt.c
+++ b/libs/libc/misc/lib_crc8ccitt.c
@@ -101,3 +101,32 @@ uint8_t crc8ccitt(FAR const uint8_t *src, size_t len)
 {
   return crc8ccittpart(src, len, 0);
 }
+
+/***************************************************************************
+ * Name: crc8smbuspart
+ *
+ * Description:
+ *   Continue an SMBus packet error code calculation using polynomial 0x07,
+ *   without reflection or a final XOR.  Pass zero for the initial CRC.
+ *
+ ***************************************************************************/
+
+uint8_t crc8smbuspart(FAR const uint8_t *src, size_t len, uint8_t crc8val)
+{
+  /* Cancel the entry and exit inversions in the shared table helper. */
+
+  return crc8table(crc8_tab, src, len, crc8val ^ 0xff) ^ 0xff;
+}
+
+/***************************************************************************
+ * Name: crc8smbus
+ *
+ * Description:
+ *   Calculate an SMBus packet error code with an initial CRC of zero.
+ *
+ ***************************************************************************/
+
+uint8_t crc8smbus(FAR const uint8_t *src, size_t len)
+{
+  return crc8smbuspart(src, len, 0);
+}

Reply via email to