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

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

commit 2ebfdf737c0e3d86bc9cce31a65d3a3b13e04018
Author: zhaohaiyang1 <[email protected]>
AuthorDate: Wed Jul 10 14:12:15 2024 +0800

    add the ability that control CAN transceiver state.
    
    add the ability that control CAN transceiver state in nuttx.
    
    Signed-off-by: zhaohaiyang1 <[email protected]>
---
 drivers/can/can.c       | 47 +++++++++++++++++++++++++++++++++
 include/nuttx/can/can.h | 70 ++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 111 insertions(+), 6 deletions(-)

diff --git a/drivers/can/can.c b/drivers/can/can.c
index 22dfdc1f8d..fd74f571c3 100644
--- a/drivers/can/can.c
+++ b/drivers/can/can.c
@@ -902,6 +902,53 @@ static int can_ioctl(FAR struct file *filep, int cmd, 
unsigned long arg)
         }
         break;
 
+      /* Set specfic can transceiver state */
+
+      case CANIOC_SET_TRANSVSTATE:
+        {
+          /* if we don't use dev->cd_transv->cts_ops, please initlize
+           * this poniter to NULL in lower board code when Board reset.
+           */
+
+          if (dev->cd_transv && dev->cd_transv->ct_ops
+              && dev->cd_transv->ct_ops->ct_setstate)
+            {
+              FAR const struct can_transv_ops_s *ct_ops =
+                                                dev->cd_transv->ct_ops;
+              ret = ct_ops->ct_setstate(dev->cd_transv, arg);
+            }
+          else
+            {
+              canerr("dev->cd_transv->cts_ops is NULL!");
+              ret = -ENOTTY;
+            }
+        }
+        break;
+
+      /* Get specfic can transceiver state */
+
+      case CANIOC_GET_TRANSVSTATE:
+        {
+          /* if we don't use dev->cd_transv->cts_ops, please initlize
+           * this poniter to NULL in lower board code when Board reset.
+           */
+
+          if (dev->cd_transv && dev->cd_transv->ct_ops
+              && dev->cd_transv->ct_ops->ct_getstate)
+            {
+              int *state = (FAR int *)arg;
+              FAR const struct can_transv_ops_s *ct_ops =
+                                                dev->cd_transv->ct_ops;
+              ret = ct_ops->ct_getstate(dev->cd_transv, state);
+            }
+          else
+            {
+              canerr("dev->cd_transv->cts_ops is NULL!");
+              ret = -ENOTTY;
+            }
+        }
+        break;
+
       /* Not a "built-in" ioctl command.. perhaps it is unique to this
        * lower-half, device driver.
        */
diff --git a/include/nuttx/can/can.h b/include/nuttx/can/can.h
index ae007d16a3..cf3f8ec1f5 100644
--- a/include/nuttx/can/can.h
+++ b/include/nuttx/can/can.h
@@ -261,8 +261,8 @@
  * CANIOC_SET_STATE
  *   Description:    Set specfic can controller state
  *
- *   Argument:       A pointer to an enumeration type that describes the CAN
- *                   state
+ *   Argument:       A pointer to an int type that describes the CAN
+ *                   controller state.
  *   returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
  *                   is returned with the errno variable set to indicate the
  *                   nature of the error.
@@ -271,8 +271,28 @@
  * CANIOC_GET_STATE
  *   Description:    Get specfic can controller state
  *
- *   Argument:       A pointer to an enumeration type that describes the CAN
- *                   state
+ *   Argument:       A pointer to an int type that describes the CAN
+ *                   controller state.
+ *   returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_SET_TRANSV_STATE
+ *   Description:    Set specfic can transceiver state
+ *
+ *   Argument:       A pointer to an int type that describes the CAN
+ *                   transceiver state.
+ *   returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_GET_TRANSV_STATE
+ *   Description:    Get specfic can transceiver state
+ *
+ *   Argument:       A pointer to an int type that describes the CAN
+ *                   transceiver state.
  *   returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
  *                   is returned with the errno variable set to indicate the
  *                   nature of the error.
@@ -296,9 +316,11 @@
 #define CANIOC_IOFLUSH            _CANIOC(15)
 #define CANIOC_SET_STATE          _CANIOC(16)
 #define CANIOC_GET_STATE          _CANIOC(17)
+#define CANIOC_SET_TRANSVSTATE    _CANIOC(18)
+#define CANIOC_GET_TRANSVSTATE    _CANIOC(19)
 
 #define CAN_FIRST                 0x0001         /* First common command */
-#define CAN_NCMDS                 15             /* 16 common commands   */
+#define CAN_NCMDS                 19             /* 20 common commands   */
 
 /* User defined ioctl commands are also supported. These will be forwarded
  * by the upper-half CAN driver to the lower-half CAN driver via the
@@ -479,6 +501,22 @@
 
 #define CAN_STATE_START           1
 
+/* Indicates that the can transceiver is in the sleep state */
+
+#define CAN_TRANSVSTATE_SLEEP     0
+
+/* Indicates that the can transceiver is in the standby state just called
+ * first-level power saving mode.
+ */
+
+#define CAN_TRANSVSTATE_STANDBY   1
+
+/* Indicates that the can transceiver is in the awake state
+ * the transceiver can transmit and receive data.
+ */
+
+#define CAN_TRANSVSTATE_NORMAL    2
+
 /* CAN bit timing support ***************************************************/
 
 #define CAN_BITTIMING_NOMINAL     0  /* Specifies nominal bittiming */
@@ -624,6 +662,21 @@ struct can_rtrwait_s
  */
 
 struct can_dev_s;
+
+/* This is the device structure as struct can_dev_s's subdevice
+ * used by the driver.
+ */
+
+struct can_transv_s;
+
+struct can_transv_ops_s
+{
+  CODE int (*ct_setstate)(FAR struct can_transv_s *transv, int state);
+
+  CODE int (*ct_getstate)(FAR struct can_transv_s *transv,
+                          FAR int *state);
+};
+
 struct can_ops_s
 {
   /* Reset the CAN device.  Called early to initialize the hardware. This
@@ -702,6 +755,11 @@ struct can_reader_s
   struct can_rxfifo_s  fifo;             /* Describes receive FIFO */
 };
 
+struct can_transv_s
+{
+  FAR const struct can_transv_ops_s *ct_ops;    /* Arch-specific operations */
+};
+
 struct can_dev_s
 {
   uint8_t              cd_crefs;         /* References counts on number of 
opens */
@@ -718,7 +776,7 @@ struct can_dev_s
   struct can_rtrwait_s cd_rtr[CONFIG_CAN_NPENDINGRTR];
   FAR const struct can_ops_s *cd_ops;    /* Arch-specific operations */
   FAR void            *cd_priv;          /* Used by the arch-specific logic */
-
+  FAR struct can_transv_s *cd_transv;    /* Describes CAN transceiver */
   FAR struct pollfd   *cd_fds[CONFIG_CAN_NPOLLWAITERS];
 };
 

Reply via email to