RA Flexible Software Package Documentation  Release v5.7.0

 
ZMOD4XXX Gas Sensor (rm_zmod4xxx)

Functions

fsp_err_t RM_ZMOD4XXX_Open (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_cfg_t const *const p_cfg)
 This function should be called when start a measurement and when measurement data is stale data. Sends the slave address to the zmod4xxx and start a measurement. Implements rm_zmod4xxx_api_t::open. More...
 
fsp_err_t RM_ZMOD4XXX_Close (rm_zmod4xxx_ctrl_t *const p_api_ctrl)
 This function should be called when close the sensor. Implements rm_zmod4xxx_api_t::close. More...
 
fsp_err_t RM_ZMOD4XXX_MeasurementStart (rm_zmod4xxx_ctrl_t *const p_api_ctrl)
 This function should be called when start a measurement. Implements rm_zmod4xxx_api_t::measurementStart. More...
 
fsp_err_t RM_ZMOD4XXX_MeasurementStop (rm_zmod4xxx_ctrl_t *const p_api_ctrl)
 This function should be called when stop a measurement. Implements rm_zmod4xxx_api_t::measurementStop. More...
 
fsp_err_t RM_ZMOD4XXX_StatusCheck (rm_zmod4xxx_ctrl_t *const p_api_ctrl)
 This function should be called when polling is used. It reads the status of sensor. Implements rm_zmod4xxx_api_t::statusCheck. More...
 
