@ -0,0 +1,203 @@
# include <stdio.h>
# include <stdlib.h>
# include "driver/i2c.h"
# include "embedded_display.c"
# include "esp_log.h"
# define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
# define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
# define ACK_VAL 0x0 /*!< I2C ack value */
# define NACK_VAL 0x1 /*!< I2C nack value */
# define I2C_MASTER_NUM CONFIG_I2C_NUM
# define APDS_9930_ADDRESS 0x39
# define APDS_9930_CMD_REPEATED 0x80 // 命令重复地址
# define APDS_9930_CMD_AUTO_INCREMENT 0x90 // 命令自动递增地址
// ----------------------------------- 描述 默认值
# define APDS_9930_REG_ENABLE 0x00 // 状态和中断的启用 0x00
# define APDS_9930_REG_ATIME 0x01 // ALS ADC 时间 0xff
# define APDS_9930_REG_PTIME 0x02 // Proximity ADC 时间 0xff
# define APDS_9930_REG_WTIME 0x03 // Wait 时间 0xff
# define APDS_9930_REG_PPULSE 0x0e // Proximity 脉冲计数 0x00
# define APDS_9930_REG_CONTROL 0x0f // 增益控制 0x00
# define APDS_9930_REG_Ch0DATAL 0x14 // Ch0 ADC Low data 0x00
# define APDS_9930_REG_Ch0DATAH 0x15 // Ch0 ADC High data 0x00
# define APDS_9930_REG_Ch1DATAL 0x16 // Ch1 ADC Low data 0x00
# define APDS_9930_REG_Ch1DATAH 0x17 // Ch1 ADC High data 0x00
# define APDS_9930_REG_PDATAL 0x18 // Proximity ADC Low data 0x00
# define APDS_9930_REG_PDATAH 0x19 // Proximity ADC High data 0x00
# define APDS_9930_REG_OFFSET 0x1e // Proximity 偏移 --
# define APDS_9930_ATIME_VALUE 0xff // 2.7 ms – minimum ALS integration time
# define APDS_9930_WTIME_VALUE 0xff // 2.7 ms – minimum Wait time
# define APDS_9930_PTIME_VALUE 0xff // 2.7 ms – minimum Prox integration time
# define APDS_9930_PPULSE_VALUE 0x08 // Minimum prox pulse count
# define APDS_9930_CONTROL_VALUE \
0b00101010 // LED 100mA, Proximity Diode Ch1,
// Proximity 4X, ALS 16 X
# define APDS_9930_ENABLE_VALUE 0b01000111
# define APDS_9930_OFFSET_VALUE 0x8f
# define AMBIENT_LIGHT_TAG "ambient-light"
esp_err_t apds_9930_write ( uint8_t command , uint8_t data ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create ( ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_WRITE ,
ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , command , ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , data , ACK_CHECK_EN ) ;
i2c_master_stop ( cmd ) ;
esp_err_t error =
i2c_master_cmd_begin ( I2C_MASTER_NUM , cmd , 1000 / portTICK_PERIOD_MS ) ;
i2c_cmd_link_delete ( cmd ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " write failed. %d " , error ) ;
}
return error ;
}
esp_err_t apds_9930_write_word ( uint8_t command , uint8_t data_l ,
uint8_t data_h ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create ( ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_WRITE ,
ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , command , ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , data_l , ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , data_h , ACK_CHECK_EN ) ;
i2c_master_stop ( cmd ) ;
esp_err_t error =
i2c_master_cmd_begin ( I2C_MASTER_NUM , cmd , 1000 / portTICK_PERIOD_MS ) ;
i2c_cmd_link_delete ( cmd ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " write failed. %d " , error ) ;
}
return error ;
}
esp_err_t apds_9930_read ( uint8_t command , uint8_t * data ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create ( ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_WRITE ,
ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , command , ACK_CHECK_EN ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_READ ,
ACK_CHECK_EN ) ;
i2c_master_read_byte ( cmd , data , NACK_VAL ) ;
i2c_master_stop ( cmd ) ;
esp_err_t error =
i2c_master_cmd_begin ( I2C_MASTER_NUM , cmd , 1000 / portTICK_PERIOD_MS ) ;
i2c_cmd_link_delete ( cmd ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " write failed. %d " , error ) ;
}
return error ;
}
esp_err_t apds_9930_read_word ( uint8_t command , uint8_t * data_l ,
uint8_t * data_h ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create ( ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_WRITE ,
ACK_CHECK_EN ) ;
i2c_master_write_byte ( cmd , command , ACK_CHECK_EN ) ;
i2c_master_start ( cmd ) ;
i2c_master_write_byte ( cmd , APDS_9930_ADDRESS < < 1 | I2C_MASTER_READ ,
ACK_CHECK_EN ) ;
i2c_master_read_byte ( cmd , data_l , ACK_VAL ) ;
i2c_master_read_byte ( cmd , data_h , NACK_VAL ) ;
i2c_master_stop ( cmd ) ;
esp_err_t error =
i2c_master_cmd_begin ( I2C_MASTER_NUM , cmd , 1000 / portTICK_PERIOD_MS ) ;
i2c_cmd_link_delete ( cmd ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " write failed. %d " , error ) ;
}
return error ;
}
void ambient_light_fetch ( void * arg ) {
esp_err_t error ;
uint16_t als_ch0_raw ;
uint16_t als_ch1_raw ;
uint16_t proximity_raw ;
char als_ch0_str [ 10 ] ;
char als_ch1_str [ 10 ] ;
char proximity_str [ 10 ] ;
uint8_t als_ch0_buffer [ ] = { 0 , 0 } ;
uint8_t als_ch1_buffer [ ] = { 0 , 0 } ;
uint8_t proximity_buffer [ ] = { 0 , 0 } ;
uint8_t enable_value ;
display_fill_rect ( 0 , 2 , 128 , 8 , 0x00 ) ;
for ( ; ; ) {
// Proximity
error =
apds_9930_read_word ( APDS_9930_CMD_AUTO_INCREMENT | APDS_9930_REG_PDATAL ,
& ( proximity_buffer [ 1 ] ) , & ( proximity_buffer [ 0 ] ) ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " read failed. %x " , error ) ;
} else {
proximity_raw = proximity_buffer [ 0 ] < < 8 | proximity_buffer [ 1 ] ;
sprintf ( proximity_str , " Prox: % 4d " , proximity_raw ) ;
display_print8_str ( 8 , 2 , proximity_str ) ;
ESP_LOGD ( AMBIENT_LIGHT_TAG , " Prox: %d %x, %x %x " , proximity_raw ,
proximity_raw , proximity_buffer [ 0 ] , proximity_buffer [ 1 ] ) ;
}
// als ch0
error = apds_9930_read_word (
APDS_9930_CMD_AUTO_INCREMENT | APDS_9930_REG_Ch0DATAL ,
& ( als_ch0_buffer [ 1 ] ) , & ( als_ch0_buffer [ 0 ] ) ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " read failed. %x " , error ) ;
} else {
als_ch0_raw = als_ch0_buffer [ 0 ] < < 8 | als_ch0_buffer [ 1 ] ;
sprintf ( als_ch0_str , " Ch0: % 5d " , als_ch0_raw ) ;
display_print8_str ( 8 , 4 , als_ch0_str ) ;
ESP_LOGD ( AMBIENT_LIGHT_TAG , " ALS Ch0: %d, %x " , als_ch0_raw ,
als_ch0_raw ) ;
}
// als ch1
error = apds_9930_read_word (
APDS_9930_CMD_AUTO_INCREMENT | APDS_9930_REG_Ch1DATAL ,
& ( als_ch1_buffer [ 1 ] ) , & ( als_ch1_buffer [ 0 ] ) ) ;
if ( error ! = ESP_OK ) {
ESP_LOGW ( AMBIENT_LIGHT_TAG , " read failed. %x " , error ) ;
} else {
als_ch1_raw = als_ch1_buffer [ 0 ] < < 8 | als_ch1_buffer [ 1 ] ;
sprintf ( als_ch1_str , " Ch1: % 5d " , als_ch1_raw ) ;
display_print8_str ( 8 , 6 , als_ch1_str ) ;
ESP_LOGD ( AMBIENT_LIGHT_TAG , " ALS Ch1: %d, %x " , als_ch1_raw ,
als_ch1_raw ) ;
}
vTaskDelay ( pdMS_TO_TICKS ( 100 ) ) ;
}
display_fill_rect ( 0 , 2 , 128 , 8 , 0x00 ) ;
}
void ambient_light_auto_fetch ( ) {
xTaskCreate ( ambient_light_fetch , " ui_input_event " , 2048 , NULL , 10 , NULL ) ;
}
void ambient_light_init ( ) {
// esp_log_level_set(AMBIENT_LIGHT_TAG, ESP_LOG_DEBUG);
ESP_ERROR_CHECK ( apds_9930_write ( APDS_9930_CMD_REPEATED | APDS_9930_REG_ATIME ,
APDS_9930_ATIME_VALUE ) ) ;
ESP_ERROR_CHECK ( apds_9930_write ( APDS_9930_CMD_REPEATED | APDS_9930_REG_PTIME ,
APDS_9930_PTIME_VALUE ) ) ;
ESP_ERROR_CHECK ( apds_9930_write ( APDS_9930_CMD_REPEATED | APDS_9930_REG_PPULSE ,
APDS_9930_PPULSE_VALUE ) ) ;
ESP_ERROR_CHECK ( apds_9930_write (
APDS_9930_CMD_REPEATED | APDS_9930_REG_CONTROL , APDS_9930_CONTROL_VALUE ) ) ;
ESP_ERROR_CHECK ( apds_9930_write ( APDS_9930_CMD_REPEATED | APDS_9930_REG_OFFSET ,
APDS_9930_OFFSET_VALUE ) ) ;
ESP_ERROR_CHECK ( apds_9930_write ( APDS_9930_CMD_REPEATED | APDS_9930_REG_ENABLE ,
APDS_9930_ENABLE_VALUE ) ) ;
}