diff options
Diffstat (limited to 'examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c')
-rw-r--r-- | examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c | 573 |
1 files changed, 492 insertions, 81 deletions
diff --git a/examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c b/examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c index 6f87be1..c820f12 100644 --- a/examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c +++ b/examples/imx7d_sdb_m4/demo_apps/sensor_demo/sensor_demo_imx7d/main.c @@ -33,10 +33,14 @@ /////////////////////////////////////////////////////////////////////////////// #include <stdint.h> #include <stdbool.h> +#include <string.h> #include "FreeRTOS.h" #include "task.h" #include "board.h" +#include "rdc_semaphore.h" #include "debug_console_imx.h" +#include "gpio_pins.h" +#include "gpio_imx.h" #include "i2c_xfer.h" #include "fxas21002.h" #include "fxos8700.h" @@ -45,130 +49,463 @@ //////////////////////////////////////////////////////////////////////////////// // Definition //////////////////////////////////////////////////////////////////////////////// -#define HEIGHT_UPDATE_THRESHOLD (0.5f) -#define TEMP_UPDATE_THRESHOLD (0.3f) -#define GYRO_UPDATE_THRESHOLD (5.0f) +#define HEIGHT_UPDATE_THRESHOLD (0.5f) +#define TEMP_UPDATE_THRESHOLD (0.3f) +#define GYRO_UPDATE_THRESHOLD (5.0f) +#define GYRO_OVERSAMPLE_RATIO (10) + +#define MPL3115_MPERCOUNT (0.0000152587890625f) // 1/65536 fixed range for MPL3115 +#define MPL3115_CPERCPOUNT (0.00390625f) // 1/256 fixed range for MPL3115 +#define FXAS21002_DEGPERSECPERCOUNT (0.0625F) // must be reciprocal of FCOUNTSPERDEGPERSEC + +//////////////////////////////////////////////////////////////////////////////// +// Type definition +//////////////////////////////////////////////////////////////////////////////// +typedef struct _gyro_sensor +{ + int32_t iSumYpFast[3]; // sum of fast measurements + float fYp[3]; // raw gyro sensor output (deg/s) + float fDegPerSecPerCount; // initialized to FDEGPERSECPERCOUNT + int16_t iYpFast[3]; // fast (typically 200Hz) readings + int16_t iYp[3]; // averaged gyro sensor output (counts) +} gyro_sensor_t; + +typedef struct _pressure_sensor +{ + float fHp; // float point type height (m) + float fTp; // float point type temperature (C) + float fmPerCount; // initialized to FMPERCOUNT + float fCPerCount; // initialized to FCPERCPOUNT +} pressure_sensor_t; + +//////////////////////////////////////////////////////////////////////////////// +// Static Variable +//////////////////////////////////////////////////////////////////////////////// +static i2c_handle_t I2C_handle; +static SemaphoreHandle_t xSemaphore; +static fxas_handle_t fxasHandle = {.device = &I2C_handle, + .address = BOARD_I2C_FXAS21002_ADDR}; +static fxos_handle_t fxosHandle = {.device = &I2C_handle, + .address = BOARD_I2C_FXOS8700_ADDR}; +static mpl_handle_t mplHandle = {.device = &I2C_handle}; //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// -void fxas21002Demo(void) +int32_t getOneDecimalPlace(float num) +{ + if (num < 0) + return -(((int32_t)(num * 10)) % 10); + else + return (((int32_t)(num * 10)) % 10); +} + +void printGyro(float Gxf, float Gyf, float Gzf) +{ + PRINTF("[FXAS21002] Rotate detected: X:%5d.%1ddps, Y:%5d.%1ddps, Z:%5d.%1ddps\n\r", + (int32_t)Gxf, + getOneDecimalPlace(Gxf), + (int32_t)Gyf, + getOneDecimalPlace(Gyf), + (int32_t)Gzf, + getOneDecimalPlace(Gzf)); +} + +void printAccMag(float Axf, float Ayf, float Azf, float Mxf, float Myf, float Mzf) +{ + PRINTF("[FXOS8700]Current Acc:X=%7d.%1dg Y=%7d.%1dg Z=%7d.%1dg\n\r", + (int32_t)Axf, + getOneDecimalPlace(Axf), + (int32_t)Ayf, + getOneDecimalPlace(Ayf), + (int32_t)Azf, + getOneDecimalPlace(Azf)); + PRINTF("[FXOS8700]Current Mag:X=%6d.%1duT Y=%6d.%1duT Z=%6d.%1duT\n\r", + (int32_t)Mxf, + getOneDecimalPlace(Mxf), + (int32_t)Myf, + getOneDecimalPlace(Myf), + (int32_t)Mzf, + getOneDecimalPlace(Mzf)); +} + +void printHeightTmp(float height, float tmp) +{ + PRINTF("[MPL3115]Current Height = %6d.%1dMeter, Current Temp = %6d.%1dCelsius\n\r", + (int32_t)height, + getOneDecimalPlace(height), + (int32_t)tmp, + getOneDecimalPlace(tmp)); +} + +void fxas21002OutputUpdate(gyro_sensor_t *gyroSensorPtr) +{ + static uint32_t count = 0, printCount = 0; + + count++; + if (count == GYRO_OVERSAMPLE_RATIO) + { + count = 0; + gyroSensorPtr->iYp[0] = gyroSensorPtr->iSumYpFast[0] / GYRO_OVERSAMPLE_RATIO; + gyroSensorPtr->iYp[1] = gyroSensorPtr->iSumYpFast[1] / GYRO_OVERSAMPLE_RATIO; + gyroSensorPtr->iYp[2] = gyroSensorPtr->iSumYpFast[2] / GYRO_OVERSAMPLE_RATIO; + gyroSensorPtr->fYp[0] = gyroSensorPtr->iYp[0] * gyroSensorPtr->fDegPerSecPerCount; + gyroSensorPtr->fYp[1] = gyroSensorPtr->iYp[1] * gyroSensorPtr->fDegPerSecPerCount; + gyroSensorPtr->fYp[2] = gyroSensorPtr->iYp[2] * gyroSensorPtr->fDegPerSecPerCount; + gyroSensorPtr->iSumYpFast[0] = 0; + gyroSensorPtr->iSumYpFast[1] = 0; + gyroSensorPtr->iSumYpFast[2] = 0; + } + + if ((gyroSensorPtr->fYp[0] > GYRO_UPDATE_THRESHOLD) || + (gyroSensorPtr->fYp[0] < -GYRO_UPDATE_THRESHOLD) || + (gyroSensorPtr->fYp[1] > GYRO_UPDATE_THRESHOLD) || + (gyroSensorPtr->fYp[1] < -GYRO_UPDATE_THRESHOLD) || + (gyroSensorPtr->fYp[2] > GYRO_UPDATE_THRESHOLD) || + (gyroSensorPtr->fYp[2] < -GYRO_UPDATE_THRESHOLD)) + { + printCount++; + if (5 == printCount) + { + printCount = 0; + printGyro(gyroSensorPtr->fYp[0], gyroSensorPtr->fYp[1], gyroSensorPtr->fYp[2]); + } + } +} + +void mpl3115OutputUpdate(pressure_sensor_t *pressureSensorPtr) +{ + static float lastHight = 0, lastTemp = 0; + + /* Print the data to terminal, if the delta exceed threshold. */ + if (((pressureSensorPtr->fHp - lastHight) > HEIGHT_UPDATE_THRESHOLD) || + ((pressureSensorPtr->fHp - lastHight) < -HEIGHT_UPDATE_THRESHOLD) || + ((pressureSensorPtr->fTp - lastTemp) > TEMP_UPDATE_THRESHOLD) || + ((pressureSensorPtr->fTp - lastTemp) < -TEMP_UPDATE_THRESHOLD)) + { + lastHight = pressureSensorPtr->fHp; + lastTemp = pressureSensorPtr->fTp; + printHeightTmp(pressureSensorPtr->fHp, pressureSensorPtr->fTp); + } +} + +void fxas21002Demo_Pol(void) { + const fxas_init_t initConfig = { + .dataRate = fxasDataRate100HZ, + .range = fxasRange2000Dps + }; + + fxas_data_t fxasData; gyro_sensor_t thisGyroSensor; - uint32_t count = 0, printCount = 0; + + memset(&thisGyroSensor, 0, sizeof(thisGyroSensor)); + thisGyroSensor.fDegPerSecPerCount = FXAS21002_DEGPERSECPERCOUNT; PRINTF("\n\r-------------- FXAS21002 Gyro data acquisition --------------\n\r\n\r"); PRINTF("FXAS21002 initialization ... "); - if (fxas21002_init(&thisGyroSensor)) + if (FXAS_Init(&fxasHandle, &initConfig)) PRINTF("OK\n\r"); else PRINTF("ERROR\n\r"); - /* delay 10ms to wait sensor init finish */ - vTaskDelay(10); + /* Active FXAS21002. */ + FXAS_Enable(&fxasHandle); + + /* Delay 100ms to wait sensor init finish */ + vTaskDelay(100); + + PRINTF("Please rotate the board to acquire current angular velocity\n\r"); while(1) { - fxas21002_read_data(&thisGyroSensor); - thisGyroSensor.iSumYpFast[0] += thisGyroSensor.iYpFast[0]; - thisGyroSensor.iSumYpFast[1] += thisGyroSensor.iYpFast[1]; - thisGyroSensor.iSumYpFast[2] += thisGyroSensor.iYpFast[2]; + vTaskDelay(10); + + FXAS_ReadData(&fxasHandle, &fxasData); + thisGyroSensor.iSumYpFast[0] += fxasData.gyroX; + thisGyroSensor.iSumYpFast[1] += fxasData.gyroY; + thisGyroSensor.iSumYpFast[2] += fxasData.gyroZ; + + fxas21002OutputUpdate(&thisGyroSensor); + } +} + +void fxas21002Demo_Int(void) +{ + const fxas_init_t initConfig = { + .dataRate = fxasDataRate100HZ, + .range = fxasRange2000Dps + }; + + fxas_data_t fxasData; + gyro_sensor_t thisGyroSensor; + + memset(&thisGyroSensor, 0, sizeof(thisGyroSensor)); + thisGyroSensor.fDegPerSecPerCount = FXAS21002_DEGPERSECPERCOUNT; - count++; - if (count == OVERSAMPLE_RATIO) + PRINTF("\n\r-------------- FXAS21002 Gyro data acquisition --------------\n\r\n\r"); + + PRINTF("FXAS21002 initialization ... "); + if (FXAS_Init(&fxasHandle, &initConfig)) + PRINTF("OK\n\r"); + else + PRINTF("ERROR\n\r"); + + /* Delay 100ms to wait sensor init finish */ + vTaskDelay(100); + + /* Enable Data Ready Interrupt. */ + // 1.Route Data Ready Interrupt to INT1 Pin; + // 2.Set INT1 Pin logic polarity to Active Low; + // 3.Set INT1 Pin output driver configuration to Open-drain; + // 4.Enable Data Ready Interrupt. + FXAS_WriteReg(&fxasHandle, FXAS21002_CTRL_REG2, 0x0C); + + /* Active FXAS21002 Sensor. */ + FXAS_Enable(&fxasHandle); + + PRINTF("Please rotate the board to acquire current angular velocity\n\r"); + + while(1) + { + /* Wait until sensor data ready. */ + if (pdTRUE == xSemaphoreTake(xSemaphore, 100)) { - count = 0; - thisGyroSensor.iYp[0] = thisGyroSensor.iSumYpFast[0] / OVERSAMPLE_RATIO; - thisGyroSensor.iYp[1] = thisGyroSensor.iSumYpFast[1] / OVERSAMPLE_RATIO; - thisGyroSensor.iYp[2] = thisGyroSensor.iSumYpFast[2] / OVERSAMPLE_RATIO; - thisGyroSensor.fYp[0] = thisGyroSensor.iYp[0] * thisGyroSensor.fDegPerSecPerCount; - thisGyroSensor.fYp[1] = thisGyroSensor.iYp[1] * thisGyroSensor.fDegPerSecPerCount; - thisGyroSensor.fYp[2] = thisGyroSensor.iYp[2] * thisGyroSensor.fDegPerSecPerCount; - thisGyroSensor.iSumYpFast[0] = 0; - thisGyroSensor.iSumYpFast[1] = 0; - thisGyroSensor.iSumYpFast[2] = 0; + /* Read data from sensor */ + FXAS_ReadData(&fxasHandle, &fxasData); + thisGyroSensor.iSumYpFast[0] += fxasData.gyroX; + thisGyroSensor.iSumYpFast[1] += fxasData.gyroY; + thisGyroSensor.iSumYpFast[2] += fxasData.gyroZ; + fxas21002OutputUpdate(&thisGyroSensor); } - - if ((thisGyroSensor.fYp[0] > GYRO_UPDATE_THRESHOLD) || - (thisGyroSensor.fYp[0] < -GYRO_UPDATE_THRESHOLD) || - (thisGyroSensor.fYp[1] > GYRO_UPDATE_THRESHOLD) || - (thisGyroSensor.fYp[1] < -GYRO_UPDATE_THRESHOLD) || - (thisGyroSensor.fYp[2] > GYRO_UPDATE_THRESHOLD) || - (thisGyroSensor.fYp[2] < -GYRO_UPDATE_THRESHOLD)) + else { - printCount++; - if (40 == printCount) - { - printCount = 0; - PRINTF("[FXAS21002] Rotate detected: X:%5.1fdps, Y:%5.1fdps, Z:%5.1fdps\n\r",\ - thisGyroSensor.fYp[0], thisGyroSensor.fYp[1], thisGyroSensor.fYp[2]); - } + /* Because the GPIO interrutp of Sensor Int pin will be masked when Linux + * boot on Cortex-A7 Core, so we provide this walkaround to enable the GPIO + * interrupt of Sensor Int pin here, if we did not get the sensor data ready + * interrupt for a long time. + */ + NVIC_DisableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); + RDC_SEMAPHORE_Lock(BOARD_GPIO_SENSOR_RDC_PDAP); + GPIO_SetPinIntMode(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin, true); + RDC_SEMAPHORE_Unlock(BOARD_GPIO_SENSOR_RDC_PDAP); + NVIC_EnableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); } } } -void fxos8700Demo(void) +void fxos8700Demo_Pol(void) { - int16_t Ax, Ay, Az, Mx, My, Mz; + const fxos_init_t initConfig = { + .dataRate = fxosDataRate400HZ, + .osr = fxosOSR7, + .hms = fxosBoth, + .range = fxosRange4gMode + }; + + fxos_data_t fxos8700Data; float Axf, Ayf, Azf, Mxf, Myf, Mzf; PRINTF("\n\r-------------- FXOS8700 Acc+Mag data acquisition --------------\n\r\n\r"); PRINTF("FXOS8700 initialization ... "); - if (fxos8700_init()) + if (FXOS_Init(&fxosHandle, &initConfig)) PRINTF("OK\n\r"); else PRINTF("ERROR\n\r"); + /* Active FXOS8700 Sensor. */ + FXOS_Enable(&fxosHandle); + while(1) { vTaskDelay(500); - fxos8700_read_data(&Ax, &Ay, &Az, &Mx, &My, &Mz); - Axf = Ax / 8192.0; - Ayf = Ay / 8192.0; - Azf = Az / 8192.0; - Mxf = Mx * 0.1; - Myf = My * 0.1; - Mzf = Mz * 0.1; - PRINTF("[FXOS8700]Current Acc:X=%7.1fg Y=%7.1fg Z=%7.1fg\n\r",Axf, Ayf, Azf); - PRINTF("[FXOS8700]Current Mag:X=%6.1fuT Y=%6.1fuT Z=%6.1fuT\n\r",Mxf, Myf, Mzf); + FXOS_ReadData(&fxosHandle, &fxos8700Data); + Axf = fxos8700Data.accX / 8192.0; + Ayf = fxos8700Data.accY / 8192.0; + Azf = fxos8700Data.accZ / 8192.0; + Mxf = fxos8700Data.magX * 0.1; + Myf = fxos8700Data.magY * 0.1; + Mzf = fxos8700Data.magZ * 0.1; + printAccMag(Axf, Ayf, Azf, Mxf, Myf, Mzf); } } -void mpl3115Demo(void) +void fxos8700Demo_Int(void) { + const fxos_init_t initConfig = { + .dataRate = fxosDataRate1_56HZ, + .osr = fxosOSR7, + .hms = fxosBoth, + .range = fxosRange4gMode + }; + + fxos_data_t fxos8700Data; + float Axf, Ayf, Azf, Mxf, Myf, Mzf; + + PRINTF("\n\r-------------- FXOS8700 Acc+Mag data acquisition --------------\n\r\n\r"); + + PRINTF("FXOS8700 initialization ... "); + if (FXOS_Init(&fxosHandle, &initConfig)) + PRINTF("OK\n\r"); + else + PRINTF("ERROR\n\r"); + + /* Enable Data Ready Interrupt. */ + // Set Interrupt pin to Active Low & Open-Drain. + FXOS_WriteReg(&fxosHandle, FXOS8700_CTRL_REG3, 0x01); + + // Route Data Ready Interrupt to Int1 Pin. + FXOS_WriteReg(&fxosHandle, FXOS8700_CTRL_REG5, 0x01); + + // Enable Data Ready Interrupt. + FXOS_WriteReg(&fxosHandle, FXOS8700_CTRL_REG4, 0x01); + + /* Active FXOS8700. */ + FXOS_Enable(&fxosHandle); + + while(1) + { + /* Wait until sensor data ready. */ + if (pdTRUE == xSemaphoreTake(xSemaphore, 1500)) + { + /* Read data from sensor */ + FXOS_ReadData(&fxosHandle, &fxos8700Data); + Axf = fxos8700Data.accX / 8192.0; + Ayf = fxos8700Data.accY / 8192.0; + Azf = fxos8700Data.accZ / 8192.0; + Mxf = fxos8700Data.magX * 0.1; + Myf = fxos8700Data.magY * 0.1; + Mzf = fxos8700Data.magZ * 0.1; + + /* Print to terminal */ + printAccMag(Axf, Ayf, Azf, Mxf, Myf, Mzf); + } + else + { + /* Because the GPIO interrutp of Sensor Int pin will be masked when Linux + * boot on Cortex-A7 Core, so we provide this walkaround to enable the GPIO + * interrupt of Sensor Int pin here, if we did not get the sensor data ready + * interrupt for a long time. + */ + NVIC_DisableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); + RDC_SEMAPHORE_Lock(BOARD_GPIO_SENSOR_RDC_PDAP); + GPIO_SetPinIntMode(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin, true); + RDC_SEMAPHORE_Unlock(BOARD_GPIO_SENSOR_RDC_PDAP); + NVIC_EnableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); + } + } +} + +void mpl3115Demo_Pol(void) +{ + const mpl3115_init_t initConfig = { + .outputFormat = mpl3115OutputFormatAltimeter, + .outputMode = mpl3115OutputModeNormal, + .oversampleRatio = mpl3115OverSampleX128 + }; + + mpl3115_data_t mpl3115Data; pressure_sensor_t thisPressureSensor; - float lastHight = 0, lastTemp = 0; + + memset(&thisPressureSensor, 0, sizeof(thisPressureSensor)); + thisPressureSensor.fmPerCount = MPL3115_MPERCOUNT; + thisPressureSensor.fCPerCount = MPL3115_CPERCPOUNT; PRINTF("\n\r-------------- MPL3115 Pressure data acquisition --------------\n\r\n\r"); PRINTF("MPL3115 initialization ... "); - if (mpl3115_init(&thisPressureSensor)) + if (MPL3115_Init(&mplHandle, &initConfig)) PRINTF("OK\n\r"); else PRINTF("ERROR\n\r"); + /* Active MPL3115 Sensor. */ + MPL3115_Enable(&mplHandle); + while(1) { - vTaskDelay(100); - mpl3115_read_data(&thisPressureSensor); - thisPressureSensor.iHp = thisPressureSensor.iHpFast;; - thisPressureSensor.iTp = thisPressureSensor.iTpFast; - thisPressureSensor.fHp = (float) thisPressureSensor.iHp *\ + vTaskDelay(500); + MPL3115_ReadData(&mplHandle, &mpl3115Data); + + thisPressureSensor.fHp = (float) mpl3115Data.presData * thisPressureSensor.fmPerCount; - thisPressureSensor.fTp = (float) thisPressureSensor.iTp *\ + thisPressureSensor.fTp = (float) mpl3115Data.tempData * thisPressureSensor.fCPerCount; - if (((thisPressureSensor.fHp - lastHight) > HEIGHT_UPDATE_THRESHOLD) || - ((thisPressureSensor.fHp - lastHight) < -HEIGHT_UPDATE_THRESHOLD) || - ((thisPressureSensor.fTp - lastTemp) > TEMP_UPDATE_THRESHOLD) || - ((thisPressureSensor.fTp - lastTemp) < -TEMP_UPDATE_THRESHOLD)) + + mpl3115OutputUpdate(&thisPressureSensor); + } +} + +void mpl3115Demo_Int(void) +{ + const mpl3115_init_t initConfig = { + .outputFormat = mpl3115OutputFormatAltimeter, + .outputMode = mpl3115OutputModeNormal, + .oversampleRatio = mpl3115OverSampleX128 + }; + + mpl3115_data_t mpl3115Data; + pressure_sensor_t thisPressureSensor; + + memset(&thisPressureSensor, 0, sizeof(thisPressureSensor)); + thisPressureSensor.fmPerCount = MPL3115_MPERCOUNT; + thisPressureSensor.fCPerCount = MPL3115_CPERCPOUNT; + + PRINTF("\n\r-------------- MPL3115 Pressure data acquisition --------------\n\r\n\r"); + + PRINTF("MPL3115 initialization ... "); + if (MPL3115_Init(&mplHandle, &initConfig)) + PRINTF("OK\n\r"); + else + PRINTF("ERROR\n\r"); + + /* Enable Data Ready Interrupt. */ + // MPL3115 Interrupt source to generate data ready event + // flag on new Pressure/Altitude or Temperature data. + MPL3115_WriteReg(&mplHandle, MPL3115_PT_DATA_CFG, 0x07); + + // Set interrupt pad INT1 & INT2 to Active Low & Open Drain. + MPL3115_WriteReg(&mplHandle, MPL3115_CTRL_REG3, 0x11); + + // Route Data Ready Interrupt to interrupt pad INT1. + MPL3115_WriteReg(&mplHandle, MPL3115_CTRL_REG5, 0x80); + + // Enable Data Ready Interrupt. + MPL3115_WriteReg(&mplHandle, MPL3115_CTRL_REG4, 0x80); + + /* Active MPL3115 Sensor. */ + MPL3115_Enable(&mplHandle); + + while(1) + { + /* Wait until sensor data ready. */ + if (pdTRUE == xSemaphoreTake(xSemaphore, 1000)) { - lastHight = thisPressureSensor.fHp; - lastTemp = thisPressureSensor.fTp; - PRINTF("[MPL3115]Current Height = %6.1fMeter, Current Temp = %5.1fCelsius\n\r", - thisPressureSensor.fHp, - thisPressureSensor.fTp); + /* Get the latest data from sensor */ + MPL3115_ReadData(&mplHandle, &mpl3115Data); + + /* Convert sensor data to standard unit. */ + thisPressureSensor.fHp = (float) mpl3115Data.presData * + thisPressureSensor.fmPerCount; + thisPressureSensor.fTp = (float) mpl3115Data.tempData * + thisPressureSensor.fCPerCount; + + mpl3115OutputUpdate(&thisPressureSensor); + } + else + { + /* Because the GPIO interrutp of Sensor Int pin will be masked when Linux + * boot on Cortex-A7 Core, so we provide this walkaround to enable the GPIO + * interrupt of Sensor Int pin here, if we did not get the sensor data ready + * interrupt for a long time. + */ + NVIC_DisableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); + RDC_SEMAPHORE_Lock(BOARD_GPIO_SENSOR_RDC_PDAP); + GPIO_SetPinIntMode(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin, true); + RDC_SEMAPHORE_Unlock(BOARD_GPIO_SENSOR_RDC_PDAP); + NVIC_EnableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); } } } @@ -177,41 +514,92 @@ void MainTask(void *pvParameters) { uint8_t demoSel; - PRINTF("\n\r-------------- iMX7D SDB on board sensor example --------------\n\r\n\r"); + /* GPIO module initialize, configure button as interrupt mode. */ + gpio_init_config_t sensorIntInitConfig = { + .pin = BOARD_GPIO_SENSOR_CONFIG->pin, + .direction = gpioDigitalInput, + .interruptMode = gpioIntFallingEdge + }; /* Setup I2C init structure. */ - i2c_init_config_t i2cInitConfig = { - .clockRate = get_i2c_clock_freq(BOARD_I2C_BASEADDR), - .baudRate = 400000u, - .slaveAddress = 0x00 + i2c_xfer_init_config_t i2cInitConfig = { + .base = BOARD_I2C_BASEADDR, + .config = { + .clockRate = get_i2c_clock_freq(BOARD_I2C_BASEADDR), + .baudRate = 400000u, + .slaveAddress = 0x00 + }, + .irqNum = BOARD_I2C_IRQ_NUM, + .irqPrio = 3 }; + PRINTF("\n\r-------------- iMX7D SDB on board sensor example --------------\n\r\n\r"); + + /* Data acquire sync semi4 init. */ + xSemaphore = xSemaphoreCreateBinary(); + /* Initialize I2C module with I2C init structure. */ - I2C_XFER_Config(&i2cInitConfig); + I2C_XFER_Init(&I2C_handle, &i2cInitConfig); + + /* Deinit on-board sensors to avoid unexpected interrupt. */ + FXAS_Deinit(&fxasHandle); + FXOS_Deinit(&fxosHandle); + MPL3115_Deinit(&mplHandle); + vTaskDelay(50); + + /* Acquire RDC semaphore before access GPIO to avoid conflict, it's + * necessary when GPIO RDC is configured as Semaphore Required */ + RDC_SEMAPHORE_Lock(BOARD_GPIO_SENSOR_RDC_PDAP); + + GPIO_Init(BOARD_GPIO_SENSOR_CONFIG->base, &sensorIntInitConfig); + + /* Clear the interrupt state, this operation is necessary, because the GPIO module maybe confuse + the first rising edge as interrupt*/ + GPIO_ClearStatusFlag(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin); + /* Enable GPIO pin interrupt */ + GPIO_SetPinIntMode(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin, true); + + RDC_SEMAPHORE_Unlock(BOARD_GPIO_SENSOR_RDC_PDAP); + + /* Set I2C Interrupt priority */ + NVIC_SetPriority(BOARD_GPIO_SENSOR_IRQ_NUM, 3); + NVIC_EnableIRQ(BOARD_GPIO_SENSOR_IRQ_NUM); /* Print the initial banner. */ PRINTF("\n\rPlease select the sensor demo you want to run:\n\r"); - PRINTF("[1].FXAS21002 3-axes Gyro sensor\n\r"); - PRINTF("[2].FXOS8700 6-axes Acc+Mag sensor\n\r"); - PRINTF("[3].MPL3115 Pressure sensor\n\r"); + PRINTF("[1].FXAS21002 3-axes Gyro sensor Polling Demo\n\r"); + PRINTF("[2].FXAS21002 3-axes Gyro sensor Interrupt Demo\n\r"); + PRINTF("[3].FXOS8700 6-axes Acc+Mag sensor Polling Demo\n\r"); + PRINTF("[4].FXOS8700 6-axes Acc+Mag sensor Interrupt Demo\n\r"); + PRINTF("[5].MPL3115 Pressure sensor Polling Demo\n\r"); + PRINTF("[6].MPL3115 Pressure sensor Interrupt Demo\n\r"); while(1) { demoSel = GETCHAR(); - if (('1' == demoSel) || ('2' == demoSel) || ('3' == demoSel)) + if ((demoSel >= '1') && (demoSel <= '6')) break; } switch(demoSel) { case '1': - fxas21002Demo(); + fxas21002Demo_Pol(); break; case '2': - fxos8700Demo(); + fxas21002Demo_Int(); break; case '3': - mpl3115Demo(); + fxos8700Demo_Pol(); + break; + case '4': + fxos8700Demo_Int(); + break; + case '5': + mpl3115Demo_Pol(); + break; + case '6': + mpl3115Demo_Int(); break; } } @@ -232,6 +620,29 @@ int main(void) while (true); } +void BOARD_I2C_HANDLER(void) +{ + I2C_XFER_Handler(&I2C_handle); +} + +void BOARD_GPIO_SENSOR_HANDLER(void) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + RDC_SEMAPHORE_Lock(BOARD_GPIO_SENSOR_RDC_PDAP); + + /* clear the interrupt status. */ + GPIO_ClearStatusFlag(BOARD_GPIO_SENSOR_CONFIG->base, BOARD_GPIO_SENSOR_CONFIG->pin); + + RDC_SEMAPHORE_Unlock(BOARD_GPIO_SENSOR_RDC_PDAP); + + /* Unlock the task to process the event. */ + xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken); + + /* Perform a context switch to wake the higher priority task. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + /******************************************************************************* * EOF ******************************************************************************/ |