Contiki 2.5
raven3290.c
Go to the documentation of this file.
1 /*
2  * \mainpage ATmega3290p LCD Driver Software for Contiki Raven
3 */
4 /**
5  * \image html raven3290p.jpg
6  * \ingroup platform
7  * \defgroup lcdraven RZRAVEN LCD 3290p
8  *
9  * \section intro_lcd LCD Introduction
10  *
11  * This Raven LCD Driver application software was designed for a user interface
12  * to the Contiki 6LoWPAN collaboration on board the ATmega3290p. The
13  * LCD functionality uses the binary command set described in the release notes.
14  * These binary commands can also be found in a list of main.h.
15  *
16  * \section compile_lcd Compiling Raven LCD Driver
17  *
18  * The Raven LCD Driver is located in /platforms/avr-ravenlcd but it is not a contiki platform.
19  * $make TARGET=avr-ravenlcd will not work! Build it using the AVR Studio project and WinAVR or
20  * in Linux/Windows cmd/Cygwin $make in that directory. The AVR Studio dependency folder will confuse
21  * additional makes, use $make CYG=1 to bypass /dep creation or do $rm -R dep as needed.
22  * The .h file dependencies will be lost, so also $make CYG=1 clean after modifying any of those.
23  *
24  *
25  * \section fuses_lcd Board fuse settings
26  *
27  * The Raven LCD (3290p device) requires the proper fuse settings to function properly.
28  * They are automatically set when flashing the .elf file. When using a .hex file set them manually:
29  * -# Raven LCD (3290p device)
30  * -# Extended: <b>0xFF</b> (No Brown Out)
31  * -# High: <b>0x99</b> (JTAG and ISP enabled, No OCDEN or EEPROM saving required)
32  * -# Low: <b>0xE2</b> (Use Int RC OSC - Start-up Time:6CK + 65ms)
33  *
34  * \section notes_lcd Operation Release Notes
35  *
36  * After programming the Raven LCD 3290p with the proper image, you will be introduced to
37  * the menu in the picture below:
38  *
39  * \image html contiki_menu_3290.jpg
40  *
41  * Operating the menu requires that the matching command set has been programmed into
42  * the ATmega1284 application. This will allow the menu to communicate properly and control the
43  * Contiki 6LoWPAN applcation on the 1284p.
44  *
45  * During normal operation, you will need to make note of these <b>IMPORTANT</b> operating instructions:
46  * -# <b>Temp Sensor</b> - The temperature sensor shares the same GPIO as the JTAG interface for the 3290p.
47  * This requires the JTAG feature to be <b>disabled</b> in order to have proper temperature readings.
48  * -# <b>Debug Menu</b> - The DEBUG menu setting is used to configure this JTAG feature.
49  * -# If the JTAG feature is enabled during a temperature reading attempt,
50  * the menu will signal a <b>caution</b> symbol to the user letting them know the JTAG
51  * feature needs to be disabled.
52  * \image html caution.gif
53  * -# The JTAG header may also need to be physically disconnected from any external
54  * programming/debugging device in order to obtain correct temperature readings.
55  * -# The software will disable JTAG in sleep/doze modes. If the JTAG connection fails during
56  * reprogramming with AVR Studio, "try again with external reset" to recover.
57  * -# <b>Temp Data</b> - Once the temperature reading is proper, the user can send this reading
58  * to the webserver for Sensor Reading Data (<b>Once</b> or <b>Auto</b>). The webserver will
59  * only update the html data when <b>refreshed</b>.
60  * -# <b>EXT_SUPL_SIG</b> - This signal connects the external supply voltage to ADC2 through a divider.
61  * Enabling MEASURE_ADC2 in temp.h causes it to be sampled and sent to the 1284p along
62  * with the temperature.
63  *
64  * More information about the operation of the Raven with Contiki can be found in the contikiwiki at http://www.sics.se/~adam/wiki/index.php/Avr_Raven.
65  * \sa http://www.sics.se/contiki/tutorials/tutorial-running-contiki-with-uipv6-and-sicslowpan-support-on-the-atmel-raven.html
66  *
67  * \section binary_lcd Binary Command Description
68  *
69  * Using the binary commmand list described in main.h, the 3290p will contruct a binary
70  * command serial frame to control the 1284p. An example command frame is contructed below:
71  * -# <b>0x01,0x01,0x81,0x01,0x04</b> - Send Ping Request number 1 to 1284p
72  * -# <b>0x01</b> - Start of binary command frame
73  * -# <b>0x01</b> - Length of binary command payload
74  * -# <b>0x81</b> - Binary command SEND_PING
75  * -# <b>0x01</b> - Payload value (eg. ping Request number 1)
76  * -# <b>0x04</b> - End of binary command frame
77  *
78  * The following commands are sent to the 1284p.
79  * -# <b>SEND_TEMP - (0x80)</b>
80  * -# <b>SEND_PING - (0x81)</b>
81  * -# <b>SEND_ADC2 - (0x82)</b>
82  * -# <b>SEND_SLEEP- (0x83)</b>
83  * -# <b>SEND_WAKE - (0x84)</b>
84  *
85  * The following commands are received from the 1284p.
86  * -# <b>REPORT_PING - (0xC0)</b>
87  * -# <b>REPORT_PING_BEEP - (0xC1)</b>
88  * -# <b>REPORT_TEXT_MSG - (0xC2)</b>
89  * -# <b>REPORT_WAKE - (0xC3)</b>
90  *
91  * \section sleep_lcd Sleep and Doze
92  * -# The Raven draws 27 milliamps when the 3290p and 1284p are both running and the RF230 in receive mode.
93  * -# Sleeping the 3290p and LCD display drops this to 21 ma with no loss in contiki functionality.
94  * -# The RF230 radio draws 15.5/16.5/7.8/1.5/0.02 ma in Rx/Tx/PLL_ON/TRX_OFF/SLEEP states.
95  * It is controlled by contiki on the 1284p according to the selected MAC power protocols to obtain the
96  * bulk of power savings; however the 3290p menu can tell it to sleep unconditionally or in a doze cycle.
97  * -# Unconditional SLEEP requires pushing the joystick button for wakeup. Once awake the 3290p sends
98  * SEND_WAKE commands to the 1284p until it responds with a REPORT_WAKE. "WAIT 1284p" is displayed during this time.
99  * Current draw is 40 microamps.
100  * -# As configured, doze sleeps the 3290p for 5 seconds after telling 1284p to sleep for 4 seconds. The 3290p
101  * wakes briefly to send temperature and voltage to the 1284p (which should be awake at this time), then tells it to
102  * sleep again. Thus the 1284p will be active 20% of the time, although it may ignore the command to sleep
103  * if there are active TCP connections. The 3290p energy usage is essentially zero in this mode; total savings will
104  * depend on actual 1284p wake time and radio usage. Alter the timings as desired, or comment out the 1284p sleep
105  * command to shut down only the 3290p in doze mode.
106 */
107 /*
108  * Copyright (c) 2008 Swedish Institute of Computer Science
109  * All rights reserved.
110  *
111  * Redistribution and use in source and binary forms, with or without
112  * modification, are permitted provided that the following conditions are met:
113  *
114  * * Redistributions of source code must retain the above copyright
115  * notice, this list of conditions and the following disclaimer.
116  * * Redistributions in binary form must reproduce the above copyright
117  * notice, this list of conditions and the following disclaimer in
118  * the documentation and/or other materials provided with the
119  * distribution.
120  * * Neither the name of the copyright holders nor the names of
121  * contributors may be used to endorse or promote products derived
122  * from this software without specific prior written permission.
123  *
124  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
125  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
126  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
127  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
128  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
129  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
130  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
131  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
132  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
133  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
134  * POSSIBILITY OF SUCH DAMAGE.
135  */
136 /**
137  * \file
138  *
139  * \brief
140  * This is the main file for the Raven LCD application.
141  *
142  * \author
143  * Mike Vidales mavida404@gmail.com
144  *
145  */
146 
147 #include "lcd.h"
148 #include "key.h"
149 #include "main.h"
150 #include "uart.h"
151 #include "timer.h"
152 #include "menu.h"
153 #include "temp.h"
154 
155 #include <avr/io.h>
156 #include <avr/fuse.h>
157 FUSES =
158  {
159  .low = 0xe2,
160  .high = 0x99,
161  .extended = 0xff,
162  };
163 
164 
165 /** \ingroup lcdraven
166  \defgroup lcd LCD Functions and data
167  * \{
168 */
169 
170 #if defined( DOXYGEN )
171 const char menu_text0[];
172 const char menu_text1[];
173 const char menu_text2[];
174 const char menu_text3[];
175 const char menu_text4[];
176 const char menu_text5[];
177 const char menu_text6[];
178 const char menu_text7[];
179 const char menu_text8[];
180 const char menu_text9[];
181 const char menu_text10[];
182 const char menu_text11[];
183 const char menu_text12[];
184 const char menu_text13[];
185 const char menu_text14[];
186 const char menu_text15[];
187 const char menu_text16[];
188 const char menu_text17[];
189 const tmenu_item menu_items[18];
190 #else /* !DOXYGEN */
191 /** \brief This is the menu text in Flash. See menu_items[] for menu operation. */
192 const char menu_text0[] PROGMEM = "CONTIKI";
193 const char menu_text1[] PROGMEM = "6LOWPAN";
194 const char menu_text2[] PROGMEM = "PING";
195 const char menu_text3[] PROGMEM = "PINGING";
196 const char menu_text4[] PROGMEM = "TEMP";
197 const char menu_text5[] PROGMEM = "MODE ";
198 const char menu_text6[] PROGMEM = "DEG F";
199 const char menu_text7[] PROGMEM = "DEG C";
200 const char menu_text8[] PROGMEM = "SEND";
201 const char menu_text9[] PROGMEM = "ONCE";
202 const char menu_text10[] PROGMEM = "AUTO";
203 const char menu_text11[] PROGMEM = "DEBUG";
204 const char menu_text12[] PROGMEM = "DBG ON";
205 const char menu_text13[] PROGMEM = "DBG OFF";
206 const char menu_text14[] PROGMEM = "SENT";
207 const char menu_text15[] PROGMEM = "SENDING";
208 const char menu_text16[] PROGMEM = "SLEEP";
209 const char menu_text17[] PROGMEM = "DOZE";
210 
211 /*---------------------------------------------------------------------------*/
212 
213 /**
214  * \brief Menus for user interface
215  *
216  * This constructs the Raven 3290p menu for the Contiki and 6lowpan collaboration. This
217  * follows the struct description of tmenu_item.
218  *
219  * { text, left, right, up, down, *state, tmenufunc enter_func}
220 */
221 const PROGMEM tmenu_item menu_items[18] = {
222  {menu_text0, 0, 2, 0, 0, 0, 0 },
223  {menu_text1, 0, 2, 0, 0, 0, 0 },
224  {menu_text2, 0, 3, 17, 4, 0, menu_ping_request },
225  {menu_text3, 2, 2, 2, 2, 0, 0 },
226  {menu_text4, 0, 5, 2, 11, 0, 0 },
227  {menu_text5, 4, 6, 8, 8, 0, 0 },
228  {menu_text6, 5, 5, 7, 7, (uint8_t*)1, menu_read_temp },
229  {menu_text7, 5, 5, 6, 6, (uint8_t*)0, menu_read_temp },
230  {menu_text8, 4, 9, 5, 5, 0, 0 },
231  {menu_text9, 8, 14, 10, 10, (uint8_t*)0, menu_prepare_temp },
232  {menu_text10, 8, 15, 9, 9, (uint8_t*)1, menu_prepare_temp },
233  {menu_text11, 0, 12, 4, 16, 0, 0 },
234  {menu_text12, 11, 11, 13, 13, (uint8_t*)1, menu_debug_mode },
235  {menu_text13, 11, 11, 12, 12, (uint8_t*)0, menu_debug_mode },
236  {menu_text14, 9, 14, 14, 14, 0, 0 },
237  {menu_text15, 10, 15, 15, 15, 0, 0 },
238  // {menu_text16, 0, 16, 11, 17, (uint8_t*)&menu_text16, menu_run_sleep },
239  // {menu_text17, 0, 17, 16, 2, (uint8_t*)&menu_text17, menu_run_doze },
240  {menu_text16, 0, 16, 11, 17, (uint8_t*)1, menu_run_sleep },//display "sleep" on wake
241  {menu_text17, 0, 17, 16, 2, (uint8_t*)1, menu_run_doze },//display "doze" on wake
242 };
243 #endif /* !DOXYGEN */
244 
245 key_state_t button=KEY_STATE_NO_KEY;
246 tmenu_item menu;
247 uint8_t count;
248 uint8_t timeout_count;
249 
250 /*---------------------------------------------------------------------------*/
251 
252 /**
253  * \brief This will read the menu_items[] from the index requested.
254  *
255  * \param ndx Position index of menu_items[] lookup.
256 */
257 void
258 read_menu(uint8_t ndx)
259 {
260  /* Reads menu structure from Flash area */
261  uint8_t i;
262  uint8_t *src = (uint8_t*)&menu_items[ndx];
263  uint8_t *dest = (uint8_t*)&menu;
264 
265  for (i=0;i<sizeof(tmenu_item);i++){
266  *dest++ = pgm_read_byte(src+i);
267  }
268 }
269 
270 /*---------------------------------------------------------------------------*/
271 char top_menu_text[20];
272 /**
273  * \brief This will toggle the CONTIKI and 6LOWPAN LCD menus in the main
274  * menu position, unless alternate text has been sent from the 1284p.
275  * The other menus will display normally.
276 */
277 void
279 {
280 uint8_t showtop=0;
281 
282  if(menu.text == menu_text0){
283  read_menu(1);
284  showtop=1;
285  }
286  else if(menu.text == menu_text1){
287  read_menu(0);
288  showtop=1;
289  }
290  if (showtop) {
291  if (top_menu_text[0]) {
292  lcd_puts(top_menu_text);
293  return;
294  }
295  }
296  lcd_puts_P(menu.text);
297 }
298 
299 /*---------------------------------------------------------------------------*/
300 
301 /**
302  * \brief This will check for the temp menu screen to determine if we need to
303  * clear the 4 digit LCD segments or stop an auto temp send. Also check for
304  * stopping a ping request.
305 */
306 void
308 {
309  if(menu.text == menu_text12){
310  menu_clear_temp();
311  }
312 
313  if(menu.text == menu_text10){
314  menu_stop_temp();
315  }
316 
317  if(menu.text == menu_text2){
318  menu_stop_ping();
319  lcd_num_clr();
320  }
321 }
322 
323 /*---------------------------------------------------------------------------*/
324 
325 /**
326  * \brief This is main...
327 */
328 int
329 main(void)
330 {
331  lcd_init();
332 
333  key_init();
334 
335  uart_init();
336 
337  eeprom_init();
338 
339  temp_init();
340 
341  timer_init();
342 
343  sei();
344 
345  lcd_symbol_set(LCD_SYMBOL_RAVEN);
346  lcd_symbol_set(LCD_SYMBOL_IP);
347 
348  /* Start with main menu */
349  read_menu(0);
350  /* and draw it */
351  lcd_puts_P(menu.text);
352 
353  timer_start();
354 
355  for (;;){
356  /* Make sure interrupts are always on */
357  sei();
358 
359  /* The one second timer has fired. */
360  if(timer_flag){
361  timer_flag = false;
362  /* Check if main menu needs toggled. */
363  check_main_menu();
364  /* Update LCD with temp data. */
365  if(temp_flag){
367  }
368  /* Auto send temp data to 1284p. */
369  if(auto_temp){
370  menu_send_temp();
371  }
372  /* If ping mode, send 4 ping requests and then stop. */
373  if(ping_mode){
374  if((PING_ATTEMPTS == count) && !timeout_flag){
375  count = 0;
376  timeout_count = 0;
377  menu_stop_ping();
378  }
379  else if(timeout_flag){
380  timeout_flag = false;
381  timeout_count++;
382  /* Display timeout message if all PING_ATTEMPTS were not successful. */
383  if(PING_ATTEMPTS == timeout_count){
384  lcd_puts_P(PSTR("PINGS FAILED"));
385  }
386  }
387  else{
388  count = menu_send_ping();
389  }
390  }
391  }
392 
393  /* Check for button press and deal with it */
394  if (is_button()){
395  /* Dispatch the button pressed */
396  switch (get_button()){
397  case KEY_UP:
398  read_menu(menu.up);
399  lcd_puts_P(menu.text);
400  break;
401  case KEY_DOWN:
402  read_menu(menu.down);
403  lcd_puts_P(menu.text);
404  break;
405  case KEY_LEFT:
406  read_menu(menu.left);
407  lcd_puts_P(menu.text);
408  break;
409  case KEY_RIGHT:
410  /*
411  * Check to see if we should show another menu or
412  * run a function
413  */
414  if (!menu.enter_func){
415  /* Just another menu to display */
416  read_menu(menu.right);
417  lcd_puts_P(menu.text);
418  break;
419  }
420  /* Drop through here */
421  case KEY_ENTER:
422  /* Call the menu function on right or enter buttons */
423  if (menu.enter_func){
424  menu.enter_func(menu.state);
425  if (menu.state){
426  /*
427  * We just called a selection menu (not a test),
428  * so re-display the text for this menu level
429  */
430  lcd_puts_P(menu.text);
431  }
432  /* After enter key, check the right button menu and display. */
433  read_menu(menu.right);
434  lcd_puts_P(menu.text);
435  }
436  break;
437  default:
438  break;
439  }
440  /* After button press, check for menus... */
441  check_menu();
442  }
443  /* Process any progress frames */
444  uart_serial_rcv_frame(false);
445  } /* end for(). */
446 } /* end main(). */
447 
448 /** \} */