fsp_err_t RM_ZMOD4XXX_Read (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::read. More...
 
fsp_err_t RM_ZMOD4XXX_Iaq1stGenDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_iaq_1st_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::iaq1stGenDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_Iaq2ndGenDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_iaq_2nd_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::iaq2ndGenDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_OdorDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_odor_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::odorDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_SulfurOdorDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_sulfur_odor_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::sulfurOdorDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_Oaq1stGenDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_oaq_1st_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::oaq1stGenDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_Oaq2ndGenDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_oaq_2nd_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::oaq2ndGenDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_RaqDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_raq_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::raqDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_RelIaqDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_rel_iaq_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::relIaqDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_PbaqDataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_pbaq_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::pbaqDataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_No2O3DataCalculate (rm_zmod4xxx_ctrl_t *const p_api_ctrl, rm_zmod4xxx_raw_data_t *const p_raw_data, rm_zmod4xxx_no2_o3_data_t *const p_zmod4xxx_data)
 This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::no2O3DataCalculate. More...
 
fsp_err_t RM_ZMOD4XXX_TemperatureAndHumiditySet (rm_zmod4xxx_ctrl_t *const p_api_ctrl, float temperature, float humidity)
 This function is valid only for OAQ_2nd_Gen and IAQ_2nd_Gen_ULP. This function should be called before DataCalculate. Humidity and temperature measurements are needed for ambient compensation. Implements rm_zmod4xxx_api_t::temperatureAndHumiditySet. More...
 
fsp_err_t RM_ZMOD4XXX_DeviceErrorCheck (rm_zmod4xxx_ctrl_t *const p_api_ctrl)
 This function is valid only for IAQ_2nd_Gen and IAQ_2nd_Gen_ULP. This function should be called before Read and DataCalculate. Check for unexpected reset occurs or getting unvalid ADC data. Implements rm_zmod4xxx_api_t::deviceErrorCheck. More...
 

Detailed Description

Middleware to implement the ZMOD4XXX sensor interface. This module implements the ZMOD4XXX Middleware Interface.

Overview

The following measurement modes are EOL.

This module provides an API for configuring and controlling the ZMOD4XXX sensor. Supported ZMOD4XXX sensors are below.

I2C communication with the ZMOD4XXX sensor is realized by connecting with the rm_comms_i2c module.

Features

The ZMOD4XXX sensor interface implementation has the following key features:

Configuration

Build Time Configurations for rm_zmod4xxx

The following build time configurations are defined in fsp_cfg/rm_zmod4xxx_cfg.h:

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected code for parameter checking is included in the build.

Configurations for Sensor > ZMOD4XXX Gas Sensor (rm_zmod4xxx)

This module can be added to the Stacks tab via New Stack > Sensor > ZMOD4XXX Gas Sensor (rm_zmod4xxx).

ConfigurationOptionsDefaultDescription
NameName must be a valid C symbolg_zmod4xxx_sensor0 Module name.
Comms I2C CallbackName must be a valid C symbolzmod4xxx_comms_i2c_callback A user COMMS I2C callback function can be provided.
IRQ CallbackName must be a valid C symbolzmod4xxx_irq_callback A user IRQ callback function can be provided.

Pin Configuration

This module use SDA and SCL pins of I2C Master and SCI I2C.

Usage Notes

ZMOD4410 datasheet is here.
The ZMOD4410 has five modes of operation.
The ZMOD4410 will respond to TVOC immediately upon start-up; however, a conditioning period of 48 hours followed by a sensor module restart in an ambient environment is recommended to improve stability and obtain maximum performance.
Best results are achieved with continuous operation because the module algorithm can learn about the environment over time.

Method Description
IAQ 1st Generation Continuous Measurement of UBA levels for IAQ and eCO2, provides continuous data
IAQ 1st Generation Low Power Measurement of UBA levels for IAQ and eCO2, fixed sampling interval of 6 seconds
IAQ 2nd Generation Using AI for improved ppm TVOC, IAQ and eCO2 functionality (recommended for new designs)
IAQ 2nd Generation Ultra Low Power Using AI for improved ppm TVOC, IAQ and eCO2 functionality. This method offers a much lower power consumption
Relative IAQ Lightweight algorithm reacts to air quality changes and outputs a relative IAQ
Relative IAQ Ultra Low Power Lightweight algorithm reacts to air quality changes and outputs a relative IAQ. This method offers a much lower power consumption
Public Building AQ Standard (PBAQ) For highly accurate and consistent sensor readings to fulfill public building standards.
Odor Control signal based on Air Quality Changes
Sulfur-based Odor Discrimination The odors in “sulfur” (sulfur based) and “acceptable” (organic based) and shows an intensity level of the smell

ZMOD4450 datasheet is here.
The ZMOD4450 has one modes of operation.
The response time for a gas stimulation is always within a few seconds, depending on the gas and its concentration. An active or direct airflow onto the sensor module is not necessary since diffusion of ambient gas does not limit the sensor module response time. The ZMOD4450 will respond to typical refrigeration gases immediate upon start-up; however, a conditioning period of 48 hours in a refrigeration environment is recommended to improve stability and get maximum performance, as the module algorithm is able to learn about the refrigeration environment over time.

Method Description
RAQ Control signal based on Refrigerator Air Quality Changes

ZMOD4510 datasheet is here.
The ZMOD4510 has two modes of operation.
The ZMOD4510 in OAQ 1st Gen operation will respond to typical outdoor gases after a warm-up time of 60 min, consisting of 20 min for stabilization and 40 min for baseline finding.
For OAQ 2nd Gen operation a response to ozone will be seen after a warmup time of 30 min.
For NO2 O3 operation a response to nitrogen_dioxide and ozone will be seen after a warmup time of 5 min.
In all operation modes a conditioning period of 48 hours followed by a sensor module restart in an ambient environment is recommended to improve stability and obtain maximum performance.

Method Description
OAQ 1st Generation Measurement of Air Quality
OAQ 2nd Generation Selective Ozone featuring Ultra-Low Power
NO2 O3 Selective nitrogen dioxide and ozone firmware

A library corresponding to each of these modes is required. By setting in RA Configuration, the library will be generated in the ra/fsp/lib/rm_zmod4xxx folder of your project.

If an RTOS is used, blocking and bus lock is available.

Notifications

The ZMOD4xxx sensor needs a reset before operation; please input a reset signal to the RES_N pin (active low).

Program flow for OAQ 2nd gen is changed in FSP v4.0.0. Please refer to the programming manual [R36US0004EU] and the application note[R01AN5899].
R01AN5899 : https://www.renesas.com/document/apn/zmod4xxx-sample-application
R36US0004EU : https://www.renesas.com/document/mat/zmod4510-programming-manual-read-me

Bus Initialization

The ZMOD4XXX interface expects a bus instance to be opened before opening any ZMOD4XXX device. The interface will handle switching between devices on the bus but will not open or close the bus instance. The user should open the bus with the appropriate I2C Master Interface open call.

Initialization

Initialize with RM_ZMOD4XXX_Open(). One channel of timer is required to measure the waiting time at initialization.

From measurement start to data acquisition

After normal completion, start the measurement with RM_ZMOD4XXX_MeasurementStart(). An endless loop continuously checks the status of the ZMOD4XXX sensor and reads its data. The raw data is subsequently processed, and the air quality values are calculated.

If IRQ is enabled

  1. Call RM_ZMOD4XXX_MeasurementStart().
  2. Wait until RM_ZMOD4XXX_EVENT_MEASUREMENT_COMPLETE is received via IRQ callback.
  3. Call RM_ZMOD4XXX_Read(). This function will read the ADC data.
  4. Wait until RM_ZMOD4XXX_EVENT_SUCCESS is received.
  5. Call the DataCalculate API according to the mode.

If IRQ is disabled

  1. Call RM_ZMOD4XXX_MeasurementStart().
  2. Wait until RM_ZMOD4XXX_EVENT_SUCCESS is received.
  3. Call RM_ZMOD4XXX_StatusCheck(). This function will execute a status check over I2C.
  4. If RM_ZMOD4XXX_EVENT_MEASUREMENT_NOT_COMPLETE is received in callback, user should wait some time and then call RM_ZMOD4XXX_StatusCheck() again.
  5. Wait until RM_ZMOD4XXX_EVENT_MEASUREMENT_COMPLETE is received.
  6. Call RM_ZMOD4XXX_Read() and read the ADC data.
  7. Wait until RM_ZMOD4XXX_EVENT_SUCCESS is received.
  8. Call the DataCalculate API according to the mode.

Checking device error for IAQ 2nd Gen.

  1. Call RM_ZMOD4XXX_DeviceErrorCheck(). This function will execute a device error check over I2C.
  2. If any device error occurs, RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET or RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT are received in callback. If no device error, RM_ZMOD4XXX_EVENT_SUCCESS is received in callback.

Examples

Basic Example

These are basic examples of minimal use of ZMOD4XXX sensor implementation in an application.

IAQ 1st Gen. Continuous mode

void rm_zmod4xxx_iaq_1st_gen_continuous_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
while (1)
{
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_Iaq1stGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

IAQ 1st Gen. Low Power mode

void rm_zmod4xxx_iaq_1st_gen_low_power_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_Iaq1stGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
/* Delay required time. See Table 3 in the ZMOD4410 Programming Manual. */
}
}

