Commit 5bd33447 authored by Projects's avatar Projects

light: Changed calculations to fixed point. Increased resolution. Fixed light sensor demo.

parent 0bb54a12
/*
* Copyright (C) 2014 Julian Lewis
* @author Matthieu Cattin <matthieu.cattin@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -25,13 +26,10 @@
*/
#include "light_sensor.h"
#include <math.h>
#include <stdio.h>
#include "i2cdrv.h"
// Writes a register
uint8_t max44009_write_reg(uint8_t reg_add, uint8_t value)
static uint8_t max44009_write_reg(uint8_t reg_add, uint8_t value)
{
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
......@@ -57,9 +55,8 @@ uint8_t max44009_write_reg(uint8_t reg_add, uint8_t value)
return 0;
}
// Reads a register
uint8_t max44009_read_reg(uint8_t reg_add, uint8_t* value)
static uint8_t max44009_read_reg(uint8_t reg_add, uint8_t *value, uint8_t length)
{
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
......@@ -73,7 +70,7 @@ uint8_t max44009_read_reg(uint8_t reg_add, uint8_t* value)
// Read value in buffer
seq.buf[1].data = value;
seq.buf[1].len = 1;
seq.buf[1].len = length;
// Initiate transfer
ret = I2CDRV_Transfer(&seq);
......@@ -85,73 +82,72 @@ uint8_t max44009_read_reg(uint8_t reg_add, uint8_t* value)
return 0;
}
uint8_t light_sensor_set_int(uint8_t enable)
/*uint8_t light_sensor_set_int(uint8_t enable)
{
return 0;
}
uint8_t light_sensor_get_isr(uint8_t* isr)
{
return 0;
}
uint8_t light_sensor_set_cfg(Light_Sensor_Conf_TypeDef *cfg)
{
return 0;
}*/
///> Converts 16-bit raw register value (registers 3 & 4) to millilux.
static uint32_t raw16_to_lux(uint16_t val)
{
uint8_t e = (val & 0xf000) >> 12; // exponent
uint8_t m = ((val & 0x0f00) >> 4) | (val & 0x0f); // mantissa
return (1 << e) * m * 45;
}
///> Converts 8-bit raw register value (register 3) to millilux.
static uint32_t raw8_to_lux(uint8_t val)
{
uint8_t e = (val >> 4); // exponent
uint8_t m = (val & 0x0f); // mantissa
uint8_t light_sensor_get_lux(double* lux)
return (1 << e) * m * 720;
}
uint8_t light_sensor_get_raw(uint16_t *val)
{
uint8_t err, high_b, low_b, m, e;
/* TODO
* For accurate reading, high and low registers have to
* be read during the same i2c transfer.
* => Apparently not possible with the current i2cdrvr!
*
* For now, only read high byte
*/
// Read Lux registers high byte
err = max44009_read_reg(MAX44009_REG_LUX_H, &high_b);
if(err)
{
return err;
}
uint8_t err;
// Read Lux registers
err = max44009_read_reg(MAX44009_REG_LUX_H, (uint8_t*)val, 2);
/*
// Read Lux register low byte
err = max44009_read_reg(MAX44009_REG_LUX_L, &low_b);
if(err)
{
return err;
}
*/
// Extract mantissa and exponent
m = high_b & 0xff;
//m = ((high_b & 0xff) << 4) + (low_b & 0xff);
e = ((high_b & 0xff00) >> 4);
return 0;
}
uint8_t light_sensor_get_lux(uint32_t *lux)
{
uint16_t raw;
uint8_t ret = light_sensor_get_raw(&raw);
if(ret != 0)
return ret; // error, no more processing
// Calculate Lux value
*lux = pow(2,(double) e) * m * 0.72;
//*lux = pow(2,(double) e) * m * 0.045;
*lux = raw16_to_lux(raw);
return 0;
}
uint8_t light_sensor_set_thres(double thres)
/*uint8_t light_sensor_set_thres(double thres)
{
return 0;
}
uint8_t light_sensor_set_thres_timer(uint8_t timer)
{
return 0;
}
}*/
/*
* Copyright (C) 2014 Julian Lewis
* @author Matthieu Cattin <matthieu.cattin@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -50,7 +51,7 @@
#define MAX44009_CFG_TIM 0x07 // Integration time
/** Ambient light sensor configuration structure. */
typedef struct
/*typedef struct
{
bool cont;
bool manual;
......@@ -61,10 +62,23 @@ typedef struct
uint8_t light_sensor_set_int(uint8_t enable);
uint8_t light_sensor_get_isr(uint8_t* isr);
uint8_t light_sensor_set_cfg(Light_Sensor_Conf_TypeDef *cfg);
uint8_t light_sensor_get_lux(double* lux);
uint8_t light_sensor_set_thres(double thres);
uint8_t light_sensor_set_thres_timer(uint8_t timer);
uint8_t light_sensor_set_cfg(Light_Sensor_Conf_TypeDef *cfg);*/
/**
* Returns raw reading from the light sensor.
* @param val is the place where the reading will be stored.
* @return 0 in case of success, error code otherwise.
*/
uint8_t light_sensor_get_raw(uint16_t* val);
/**
* Returns light level expressed in millilux.
* @param lux is the variable where the computed value will be stored.
* @return 0 in case of success, error code otherwise.
*/
uint8_t light_sensor_get_lux(uint32_t *lux);
/*uint8_t light_sensor_set_thres(double thres);
uint8_t light_sensor_set_thres_timer(uint8_t timer);*/
#endif /* LIGHT_SENSOR_H */
......@@ -143,13 +143,17 @@ INCLUDEPATHS += \
C_SRC += \
../common/Device/EnergyMicro/EFM32GG/Source/system_efm32gg.c \
../common/drivers/lcd.c \
../common/drivers/dmactrl.c \
../common/drivers/lcd_dma.c \
../common/emlib/src/em_assert.c \
../common/emlib/src/em_cmu.c \
../common/emlib/src/em_dma.c \
../common/emlib/src/em_emu.c \
../common/emlib/src/em_gpio.c \
../common/emlib/src/em_i2c.c \
../common/emlib/src/em_int.c \
../common/emlib/src/em_system.c \
../common/emlib/src/em_timer.c \
../common/emlib/src/em_rtc.c \
../common/emlib/src/em_usart.c \
../common/gfx/graphics.c \
......@@ -158,7 +162,6 @@ C_SRC += \
../common/gfx/font_helv17b.c \
../common/gfx/font_xm4x5.c \
../common/gfx/font_xm4x6.c \
../common/udelay.c \
../common/delay.c \
../common/drivers/i2cdrv.c \
../common/drivers/light_sensor.c \
......
/*
* Copyright (C) 2014 Julian Lewis
* @author Maciej Suminski <maciej.suminski@cern.ch>
* @author Matthieu Cattin <matthieu.cattin@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -51,7 +52,7 @@ int main(void)
double temp = 0;
double pressure = 0;
double altitude = 0;
double lux;
uint32_t lux;
/* Setup SysTick Timer for 1 msec interrupts */
if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1);
......@@ -76,7 +77,7 @@ int main(void)
{
err = light_sensor_get_lux(&lux);
sprintf(str, "light: %3.3f lux", lux);
sprintf(str, "light: %u lux", lux);
text(&font_helv11, 5, 10, str);
err = alti_get_temp_pressure(&temp, &pressure, true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment