-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtiny_code_reader.h
65 lines (55 loc) · 2.57 KB
/
tiny_code_reader.h
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
#ifndef INCLUDE_TINY_CODE_READER_H
#define INCLUDE_TINY_CODE_READER_H
// Definitions for the Useful Sensors Tiny Code Reader module.
// Includes the standard I2C address of the sensor, constants for the
// configuration commands, and the data structures used to communicate results
// to the main system.
// See the full developer guide at https://usfl.ink/tcr_dev for more information.
#include "hardware/i2c.h"
#include <stdint.h>
// The I2C address of the tiny code reader board.
#define TINY_CODE_READER_I2C_ADDRESS (0x0c)
// Configuration commands for the sensor. Write this as a byte to the I2C bus
// followed by a second byte as an argument value.
#define TINY_CODE_READER_REG_LED_STATE (0x01)
// The following structures represent the data format returned from the code
// reader over the I2C communication protocol. The C standard doesn't
// guarantee the byte-wise layout of a regular struct across different
// platforms, so we add the non-standard (but widely supported) __packed__
// attribute to ensure the layouts are the same as the wire representation.
// The results returned from the module have a 16-bit unsigned integer
// representing the length of the code content, followed by 254 bytes
// containing the content itself, commonly as a UTF-8 string.
#define TINY_CODE_READER_CONTENT_BYTE_COUNT (254)
typedef struct __attribute__ ((__packed__)) {
uint16_t content_length;
uint8_t content_bytes[TINY_CODE_READER_CONTENT_BYTE_COUNT];
} tiny_code_reader_results_t;
// Fetch the latest results from the sensor. Returns false if the read didn't
// succeed.
inline bool tiny_code_reader_read(tiny_code_reader_results_t* results) {
int num_bytes_read = i2c_read_blocking(
i2c_default,
TINY_CODE_READER_I2C_ADDRESS,
(uint8_t*)(results),
sizeof(tiny_code_reader_results_t),
false);
// Make sure the content string is null terminated. Older firmware didn't
// guarantee this, but all post-prototype modules do.
if (results->content_length >= TINY_CODE_READER_CONTENT_BYTE_COUNT) {
results->content_length = (TINY_CODE_READER_CONTENT_BYTE_COUNT - 1);
}
results->content_bytes[results->content_length] = 0;
return (num_bytes_read == sizeof(tiny_code_reader_results_t));
}
// Writes the value to the sensor register over the I2C bus.
inline void tiny_code_reader_write_reg(uint8_t reg, uint8_t value) {
uint8_t write_bytes[2] = {reg, value};
i2c_write_blocking(
i2c_default,
TINY_CODE_READER_I2C_ADDRESS,
write_bytes,
2,
false);
}
#endif // INCLUDE_TINY_CODE_READER_H