//***************************************************************************** // // 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); } }
void ISL29023AppCallback(void *pvCallbackData, unsigned int ui8Status) { float fAmbient; unsigned char tempString[30]={0}; float tempfAmbient; uint8_t ui8NewRange; if(ui8Status == I2CM_STATUS_SUCCESS&&sensorTurn==2) { // // Get a local floating point copy of the latest light data // ISL29023DataLightVisibleGetFloat(&g_sISL29023Inst, &fAmbient); // // Perform the conversion from float to a printable set of integers // ISL290_i32IntegerPart = (int32_t)fAmbient; ISL290_i32FractionPart = (int32_t)(fAmbient * 1000.0f); ISL290_i32FractionPart = ISL290_i32FractionPart - (ISL290_i32IntegerPart * 1000); if(ISL290_i32FractionPart < 0) { ISL290_i32FractionPart *= -1; } // // Print the temperature as integer and fraction parts. // //sprintf(tempString,"Visible Lux: %3d.%03d\n\r", ISL290_i32IntegerPart,ISL290_i32FractionPart); //CLI_Write(tempString); if(g_vui8IntensityFlag) { IntPriorityMaskSet(0x40); // // Reset the intensity trigger flag. // g_vui8IntensityFlag = 0; // // Adjust the lux range. // ui8NewRange = g_sISL29023Inst.ui8Range; // // Get a local floating point copy of the latest light data // ISL29023DataLightVisibleGetFloat(&g_sISL29023Inst, &tempfAmbient); // // Check if we crossed the upper threshold. // if(tempfAmbient > 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(tempfAmbient < g_fThresholdLow[g_sISL29023Inst.ui8Range]) { // // If possible go to the next lower range setting and reconfig 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) { ISL29023ReadModifyWrite(&g_sISL29023Inst, ISL29023_O_CMD_II, ~ISL29023_CMD_II_RANGE_M, ui8NewRange, ISL29023AppCallback, &g_sISL29023Inst); } SysCtlDelay(g_SysClock / (100 * 3)); // // 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 transaction to complete // SysCtlDelay(g_SysClock / (100 * 3)); // // Disable priority masking so all interrupts are enabled. // IntPriorityMaskSet(0); } sensorTurn=(sensorTurn+1)%NumberOfSensor; TimerEnable(TIMER1_BASE, TIMER_A); } }
//***************************************************************************** // // Main 'C' Language entry point. // //***************************************************************************** int main(void) { float fAmbient; int32_t i32IntegerPart, i32FractionPart; uint8_t ui8Mask; // // Setup the system clock to run at 40 Mhz from PLL with crystal reference // ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); // // Enable the peripherals used by this example. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // // Initialize the UART and its pins. // ConfigureUART(); // // Print the welcome message to the terminal. // UARTprintf("\033[2JISL29023 Example\n"); // // Set the color to a white approximation. // g_pui32Colors[RED] = 0x8000; g_pui32Colors[BLUE] = 0x8000; g_pui32Colors[GREEN] = 0x8000; // // Initialize RGB driver. Use a default intensity and blink rate. // RGBInit(0); RGBColorSet(g_pui32Colors); RGBIntensitySet(0.5f); RGBEnable(); // // The I2C3 peripheral must be enabled before use. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // // Configure the pin muxing for I2C3 functions on port D0 and D1. // This step is not necessary if your part does not support pin muxing. // ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL); ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA); // // Select the I2C function for these pins. This function will also // configure the GPIO pins pins for I2C operation, setting them to // open-drain operation with weak pull-ups. Consult the data sheet // to see which functions are allocated per pin. // GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0); ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1); // // Configure and Enable the GPIO interrupt. Used for INT signal from the // ISL29023 // ROM_GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_5); GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_5); ROM_GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_5, GPIO_FALLING_EDGE); ROM_IntEnable(INT_GPIOE); // // Keep only some parts of the systems running while in sleep mode. // GPIOE is for the ISL29023 interrupt pin. // UART0 is the virtual serial port // TIMER0, TIMER1 and WTIMER5 are used by the RGB driver // I2C3 is the I2C interface to the ISL29023 // ROM_SysCtlPeripheralClockGating(true); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_GPIOE); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER0); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_TIMER1); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_I2C3); ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_WTIMER5); // // Configure desired interrupt priorities. Setting the I2C interrupt to be // of more priority than SysTick and the GPIO interrupt means those // interrupt routines can use the I2CM_DRV Application context does not use // I2CM_DRV API and GPIO and SysTick are at the same priority level. This // prevents re-entrancy problems with I2CM_DRV but keeps the MCU in sleep // state as much as possible. UART is at least priority so it can operate // in the background. // ROM_IntPrioritySet(INT_I2C3, 0x00); ROM_IntPrioritySet(FAULT_SYSTICK, 0x40); ROM_IntPrioritySet(INT_GPIOE, 0x80); ROM_IntPrioritySet(INT_UART0, 0x80); // // Enable interrupts to the processor. // ROM_IntMasterEnable(); // // Initialize I2C3 peripheral. // I2CMInit(&g_sI2CInst, I2C3_BASE, INT_I2C3, 0xff, 0xff, ROM_SysCtlClockGet()); // // Initialize the ISL29023 Driver. // ISL29023Init(&g_sISL29023Inst, &g_sI2CInst, ISL29023_I2C_ADDRESS, ISL29023AppCallback, &g_sISL29023Inst); // // Wait for transaction to complete // ISL29023AppI2CWait(__FILE__, __LINE__); // // Configure the ISL29023 to measure ambient 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 // ISL29023AppI2CWait(__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 // ISL29023AppI2CWait(__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 // ISL29023AppI2CWait(__FILE__, __LINE__); // //Configure and enable SysTick Timer // ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND); ROM_SysTickIntEnable(); ROM_SysTickEnable(); // // After all the init and config we start blink the LED // RGBBlinkRateSet(1.0f); // // Loop Forever // while(1) { ROM_SysCtlSleep(); if(g_vui8DataFlag) { g_vui8DataFlag = 0; // // Get a local floating point copy of the latest light data // ISL29023DataLightVisibleGetFloat(&g_sISL29023Inst, &fAmbient); // // Perform the conversion from float to a printable set of integers // i32IntegerPart = (int32_t)fAmbient; i32FractionPart = (int32_t)(fAmbient * 1000.0f); i32FractionPart = i32FractionPart - (i32IntegerPart * 1000); if(i32FractionPart < 0) { i32FractionPart *= -1; } // // Print the temperature as integer and fraction parts. // UARTprintf("Visible Lux: %3d.%03d\n", i32IntegerPart, i32FractionPart); // // Check if the intensity of light has crossed a threshold. If so // then adjust range of sensor readings to track intensity. // if(g_vui8IntensityFlag) { // // Disable the low priority interrupts leaving only the I2C // interrupt enabled. // ROM_IntPriorityMaskSet(0x40); // // Reset the intensity trigger flag. // g_vui8IntensityFlag = 0; // // Adjust the lux range. // ISL29023AppAdjustRange(&g_sISL29023Inst); // // 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 transaction to complete // ISL29023AppI2CWait(__FILE__, __LINE__); // // Disable priority masking so all interrupts are enabled. // ROM_IntPriorityMaskSet(0); } } } }