//***************************************************************************** // // Function to wait for the ISL29023 transactions to complete. // //***************************************************************************** void ISL29023AppI2CWait(char *pcFilename, uint_fast32_t ui32Line) { // // Put the processor to sleep while we wait for the I2C driver to // indicate that the transaction is complete. // while((g_vui8DataFlag == 0) && (g_vui8ErrorFlag == 0)) { // // Do Nothing // } // // If an error occurred call the error handler immediately. // if(g_vui8ErrorFlag) { ISL29023AppErrorHandler(pcFilename, ui32Line); } // // clear the data flag for next use. // g_vui8DataFlag = 0; }
//***************************************************************************** // // This task captures data from the ISL29023 sensor and puts it into the shared // data structure. // //***************************************************************************** static void ISL29023Task(void *pvParameters) { portTickType xLastWakeTime; float fVisible; uint8_t ui8Mask; // // The binary semaphore is created full so we empty it first so we can // use it to wait for the AppCallback function. // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, 0); xSemaphoreTake(g_xISL29023AdjustRangeSemaphore, 0); // // Take the I2C semaphore so we can init the sensor. Keep it until all init // is complete for this sensor. // xSemaphoreTake(g_xI2CSemaphore, portMAX_DELAY); // // Initialize the ISL29023 Driver. // ISL29023Init(&g_sISL29023Inst, &g_sI2CInst, ISL29023_I2C_ADDRESS, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { // // Give back the I2C Semaphore // xSemaphoreGive(g_xI2CSemaphore); // // Call the error handler. // ISL29023AppErrorHandler(__FILE__, __LINE__); } // // Configure the ISL29023 to measure Visible light continuously. Set a 8 // sample persistence before the INT pin is asserted. Clears the INT flag. // Persistence setting of 8 is sufficient to ignore camera flashes. // ui8Mask = (ISL29023_CMD_I_OP_MODE_M | ISL29023_CMD_I_INT_PERSIST_M | ISL29023_CMD_I_INT_FLAG_M); ISL29023ReadModifyWrite(&g_sISL29023Inst, ISL29023_O_CMD_I, ~ui8Mask, (ISL29023_CMD_I_OP_MODE_ALS_CONT | ISL29023_CMD_I_INT_PERSIST_8), ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { // // Give back the I2C Semaphore // xSemaphoreGive(g_xI2CSemaphore); // // Call the Error handler. // ISL29023AppErrorHandler(__FILE__, __LINE__); } // // Configure the upper threshold to 80% of maximum value // g_sISL29023Inst.pui8Data[1] = 0xCC; g_sISL29023Inst.pui8Data[2] = 0xCC; ISL29023Write(&g_sISL29023Inst, ISL29023_O_INT_HT_LSB, g_sISL29023Inst.pui8Data, 2, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { // // Give back the I2C Semaphore // xSemaphoreGive(g_xI2CSemaphore); // // Call the error handler. // ISL29023AppErrorHandler(__FILE__, __LINE__); } // // Configure the lower threshold to 20% of maximum value // g_sISL29023Inst.pui8Data[1] = 0x33; g_sISL29023Inst.pui8Data[2] = 0x33; ISL29023Write(&g_sISL29023Inst, ISL29023_O_INT_LT_LSB, g_sISL29023Inst.pui8Data, 2, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // Give back the I2C Semaphore // xSemaphoreGive(g_xI2CSemaphore); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { ISL29023AppErrorHandler(__FILE__, __LINE__); } // // Get the current time as a reference to start our delays. // xLastWakeTime = xTaskGetTickCount(); // // Loop forever. // while(1) { // // Wait for the required amount of time to check back. // vTaskDelayUntil(&xLastWakeTime, ISL29023_TASK_PERIOD_MS / portTICK_RATE_MS); // // Take the I2C semaphore. Given back in the Interrupt contect in the // callback function after I2C transaction is complete. // xSemaphoreTake(g_xI2CSemaphore, portMAX_DELAY); // // Go get the latest data from the sensor. // ISL29023DataRead(&g_sISL29023Inst, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for the I2C Driver to tell us that transaction is complete. // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // Give back the I2C Semaphore so other can use the I2C interface. // xSemaphoreGive(g_xI2CSemaphore); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { ISL29023AppErrorHandler(__FILE__, __LINE__); } // // Get a local floating point copy of the latest light data // ISL29023DataLightVisibleGetFloat(&g_sISL29023Inst, &fVisible); // // Check if the intensity of light has crossed a threshold. If so // then adjust range of sensor readings to track intensity. // if(xSemaphoreTake(g_xISL29023AdjustRangeSemaphore, 0) == pdTRUE) { // // Adjust the lux range. // ISL29023AppAdjustRange(fVisible); // // Take the I2C semaphore. Given back in the Interrupt contect in // the callback function after I2C transaction is complete. // xSemaphoreTake(g_xI2CSemaphore, portMAX_DELAY); // // Now we must manually clear the flag in the ISL29023 // register. // ISL29023Read(&g_sISL29023Inst, ISL29023_O_CMD_I, g_sISL29023Inst.pui8Data, 1, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for the I2C Driver to tell us that transaction is complete. // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // Give back the I2C Semaphore so other can use the I2C interface. // xSemaphoreGive(g_xI2CSemaphore); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { ISL29023AppErrorHandler(__FILE__, __LINE__); } } // // Publish the data to the global structure for consumption by other // tasks. // xSemaphoreTake(g_xCloudDataSemaphore, portMAX_DELAY); g_sISL29023Data.fVisible = fVisible; g_sISL29023Data.xTimeStampTicks = xTaskGetTickCount(); g_sISL29023Data.ui8Range = g_sISL29023Inst.ui8Range; xSemaphoreGive(g_xCloudDataSemaphore); } }
//***************************************************************************** // // Intensity and Range Tracking Function. This adjusts the range and interrupt // thresholds as needed. Uses an 80/20 rule. If light is greather then 80% of // maximum value in this range then go to next range up. If less than 20% of // potential value in this range go the next range down. // //***************************************************************************** void ISL29023AppAdjustRange(float fVisible) { uint8_t ui8NewRange; // // Initialize the local variable. // ui8NewRange = g_sISL29023Inst.ui8Range; // // Check if we crossed the upper threshold. // if(fVisible > g_fThresholdHigh[g_sISL29023Inst.ui8Range]) { // // The current intensity is over our threshold so adjsut the range // accordingly // if(g_sISL29023Inst.ui8Range < ISL29023_CMD_II_RANGE_64K) { ui8NewRange = g_sISL29023Inst.ui8Range + 1; } } // // Check if we crossed the lower threshold // if(fVisible < g_fThresholdLow[g_sISL29023Inst.ui8Range]) { // // If possible go to the next lower range setting and re-config the // thresholds. // if(g_sISL29023Inst.ui8Range > ISL29023_CMD_II_RANGE_1K) { ui8NewRange = g_sISL29023Inst.ui8Range - 1; } } // // If the desired range value changed then send the new range to the sensor // if(ui8NewRange != g_sISL29023Inst.ui8Range) { // // Take the I2C semaphore. // xSemaphoreTake(g_xI2CSemaphore, portMAX_DELAY); // // Perform a read, modify, write over I2C to set the new range. // ISL29023ReadModifyWrite(&g_sISL29023Inst, ISL29023_O_CMD_II, ~ISL29023_CMD_II_RANGE_M, ui8NewRange, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // xSemaphoreTake(g_xISL29023TransactionCompleteSemaphore, portMAX_DELAY); // // Give back the I2C Semaphore // xSemaphoreGive(g_xI2CSemaphore); // // If an error occurred call the error handler immediately. // if(g_vui8ISL29023I2CErrorStatus) { ISL29023AppErrorHandler(__FILE__, __LINE__); } } }