Added SHT11 driver for TMote.
[sos-2x.git] / modules / vire / wiring_test / combine_3.c
blobeb2701ca84597dea62f59c8dcf29bd42f46eeb1a
1 /* -*- Mode: C; tab-width:4 -*- */
2 /* ex: set ts=4 shiftwidth=4 softtabstop=4 cindent: */
4 #include <module.h>
5 #include <sys_module.h>
6 #include <wiring_config.h>
8 //#define LED_DEBUG
9 #include <led_dbg.h>
11 // Private
12 #define COMBINE3_MOD_PID (DFLT_APP_ID0+6)
14 enum {
15 IDLE = 0,
16 WAITING_FOR_1,
17 WAITING_FOR_2,
20 // Element state.
21 // The pointers to function control blocks corresponding to
22 // the output(s) should appear first in the state. Other
23 // function CB's should follow after that.
24 typedef struct {
25 func_cb_ptr output0; //!< Function control block for output port 0
26 //func_cb_ptr put_token; //!< This function control block is used in SOS_CALL
27 //!< when the element
28 //!< needs to put a token on any output port.
29 //!< The output port is identified by passing
30 //!< one of the function control blocks defined
31 //!< above (output0 or output1).
32 func_cb_ptr signal_error; //!< Used with split-phase operations to indicate
33 //!< an error to the wiring engine after accepting
34 //!< the input token.
35 uint8_t status;
36 sos_pid_t pid;
37 uint8_t stored_input[2]; //!< Global variable to hold inputs while waiting for
38 //!< the others.
39 } element_state_t;
41 // Internal functions
42 static int8_t element_module(void *state, Message *msg);
43 static int8_t process_input(element_state_t *s, uint8_t data);
45 // Function corresponding to the input port. Each port will
46 // have its own input function which will be published by the module.
47 // The prototypes of the input and output functions should match,
48 // else linking through the wiring engine will also not work.
49 // Since, all the input functions have a common prototype (for
50 // the indirect call through engine to work), the output
51 // functions should also have "cyC2" as their prototype.
52 // This is currently kept for simplicity, but can easily be
53 // used to enforce type checking at run-time too without any overhead.
54 // Split-phase operations should return -EBUSY after accepting
55 // an input token so that the wiring engine knows that the module
56 // will take long to complete that operation and it should queue
57 // all the tokens meant for that module till the module puts
58 // a result on any of its output ports.
59 static int8_t input0 (func_cb_ptr p, token_type_t *t);
60 static int8_t input1 (func_cb_ptr p, token_type_t *t);
61 static int8_t input2 (func_cb_ptr p, token_type_t *t);
63 static mod_header_t mod_header SOS_MODULE_HEADER = {
64 .mod_id = COMBINE3_MOD_PID,
65 .code_id = ehtons(COMBINE3_MOD_PID),
66 .platform_type = HW_TYPE,
67 .processor_type = MCU_TYPE,
68 .state_size = sizeof(element_state_t),
69 .num_out_port = 1,
70 .num_sub_func = 2,
71 .num_prov_func = 3,
72 .module_handler = element_module,
73 .funct = {
74 {error_8, "cyC2", COMBINE3_MOD_PID, INVALID_GID},
75 //{error_8, "cyC4", MULTICAST_SERV_PID, DISPATCH_FID},
76 {error_8, "ccv1", MULTICAST_SERV_PID, SIGNAL_ERR_FID},
77 {input0, "cyC2", COMBINE3_MOD_PID, INPUT_PORT_0},
78 {input1, "cyC2", COMBINE3_MOD_PID, INPUT_PORT_1},
79 {input2, "cyC2", COMBINE3_MOD_PID, INPUT_PORT_2},
80 },
83 static int8_t element_module(void *state, Message *msg) {
84 element_state_t *s = (element_state_t *)state;
86 switch (msg->type) {
87 case MSG_INIT:
89 s->status = IDLE;
90 s->pid = msg->did;
91 break;
93 case MSG_FINAL:
95 break;
97 default: return -EINVAL;
99 return SOS_OK;
102 static int8_t process_input(element_state_t *s, uint8_t data) {
103 uint8_t out_value;
105 // Get token from port.
106 // If want to break the chain of calls here, then copy the token into a private
107 // data structure(global), and return appropriate value (-EBUSY).
108 switch (s->status) {
109 case IDLE:
111 s->stored_input[0] = data;
112 s->status = WAITING_FOR_1;
113 return -EBUSY;
115 case WAITING_FOR_1:
117 s->stored_input[1] = data;
118 s->status = WAITING_FOR_2;
119 return -EBUSY;
121 case WAITING_FOR_2:
123 // Process input: Combine (OR) the three inputs and pass the result on to the next function.
124 // We need a separate place to hold the output as we are modifying the input.
125 // Remember, this module does not own the input token, so should not
126 // overwrite it.
127 out_value = data | s->stored_input[0] | s->stored_input[1];
129 DEBUG("COMBINE: Output - token %d.\n", out_value);
130 token_type_t *my_token = create_token(&out_value, sizeof(uint8_t), s->pid);
131 if (my_token == NULL) return -ENOMEM;
132 //SOS_CALL(s->put_token, put_token_func_t, s->output0, my_token);
133 dispatch(s->output0, my_token);
134 s->status = IDLE;
135 destroy_token(my_token);
136 return SOS_OK;
138 default: return SOS_OK;
141 return SOS_OK;
144 //--------------------------------------------------------
146 static int8_t input0 (func_cb_ptr p, token_type_t *t) {
147 element_state_t *s = (element_state_t *)sys_get_state();
148 DEBUG("COMBINE: Accept - token %d on input 0.\n", *((uint8_t *)get_token_data(t)));
149 return process_input(s, *((uint8_t *)get_token_data(t)));
152 static int8_t input1 (func_cb_ptr p, token_type_t *t) {
153 element_state_t *s = (element_state_t *)sys_get_state();
154 DEBUG("COMBINE: Accept - token %d on input 1.\n", *((uint8_t *)get_token_data(t)));
155 return process_input(s, *((uint8_t *)get_token_data(t)));
158 static int8_t input2 (func_cb_ptr p, token_type_t *t) {
159 element_state_t *s = (element_state_t *)sys_get_state();
160 DEBUG("COMBINE: Accept - token %d on input 2.\n", *((uint8_t *)get_token_data(t)));
161 return process_input(s, *((uint8_t *)get_token_data(t)));
164 //--------------------------------------------------------
165 #ifndef _MODULE_
166 mod_header_ptr combine3_get_header()
168 return sos_get_header_address(mod_header);
170 #endif