Add a TSL4531 driver and example
This commit is contained in:
		
							parent
							
								
									813477aa8a
								
							
						
					
					
						commit
						8b5ee93b55
					
				
					 6 changed files with 291 additions and 2 deletions
				
			
		
							
								
								
									
										3
									
								
								examples/tsl4531/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								examples/tsl4531/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					PROGRAM=tsl4531_example
 | 
				
			||||||
 | 
					EXTRA_COMPONENTS = extras/i2c extras/tsl4531
 | 
				
			||||||
 | 
					include ../../common.mk
 | 
				
			||||||
							
								
								
									
										55
									
								
								examples/tsl4531/tsl4531_example.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								examples/tsl4531/tsl4531_example.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This sample code is in the public domain.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include "esp/uart.h"
 | 
				
			||||||
 | 
					#include "FreeRTOS.h"
 | 
				
			||||||
 | 
					#include "i2c/i2c.h"
 | 
				
			||||||
 | 
					#include "task.h"
 | 
				
			||||||
 | 
					#include "tsl4531/tsl4531.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* An example using the TSL4531 light sensor
 | 
				
			||||||
 | 
					 * to read and print lux values from a sensor
 | 
				
			||||||
 | 
					 * attached to GPIO pin 2 (SCL) and GPIO pin 0 (SDA)
 | 
				
			||||||
 | 
					 * Connect 3.3v from the ESP to Vin and GND to GND
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SCL_PIN (2)
 | 
				
			||||||
 | 
					#define SDA_PIN (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tsl4531MeasurementTask(void *pvParameters)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    tsl4531_t lightSensor;
 | 
				
			||||||
 | 
					    lightSensor.i2c_addr = TSL4531_I2C_ADDR;
 | 
				
			||||||
 | 
					    tsl4531_init(&lightSensor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tsl4531_set_integration_time(&lightSensor, TSL4531_INTEGRATION_400MS);
 | 
				
			||||||
 | 
					    tsl4531_set_power_save_skip(&lightSensor, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t lux = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (tsl4531_read_lux(&lightSensor, &lux))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            printf("Lux: %u\n", lux);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            printf("Could not read data from TSL4531\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 0.05 second delay
 | 
				
			||||||
 | 
					        vTaskDelay(50 / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void user_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uart_set_baud(0, 115200);
 | 
				
			||||||
 | 
					    i2c_init(SCL_PIN, SDA_PIN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xTaskCreate(tsl4531MeasurementTask, "tsl4531MeasurementTask", 256, NULL, 2, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -107,9 +107,9 @@ static uint8_t read_register(uint8_t i2c_addr, uint8_t reg)
 | 
				
			||||||
    uint8_t data[1];
 | 
					    uint8_t data[1];
 | 
				
			||||||
    reg = TSL2561_REG_COMMAND | reg;
 | 
					    reg = TSL2561_REG_COMMAND | reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (i2c_slave_read(i2c_addr, ® , data, 1))
 | 
					    if (i2c_slave_read(i2c_addr, ®, data, 1))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        printf("Error in tsl261 read_register\n");
 | 
					        printf("Error in tsl2561 read_register\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return data[0];
 | 
					    return data[0];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								extras/tsl4531/component.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								extras/tsl4531/component.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					# Component makefile for extras/tsl4531
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Include the TSL4531 driver as "tsl4531/tsl4531.h"
 | 
				
			||||||
 | 
					INC_DIRS += $(tsl4531_ROOT)..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# args for passing into compile rule generation
 | 
				
			||||||
 | 
					tsl4531_SRC_DIR = $(tsl4531_ROOT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(eval $(call component_compile_rules,tsl4531))
 | 
				
			||||||
							
								
								
									
										166
									
								
								extras/tsl4531/tsl4531.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								extras/tsl4531/tsl4531.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,166 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Part of esp-open-rtos
 | 
				
			||||||
 | 
					 * Copyright (C) 2017 Brian Schwind (https://github.com/bschwind)
 | 
				
			||||||
 | 
					 * BSD Licensed as described in the file LICENSE
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "FreeRTOS.h"
 | 
				
			||||||
 | 
					#include "i2c/i2c.h"
 | 
				
			||||||
 | 
					#include "task.h"
 | 
				
			||||||
 | 
					#include "tsl4531.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Registers
 | 
				
			||||||
 | 
					#define TSL4531_REG_COMMAND 0x80
 | 
				
			||||||
 | 
					#define TSL4531_REG_CONTROL 0x00
 | 
				
			||||||
 | 
					#define TSL4531_REG_CONFIG 0x01
 | 
				
			||||||
 | 
					#define TSL4531_REG_DATA_LOW 0x04
 | 
				
			||||||
 | 
					#define TSL4531_REG_DATA_HIGH 0x05
 | 
				
			||||||
 | 
					#define TSL4531_REG_DEVICE_ID 0x0A
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TSL4531 Misc Values
 | 
				
			||||||
 | 
					#define TSL4531_ON 0x03
 | 
				
			||||||
 | 
					#define TSL4531_OFF 0x00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Integration times in milliseconds
 | 
				
			||||||
 | 
					#define TSL4531_INTEGRATION_TIME_100MS 120
 | 
				
			||||||
 | 
					#define TSL4531_INTEGRATION_TIME_200MS 240
 | 
				
			||||||
 | 
					#define TSL4531_INTEGRATION_TIME_400MS 480 // Default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int write_register(uint8_t i2c_addr, uint8_t reg, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    reg = TSL4531_REG_COMMAND | reg;
 | 
				
			||||||
 | 
					    return i2c_slave_write(i2c_addr, ®, &value, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint8_t read_register(uint8_t i2c_addr, uint8_t reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t data[1];
 | 
				
			||||||
 | 
					    reg = TSL4531_REG_COMMAND | reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i2c_slave_read(i2c_addr, ®, data, 1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("Error in tsl4531 read_register\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data[0];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint16_t read_register_16(uint8_t i2c_addr, uint8_t low_register_addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint16_t value = 0;
 | 
				
			||||||
 | 
					    uint8_t data[2];
 | 
				
			||||||
 | 
					    low_register_addr = TSL4531_REG_COMMAND | low_register_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i2c_slave_read(i2c_addr, &low_register_addr, data, 2))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("Error with i2c_slave_read in read_register_16\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    value = ((uint16_t)data[1] << 8) | (data[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int enable(tsl4531_t *device)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return write_register(device->i2c_addr, TSL4531_REG_CONTROL, TSL4531_ON);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int disable(tsl4531_t *device)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return write_register(device->i2c_addr, TSL4531_REG_CONTROL, TSL4531_OFF);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tsl4531_init(tsl4531_t *device)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (enable(device))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        printf("Error initializing tsl4531, the enable write failed\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t control_reg = read_register(device->i2c_addr, TSL4531_REG_CONTROL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (control_reg != TSL4531_ON) {
 | 
				
			||||||
 | 
					        printf("Error initializing tsl4531, control register wasn't set to ON\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t idRegister = read_register(device->i2c_addr, TSL4531_REG_DEVICE_ID);
 | 
				
			||||||
 | 
					    uint8_t id = (idRegister & 0xF0) >> 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (id == TSL4531_PART_TSL45317) {
 | 
				
			||||||
 | 
					        device->part_id = TSL4531_PART_TSL45317;
 | 
				
			||||||
 | 
					    } else if (id == TSL4531_PART_TSL45313) {
 | 
				
			||||||
 | 
					        device->part_id = TSL4531_PART_TSL45313;
 | 
				
			||||||
 | 
					    } else if (id == TSL4531_PART_TSL45315) {
 | 
				
			||||||
 | 
					        device->part_id = TSL4531_PART_TSL45315;
 | 
				
			||||||
 | 
					    } else if (id == TSL4531_PART_TSL45311) {
 | 
				
			||||||
 | 
					        device->part_id = TSL4531_PART_TSL45311;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        printf("Unknown part id for TSL4531 sensor: %u\n", id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    disable(device);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tsl4531_set_integration_time(tsl4531_t *device, tsl4531_integration_time_t integration_time_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t power_save_bit = device->skip_power_save ? 0x08 : 0x00;
 | 
				
			||||||
 | 
					    uint8_t integration_time_bits = 0x03 & integration_time_id;
 | 
				
			||||||
 | 
					    uint8_t new_config_reg = power_save_bit | integration_time_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enable(device);
 | 
				
			||||||
 | 
					    write_register(device->i2c_addr, TSL4531_REG_CONFIG, new_config_reg);
 | 
				
			||||||
 | 
					    disable(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    device->integration_time_id = integration_time_id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tsl4531_set_power_save_skip(tsl4531_t *device, bool skip_power_save)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t power_save_bit = skip_power_save ? 0x08 : 0x00;
 | 
				
			||||||
 | 
					    uint8_t integration_time_bits = 0x03 & device->integration_time_id;
 | 
				
			||||||
 | 
					    uint8_t new_config_reg = power_save_bit | integration_time_bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enable(device);
 | 
				
			||||||
 | 
					    write_register(device->i2c_addr, TSL4531_REG_CONFIG, new_config_reg);
 | 
				
			||||||
 | 
					    disable(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    device->skip_power_save = skip_power_save;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool tsl4531_read_lux(tsl4531_t *device, uint16_t *lux)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool success = true;
 | 
				
			||||||
 | 
					    uint16_t multiplier = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enable(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (device->integration_time_id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case TSL4531_INTEGRATION_100MS:
 | 
				
			||||||
 | 
					            multiplier = 4;
 | 
				
			||||||
 | 
					            vTaskDelay(TSL4531_INTEGRATION_TIME_100MS / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case TSL4531_INTEGRATION_200MS:
 | 
				
			||||||
 | 
					            multiplier = 2;
 | 
				
			||||||
 | 
					            vTaskDelay(TSL4531_INTEGRATION_TIME_200MS / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case TSL4531_INTEGRATION_400MS:
 | 
				
			||||||
 | 
					            multiplier = 1;
 | 
				
			||||||
 | 
					            vTaskDelay(TSL4531_INTEGRATION_TIME_400MS / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            multiplier = 1;
 | 
				
			||||||
 | 
					            vTaskDelay(TSL4531_INTEGRATION_TIME_400MS / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t lux_data = read_register_16(device->i2c_addr, TSL4531_REG_DATA_LOW);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    disable(device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *lux = multiplier * lux_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								extras/tsl4531/tsl4531.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								extras/tsl4531/tsl4531.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,56 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Part of esp-open-rtos
 | 
				
			||||||
 | 
					 * Copyright (C) 2017 Brian Schwind (https://github.com/bschwind)
 | 
				
			||||||
 | 
					 * BSD Licensed as described in the file LICENSE
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __TSL4531_H__
 | 
				
			||||||
 | 
					#define __TSL4531_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// I2C Addresses
 | 
				
			||||||
 | 
					typedef enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TSL4531_I2C_ADDR = 0x29
 | 
				
			||||||
 | 
					} tsl4531_i2c_addr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Integration time IDs
 | 
				
			||||||
 | 
					typedef enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TSL4531_INTEGRATION_100MS = 0x02,
 | 
				
			||||||
 | 
					    TSL4531_INTEGRATION_200MS = 0x01,
 | 
				
			||||||
 | 
					    TSL4531_INTEGRATION_400MS = 0x00 // Default
 | 
				
			||||||
 | 
					} tsl4531_integration_time_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Part IDs
 | 
				
			||||||
 | 
					typedef enum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TSL4531_PART_TSL45317 = 0x08,
 | 
				
			||||||
 | 
					    TSL4531_PART_TSL45313 = 0x09,
 | 
				
			||||||
 | 
					    TSL4531_PART_TSL45315 = 0x0A,
 | 
				
			||||||
 | 
					    TSL4531_PART_TSL45311 = 0x0B
 | 
				
			||||||
 | 
					} tsl4531_part_id_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    tsl4531_i2c_addr_t i2c_addr;
 | 
				
			||||||
 | 
					    uint8_t integration_time_id;
 | 
				
			||||||
 | 
					    bool skip_power_save;
 | 
				
			||||||
 | 
					    tsl4531_part_id_t part_id;
 | 
				
			||||||
 | 
					} tsl4531_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void tsl4531_init(tsl4531_t *device);
 | 
				
			||||||
 | 
					void tsl4531_set_integration_time(tsl4531_t *device, tsl4531_integration_time_t integration_time_id);
 | 
				
			||||||
 | 
					void tsl4531_set_power_save_skip(tsl4531_t *device, bool skip_power_save);
 | 
				
			||||||
 | 
					bool tsl4531_read_lux(tsl4531_t *device, uint16_t *lux);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif  // __TSL4531_H__
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue