Rev 281 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#include "defines.h"#include "I2C1.h"#include "TSL2561.h"extern TSL2561_DATA tsl2561_data;void TSL2561_Init(uint8_t address) {tsl2561_data.address = address;tsl2561_data.integration = TSL2561_INTEGRATIONTIME_13MS;tsl2561_data.gain = TSL2561_GAIN_16X;uint8_t buffer[1];I2C1_Master_Restart(tsl2561_data.address, TSL2561_REGISTER_ID, 1);while (!I2C1_Get_Status());I2C1_Read_Buffer(buffer);// Set default integration time and gainTSL2561_Set_Timing(tsl2561_data.integration);TSL2561_Set_Gain(tsl2561_data.gain);// Start the chip in power-down modeTSL2561_Disable();}void TSL2561_Enable() {TSL2561_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON);}void TSL2561_Disable() {TSL2561_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF);}void TSL2561_Set_Gain(tsl2561Gain_t gain) {TSL2561_Enable();tsl2561_data.gain = gain;TSL2561_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,tsl2561_data.integration | tsl2561_data.gain);TSL2561_Disable();}void TSL2561_Set_Timing(tsl2561IntegrationTime_t integration) {TSL2561_Enable();tsl2561_data.integration = integration;TSL2561_Write_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,tsl2561_data.integration | tsl2561_data.gain);TSL2561_Disable();}uint32_t TSL2561_Calculate_Lux(uint16_t ch0, uint16_t ch1) {uint32_t chScale, channel0, channel1, ratio1, ratio, temp, lux;uint16_t b, m;switch (tsl2561_data.integration) {case TSL2561_INTEGRATIONTIME_13MS:chScale = TSL2561_LUX_CHSCALE_TINT0;break;case TSL2561_INTEGRATIONTIME_101MS:chScale = TSL2561_LUX_CHSCALE_TINT1;break;default: // No scaling ... integration time = 402mschScale = (1 << TSL2561_LUX_CHSCALE);break;}// Scale for gain (1x or 16x)if (!tsl2561_data.gain)chScale = chScale << 4;// scale the channel valueschannel0 = (ch0 * chScale) >> TSL2561_LUX_CHSCALE;channel1 = (ch1 * chScale) >> TSL2561_LUX_CHSCALE;// find the ratio of the channel values (Channel1/Channel0)ratio1 = 0;if (channel0 != 0)ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;// round the ratio valueratio = (ratio1 + 1) >> 1;#ifdef TSL2561_PACKAGE_CSif ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {b = TSL2561_LUX_B1C; m = TSL2561_LUX_M1C;} else if (ratio <= TSL2561_LUX_K2C) {b = TSL2561_LUX_B2C; m = TSL2561_LUX_M2C;} else if (ratio <= TSL2561_LUX_K3C) {b = TSL2561_LUX_B3C; m = TSL2561_LUX_M3C;} else if (ratio <= TSL2561_LUX_K4C) {b = TSL2561_LUX_B4C; m = TSL2561_LUX_M4C;} else if (ratio <= TSL2561_LUX_K5C) {b = TSL2561_LUX_B5C; m = TSL2561_LUX_M5C;} else if (ratio <= TSL2561_LUX_K6C) {b = TSL2561_LUX_B6C; m = TSL2561_LUX_M6C;} else if (ratio <= TSL2561_LUX_K7C) {b = TSL2561_LUX_B7C; m = TSL2561_LUX_M7C;} else if (ratio > TSL2561_LUX_K8C) {b = TSL2561_LUX_B8C; m = TSL2561_LUX_M8C;}#else// if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {if ((ratio <= TSL2561_LUX_K1T)) {b = TSL2561_LUX_B1T; m = TSL2561_LUX_M1T;} else if (ratio <= TSL2561_LUX_K2T) {b = TSL2561_LUX_B2T; m = TSL2561_LUX_M2T;} else if (ratio <= TSL2561_LUX_K3T) {b = TSL2561_LUX_B3T; m = TSL2561_LUX_M3T;} else if (ratio <= TSL2561_LUX_K4T) {b = TSL2561_LUX_B4T; m = TSL2561_LUX_M4T;} else if (ratio <= TSL2561_LUX_K5T) {b = TSL2561_LUX_B5T; m = TSL2561_LUX_M5T;} else if (ratio <= TSL2561_LUX_K6T) {b = TSL2561_LUX_B6T; m = TSL2561_LUX_M6T;} else if (ratio <= TSL2561_LUX_K7T) {b = TSL2561_LUX_B7T; m = TSL2561_LUX_M7T;} else if (ratio > TSL2561_LUX_K8T) {b = TSL2561_LUX_B8T; m = TSL2561_LUX_M8T;}#endif// temp = ((channel0 * b) - (channel1 * m));// TODO: Change this back once they fix compilertemp = (channel0 * b);temp -= (channel1 * m);// // do not allow negative lux value// if (temp < 0)// temp = 0;// round lsb (2^(LUX_SCALE-1))temp += (1 << (TSL2561_LUX_LUXSCALE-1));// strip off fractional portionlux = temp >> TSL2561_LUX_LUXSCALE;return lux;}uint32_t TSL2561_Get_Full_Luminosity() {uint32_t x;// Enable the device by setting the control bit to 0x03TSL2561_Enable();// Wait x ms for ADC to completeswitch (tsl2561_data.integration) {case TSL2561_INTEGRATIONTIME_13MS:__delay_ms(15);break;case TSL2561_INTEGRATIONTIME_101MS:__delay_ms(105);break;default:__delay_ms(405);break;}x = TSL2561_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);x <<= 16;x |= TSL2561_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);TSL2561_Disable();return x;}uint16_t TSL2561_Get_Luminosity(uint8_t channel) {// Enable the device by setting the control bit to 0x03TSL2561_Enable();// Wait x ms for ADC to completeswitch (tsl2561_data.integration) {case TSL2561_INTEGRATIONTIME_13MS:__delay_ms(15);break;case TSL2561_INTEGRATIONTIME_101MS:__delay_ms(105);break;default:__delay_ms(405);break;}if (channel == 0) {// Reads two byte value from channel 0 (visible + infrared)return TSL2561_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN0_LOW);} else if (channel == 1) {// Reads two byte value from channel 1 (infrared)return TSL2561_Read_2_Bytes(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT | TSL2561_REGISTER_CHAN1_LOW);}TSL2561_Disable();// Unknown channel!return 0;}void TSL2561_Write_2_Bytes(uint8_t reg, uint8_t value) {uint8_t buffer[2];buffer[0] = reg;buffer[1] = value;I2C1_Master_Send(tsl2561_data.address, 2, buffer);while (!I2C1_Get_Status());}uint16_t TSL2561_Read_2_Bytes(uint8_t reg) {uint8_t buffer[2];uint16_t ret;I2C1_Master_Restart(tsl2561_data.address, reg, 2);while (!I2C1_Get_Status());I2C1_Read_Buffer(buffer);ret = buffer[1] << 8;ret |= buffer[0];return ret;}