IAQ 2nd Gen.

void rm_zmod4xxx_iaq_2nd_gen_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
float temperature = ZMOD4XXX_DEFAULT_TEMPERATURE_20F;
float humidity = ZMOD4XXX_DEFAULT_HUMIDITY_50F;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
/* Delay required time. See Table 3 in the ZMOD4410 Programming Manual. */
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Check validness of ADC results:
* - RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET : Unvalid ADC results due to an unexpected reset.
* - RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT: Unvalid ADC results due a still running measurement while results readout.
*//* Please reset device. */
while (1)
{
;
}
}
/* Set the current temperature and humidity */
err = RM_ZMOD4XXX_TemperatureAndHumiditySet(&g_zmod4xxx_ctrl, temperature, humidity);
handle_error(err);
err = RM_ZMOD4XXX_Iaq2ndGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

IAQ 2nd Gen. ULP

void rm_zmod4xxx_iaq_2nd_gen_ulp_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
float temperature = ZMOD4XXX_DEFAULT_TEMPERATURE_20F;
float humidity = ZMOD4XXX_DEFAULT_HUMIDITY_50F;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
/* First delay. See Table 4 in the ZMOD4410 Programming Manual. It should be longer than 1010 ms. */
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status or Measurement not completed due to unexpected reset. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Check validness of ADC results:
* - RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET : Unvalid ADC results due to an unexpected reset.
* - RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT: Unvalid ADC results due a still running measurement while results readout.
*//* Please reset device. */
while (1)
{
;
}
}
/* Set the current temperature and humidity */
err = RM_ZMOD4XXX_TemperatureAndHumiditySet(&g_zmod4xxx_ctrl, temperature, humidity);
handle_error(err);
err = RM_ZMOD4XXX_Iaq2ndGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
/* Second delay. See Table 4 in the ZMOD4410 Programming Manual. The sum of the first and second delay should amount 90 seconds. */
R_BSP_SoftwareDelay(ZMOD4XXX_WAIT_90000_MS - ZMOD4XXX_WAIT_1010_MS, BSP_DELAY_UNITS_MILLISECONDS);
}
}

