-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmist_mod_lux.c
More file actions
133 lines (108 loc) · 3.08 KB
/
mist_mod_lux.c
File metadata and controls
133 lines (108 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* Basic example for setting up a light sensor.
*
* Copyright Thinnect Inc. 2020
* @license MIT
*/
#include "mist_middleware.h"
#include "dt_types.h"
#include "MLE.h"
#include "platform.h"
#include "retargeti2c.h"
#include <inttypes.h>
#include <string.h>
#include "loglevels.h"
#define __MODUUL__ "m_m_lx"
#define __LOG_LEVEL__ (LOG_LEVEL_mist_mod_illuminance & BASE_LOG_LEVEL)
#include "log.h"
// d22721b7-c5cc-4d69-bfe7-50f11aaab845
#define UUID_LIGHT_LX_RESOURCE ((uint8_t*)"\xd2\x27\x21\xb7\xc5\xcc\x4d\x69\xbf\xe7\x50\xf1\x1a\xaa\xb8\x45")
static mist_module_t m_illuminance_module;
static int32_t m_light_lx = 0;
#define VEML6030_ADDR 0x10
//#define VEML6030_ADDR 0x48
/**
* Really basic lightsensor read implementation for VEML6030.
*/
static int32_t veml6030_read ()
{
int32_t lux = -1;
// platform_i2c_request(I2C0, osWaitForever); // TODO: I2C bus must first be acuired.
RETARGET_I2CInit();
// gain = 0b11 (1/4), it = 100ms
if (0 == RETARGET_I2CWrite(VEML6030_ADDR, 0x00, (uint8_t *)"\x00\x11", 2))
{
debug2("initd");
osDelay(1000);
uint8_t buffer[2];
if (0 == RETARGET_I2CRead(VEML6030_ADDR, 0x04, buffer, sizeof(buffer)))
{
lux = (buffer[0] | ((uint16_t)buffer[1] << 8));
lux = lux * 2304;
lux = lux / 10000;
debug1("rd %"PRIu32, lux);
}
else
{
err1("i2c_r");
}
}
else
{
err1("i2c_w");
}
RETARGET_I2CDeinit();
// platform_i2c_release(I2C0); // TODO: and subsequently released
return lux;
}
static mist_error_t light_sensor(
mist_item_type_t itype, void * input, uint16_t input_length,
mist_item_type_t * otype, void * output, uint16_t output_size, uint16_t * output_length)
{
if (MIST_ITEM_NULL == itype) // No input - return current state
{
debug1("read");
*otype = MIST_ITEM_INT32;
*((int32_t*)output) = m_light_lx;
*output_length = sizeof(int32_t);
return MIST_SUCCESS;
}
return MIST_FAIL; // Control actions not supported by movement sensor
}
// Fake a motion detector by polling the platform button (assuming there is something behind it)
static void light_sensor_thread(void * arg)
{
for (;;)
{
osDelay(10000);
m_light_lx = veml6030_read();
info1("light %"PRIi32, m_light_lx);
mist_error_t r = mist_spontaneous_event(&m_illuminance_module, MIST_ITEM_INT32, &m_light_lx, sizeof(int32_t));
if (MIST_SUCCESS != r)
{
warn1("light spnt evt %d", (int)r); // Something went wrong
}
}
}
bool mist_mod_lux_init()
{
// Register movement sensor
m_illuminance_module.data_type = dt_light_lx;
m_illuminance_module.function = light_sensor;
memcpy(m_illuminance_module.uuid, UUID_LIGHT_LX_RESOURCE, UUID_LENGTH);
mist_error_t result = mist_register_handler(&m_illuminance_module);
if (MIST_SUCCESS != result)
{
err1("mist reg %d", result);
return false;
}
// Configure lux events to have a max 60 second backoff.
mist_configure_spontaneous_event_backoff(&m_illuminance_module, 30, 60, 30);
const osThreadAttr_t thread_attr = { .name = "lux", .stack_size = 1536 };
if (NULL == osThreadNew(light_sensor_thread, NULL, &thread_attr))
{
err1("thrd lux");
return false;
}
return true;
}