Initial commit.

This commit is contained in:
David Žaitlík 2022-06-17 18:23:23 +02:00
parent 97e9cbe142
commit a937c1c08b
2 changed files with 295 additions and 0 deletions

202
ltr329.c Normal file
View File

@ -0,0 +1,202 @@
/*
* ltr329.c
*
* Created on: May 22, 2022
* Author: david
*/
#include "ltr329.h"
#include "main.h" /* for uart_disable_interrupts() */
static int8_t ltr329_read_register (ltr329_cmd_t register_addr, uint8_t *register_data )
{
uint8_t tx_buffer[1];
uint8_t rx_buffer[1];
int result;
// start measurement
tx_buffer[0] = register_addr;
/* disable interrupts to prevent modbus/i2c conflict */
uart_disable_interrupts();
result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 1);
uart_enable_interrupts();
if (result != I2C_OK) {
return LTR329_ERROR;
}
LL_mDelay(10); /* 10 ms should be enough */
/* read out */
uart_disable_interrupts();
result = i2c_receive(LTR329_I2C_ADDRESS<<1, rx_buffer, 1);
uart_enable_interrupts();
if (result != I2C_OK) {
return LTR329_ERROR;
}
*register_data = rx_buffer[0];
return LTR329_OK;
}
static int8_t ltr329_write_register (ltr329_cmd_t register_addr, uint8_t register_data)
{
uint8_t tx_buffer[2];
int result;
// start measurement
tx_buffer[0] = register_addr;
tx_buffer[1] = register_data;
/* disable interrupts to prevent modbus/i2c conflict */
uart_disable_interrupts();
result = i2c_transmit(LTR329_I2C_ADDRESS<<1, tx_buffer, 2);
uart_enable_interrupts();
if (result != I2C_OK) {
return LTR329_ERROR;
}
return LTR329_OK;
}
int8_t ltr329_write_settings (ltr329_gain_t gain, ltr329_als_mode_t mode, ltr329_integration_time_t integ_time, ltr329_measurement_rate_t meas_rate)
{
int8_t result;
/* Write Gain and ALS Mode */
result = ltr329_write_register(LTR329_ALS_CONTR, (gain | mode));
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
/* Write Integration Time and Measurement Rate */
result = ltr329_write_register(LTR329_ALS_MEAS_RATE, (integ_time | meas_rate));
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
return LTR329_OK;
}
int8_t ltr329_read_settings (ltr329_gain_t *gain, ltr329_als_mode_t *mode, ltr329_integration_time_t *integ_time, ltr329_measurement_rate_t *meas_rate)
{
int8_t result;
uint8_t control_register_data;
uint8_t rate_register_data;
result = ltr329_read_register(LTR329_ALS_CONTR, &control_register_data);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
result = ltr329_read_register(LTR329_ALS_MEAS_RATE, &rate_register_data);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
uint8_t control_register_gain_mask = 0b00011100;
uint8_t control_register_mode_mask = 0b00000001;
uint8_t rate_register_int_time_mask = 0b00111000;
uint8_t rate_register_rate_mask = 0b00000111;
/* Return Registers Values */
/* TODO: This might not be safe */
*gain = control_register_data & control_register_gain_mask;
*mode = control_register_data & control_register_mode_mask;
*integ_time = rate_register_data & rate_register_int_time_mask;
*meas_rate = rate_register_data & rate_register_rate_mask;
return LTR329_OK;
}
int8_t ltr329_sw_reset( void )
{
int8_t result;
/* Write Gain and ALS Mode */
result = ltr329_write_register(LTR329_ALS_CONTR, 0b00000010);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
return LTR329_OK;
}
int8_t ltr329_measure (uint16_t *data_ch0, uint16_t *data_ch1)
{
uint8_t ch0_l, ch0_h, ch1_l, ch1_h;
int result;
result = ltr329_read_register(LTR329_ALS_DATA_CH0_0, &ch0_l);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
result = ltr329_read_register(LTR329_ALS_DATA_CH0_1, &ch0_h);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
result = ltr329_read_register(LTR329_ALS_DATA_CH1_0, &ch1_l);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
result = ltr329_read_register(LTR329_ALS_DATA_CH1_1, &ch1_h);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
*data_ch0 = (ch0_h << 8) + ch0_l;
*data_ch1 = (ch1_h << 8) + ch1_l;
return LTR329_OK;
}
int8_t ltr329_read_status_register(uint8_t *data_valid, uint8_t *new_data, ltr329_gain_t *gain)
{
int8_t result;
uint8_t status_register_data;
result = ltr329_read_register(LTR329_ALS_STATUS, &status_register_data);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
/* Check data valid */
uint8_t data_invalid_mask = 0b10000000;
if ((status_register_data & data_invalid_mask) == data_invalid_mask)
{
*data_valid = 0;
} else
{
*data_valid = 1;
}
/* Check if there is new data */
uint8_t data_status_mask = 0b00000100;
if ((status_register_data & data_status_mask) == data_status_mask)
{
*new_data = 1;
} else
{
*new_data = 0;
}
/* Check Gain */
/* TODO: This might not be safe */
uint8_t gain_mask = 0b01110000;
*gain = status_register_data & gain_mask;
return LTR329_OK;
}
int8_t ltr329_read_device_info (uint8_t *manufacturer_id, uint8_t *part_id)
{
int8_t result;
result = ltr329_read_register(LTR329_MANUFAC_ID, manufacturer_id);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
result = ltr329_read_register(LTR329_PART_ID, part_id);
if (result != LTR329_OK)
{
return LTR329_ERROR;
}
return LTR329_OK;
}