Relative IAQ

void rm_zmod4xxx_rel_iaq_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
/* Delay required time. See Table 6 in the ZMOD4410 Programming Manual. */
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_RelIaqDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

Relative IAQ ULP

void rm_zmod4xxx_rel_iaq_ulp_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
/* First delay. See Table 7 in the ZMOD4410 Programming Manual. It should be longer than 1010 ms. */
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status or Measurement not completed due to unexpected reset. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Check validness of ADC results:
* - RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET : Unvalid ADC results due to an unexpected reset.
* - RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT: Unvalid ADC results due a still running measurement while results readout.
*//* Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_RelIaqDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
/* Second delay. See Table 7 in the ZMOD4410 Programming Manual. The sum of the first and second delay should amount 90 seconds. */
R_BSP_SoftwareDelay(ZMOD4XXX_WAIT_90000_MS - ZMOD4XXX_WAIT_1010_MS, BSP_DELAY_UNITS_MILLISECONDS);
}
}

PBAQ

void rm_zmod4xxx_pbaq_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
rm_zmod4xxx_pbaq_data_t zmod4410_data;
float temperature = ZMOD4XXX_DEFAULT_TEMPERATURE_20F;
float humidity = ZMOD4XXX_DEFAULT_HUMIDITY_50F;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
/* Delay required time. See Table 5 in the ZMOD4410 Programming Manual. */
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status. Please reset device. */
while (1)
{
;
}
}
/* Set the current temperature and humidity */
err = RM_ZMOD4XXX_TemperatureAndHumiditySet(&g_zmod4xxx_ctrl, temperature, humidity);
handle_error(err);
err = RM_ZMOD4XXX_PbaqDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

Odor

void rm_zmod4xxx_odor_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
rm_zmod4xxx_odor_data_t zmod4410_data;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
while (1)
{
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_OdorDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

Sulfur Odor

void rm_zmod4xxx_sulfur_odor_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_SulfurOdorDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
/* Delay required time. See Table 6 in the ZMOD4410 Programming Manual. */
}
}

OAQ 1st Gen.

void rm_zmod4xxx_oaq_1st_gen_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_Oaq1stGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4510_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4510_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

OAQ 2nd Gen.

void rm_zmod4xxx_oaq_2nd_gen_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
float temperature = ZMOD4XXX_DEFAULT_TEMPERATURE_20F;
float humidity = ZMOD4XXX_DEFAULT_HUMIDITY_50F;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
/* Delay required time. See Table 4 in the ZMOD4510 Programming Manual. */
g_zmod4xxx_i2c_callback_flag = 0;
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status or Measurement not completed due to unexpected reset. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Check validness of ADC results:
* - RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET : Unvalid ADC results due to an unexpected reset.
* - RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT: Unvalid ADC results due a still running measurement while results readout.
*//* Please reset device. */
while (1)
{
;
}
}
/* Set the current temperature and humidity */
err = RM_ZMOD4XXX_TemperatureAndHumiditySet(&g_zmod4xxx_ctrl, temperature, humidity);
handle_error(err);
err = RM_ZMOD4XXX_Oaq2ndGenDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4510_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4510_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

NO2 O3

