Contiki 2.6
|
00001 /* Copyright (c) 2008, Swedish Institute of Computer Science 00002 * All rights reserved. 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in 00013 * the documentation and/or other materials provided with the 00014 * distribution. 00015 * * Neither the name of the copyright holders nor the names of 00016 * contributors may be used to endorse or promote products derived 00017 * from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 /** 00034 * \brief This module contains code to interface a Contiki-based 00035 * project on the AVR Raven platform's ATMega1284P chip to the LCD 00036 * driver chip (ATMega3290P) on the Raven. 00037 * 00038 * \author Durvy Mathilde <mdurvy@cisco.com> 00039 * 00040 */ 00041 00042 /** \addtogroup raven 00043 * @{ 00044 */ 00045 00046 /** 00047 * \defgroup ravenserial Serial interface between Raven processors 00048 * @{ 00049 */ 00050 00051 /** 00052 * \file 00053 * This file contains code to connect the two AVR Raven processors via 00054 * a serial connection for the IPSO interop application 00055 * 00056 */ 00057 00058 #include "contiki.h" 00059 #include "contiki-lib.h" 00060 #include "contiki-net.h" 00061 00062 #include "mac.h" 00063 00064 #include "raven-lcd.h" 00065 00066 #include <string.h> 00067 #include <stdio.h> 00068 00069 #define cmd_len 8 00070 #define data_len 20 00071 00072 static uint8_t seqno; 00073 uip_ipaddr_t ping_addr; 00074 uip_ipaddr_t udp_addr; 00075 static struct uip_udp_conn *udp_conn; 00076 char udp_data[data_len]; 00077 00078 static struct{ 00079 uint8_t frame[cmd_len]; 00080 uint8_t ndx; 00081 uint8_t len; 00082 uint8_t cmd; 00083 uint8_t done; 00084 } cmd; 00085 00086 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) 00087 #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) 00088 00089 void rs232_send(uint8_t port, unsigned char c); 00090 00091 /*------------------------------------------------------------------*/ 00092 /* Sends a ping packet out the radio */ 00093 void 00094 raven_ping6(void) 00095 { 00096 00097 /* ping ipv6.google.com*/ 00098 uip_ip6addr(&ping_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB); 00099 //uip_ip6addr(&ping_addr, 0x2001, 0x4860, 0, 0x2001, 0, 0, 0, 0x68); 00100 //uip_ip6addr(&ping_addr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); 00101 00102 UIP_IP_BUF->vtc = 0x60; 00103 UIP_IP_BUF->tcflow = 1; 00104 UIP_IP_BUF->flow = 0; 00105 UIP_IP_BUF->proto = UIP_PROTO_ICMP6; 00106 //UIP_IP_BUF->ttl = uip_netif_physical_if.cur_hop_limit; 00107 UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; 00108 uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &ping_addr); 00109 //uip_netif_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); 00110 uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); 00111 UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST; 00112 UIP_ICMP_BUF->icode = 0; 00113 /* set identifier and sequence number to 0 */ 00114 memset((void *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4); 00115 00116 uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN; 00117 UIP_IP_BUF->len[0] = (uint8_t)((uip_len - 40) >> 8); 00118 UIP_IP_BUF->len[1] = (uint8_t)((uip_len - 40) & 0x00FF); 00119 00120 UIP_ICMP_BUF->icmpchksum = 0; 00121 UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); 00122 00123 tcpip_ipv6_output(); 00124 } 00125 00126 /*------------------------------------------------------------------*/ 00127 /* Send a serial command frame to the ATMega3290 Processsor on Raven 00128 via serial port */ 00129 static void 00130 send_frame(uint8_t cmd, uint8_t len, uint8_t *payload) 00131 { 00132 uint8_t i; 00133 00134 rs232_send(0, SOF_CHAR); /* Start of Frame */ 00135 rs232_send(0, len); 00136 rs232_send(0, cmd); 00137 for (i=0;i<len;i++) 00138 rs232_send(0,*payload++); 00139 rs232_send(0, EOF_CHAR); 00140 } 00141 00142 /*------------------------------------------------------------------*/ 00143 static uint8_t 00144 raven_gui_loop(process_event_t ev, process_data_t data) 00145 { 00146 if(ev == tcpip_icmp6_event) { 00147 switch(*((uint8_t *)data)){ 00148 case ICMP6_ECHO_REQUEST: 00149 /* We have received a ping request over the air. Tell 3290 */ 00150 send_frame(REPORT_PING_BEEP, 0, 0); 00151 break; 00152 case ICMP6_ECHO_REPLY: 00153 /* We have received a ping reply over the air. Pass seqno to 3290 */ 00154 send_frame(REPORT_PING, 1, &seqno); 00155 break; 00156 } 00157 } else { 00158 switch(ev){ 00159 case SERIAL_CMD: 00160 /* Check for command from serial port, execute it. */ 00161 if (cmd.done){ 00162 /* Execute the waiting command */ 00163 switch (cmd.cmd){ 00164 case SEND_PING: 00165 /* Send ping request over the air */ 00166 seqno = cmd.frame[0]; 00167 raven_ping6(); 00168 break; 00169 case SEND_TEMP: 00170 /* Set temperature string in web server */ 00171 sprintf(udp_data, "T%s\r\n", (char *)cmd.frame); 00172 uip_udp_packet_send(udp_conn, udp_data, data_len); 00173 break; 00174 default: 00175 break; 00176 } 00177 /* Reset command done flag. */ 00178 cmd.done = 0; 00179 } 00180 break; 00181 default: 00182 break; 00183 } 00184 } 00185 return 0; 00186 } 00187 00188 /*--------------------------------------------------------------------*/ 00189 /* Process an input character from serial port. 00190 * ** This is called from an ISR!! 00191 */ 00192 int raven_lcd_serial_input(unsigned char ch) 00193 { 00194 /* Parse frame, */ 00195 switch (cmd.ndx){ 00196 case 0: 00197 /* first byte, must be 0x01 */ 00198 cmd.done = 0; 00199 if (ch != 0x01){ 00200 return 0; 00201 } 00202 break; 00203 case 1: 00204 /* Second byte, length of payload */ 00205 cmd.len = ch; 00206 break; 00207 case 2: 00208 /* Third byte, command byte */ 00209 cmd.cmd = ch; 00210 break; 00211 default: 00212 /* Payload and ETX */ 00213 if (cmd.ndx >= cmd.len+3){ 00214 /* all done, check ETX */ 00215 if (ch == 0x04){ 00216 cmd.done = 1; 00217 process_post(&raven_lcd_process, SERIAL_CMD, 0); 00218 } else { 00219 /* Failed ETX */ 00220 cmd.ndx = 0; 00221 } 00222 } else { 00223 /* Just grab and store payload */ 00224 cmd.frame[cmd.ndx - 3] = ch; 00225 } 00226 break; 00227 } 00228 00229 cmd.ndx++; 00230 00231 return 0; 00232 } 00233 00234 /*---------------------------------------------------------------------------*/ 00235 PROCESS(raven_lcd_process, "Raven LCD interface process"); 00236 PROCESS_THREAD(raven_lcd_process, ev, data) 00237 { 00238 uint8_t error; 00239 00240 PROCESS_BEGIN(); 00241 00242 /*Create a udp connection to the IPSOserver*/ 00243 00244 //swisscom uip_ip6addr(&udp_addr,0x2001,918,0xfff9,0,0,0,0,1); 00245 //HE uip_ip6addr(&udp_addr,0x2001,0x470,0x1f12,0x5ec,0x12,0x13ff,0xfe14,0x1516); 00246 uip_ip6addr(&udp_addr,0x2001,0x420,0x5FFF,0x7D,0x2D0,0xB7FF,0xFE23,0xE6DB); 00247 00248 /* set destination parameters*/ 00249 udp_conn = udp_new(&udp_addr, UIP_HTONS(0xF0B0), NULL); 00250 /*set local port */ 00251 udp_bind(udp_conn, UIP_HTONS(0xF0B0+1)); 00252 00253 if((error = icmp6_new(NULL)) == 0) { 00254 while(1) { 00255 PROCESS_YIELD(); 00256 raven_gui_loop(ev, data); 00257 } 00258 } 00259 PROCESS_END(); 00260 } 00261 /** @} */ 00262 /** @} */