93
ltr329.h Normal file
View File

@ -0,0 +1,93 @@
/*
* ltr329.h
*
* Created on: May 22, 2022
* Author: david
*/
#ifndef INC_LTR329_H_
#define INC_LTR329_H_
#include "stdint.h"
#include "stm32l0xx_ll_i2c.h"
#include "stm32l0xx_ll_utils.h"
#include "i2c.h"
#define LTR329_I2C_ADDRESS 0x29
/*
* Return values
*/
#define LTR329_OK 0
#define LTR329_ERROR -1 // generic error
/* LTR-329ALS-01 Registers */
/* Datasheet: https://optoelectronics.liteon.com/upload/download/DS86-2014-0006/LTR-329ALS-01_DS_V1.pdf */
typedef enum
{
LTR329_ALS_CONTR = 0x80, /* RW */
LTR329_ALS_MEAS_RATE = 0x85, /* RW */
LTR329_PART_ID = 0x86, /* R */
LTR329_MANUFAC_ID = 0x87, /* R */
LTR329_ALS_DATA_CH1_0 = 0x88, /* R */
LTR329_ALS_DATA_CH1_1 = 0x89, /* R */
LTR329_ALS_DATA_CH0_0 = 0x8A, /* R */
LTR329_ALS_DATA_CH0_1 = 0x8B, /* R */
LTR329_ALS_STATUS = 0x8C /* R */
} ltr329_cmd_t;
/* Bit masks for ALS Mode */
typedef enum
{
LTR329_MODE_STAND_BY = 0b00000000, /* DEFAULT */
LTR329_MODE_ACTIVE = 0b00000001
} ltr329_als_mode_t;
/* Bit masks for Gain settings */
typedef enum
{
LTR329_GAIN_1X = 0b00000000, /* DEFAULT */
LTR329_GAIN_2X = 0b00000100,
LTR329_GAIN_4X = 0b00001000,
LTR329_GAIN_8X = 0b00001100,
LTR329_GAIN_48X = 0b00011000,
LTR329_GAIN_96X = 0b00011100,
LTR329_GAIN_RESERVED1 = 0b00010000,
LTR329_GAIN_RESERVED2 = 0b00010100
} ltr329_gain_t;
/* Bit masks for Integration Time settings */
typedef enum
{
LTR329_INTEGRATION_50MS = 0b00001000,
LTR329_INTEGRATION_100MS = 0b00000000, /* DEFAULT */
LTR329_INTEGRATION_150MS = 0b00100000,
LTR329_INTEGRATION_200MS = 0b00010000,
LTR329_INTEGRATION_250MS = 0b00101000,
LTR329_INTEGRATION_300MS = 0b00110000,
LTR329_INTEGRATION_350MS = 0b00111000,
LTR329_INTEGRATION_400MS = 0b00011000
} ltr329_integration_time_t;
/* Bit masks for Measurement Rate settings */
typedef enum
{
LTR329_MEAS_RATE_50MS = 0b00000000,
LTR329_MEAS_RATE_100MS = 0b00000001,
LTR329_MEAS_RATE_200MS = 0b00000010,
LTR329_MEAS_RATE_500MS = 0b00000011, /* DEFAULT */
LTR329_MEAS_RATE_1000MS = 0b00000100,
LTR329_MEAS_RATE_2000MS = 0b00000111
} ltr329_measurement_rate_t;
static int8_t ltr329_read_register (ltr329_cmd_t register_addr, uint8_t *register_data );
static int8_t ltr329_write_register (ltr329_cmd_t register_addr, uint8_t register_data);
int8_t ltr329_write_settings (ltr329_gain_t gain, ltr329_als_mode_t mode, ltr329_integration_time_t integ_time, ltr329_measurement_rate_t meas_rate);
int8_t ltr329_read_settings (ltr329_gain_t *gain, ltr329_als_mode_t *mode, ltr329_integration_time_t *integ_time, ltr329_measurement_rate_t *meas_rate);
int8_t ltr329_sw_reset( void );
int8_t ltr329_measure (uint16_t *data_ch0, uint16_t *data_ch1);
int8_t ltr329_read_status_register(uint8_t *data_valid, uint8_t *new_data, ltr329_gain_t *gain);
int8_t ltr329_read_device_info (uint8_t *manufacturer_id, uint8_t *part_id);
#endif /* INC_LTR329_H_ */