void rm_zmod4xxx_no2_o3_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
float temperature = ZMOD4XXX_DEFAULT_TEMPERATURE_20F;
float humidity = ZMOD4XXX_DEFAULT_HUMIDITY_50F;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
while (1)
{
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
/* Delay required time. See Table 3 in the ZMOD4510 Programming Manual. */
g_zmod4xxx_i2c_callback_flag = 0;
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Error during read of sensor status or Measurement not completed due to unexpected reset. Please reset device. */
while (1)
{
;
}
}
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_DeviceErrorCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
if ((RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET == g_zmod4xxx_i2c_callback_event) ||
(RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT == g_zmod4xxx_i2c_callback_event))
{
/* Check validness of ADC results:
* - RM_ZMOD4XXX_EVENT_DEV_ERR_POWER_ON_RESET : Unvalid ADC results due to an unexpected reset.
* - RM_ZMOD4XXX_EVENT_DEV_ERR_ACCESS_CONFLICT: Unvalid ADC results due a still running measurement while results readout.
*//* Please reset device. */
while (1)
{
;
}
}
/* Set the current temperature and humidity */
err = RM_ZMOD4XXX_TemperatureAndHumiditySet(&g_zmod4xxx_ctrl, temperature, humidity);
handle_error(err);
err = RM_ZMOD4XXX_No2O3DataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4510_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4510_data */
}
{
/* Gas data is invalid. */
}
else if (FSP_ERR_SENSOR_INVALID_DATA == err)
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

RAQ

void rm_zmod4xxx_raq_basic_example (void)
{
fsp_err_t err = FSP_SUCCESS;
rm_zmod4xxx_raq_data_t zmod4410_data;
/* Open the I2C bus if it is not already open. */
rm_comms_i2c_bus_extended_cfg_t * p_extend =
(rm_comms_i2c_bus_extended_cfg_t *) g_zmod4xxx_cfg.p_comms_instance->p_cfg->p_extend;
i2c_master_instance_t * p_driver_instance = (i2c_master_instance_t *) p_extend->p_driver_instance;
p_driver_instance->p_api->open(p_driver_instance->p_ctrl, p_driver_instance->p_cfg);
#if BSP_CFG_RTOS
/* Create a semaphore for blocking if a semaphore is not NULL */
if (NULL != p_extend->p_blocking_semaphore)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_semaphore_create(p_extend->p_blocking_semaphore->p_semaphore_handle,
p_extend->p_blocking_semaphore->p_semaphore_name,
(ULONG) 0);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_blocking_semaphore->p_semaphore_handle) =
xSemaphoreCreateCountingStatic((UBaseType_t) 1,
(UBaseType_t) 0,
p_extend->p_blocking_semaphore->p_semaphore_memory);
#endif
}
/* Create a recursive mutex for bus lock if a recursive mutex is not NULL */
if (NULL != p_extend->p_bus_recursive_mutex)
{
#if BSP_CFG_RTOS == 1 // AzureOS
tx_mutex_create(p_extend->p_bus_recursive_mutex->p_mutex_handle,
p_extend->p_bus_recursive_mutex->p_mutex_name,
TX_INHERIT);
#elif BSP_CFG_RTOS == 2 // FreeRTOS
*(p_extend->p_bus_recursive_mutex->p_mutex_handle) =
xSemaphoreCreateRecursiveMutexStatic(p_extend->p_bus_recursive_mutex->p_mutex_memory);
#endif
}
#endif
/* Reset ZMOD sensor (active low). Please change to the IO port connected to the RES_N pin of the ZMOD sensor on the customer board. */
err = RM_ZMOD4XXX_Open(&g_zmod4xxx_ctrl, &g_zmod4xxx_cfg);
/* Handle any errors. This function should be defined by the user. */
handle_error(err);
#if ZMOD4XXX_IRQ_ENABLE
g_zmod4xxx_irq_callback_flag = 0;
#endif
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_MeasurementStart(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
while (1)
{
do
{
#if ZMOD4XXX_IRQ_ENABLE
while (0U == g_zmod4xxx_irq_callback_flag)
{
}
g_zmod4xxx_irq_callback_flag = 0;
#else
err = RM_ZMOD4XXX_StatusCheck(&g_zmod4xxx_ctrl);
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
#endif
err = RM_ZMOD4XXX_Read(&g_zmod4xxx_ctrl, &raw_data);
{
}
handle_error(err);
while (0U == g_zmod4xxx_i2c_callback_flag)
{
}
g_zmod4xxx_i2c_callback_flag = 0;
err = RM_ZMOD4XXX_RaqDataCalculate(&g_zmod4xxx_ctrl, &raw_data, &zmod4410_data);
if (FSP_SUCCESS == err)
{
/* Describe the process by referring to zmod4410_data */
}
{
/* Gas data is invalid. */
}
else
{
handle_error(err);
}
}
}

Data Structures

struct  rm_zmod4xxx_init_process_params_t
 
struct  rm_zmod4xxx_instance_ctrl_t
 

Enumerations

enum  rm_zmod4xxx_lib_type_t
 

Data Structure Documentation

◆ rm_zmod4xxx_init_process_params_t

struct rm_zmod4xxx_init_process_params_t

ZMOD4XXX initialization process block

Data Fields
volatile uint32_t delay_ms Delay milliseconds.
volatile bool communication_finished Communication flag for blocking.
volatile bool measurement_finished IRQ flag.
volatile rm_zmod4xxx_event_t event Callback event.

◆ rm_zmod4xxx_instance_ctrl_t

struct rm_zmod4xxx_instance_ctrl_t

ZMOD4XXX control block

Data Fields

uint32_t open
 Open flag.
 
uint8_t buf [RM_ZMOD4XXX_MAX_I2C_BUF_SIZE]
 Buffer for I2C communications.
 
uint8_t register_address
 Register address to access.
 
rm_zmod4xxx_status_params_t status
 Status parameter.
 
volatile bool dev_err_check
 Flag for checking device error.
 
volatile rm_zmod4xxx_event_t event
 Callback event.
 
rm_zmod4xxx_init_process_params_t init_process_params
 For the initialization process.
 
rm_zmod4xxx_cfg_t const * p_cfg
 Pointer of configuration block.
 
rm_comms_instance_t const * p_comms_i2c_instance
 Pointer of I2C Communications Middleware instance structure.
 
rm_zmod4xxx_lib_extended_cfg_t * p_zmod4xxx_lib
 Pointer of ZMOD4XXX Lib extended configuration.
 
void const * p_irq_instance
 Pointer to IRQ instance.
 
void const * p_context
 Pointer to the user-provided context.
 
void(* p_comms_callback )(rm_zmod4xxx_callback_args_t *p_args)
 I2C Communications callback.
 
void(* p_irq_callback )(rm_zmod4xxx_callback_args_t *p_args)
 IRQ callback.
 

Enumeration Type Documentation

◆ rm_zmod4xxx_lib_type_t

ZMOD4XXX Library type

Function Documentation

◆ RM_ZMOD4XXX_Open()

fsp_err_t RM_ZMOD4XXX_Open ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_cfg_t const *const  p_cfg 
)

