libyggdrasil  v1.0.0
color_sensor.hpp
Go to the documentation of this file.
1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * _____.___. .___ .__.__ *
3  * \__ | | ____ ____ __| _/___________ _____|__| | *
4  * / | |/ ___\ / ___\ / __ |\_ __ \__ \ / ___/ | | *
5  * \____ / /_/ > /_/ > /_/ | | | \// __ \_\___ \| | |__ *
6  * / ______\___ /\___ /\____ | |__| (____ /____ >__|____/ *
7  * \/ /_____//_____/ \/ \/ \/ *
8  * - Yggdrasil - *
9  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  * This software can be used by students and other personal of the *
11  * Bern University of Applied Sciences under the terms of the MIT *
12  * license. *
13  * For other persons this software is under the terms of the GNU *
14  * General Public License version 2. *
15  * *
16  * Copyright © 2021, Bern University of Applied Sciences. *
17  * All rights reserved. *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #pragma once
27 
29 #include <cpp/common/types.hpp>
30 #include <cpp/common/utils.hpp>
31 
32 namespace bsp::ygg::prph {
33 
37  class ColorSensor {
38  public:
39  ColorSensor() = delete;
40 
44  enum class IntegrationTime {
45  _2_4ms = 0xFF,
46  _10ms = 0xFB,
47  _24ms = 0xF6,
48  _50ms = 0xEB,
49  _101ms = 0xD5,
50  _154ms = 0xC0,
51  _700ms = 0x00
52  };
53 
57  enum class Gain {
58  _1x = 0x00,
59  _4x = 0x01,
60  _16x = 0x02,
61  _60x = 0x03
62  };
63 
70  static bool init() {
71  u8 retries = 0;
72  do{
73  if(bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::ID)) != DeviceID){ // Check device id
74  core::delay(1);
75  retries++;
76  if(retries > 10) return false;
77  }
78  else{
79  break;
80  }
81  }
82  while(true);
83 
84 
85 
86  setIntergrationTime(IntegrationTime::_2_4ms); // Set integration time
87  setGain(Gain::_1x); // Set gain
88  enable(); // Enable sensor
89  startConversion(); // Start a conversion
90 
91  core::delay(3); // Wait for the conversion to complete
92 
93  return true;
94 
95  }
96 
97 
104  static inline void setIntergrationTime(IntegrationTime integrationTime) {
105  ColorSensor::s_integrationTime = enumValue(integrationTime);
106  bsp::I2CA::write<u8>(DeviceAddress, enumValue(RegisterID::ATIME), enumValue(integrationTime)); // Write integration time in the ATIME register
107  }
108 
115  static inline void setGain(Gain gain) {
116  bsp::I2CA::write<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::CTRL), enumValue(gain)); // Set gain value in the CTRL register
117  }
118 
123  static void enable() {
124  EnableRegister enRegister = { 0 };
125  enRegister.PON = 1;
126 
127  bsp::I2CA::write<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::EN), bit_cast<u8>(enRegister)); // Enable sensor
128 
129  core::delay(3); // Wait for power up
130  }
131 
135  static void disable() {
136  EnableRegister enRegister = { 0 };
137  bsp::I2CA::write<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::EN), bit_cast<u8>(enRegister)); // Disable sensor
138  }
139 
145  static u16 startConversion() {
146  EnableRegister enRegister = { 0 };
147 
148  enRegister.PON = 1; // Enable
149  enRegister.AEN = 1; // Enable RGBC
150  bsp::I2CA::write<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::EN), bit_cast<u8>(enRegister)); // Write enable register
151 
152  return static_cast<u16>((256 - ColorSensor::s_integrationTime) * 2.4F + 0.9);
153  }
154 
155 
161  static bool isDone() {
162  return (bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::STATUS)) & ConversionDone); // Wait for conversion to complete
163  }
164 
165 
173  static RGBA16 getColor16(bool restart = true) {
174  while (!isDone()) { // Wait for conversion to be done
175  core::delay(1); // Avoid spamming the I2C
176  }
177 
178  RGBA16 color = { 0 };
179 
180  color.r = bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::RDATA));
181  color.r |= bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::RDATAH)) << 8;
182 
183  color.g = bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::GDATA));
184  color.g |= bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::GDATAH)) << 8;
185 
186  color.b = bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::BDATA));
187  color.b |= bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::BDATAH)) << 8;
188 
189  color.a = bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::BDATA));
190  color.a |= bsp::I2CA::read<u8>(DeviceAddress, CommandBit | enumValue(RegisterID::BDATAH)) << 8;
191 
192  if(restart) startConversion();
193 
194  return color;
195  }
196 
204  static RGBA8 getColor8(bool restart = true) {
205  RGBA16 color16 = getColor16(restart);
206 
207  RGBA8 color8 = {0};
208  color8.r = static_cast<u8>(color16.r >> 8);
209  color8.g = static_cast<u8>(color16.g >> 8);
210  color8.b = static_cast<u8>(color16.b >> 8);
211  color8.a = static_cast<u8>(color16.a >> 8);
212 
213 
214  return color8;
215  }
216 
217  private:
218 
219  static inline u8 s_integrationTime;
220 
224  enum class RegisterID : u8{
225  EN = 0x00,
226  ATIME = 0x01,
227  WTIME = 0x02,
228  AILTL = 0x04,
229  AILTH = 0x05,
230  AIHTL = 0x06,
231  AIHTH = 0x07,
232  PERS = 0x0C,
233  CNFG = 0x0D,
234  CTRL = 0x0F,
235  ID = 0x12,
236  STATUS = 0x13,
237  CDATA = 0x14,
238  CDATAH = 0x15,
239  RDATA = 0x16,
240  RDATAH = 0x17,
241  GDATA = 0x18,
242  GDATAH = 0x19,
243  BDATA = 0x1A,
244  BDATAH = 0x1B,
245 
246  };
247 
251  struct EnableRegister {
252  u8 PON : 1;
253  u8 AEN : 1;
254  u8 Reserved : 1;
255  u8 WEN : 1;
256  u8 AIEN : 1;
257  u8 Reserved2 : 3;
258  };
259  static_assert (sizeof(EnableRegister) == sizeof(u8), "Enable register definition wrong");
260 
264  struct StatusRegister {
265  u8 AVALID : 1;
266  u8 Reserved1 : 3;
267  u8 AINT : 1;
268  u8 Reserved2 : 3;
269  };
270  static_assert (sizeof(StatusRegister) == sizeof(u8), "Status register definition wrong");
271 
272  constexpr static inline u8 DeviceAddress = 0x52;
273  constexpr static inline u8 DeviceID = 0x44;
274  constexpr static inline u8 CommandBit = 0x80;
275  constexpr static inline u8 ConversionDone = 0x01;
276 
277 
278 
279  };
280 
281 }
bsp::ygg::RGBA16
RGBA16 color type.
Definition: types.hpp:43
bsp::ygg::RGBA8
RGBA8 color type.
Definition: types.hpp:33
bsp::ygg::prph::ColorSensor::IntegrationTime::_50ms
@ _50ms
50ms - 20 cycles
bsp::ygg::prph::ColorSensor::IntegrationTime::_24ms
@ _24ms
24ms - 10 cycles
bsp::ygg::prph::ColorSensor::IntegrationTime::_101ms
@ _101ms
101ms - 42 cycles
bsp::ygg::prph::ColorSensor::IntegrationTime::_2_4ms
@ _2_4ms
2.4ms - 1 cycle
u16
uint16_t u16
Definition: types.h:37
utils.hpp
Commonly used helper functions.
u8
uint8_t u8
Unsigned integer definitions.
Definition: types.h:36
bsp::ygg::prph::ColorSensor
Color sensor TCS3472 driver.
Definition: color_sensor.hpp:37
bsp::ygg::prph::ColorSensor::Gain::_1x
@ _1x
No gain.
bsp::ygg::prph::ColorSensor::enable
static void enable()
Enable the sensor.
Definition: color_sensor.hpp:123
bsp::ygg::prph::ColorSensor::setIntergrationTime
static void setIntergrationTime(IntegrationTime integrationTime)
Set the integration time.
Definition: color_sensor.hpp:104
bsp::ygg::prph::ColorSensor::getColor16
static RGBA16 getColor16(bool restart=true)
Get the color values and start a new measurement (optional)
Definition: color_sensor.hpp:173
types.hpp
Commonly used type definitions and helper templates.
bsp::ygg::RGBA8::b
u8 b
Definition: types.hpp:35
bsp::ygg::prph::ColorSensor::IntegrationTime::_700ms
@ _700ms
700ms - 256 cycles
bsp::ygg::prph::ColorSensor::IntegrationTime
IntegrationTime
Integration time = (256 - IntegrationTime) * 2.4ms.
Definition: color_sensor.hpp:44
bsp::ygg::RGBA16::b
u16 b
Definition: types.hpp:45
bsp::ygg::prph::ColorSensor::getColor8
static RGBA8 getColor8(bool restart=true)
Get the color values and start a new measurement (optional)
Definition: color_sensor.hpp:204
bsp::ygg::RGBA8::r
u8 r
Definition: types.hpp:35
bsp::ygg::prph::ColorSensor::startConversion
static u16 startConversion()
Start a conversion and returns the set integration time.
Definition: color_sensor.hpp:145
bsp::ygg::prph::ColorSensor::init
static bool init()
Initialization of the TCS3472 color sensor.
Definition: color_sensor.hpp:70
bsp::ygg::prph::ColorSensor::IntegrationTime::_154ms
@ _154ms
154ms - 64 cycles
bsp::enumValue
auto enumValue(T value)
Casts a scoped enum type into its underlying value.
Definition: utils.hpp:151
bsp::ygg::prph::ColorSensor::IntegrationTime::_10ms
@ _10ms
10ms - 4 cycles
bsp::ygg::prph::ColorSensor::disable
static void disable()
Disables the sensor.
Definition: color_sensor.hpp:135
bsp::ygg::RGBA16::g
u16 g
Definition: types.hpp:45
bsp::ygg::prph::ColorSensor::ColorSensor
ColorSensor()=delete
bsp::ygg::RGBA8::g
u8 g
Definition: types.hpp:35
bsp::ygg::prph::ColorSensor::Gain::_60x
@ _60x
60x gain
bsp::ygg::prph::ColorSensor::Gain::_16x
@ _16x
16x gain
bsp::ygg::RGBA16::r
u16 r
Definition: types.hpp:45
bsp::ygg::prph::ColorSensor::setGain
static void setGain(Gain gain)
Set the gain.
Definition: color_sensor.hpp:115
bsp::ygg::prph::ColorSensor::isDone
static bool isDone()
Used to poll a conversion.
Definition: color_sensor.hpp:161
attributes.hpp
Commonly used C++ and GNU attributes.
bsp::core::delay
ALWAYS_INLINE void delay(u32 ms)
Delays execution by a certain number of milliseconds.
Definition: cortex.hpp:39
bsp::ygg::prph
Definition: color_sensor.hpp:32
bsp::ygg::RGBA16::a
u16 a
Definition: types.hpp:45
bsp::ygg::RGBA8::a
u8 a
Definition: types.hpp:35
bsp::ygg::prph::ColorSensor::Gain
Gain
Gain settings.
Definition: color_sensor.hpp:57
bsp::ygg::prph::ColorSensor::Gain::_4x
@ _4x
4x gain