mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +08:00
sensors/mcp9600: Converted MCP9600 legacy driver to UORB driver as per suggestions on PR #15525.
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
|
=======
|
||||||
MCP9600
|
MCP9600
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Contributed by Matteo Golin.
|
Contributed by Matteo Golin.
|
||||||
|
|
||||||
The MCP9600 is a thermocouple EMF to temperature converter made by Microchip. It is also sold as a `breakout board module
|
The MCP9600 is a thermocouple EMF to temperature converter made by Microchip. It
|
||||||
by Adafruit <https://learn.adafruit.com/adafruit-mcp9600-i2c-thermocouple-amplifier>`_.
|
is also sold as a `breakout board module by Adafruit
|
||||||
|
<https://learn.adafruit.com/adafruit-mcp9600-i2c-thermocouple-amplifier>`_.
|
||||||
|
|
||||||
Application Programming Interface
|
Application Programming Interface
|
||||||
==================================
|
==================================
|
||||||
@@ -15,26 +17,63 @@ The header file for the MCP9600 driver interface can be included using:
|
|||||||
|
|
||||||
#include <nuttx/sensors/mcp9600.h>
|
#include <nuttx/sensors/mcp9600.h>
|
||||||
|
|
||||||
The MCP9600 registration function allows the driver to be registered as a POSIX
|
The MCP9600 registration function allows the driver to be registered as a
|
||||||
character driver.
|
:doc:`UORB </components/drivers/special/sensors/sensors_uorb>` sensor.
|
||||||
|
|
||||||
The standard POSIX `read()` operation will return the device information in
|
The MCP9600 measures three types of temperature:
|
||||||
plain-text, which is useful when debugging/testing the driver using `cat` from
|
* Hot junction temperature
|
||||||
the shell.
|
* Cold junction temperature
|
||||||
|
* Temperature delta
|
||||||
|
|
||||||
The `write()` operation is not implemented for this sensor.
|
Registering this sensor will create three UORB temperature topics, each with
|
||||||
|
their own unique device number. You must specify the unique device numbers for
|
||||||
|
each topic in the registration function:
|
||||||
|
|
||||||
Specific operations the sensor offers can be performed via the POSIX `ioctl`
|
.. code-block:: c
|
||||||
operation. The supported commands are:
|
|
||||||
|
|
||||||
|
/* Registers sensor_temp1, sensor_temp2 and sensor_temp 3, where 1 is the
|
||||||
|
* hot junction topic, 2 is the cold junction topic and 3 is the delta
|
||||||
|
*/
|
||||||
|
|
||||||
|
int err;
|
||||||
|
err = mcp9600_register(i2c_master, 0x60, 1, 2, 3);
|
||||||
|
if (err < 0) {
|
||||||
|
syslog(LOG_ERR, "Could not register MCP9600: %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
This sensor offers some additional control commands for features that are not
|
||||||
|
accessible with the standard UORB interface.
|
||||||
|
|
||||||
|
* :c:macro:`SNIOC_SET_THERMO`
|
||||||
* :c:macro:`SNIOC_WHO_AM_I`
|
* :c:macro:`SNIOC_WHO_AM_I`
|
||||||
* :c:macro:`SNIOC_READ_RAW_DATA`
|
* :c:macro:`SNIOC_READ_RAW_DATA`
|
||||||
* :c:macro:`SNIOC_CHECK_STATUS_REG`
|
* :c:macro:`SNIOC_CHECK_STATUS_REG`
|
||||||
* :c:macro:`SNIOC_CONFIGURE`
|
* :c:macro:`SNIOC_CONFIGURE`
|
||||||
* :c:macro:`SNIOC_WRITECONF`
|
* :c:macro:`SNIOC_WRITECONF`
|
||||||
* :c:macro:`SNIOC_READTEMP`
|
|
||||||
* :c:macro:`SNIOC_SHUTDOWN`
|
``SNIOC_SET_THERMO``
|
||||||
* :c:macro:`SNIOC_START`
|
--------------------
|
||||||
|
|
||||||
|
This command configures the thermocouple type of the MCP9600. The device
|
||||||
|
supports the following thermocouple types:
|
||||||
|
|
||||||
|
* K
|
||||||
|
* J
|
||||||
|
* T
|
||||||
|
* N
|
||||||
|
* E
|
||||||
|
* S
|
||||||
|
* B
|
||||||
|
* R
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int err;
|
||||||
|
err = orb_ioctl(sensor, SNIOC_SET_THERMO, SENSOR_THERMO_TYPE_J);
|
||||||
|
if (err < 0) {
|
||||||
|
syslog(LOG_ERR, "Failed to set thermocouple type: %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
``SNIOC_WHO_AM_I``
|
``SNIOC_WHO_AM_I``
|
||||||
------------------
|
------------------
|
||||||
@@ -46,7 +85,7 @@ type ``struct mcp9600_devinfo_s *``.
|
|||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
struct mcp9600_devinfo_s devinfo;
|
struct mcp9600_devinfo_s devinfo;
|
||||||
err = ioctl(sensor, SNIOC_WHO_AM_I, &devinfo);
|
err = orb_ioctl(sensor, SNIOC_WHO_AM_I, &devinfo);
|
||||||
|
|
||||||
uint8_t revision_minor = MCP9600_REV_MINOR(devinfo.revision);
|
uint8_t revision_minor = MCP9600_REV_MINOR(devinfo.revision);
|
||||||
uint8_t revision_major = MCP9600_REV_MAJOR(devinfo.revision);
|
uint8_t revision_major = MCP9600_REV_MAJOR(devinfo.revision);
|
||||||
@@ -64,7 +103,7 @@ configured resolution; consult the data sheet.
|
|||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
int32_t raw;
|
int32_t raw;
|
||||||
err = ioctl(sensor, SNIOC_READ_RAW_DATA, &raw);
|
err = orb_ioctl(sensor, SNIOC_READ_RAW_DATA, &raw);
|
||||||
|
|
||||||
``SNIOC_CHECK_STATUS_REG``
|
``SNIOC_CHECK_STATUS_REG``
|
||||||
--------------------------
|
--------------------------
|
||||||
@@ -75,7 +114,7 @@ this command must be a pointer to type ``struct mcp9600_status_s``.
|
|||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
struct mcp9600_status_s status;
|
struct mcp9600_status_s status;
|
||||||
err = ioctl(sensor, SNIOC_CHECK_STATUS_REG, &status);
|
err = orb_ioctl(sensor, SNIOC_CHECK_STATUS_REG, &status);
|
||||||
|
|
||||||
``SNIOC_CONFIGURE``
|
``SNIOC_CONFIGURE``
|
||||||
-------------------
|
-------------------
|
||||||
@@ -93,7 +132,7 @@ mcp9600_devconf_s``.
|
|||||||
.resolution = MCP9600_ADC_RES_18,
|
.resolution = MCP9600_ADC_RES_18,
|
||||||
/* More fields ... */
|
/* More fields ... */
|
||||||
};
|
};
|
||||||
err = ioctl(sensor, SNIOC_CONFIGURE, &conf);
|
err = orb_ioctl(sensor, SNIOC_CONFIGURE, &conf);
|
||||||
|
|
||||||
``SNIOC_WRITECONF``
|
``SNIOC_WRITECONF``
|
||||||
-------------------
|
-------------------
|
||||||
@@ -111,36 +150,4 @@ mcp9600_alertconf_s``.
|
|||||||
.limit = 40 / 0.25,
|
.limit = 40 / 0.25,
|
||||||
/* More fields ... */
|
/* More fields ... */
|
||||||
};
|
};
|
||||||
err = ioctl(sensor, SNIOC_WRITECONF, &conf);
|
err = orb_ioctl(sensor, SNIOC_WRITECONF, &conf);
|
||||||
|
|
||||||
``SNIOC_READTEMP``
|
|
||||||
------------------
|
|
||||||
|
|
||||||
This command lets you read the three different types of temperature that the
|
|
||||||
MCP9600 can measure. The argument to this command must be a pointer to type
|
|
||||||
``struct mcp9600_temp_s``.
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
struct mcp9600_temp_s temps;
|
|
||||||
err = ioctl(sensor, SNIOC_READTEMP, &temps);
|
|
||||||
|
|
||||||
printf("Temperature: %d C\n", temps.hot_junc);
|
|
||||||
|
|
||||||
``SNIOC_SHUTDOWN``
|
|
||||||
------------------
|
|
||||||
|
|
||||||
This command shuts down the sensor. It takes no arguments.
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
err = ioctl(sensor, SNIOC_SHUTDOWN, NULL);
|
|
||||||
|
|
||||||
``SNIOC_START``
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This command starts the sensor in normal mode. It takes no arguments.
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
err = ioctl(sensor, SNIOC_START, NULL);
|
|
||||||
|
|||||||
@@ -549,9 +549,9 @@ int rp2040_common_bringup(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SENSORS_MCP9600
|
#ifdef CONFIG_SENSORS_MCP9600
|
||||||
/* Try to register MCP9600 device as /dev/thermo0 at I2C0. */
|
/* Try to register MCP9600 device as /dev/therm0 at I2C0. */
|
||||||
|
|
||||||
ret = mcp9600_register("/dev/thermo0", rp2040_i2cbus_initialize(0), 0x60);
|
ret = mcp9600_register(rp2040_i2cbus_initialize(0), 0x60, 1, 2, 3);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ERROR: couldn't initialize MCP9600: %d\n", ret);
|
syslog(LOG_ERR, "ERROR: couldn't initialize MCP9600: %d\n", ret);
|
||||||
|
|||||||
@@ -965,6 +965,21 @@ config MCP9600_I2C_FREQUENCY
|
|||||||
range 10000 100000
|
range 10000 100000
|
||||||
depends on SENSORS_MCP9600
|
depends on SENSORS_MCP9600
|
||||||
|
|
||||||
|
config SENSORS_MCP9600_POLL
|
||||||
|
bool "MCP9600 polling"
|
||||||
|
default y
|
||||||
|
depends on SENSORS_MCP9600
|
||||||
|
---help---
|
||||||
|
Enable the worker thread for polling the MCP9600 and collecting
|
||||||
|
measurements
|
||||||
|
|
||||||
|
config MCP9600_THREAD_STACKSIZE
|
||||||
|
int "MCP9600 stack size"
|
||||||
|
default 1024
|
||||||
|
depends on SENSORS_MCP9600
|
||||||
|
---help---
|
||||||
|
Stack size of the worker thread polling the MCP9600 for measurements
|
||||||
|
|
||||||
endif # SENSORS_MCP9600
|
endif # SENSORS_MCP9600
|
||||||
|
|
||||||
config SENSORS_MCP9844
|
config SENSORS_MCP9844
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ ifeq ($(CONFIG_SENSORS_MB7040),y)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SENSORS_MCP9600),y)
|
ifeq ($(CONFIG_SENSORS_MCP9600),y)
|
||||||
CSRCS += mcp9600.c
|
CSRCS += mcp9600_uorb.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SENSORS_MCP9844),y)
|
ifeq ($(CONFIG_SENSORS_MCP9844),y)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -454,7 +454,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Command: SNIOC_FLUSH
|
/* Command: SNIOC_FLUSH
|
||||||
* Description: Flush sensor harware fifo buffer.
|
* Description: Flush sensor hardware fifo buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SNIOC_FLUSH _SNIOC(0x009D)
|
#define SNIOC_FLUSH _SNIOC(0x009D)
|
||||||
@@ -466,4 +466,31 @@
|
|||||||
|
|
||||||
#define SNIOC_GET_EVENTS _SNIOC(0x009E)
|
#define SNIOC_GET_EVENTS _SNIOC(0x009E)
|
||||||
|
|
||||||
|
/* Command: SNIOC_SET_THERMO
|
||||||
|
* Description: Set the thermocouple type.
|
||||||
|
* Argument: An option from `enum sensor_thermo_type_e`
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SNIOC_SET_THERMO _SNIOC(0x009F)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Possible thermocouple types. Implementations should not rely on the enum's
|
||||||
|
* underlying value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum sensor_thermo_type_e
|
||||||
|
{
|
||||||
|
SENSOR_THERMO_TYPE_K,
|
||||||
|
SENSOR_THERMO_TYPE_J,
|
||||||
|
SENSOR_THERMO_TYPE_T,
|
||||||
|
SENSOR_THERMO_TYPE_N,
|
||||||
|
SENSOR_THERMO_TYPE_S,
|
||||||
|
SENSOR_THERMO_TYPE_E,
|
||||||
|
SENSOR_THERMO_TYPE_B,
|
||||||
|
SENSOR_THERMO_TYPE_R,
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */
|
#endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */
|
||||||
|
|||||||
@@ -56,20 +56,6 @@ enum mcp9600_alert_e
|
|||||||
MCP9600_ALERT4 = 3, /* Alert 4 */
|
MCP9600_ALERT4 = 3, /* Alert 4 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Thermocouple types */
|
|
||||||
|
|
||||||
enum mcp9600_thermocouple_e
|
|
||||||
{
|
|
||||||
MCP9600_THERMO_TYPE_K = 0x0,
|
|
||||||
MCP9600_THERMO_TYPE_J = 0x1,
|
|
||||||
MCP9600_THERMO_TYPE_T = 0x2,
|
|
||||||
MCP9600_THERMO_TYPE_N = 0x3,
|
|
||||||
MCP9600_THERMO_TYPE_S = 0x4,
|
|
||||||
MCP9600_THERMO_TYPE_E = 0x5,
|
|
||||||
MCP9600_THERMO_TYPE_B = 0x6,
|
|
||||||
MCP9600_THERMO_TYPE_R = 0x7,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ADC resolution */
|
/* ADC resolution */
|
||||||
|
|
||||||
enum mcp9600_resolution_e
|
enum mcp9600_resolution_e
|
||||||
@@ -134,7 +120,7 @@ struct mcp9600_alert_conf_s
|
|||||||
|
|
||||||
struct mcp9600_devconf_s
|
struct mcp9600_devconf_s
|
||||||
{
|
{
|
||||||
enum mcp9600_thermocouple_e thermo_type; /* Thermocouple type */
|
enum sensor_thermo_type_e thermo_type; /* Thermocouple type */
|
||||||
uint8_t filter_coeff; /* Filter coefficient */
|
uint8_t filter_coeff; /* Filter coefficient */
|
||||||
enum mcp9600_resolution_e resolution; /* ADC resolution */
|
enum mcp9600_resolution_e resolution; /* ADC resolution */
|
||||||
enum mcp9600_samples_e num_samples; /* Number of samples */
|
enum mcp9600_samples_e num_samples; /* Number of samples */
|
||||||
@@ -161,15 +147,6 @@ struct mcp9600_status_s
|
|||||||
bool alerts[4]; /* Alert statuses for alerts 1-4 (0-3) */
|
bool alerts[4]; /* Alert statuses for alerts 1-4 (0-3) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Temperature readings */
|
|
||||||
|
|
||||||
struct mcp9600_temp_s
|
|
||||||
{
|
|
||||||
int16_t temp_delta; /* Temperature delta in degrees Celsius */
|
|
||||||
int16_t hot_junc; /* Hot junction temperature in degrees Celsius */
|
|
||||||
int16_t cold_junc; /* Cold junction temperature in degrees Celsius */
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -178,20 +155,24 @@ struct mcp9600_temp_s
|
|||||||
* Name: mcp9600_register
|
* Name: mcp9600_register
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Register the MCP9600 character device as 'devpath'
|
* Register the MCP9600 UORB sensor. This registers 3 temperature UORB
|
||||||
|
* topics.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* devpath - The full path to the driver to register. E.g., "/dev/temp0"
|
|
||||||
* i2c - An instance of the I2C interface to use to communicate with
|
* i2c - An instance of the I2C interface to use to communicate with
|
||||||
* the MCP9600
|
* the MCP9600
|
||||||
* addr - The I2C address of the MCP9600, between 0x60 and 0x67
|
* addr - The I2C address of the MCP9600, between 0x60 and 0x67
|
||||||
*
|
*
|
||||||
|
* h_devno - The device number for the hot junction topic
|
||||||
|
* c_devno - The device number for the cold junction topic
|
||||||
|
* d_devno - The device number for the delta topic
|
||||||
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno value on failure.
|
* Zero (OK) on success; a negated errno value on failure.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int mcp9600_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
|
int mcp9600_register(FAR struct i2c_master_s *i2c, uint8_t addr,
|
||||||
uint8_t addr);
|
uint8_t h_devno, uint8_t c_devno, uint8_t d_devno);
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_SENSORS_MCP9600_H */
|
#endif /* __INCLUDE_NUTTX_SENSORS_MCP9600_H */
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
* Celsius.
|
* Celsius.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SENSOR_TYPE_TEMPERAUTRE 7
|
#define SENSOR_TYPE_TEMPERATURE 7
|
||||||
|
|
||||||
/* Proximity
|
/* Proximity
|
||||||
* The values correspond to the distance to the nearest
|
* The values correspond to the distance to the nearest
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
|
|
||||||
#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
|
#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
|
||||||
|
|
||||||
/* Magneric Field Uncalibrated
|
/* Magnetic Field Uncalibrated
|
||||||
* Similar to MAGNETIC_FIELD, all values are in micro-Tesla (uT)
|
* Similar to MAGNETIC_FIELD, all values are in micro-Tesla (uT)
|
||||||
* and measure the geomagnetic field in X, Y and Z axis.
|
* and measure the geomagnetic field in X, Y and Z axis.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user