This function should be called when start a measurement and when measurement data is stale data. Sends the slave address to the zmod4xxx and start a measurement. Implements rm_zmod4xxx_api_t::open.

Return values
FSP_SUCCESSSuccessfully started.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_ALREADY_OPENModule is already open.
FSP_ERR_UNSUPPORTEDUnsupport product ID.
FSP_ERR_TIMEOUTcommunication is timeout.
FSP_ERR_ABORTEDcommunication is aborted.

◆ RM_ZMOD4XXX_Close()

fsp_err_t RM_ZMOD4XXX_Close ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl)

This function should be called when close the sensor. Implements rm_zmod4xxx_api_t::close.

Return values
FSP_SUCCESSSuccessfully closed.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not open.

◆ RM_ZMOD4XXX_MeasurementStart()

fsp_err_t RM_ZMOD4XXX_MeasurementStart ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl)

This function should be called when start a measurement. Implements rm_zmod4xxx_api_t::measurementStart.

Return values
FSP_SUCCESSSuccessfully started.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_TIMEOUTcommunication is timeout.
FSP_ERR_ABORTEDcommunication is aborted.

◆ RM_ZMOD4XXX_MeasurementStop()

fsp_err_t RM_ZMOD4XXX_MeasurementStop ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl)

This function should be called when stop a measurement. Implements rm_zmod4xxx_api_t::measurementStop.

Return values
FSP_SUCCESSSuccessfully started.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_TIMEOUTcommunication is timeout.
FSP_ERR_ABORTEDcommunication is aborted.

