Jackdaw additions
[contiki-2.x.git] / apps / shell / shell-sky.c
blob730f0b16cd41e4f6ec3b3222e6aed9b25aa1b773
1 /*
2 * Copyright (c) 2008, Swedish Institute of Computer Science.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * This file is part of the Contiki operating system.
31 * $Id: shell-sky.c,v 1.14 2010/01/14 15:05:40 joxe Exp $
34 /**
35 * \file
36 * Tmote Sky-specific Contiki shell commands
37 * \author
38 * Adam Dunkels <adam@sics.se>
41 #include "contiki.h"
42 #include "shell-sky.h"
44 #include "dev/watchdog.h"
46 #include "net/rime.h"
47 #include "dev/cc2420.h"
48 #include "dev/leds.h"
49 #include "dev/light-sensor.h"
50 #include "dev/battery-sensor.h"
51 #include "dev/sht11.h"
53 #include "net/rime/timesynch.h"
55 #include "node-id.h"
57 #include <stdio.h>
58 #include <string.h>
60 /*---------------------------------------------------------------------------*/
61 PROCESS(shell_nodeid_process, "nodeid");
62 SHELL_COMMAND(nodeid_command,
63 "nodeid",
64 "nodeid: set node ID",
65 &shell_nodeid_process);
66 PROCESS(shell_sense_process, "sense");
67 SHELL_COMMAND(sense_command,
68 "sense",
69 "sense: print out sensor data",
70 &shell_sense_process);
71 PROCESS(shell_senseconv_process, "senseconv");
72 SHELL_COMMAND(senseconv_command,
73 "senseconv",
74 "senseconv: convert 'sense' data to human readable format",
75 &shell_senseconv_process);
76 PROCESS(shell_txpower_process, "txpower");
77 SHELL_COMMAND(txpower_command,
78 "txpower",
79 "txpower <power>: change CC2420 transmission power (0 - 31)",
80 &shell_txpower_process);
81 PROCESS(shell_rfchannel_process, "rfchannel");
82 SHELL_COMMAND(rfchannel_command,
83 "rfchannel",
84 "rfchannel <channel>: change CC2420 radio channel (11 - 26)",
85 &shell_rfchannel_process);
86 /*---------------------------------------------------------------------------*/
87 #define MAX(a, b) ((a) > (b)? (a): (b))
88 #define MIN(a, b) ((a) < (b)? (a): (b))
89 struct spectrum {
90 int channel[16];
92 #define NUM_SAMPLES 4
93 static struct spectrum rssi_samples[NUM_SAMPLES];
94 static int
95 do_rssi(void)
97 static int sample;
98 int channel;
100 rime_mac->off(0);
102 cc2420_on();
103 for(channel = 11; channel <= 26; ++channel) {
104 cc2420_set_channel(channel);
105 rssi_samples[sample].channel[channel - 11] = cc2420_rssi() + 53;
108 rime_mac->on();
110 sample = (sample + 1) % NUM_SAMPLES;
113 int channel, tot;
114 tot = 0;
115 for(channel = 0; channel < 16; ++channel) {
116 int max = -256;
117 int i;
118 for(i = 0; i < NUM_SAMPLES; ++i) {
119 max = MAX(max, rssi_samples[i].channel[channel]);
121 tot += max / 20;
123 return tot;
126 /*---------------------------------------------------------------------------*/
127 struct sense_msg {
128 uint16_t len;
129 uint16_t clock;
130 uint16_t timesynch_time;
131 uint16_t light1;
132 uint16_t light2;
133 uint16_t temp;
134 uint16_t humidity;
135 uint16_t rssi;
136 uint16_t voltage;
138 /*---------------------------------------------------------------------------*/
139 PROCESS_THREAD(shell_sense_process, ev, data)
141 struct sense_msg msg;
142 PROCESS_BEGIN();
144 msg.len = 7;
145 msg.clock = clock_time();
146 msg.timesynch_time = timesynch_time();
147 msg.light1 = light_sensor.value(0);
148 msg.light2 = light_sensor.value(1);
149 msg.temp = sht11_temp();
150 msg.humidity = sht11_humidity();
151 msg.rssi = do_rssi();
152 msg.voltage = battery_sensor.value(0);
154 shell_output(&sense_command, &msg, sizeof(msg), "", 0);
155 PROCESS_END();
157 /*---------------------------------------------------------------------------*/
158 PROCESS_THREAD(shell_senseconv_process, ev, data)
160 struct shell_input *input;
161 struct sense_msg *msg;
162 PROCESS_BEGIN();
163 while(1) {
164 PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
165 input = data;
167 if(input->len1 + input->len2 == 0) {
168 PROCESS_EXIT();
170 msg = (struct sense_msg *)input->data1;
172 if(msg != NULL) {
173 char buf[40];
174 snprintf(buf, sizeof(buf),
175 "%d", 10 * msg->light1 / 7);
176 shell_output_str(&senseconv_command, "Light 1 ", buf);
177 snprintf(buf, sizeof(buf),
178 "%d", 46 * msg->light2 / 10);
179 shell_output_str(&senseconv_command, "Light 2 ", buf);
180 snprintf(buf, sizeof(buf),
181 "%d.%d", (msg->temp / 10 - 396) / 10,
182 (msg->temp / 10 - 396) % 10);
183 shell_output_str(&senseconv_command, "Temperature ", buf);
184 snprintf(buf, sizeof(buf),
185 "%d", (int)(-4L + 405L * msg->humidity / 10000L));
186 shell_output_str(&senseconv_command, "Relative humidity ", buf);
187 snprintf(buf, sizeof(buf),
188 "%d", msg->rssi);
189 shell_output_str(&senseconv_command, "RSSI ", buf);
190 snprintf(buf, sizeof(buf), /* 819 = 4096 / 5 */
191 "%d.%d", (msg->voltage / 819), (10 * msg->voltage / 819) % 10);
192 shell_output_str(&senseconv_command, "Voltage ", buf);
195 PROCESS_END();
197 /*---------------------------------------------------------------------------*/
198 PROCESS_THREAD(shell_txpower_process, ev, data)
200 struct {
201 uint16_t len;
202 uint16_t txpower;
203 } msg;
204 const char *newptr;
205 PROCESS_BEGIN();
207 msg.txpower = shell_strtolong(data, &newptr);
209 /* If no transmission power was given on the command line, we print
210 out the current txpower. */
212 if(newptr == data) {
213 msg.txpower = cc2420_get_txpower();
214 } else {
215 cc2420_set_txpower(msg.txpower);
218 msg.len = 1;
220 shell_output(&txpower_command, &msg, sizeof(msg), "", 0);
222 PROCESS_END();
224 /*---------------------------------------------------------------------------*/
225 PROCESS_THREAD(shell_rfchannel_process, ev, data)
227 struct {
228 uint16_t len;
229 uint16_t channel;
230 } msg;
231 const char *newptr;
232 PROCESS_BEGIN();
234 msg.channel = shell_strtolong(data, &newptr);
236 /* If no channel was given on the command line, we print out the
237 current channel. */
238 if(newptr == data) {
239 msg.channel = cc2420_get_channel();
240 } else {
241 cc2420_set_channel(msg.channel);
244 msg.len = 1;
246 shell_output(&txpower_command, &msg, sizeof(msg), "", 0);
248 PROCESS_END();
250 /*---------------------------------------------------------------------------*/
251 PROCESS_THREAD(shell_nodeid_process, ev, data)
253 uint16_t nodeid;
254 char buf[20];
255 const char *newptr;
256 PROCESS_BEGIN();
258 nodeid = shell_strtolong(data, &newptr);
260 /* If no node ID was given on the command line, we print out the
261 current channel. Else we burn the new node ID. */
262 if(newptr == data) {
263 nodeid = node_id;
264 } else {
265 nodeid = shell_strtolong(data, &newptr);
266 watchdog_stop();
267 leds_on(LEDS_RED);
268 node_id_burn(nodeid);
269 leds_on(LEDS_BLUE);
270 node_id_restore();
271 leds_off(LEDS_RED + LEDS_BLUE);
272 watchdog_start();
275 snprintf(buf, sizeof(buf), "%d", nodeid);
276 shell_output_str(&nodeid_command, "Node ID: ", buf);
278 PROCESS_END();
280 /*---------------------------------------------------------------------------*/
281 void
282 shell_sky_init(void)
284 shell_register_command(&txpower_command);
285 shell_register_command(&rfchannel_command);
286 shell_register_command(&sense_command);
287 shell_register_command(&senseconv_command);
288 shell_register_command(&nodeid_command);
291 /*---------------------------------------------------------------------------*/