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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \ingroup pbdrv
* \ingroup pbdrv-mod
* \defgroup pb_types Types
* \brief Datatypes used within \ref pbdrv
*
* \{
*/
#ifdef __GNUC__
#define __weak __attribute__((weak))
#endif
#ifndef __weak
#error Could not determine weak attribute for current compiler
//! Mark function as weak (allow user to override implementation)
#define __weak
#endif
//! I2C address (10 or 7 bit)
typedef uint16_t i2c_addr_t;
//! Puzzle bus command types
typedef enum {
/**
* \brief puzzle module property (\ref pb_route_cmd_prop_req "REQ", \ref
* pb_route_cmd_prop_res "RES", \ref pb_route_cmd_prop_set "SET")
*
* The \c PROP command type is used for exchanging arbitrary data between
* puzzle modules and/or the puzzle box client (pbc) over the TCP bridge.
* These properties are not used by the puzzle framework.
*/
PB_CMD_PROP,
/**
* \brief puzzle module global state variable (\ref pb_route_cmd_state_req
* "REQ", \ref pb_route_cmd_state_res "RES", \ref pb_route_cmd_state_set
* "SET")
*
* The \c STATE command is used by puzzle modules to inform the main
* controller about their global state. The main controller aggregates the
* states of all connected puzzle modules and exchanges this aggregated state
* with the puzzle modules to indicate when the entire puzzle box is solved.
*/
PB_CMD_STATE,
/**
* \brief magic (handshake) (\ref pb_route_cmd_magic_req "REQ", \ref
* pb_route_cmd_magic_res "RES")
*
* The \c MAGIC command effectively serves as a 'secret handshake' (using a
* _magic_ value) which is used to distinguish between puzzle modules and
* unrelated I2C devices.
*/
PB_CMD_MAGIC,
} pb_cmd_id_t;
//! Puzzle bus command action types
typedef enum {
PB_ACTION_REQ, //!< request
PB_ACTION_RES, //!< response
PB_ACTION_SET, //!< (over)write
} pb_action_t;
//! Puzzle module global states
typedef enum {
PB_GS_NOINIT, //!< uninitialized (only used by puzzle modules)
PB_GS_IDLE, //!< puzzle not started yet
PB_GS_PLAYING, //!< puzzle actively being solved
PB_GS_SOLVED, //!< puzzle completed
} pb_global_state_t;
/**
* \brief Magic sent from main controller to puzzle module (="puzbus")
*
* The size of this array can be obtained by \c sizeof(pb_cmd_magic_req).
*/
static const char pb_cmd_magic_req[] = { 0x70, 0x75, 0x7a, 0x62, 0x75, 0x73 };
/**
* \brief Magic reply from puzzle module back to main controller (="gaming")
*
* The size of this array can be obtained by \c sizeof(pb_cmd_magic_res).
*/
static const char pb_cmd_magic_res[] = { 0x67, 0x61, 0x6d, 0x69, 0x6e, 0x67 };
//! puzzle bus message header / container (shared by all commands)
typedef struct {
/**
* \brief Command type (see \ref pb_cmd_id_t)
*
* This is used to identify what the message is about.
*/
pb_cmd_id_t type;
/**
* \brief Command action (see \ref pb_action_t)
*
* This is used to specify what should happen as a result of this message.
*/
pb_action_t action;
/**
* \brief I2C address of sender
*
* This is used to facilitate the 'network' features, as the sender of an I2C
* write is unknown.
*/
i2c_addr_t sender;
/**
* \brief Command data (dependent on \p type)
*
* Struct containing command type-specific data.
*/
void * cmd;
} pb_msg_t;
//! \ref PB_CMD_PROP data
typedef struct {
uint8_t propid; //!< id of state property
uint8_t * value; //!< new or current value
size_t _value_size; //!< size of \p value
} pb_cmd_prop_t;
//! \ref PB_CMD_STATE data
typedef struct {
pb_global_state_t state; //!< global state
} pb_cmd_state_t;
//! PB_MOD_STATE data
typedef struct {
i2c_addr_t sender; //!< i2c address of sender
pb_global_state_t state; //!< global state
} pb_puzzle_module_t;
//! \ref PB_CMD_MAGIC data
typedef struct {
char * magic; //!< magic value
size_t _magic_size; //!< size of \p magic
} pb_cmd_magic_t;
/// \}
#ifdef __cplusplus
}
#endif
|