◆ RM_ZMOD4XXX_StatusCheck()

fsp_err_t RM_ZMOD4XXX_StatusCheck ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl)

This function should be called when polling is used. It reads the status of sensor. Implements rm_zmod4xxx_api_t::statusCheck.

Return values
FSP_SUCCESSSuccessfully started.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_TIMEOUTcommunication is timeout.
FSP_ERR_ABORTEDcommunication is aborted.

◆ RM_ZMOD4XXX_Read()

fsp_err_t RM_ZMOD4XXX_Read ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::read.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_TIMEOUTCommunication is timeout.
FSP_ERR_ABORTEDCommunication is aborted.
FSP_ERR_SENSOR_MEASUREMENT_NOT_FINISHEDMeasurement is not finished.

◆ RM_ZMOD4XXX_Iaq1stGenDataCalculate()

fsp_err_t RM_ZMOD4XXX_Iaq1stGenDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_iaq_1st_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::iaq1stGenDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_Iaq2ndGenDataCalculate()

fsp_err_t RM_ZMOD4XXX_Iaq2ndGenDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_iaq_2nd_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::iaq2ndGenDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_OdorDataCalculate()

fsp_err_t RM_ZMOD4XXX_OdorDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_odor_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::odorDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_SulfurOdorDataCalculate()

fsp_err_t RM_ZMOD4XXX_SulfurOdorDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_sulfur_odor_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::sulfurOdorDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_Oaq1stGenDataCalculate()

fsp_err_t RM_ZMOD4XXX_Oaq1stGenDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_oaq_1st_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::oaq1stGenDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_Oaq2ndGenDataCalculate()

fsp_err_t RM_ZMOD4XXX_Oaq2ndGenDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_oaq_2nd_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::oaq2ndGenDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_RaqDataCalculate()

fsp_err_t RM_ZMOD4XXX_RaqDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_raq_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::raqDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_RelIaqDataCalculate()

fsp_err_t RM_ZMOD4XXX_RelIaqDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_rel_iaq_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::relIaqDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_PbaqDataCalculate()

fsp_err_t RM_ZMOD4XXX_PbaqDataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_pbaq_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::pbaqDataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_No2O3DataCalculate()

fsp_err_t RM_ZMOD4XXX_No2O3DataCalculate ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
rm_zmod4xxx_raw_data_t *const  p_raw_data,
rm_zmod4xxx_no2_o3_data_t *const  p_zmod4xxx_data 
)

This function should be called when measurement finishes. To check measurement status either polling or busy/interrupt pin can be used. Implements rm_zmod4xxx_api_t::no2O3DataCalculate.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter or library internal error occured.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_SENSOR_IN_STABILIZATIONModule is stabilizing.
FSP_ERR_SENSOR_INVALID_DATASensor probably damaged. Algorithm results may be incorrect.

◆ RM_ZMOD4XXX_TemperatureAndHumiditySet()

fsp_err_t RM_ZMOD4XXX_TemperatureAndHumiditySet ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl,
float  temperature,
float  humidity 
)

This function is valid only for OAQ_2nd_Gen and IAQ_2nd_Gen_ULP. This function should be called before DataCalculate. Humidity and temperature measurements are needed for ambient compensation. Implements rm_zmod4xxx_api_t::temperatureAndHumiditySet.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.

◆ RM_ZMOD4XXX_DeviceErrorCheck()

fsp_err_t RM_ZMOD4XXX_DeviceErrorCheck ( rm_zmod4xxx_ctrl_t *const  p_api_ctrl)

This function is valid only for IAQ_2nd_Gen and IAQ_2nd_Gen_ULP. This function should be called before Read and DataCalculate. Check for unexpected reset occurs or getting unvalid ADC data. Implements rm_zmod4xxx_api_t::deviceErrorCheck.

Return values
FSP_SUCCESSSuccessfully results are read.
FSP_ERR_ASSERTIONNull pointer passed as a parameter.
FSP_ERR_NOT_OPENModule is not opened configured.
FSP_ERR_TIMEOUTcommunication is timeout.
FSP_ERR_ABORTEDcommunication is aborted.