diff --git a/drivers/can/can.c b/drivers/can/can.c index 22dfdc1f8d02f..fd74f571c3add 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 ae007d16a3859..cf3f8ec1f5b8f 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]; };