commit f4a271b8bdedcede8510e4f25623447f51bcaca5 Author: Robert Date: Mon Dec 24 21:30:51 2012 +0100 new file: platform/avr-pluto/Makefile.avr-pluto new file: platform/avr-pluto/apps/rime-bc/Makefile new file: platform/avr-pluto/apps/rime-bc/README.bc new file: platform/avr-pluto/apps/rime-bc/bc.c new file: platform/avr-pluto/apps/rime-bc/pluto_v1.4.h new file: platform/avr-pluto/button-sensor.c new file: platform/avr-pluto/contiki-conf.h new file: platform/avr-pluto/contiki-main.c new file: platform/avr-pluto/params.c new file: platform/avr-pluto/params.h new file: platform/avr-pluto/raven-lcd.h new file: platform/avr-pluto/slip_uart0.c diff --git a/platform/avr-pluto/Makefile.avr-pluto b/platform/avr-pluto/Makefile.avr-pluto new file mode 100644 index 0000000..46b03bf --- /dev/null +++ b/platform/avr-pluto/Makefile.avr-pluto @@ -0,0 +1,32 @@ +CONTIKI_TARGET_DIRS = . apps net loader + +CONTIKI_CORE=contiki-main +CONTIKI_TARGET_MAIN = ${CONTIKI_CORE}.o +CONTIKI_TARGET_SOURCEFILES += contiki-main.c params.c +#Needed for slip +CONTIKI_TARGET_SOURCEFILES += button-sensor.c sensors.c slip_uart0.c slip.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr +CONTIKIBOARD=. + +CONTIKI_PLAT_DEFS = -DF_CPU=8000000UL -DAUTO_CRC_PADDING=2 + +MCU=atmega128rfa1 + +AVRDUDE_PROGRAMMER=jtag2 + +# For usb devices, you may either use PORT=usb, or (e.g. if you have more than one +# programmer connected) you can use the following trick to find out the serial number: +# +# The example is for an JTAGICE mkII used to program an ATmega128: +# avrdude -v -P usb:xxxx -c jtag2 -p atmega128 +AVRDUDE_PORT=usb:00B000000D79 + + +# Additional avrdude options +# Verify off +AVRDUDE_OPTIONS=-V + + +include $(CONTIKIAVR)/Makefile.avr +include $(CONTIKIAVR)/radio/Makefile.radio diff --git a/platform/avr-pluto/apps/rime-bc/Makefile b/platform/avr-pluto/apps/rime-bc/Makefile new file mode 100644 index 0000000..cc03b00 --- /dev/null +++ b/platform/avr-pluto/apps/rime-bc/Makefile @@ -0,0 +1,16 @@ +CONTIKI = ../../../.. +OBJCOPY = avr-objcopy + +## +PRINTF_LIB_FLT = -Wl,-u,vfprintf -lprintf_flt -lm +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min +PRINTF_LIB = $(PRINTF_LIB_FLT) +CLIBS = $(PRINTF_LIB) + +include $(CONTIKI)/Makefile.include + +all: hex bc + +hex : + $(OBJCOPY) bc.avr-pluto -j .text -j .data -O ihex bc.hex + diff --git a/platform/avr-pluto/apps/rime-bc/README.bc b/platform/avr-pluto/apps/rime-bc/README.bc new file mode 100644 index 0000000..dd466c5 --- /dev/null +++ b/platform/avr-pluto/apps/rime-bc/README.bc @@ -0,0 +1,20 @@ + +Pluto example application. +------------------------- + +* Yellow LED flashes when Rime broadcast with MCU voltage and MCU temperature + is transmitted + +* Read LED flashes when Rime broadcast is received + +* Data is alo printed via UART. 38400 bps, 2 stopbits, No flowcontrol. + +Consult the code. + +Make: +make bc hex TARGET=avr-pluto + +Program with serial bootloader. (TTL-USB cable) + +avrdude -p m128rfa1 -c avr109 -P /dev/ttyUSB0 -b 38400 -e -U flash:w:bc.hex + diff --git a/platform/avr-pluto/apps/rime-bc/bc.c b/platform/avr-pluto/apps/rime-bc/bc.c new file mode 100644 index 0000000..07398ca --- /dev/null +++ b/platform/avr-pluto/apps/rime-bc/bc.c @@ -0,0 +1,271 @@ +/* + Contiki Rime BRD demo. + Broadcast Temp, Bat Voltage, RSSI, LQI DEMO. Robert Olsson GPL + + Almost all code comes from: + + * Copyright (c) 2007, Swedish Institute of Computer Science. + * All rights reserved. + * + + See Contiki for full copyright. + +*/ + +#include +#include "contiki.h" +#include "lib/list.h" +#include "lib/memb.h" +#include "lib/random.h" +#include "net/rime.h" +#include +#include "pluto_v1.4.h" + +#define MAX_NEIGHBORS 64 +#define SIZE 40 + +unsigned char charbuf[SIZE]; + +uint16_t h,m; +double v_avr; +double temp; + +struct broadcast_message { + uint8_t seqno; + uint8_t buf[40]; +}; + +struct neighbor { + struct neighbor *next; + rimeaddr_t addr; + + /* The ->last_rssi and ->last_lqi fields hold the Received Signal + Strength Indicator (RSSI) and CC2420 Link Quality Indicator (LQI) + values that are received for the incoming broadcast packets. */ + uint16_t last_rssi, last_lqi; + uint8_t last_seqno; + + /* The ->avg_gap contains the average seqno gap that we have seen + from this neighbor. */ + uint32_t avg_seqno_gap; +}; + +MEMB(neighbors_memb, struct neighbor, MAX_NEIGHBORS); +LIST(neighbors_list); + +static struct broadcast_conn broadcast; + +#define SEQNO_EWMA_UNITY 0x100 /* Moving average */ +#define SEQNO_EWMA_ALPHA 0x040 + +PROCESS(init_process, "Init process"); +PROCESS(broadcast_process, "Broadcast process"); + +AUTOSTART_PROCESSES(&init_process, &broadcast_process); + + +int radio_sleep = 0; + +#define RTC_SCALE 16 + +static void rtcc_init(void) +{ + TIMSK2 &=~((1< 1s */ + TCCR2B = 0x02; /* prescale the timer to / 8 16 Hz*/ + while(ASSR&0x07); + TIMSK2 |= (1<>2); //Convert to celcius*10 (should be 11.3*h, approximate with 11.25*h) + ADCSRA = 0; //disable ADC + ADMUX = 0; //turn off internal vref + m = h/10; s=h-10*m; + + for ( p1=16; p1<31; p1++) { + BATMON = p1; + /* delay_us(100); */ + if ((BATMON & (1<addr, from)) + break; + } + + if(n == NULL) { + n = memb_alloc(&neighbors_memb); /* New neighbor */ + + if(! n ) + goto out; + + rimeaddr_copy(&n->addr, from); + n->last_seqno = msg->seqno - 1; + n->avg_seqno_gap = SEQNO_EWMA_UNITY; + list_add(neighbors_list, n); + } + + n->last_rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI); + n->last_lqi = packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY); + + /* Compute the average sequence number gap from this neighbor. */ + seqno_gap = msg->seqno - n->last_seqno; + + + n->avg_seqno_gap = (((uint32_t)seqno_gap * SEQNO_EWMA_UNITY) * + SEQNO_EWMA_ALPHA) / SEQNO_EWMA_UNITY + + ((uint32_t)n->avg_seqno_gap * (SEQNO_EWMA_UNITY - + SEQNO_EWMA_ALPHA)) / SEQNO_EWMA_UNITY; + + n->last_seqno = msg->seqno; + + printf("&: %s [ADDR=%-d.%-d SEQ=%-d RSSI=%-u LQI=%-u DRP=%-d.%02d]\n", + msg->buf, + from->u8[0], from->u8[1], msg->seqno, + n->last_rssi, + n->last_lqi, + (int)(n->avg_seqno_gap / SEQNO_EWMA_UNITY), + (int)(((100UL * n->avg_seqno_gap) / SEQNO_EWMA_UNITY) % 100)); + +out: + PORTE |= LED_RED; /* OFF */ +} + + +static const struct broadcast_callbacks broadcast_call = {broadcast_recv}; + +/* + Channel 11 - 26 + + MAX TX_PWR_3DBM ( 0 ) + MIN TX_PWR_17_2DBM ( 15 ) + + Channels (11, 15, 20, 25 are WiFi-free). + RSSI is high while LQI is low -> Strong interference, + Both are low -> Try different locations. +*/ + +PROCESS_THREAD(broadcast_process, ev, data) +{ + static struct etimer et; + static uint8_t seqno; + struct broadcast_message msg; + uint8_t ch, txpwr; + + PROCESS_EXITHANDLER(broadcast_close(&broadcast);) + PROCESS_BEGIN(); + broadcast_open(&broadcast, 129, &broadcast_call); + + //rf230_set_txpower(15); + txpwr = rf230_get_txpower(); + ch = rf230_get_channel(); + // rf230_set_channel(ch); + printf("Ch=%-d TxPwr=%-d\n", ch, txpwr); + + while(1) { + int len; + + //etimer_set(&et, CLOCK_SECOND * 2); + //PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PROCESS_YIELD_UNTIL(ev == 0x12); + + PORTE &= ~LED_YELLOW; /* On */ + + read_sensors(); + + len = snprintf((char *) msg.buf, sizeof(msg.buf), + "T_MCU=%-5.1f V_MCU=%-4.2f ", temp, v_avr); + msg.seqno = seqno; + packetbuf_copyfrom(&msg, sizeof(struct broadcast_message)); + + rf230_on(); + + broadcast_send(&broadcast); + + seqno++; + + printf("&: %s\n", msg.buf); + + PORTE |= LED_YELLOW; + } + PROCESS_END(); +} + +PROCESS_THREAD(init_process, ev, data) +{ + PROCESS_BEGIN(); + + printf("Init\n"); + + DDRE |= LED_YELLOW; + DDRE |= LED_RED; + + PORTE |= LED_RED; + PORTE |= LED_YELLOW; + + DDRD |= (1<<4); + + rtcc_init(); + + PROCESS_END(); +} + +static struct pt send_thread; + +PT_THREAD(send_message(char *txt, rimeaddr_t b, int *retval)) +{ + PT_BEGIN(&send_thread); + + printf("%s \n", txt); + + *retval = 0; + PT_END(&send_thread); +} diff --git a/platform/avr-pluto/apps/rime-bc/pluto_v1.4.h b/platform/avr-pluto/apps/rime-bc/pluto_v1.4.h new file mode 100644 index 0000000..108e608 --- /dev/null +++ b/platform/avr-pluto/apps/rime-bc/pluto_v1.4.h @@ -0,0 +1,33 @@ + +/* + Pin assigments for sensors board revision 1.4 + using MCU AtMega128rfa1 +*/ + +#define LED_YELLOW (1< + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +/* MCU and clock rate */ +#define PLATFORM PLATFORM_AVR +#define HARWARE_REVISION ATMEGA128RFA1 +#ifndef F_CPU +#define F_CPU 8000000UL +#endif +#include + +typedef int32_t s32_t; +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned long u32_t; +typedef unsigned short clock_time_t; +typedef unsigned short uip_stats_t; +typedef unsigned long off_t; + +void clock_delay(unsigned int us2); +void clock_wait(int ms10); +void clock_set_seconds(unsigned long s); +unsigned long clock_seconds(void); + +/* Maximum timer interval for 16 bit clock_time_t */ +#define INFINITE_TIME 0xffff + +/* Clock ticks per second */ +#define CLOCK_CONF_SECOND 128 + +/* Maximum tick interval is 0xffff/128 = 511 seconds */ +#define RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ +#define COLLECT_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME INFINITE_TIME/CLOCK_CONF_SECOND /* Default uses 600 */ + +/* Michael Hartman's atmega128rfa1 board has an external 32768Hz crystal connected to TOSC1 and 2 pins similar to the Raven 1284p */ +/* and theoretically can use TIMER2 with it to keep time. Else TIMER0 is used. */ +/* The sleep timer in raven-lcd.c also uses the crystal and adds a TIMER2 interrupt routine if not already define by clock.c */ +/* This has not been tested yet */ +#define AVR_CONF_USE32KCRYSTAL 0 + +/* Michael Hartman's protobyte board has LED on PORTE1, can be used for pings and radio on indication */ +/* However it requires disabling UART0. */ +#undef RF230BB_CONF_LEDONPORTE1 //1 + +/* COM port to be used for SLIP connection. This is usually UART0, but see above */ +#if RF230BB_CONF_LEDONPORTE1 +#define SLIP_PORT RS232_PORT_1 +#else +#define SLIP_PORT RS232_PORT_0 +#endif + +/* Pre-allocated memory for loadable modules heap space (in bytes)*/ +/* Default is 4096. Currently used only when elfloader is present. Not tested on Raven */ +//#define MMEM_CONF_SIZE 256 + +/* Starting address for code received via the codeprop facility. Not tested on Raven */ +//#define EEPROMFS_ADDR_CODEPROP 0x8000 + +/* RADIOSTATS is used in rf230bb, clock.c and the webserver cgi to report radio usage */ +#define RADIOSTATS 1 + +/* More extensive stats */ +#define ENERGEST_CONF_ON 1 + +/* Possible watchdog timeouts depend on mcu. Default is WDTO_2S. -1 Disables the watchdog. */ +//#define WATCHDOG_CONF_TIMEOUT -1 + +/* Debugflow macro, useful for tracing path through mac and radio interrupts */ +//#define DEBUGFLOWSIZE 128 + +/* Network setup. The new NETSTACK interface requires RF230BB (as does ip4) */ +#if RF230BB +#undef PACKETBUF_CONF_HDR_SIZE //Use the packetbuf default for header size +#else +#define PACKETBUF_CONF_HDR_SIZE 0 //RF230 combined driver/mac handles headers internally +#endif /*RF230BB */ + +#if UIP_CONF_IPV6 +#define RIMEADDR_CONF_SIZE 8 +#define UIP_CONF_ICMP6 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_TCP 1 +//#define UIP_CONF_IPV6_RPL 0 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#else +/* ip4 should build but is largely untested */ +#define RIMEADDR_CONF_SIZE 2 +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* UIP_CONF_IPV6 */ + +/* See uip-ds6.h */ +#define UIP_CONF_DS6_NBR_NBU 20 +#define UIP_CONF_DS6_DEFRT_NBU 2 +#define UIP_CONF_DS6_PREFIX_NBU 3 +#define UIP_CONF_DS6_ROUTE_NBU 20 +#define UIP_CONF_DS6_ADDR_NBU 3 +#define UIP_CONF_DS6_MADDR_NBU 0 +#define UIP_CONF_DS6_AADDR_NBU 0 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +/* 10 bytes per stateful address context - see sicslowpan.c */ +/* Default is 1 context with prefix aaaa::/64 */ +/* These must agree with all the other nodes or there will be a failure to communicate! */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 {addr_contexts[0].prefix[0]=0xaa;addr_contexts[0].prefix[1]=0xaa;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_1 {addr_contexts[1].prefix[0]=0xbb;addr_contexts[1].prefix[1]=0xbb;} +#define SICSLOWPAN_CONF_ADDR_CONTEXT_2 {addr_contexts[2].prefix[0]=0x20;addr_contexts[2].prefix[1]=0x01;addr_contexts[2].prefix[2]=0x49;addr_contexts[2].prefix[3]=0x78,addr_contexts[2].prefix[4]=0x1d;addr_contexts[2].prefix[5]=0xb1;} + +/* 211 bytes per queue buffer */ +#define QUEUEBUF_CONF_NUM 8 + +/* 54 bytes per queue ref buffer */ +#define QUEUEBUF_CONF_REF_NUM 2 + +/* Take the default TCP maximum segment size for efficiency and simpler wireshark captures */ +/* Use this to prevent 6LowPAN fragmentation (whether or not fragmentation is enabled) */ +//#define UIP_CONF_TCP_MSS 48 + +/* 30 bytes per TCP connection */ +/* 6LoWPAN does not do well with concurrent TCP streams, as new browser GETs collide with packets coming */ +/* from previous GETs, causing decreased throughput, retransmissions, and timeouts. Increase to study this. */ +/* ACKs to other ports become interleaved with computation-intensive GETs, so ACKs are particularly missed. */ +/* Increasing the number of packet receive buffers in RAM helps to keep ACKs from being lost */ + +#define UIP_CONF_MAX_CONNECTIONS 4 + +/* 2 bytes per TCP listening port */ +#define UIP_CONF_MAX_LISTENPORTS 4 + +/* 25 bytes per UDP connection */ +#define UIP_CONF_UDP_CONNS 10 + +#define UIP_CONF_IP_FORWARD 0 +#define UIP_CONF_FWCACHE_SIZE 0 + +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_QUEUE_PKT 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 + +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_DHCP_LIGHT 1 + + +#if 1 /* No radio cycling */ + +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC sicslowmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO rf230_driver +#define CHANNEL_802_15_4 26 +/* AUTOACK receive mode gives better rssi measurements, even if ACK is never requested */ +#define RF230_CONF_AUTOACK 1 +/* Request 802.15.4 ACK on all packets sent (else autoretry). This is primarily for testing. */ +#define SICSLOWPAN_CONF_ACK_ALL 0 +/* Number of auto retry attempts 0-15 (0 implies don't use extended TX_ARET_ON mode with CCA) */ +#define RF230_CONF_AUTORETRIES 2 +/* Default is one RAM buffer for received packets. More than one may benefit multiple TCP connections or ports */ +#define RF230_CONF_RX_BUFFERS 3 +#define SICSLOWPAN_CONF_FRAG 1 +/* Most browsers reissue GETs after 3 seconds which stops fragment reassembly so a longer MAXAGE does no good */ +#define SICSLOWPAN_CONF_MAXAGE 3 +/* How long to wait before terminating an idle TCP connection. Smaller to allow faster sleep. Default is 120 seconds */ +/* If wait is too short the connection can be reset as a result of multiple fragment reassembly timeouts */ +#define UIP_CONF_WAIT_TIMEOUT 20 + +#elif 1 /* Contiki-mac radio cycling */ +#define NETSTACK_CONF_MAC nullmac_driver +//#define NETSTACK_CONF_MAC csma_driver +#define NETSTACK_CONF_RDC contikimac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO rf230_driver +#define CHANNEL_802_15_4 26 +/* The radio needs to interrupt during an rtimer interrupt */ +#define RTIMER_CONF_NESTED_INTERRUPTS 1 +#define RF230_CONF_AUTOACK 1 +#define RF230_CONF_AUTORETRIES 1 +#define RF230_CONF_CSMARETRIES 1 +#define CONTIKIMAC_CONF_RADIO_ALWAYS_ON 0 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 + +#elif 1 /* cx-mac radio cycling */ +/* RF230 does clear-channel assessment in extended mode (autoretries>0) */ +#define RF230_CONF_AUTORETRIES 1 +#if RF230_CONF_AUTORETRIES +#define NETSTACK_CONF_MAC nullmac_driver +#else +#define NETSTACK_CONF_MAC csma_driver +#endif +#define NETSTACK_CONF_RDC cxmac_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_RADIO rf230_driver +#define CHANNEL_802_15_4 26 +#define RF230_CONF_AUTOACK 1 +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 3 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 + +//Below gives 10% duty cycle, undef for default 5% +//#define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 80) +//Below gives 50% duty cycle +//#define CXMAC_CONF_ON_TIME (RTIMER_ARCH_SECOND / 16) + +#else +#error Network configuration not specified! +#endif /* Network setup */ + +/* Logging adds 200 bytes to program size */ +#define LOG_CONF_ENABLED 1 + +/* ************************************************************************** */ +//#pragma mark RPL Settings +/* ************************************************************************** */ +#if UIP_CONF_IPV6_RPL + +/* Define MAX_*X_POWER to reduce tx power and ignore weak rx packets for testing a miniature multihop network. + * Leave undefined for full power and sensitivity. + * tx=0 (3dbm, default) to 15 (-17.2dbm) + * RF230_CONF_AUTOACK sets the extended mode using the energy-detect register with rx=0 (-91dBm) to 84 (-7dBm) + * else the rssi register is used having range 0 (91dBm) to 28 (-10dBm) + * For simplicity RF230_MIN_RX_POWER is based on the energy-detect value and divided by 3 when autoack is not set. + * On the RF230 a reduced rx power threshold will not prevent autoack if enabled and requested. + * These numbers applied to both Raven and Jackdaw give a maximum communication distance of about 15 cm + * and a 10 meter range to a full-sensitivity RF230 sniffer. +#define RF230_MAX_TX_POWER 15 +#define RF230_MIN_RX_POWER 30 + */ + +#define UIP_CONF_ROUTER 1 +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#undef UIP_CONF_UDP_CONNS +#define UIP_CONF_UDP_CONNS 12 +/* For slow slip connections, to prevent buffer overruns */ +//#define UIP_CONF_RECEIVE_WINDOW 300 +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#endif /* RPL */ + +#define CCIF +#define CLIF + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/avr-pluto/contiki-main.c b/platform/avr-pluto/contiki-main.c new file mode 100644 index 0000000..0cb2c79 --- /dev/null +++ b/platform/avr-pluto/contiki-main.c @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2006, Technical University of Munich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) + +#define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size +#if ANNOUNCE_BOOT +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTA(...) +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +#else +#define PRINTD(...) +#endif + +/* Track interrupt flow through mac, rdc and radio driver */ +#if DEBUGFLOWSIZE +uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; +#define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c +#else +#define DEBUGFLOW(c) +#endif + +#include +#include +#include +#include +#include +#include + +#include "loader/symbols-def.h" +#include "loader/symtab.h" + +#include "params.h" +#include "radio/rf230bb/rf230bb.h" +#include "net/mac/frame802154.h" +#include "net/mac/framer-802154.h" +#include "net/sicslowpan.h" + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "dev/rs232.h" +#include "dev/serial-line.h" +#include "dev/slip.h" + +#ifdef RAVEN_LCD_INTERFACE +#include "raven-lcd.h" +#endif + +#if AVR_WEBSERVER +#include "httpd-fs.h" +#include "httpd-cgi.h" +#endif + +#ifdef COFFEE_FILES +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#endif + +#if UIP_CONF_ROUTER&&0 +#include "net/routing/rimeroute.h" +#include "net/rime/rime-udp.h" +#endif + +#include "net/rime.h" + +/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ +/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ +/* STAMPS will print ENERGEST outputs if that is enabled. */ +#define PERIODICPRINTS 1 +#if PERIODICPRINTS +//#define PINGS 64 +#define ROUTES 600 +#define STAMPS 60 +#define STACKMONITOR 1024 +uint32_t clocktime; +#define TESTRTIMER 0 +#if TESTRTIMER +uint8_t rtimerflag=1; +struct rtimer rt; +void rtimercycle(void) {rtimerflag=1;} +#endif +#endif + +uint16_t ledtimer; + +/*-------------------------------------------------------------------------*/ +/*----------------------Configuration of the .elf file---------------------*/ +#if 1 +/* The proper way to set the signature is */ +#include +#else +/* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ +typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; +#define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) +SIGNATURE = { + .B2 = 0x01,//SIGNATURE_2, //ATMEGA128rfa1 + .B1 = 0xA7,//SIGNATURE_1, //128KB flash + .B0 = 0x1E,//SIGNATURE_0, //Atmel +}; +#endif + +#if 1 +/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */ +FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,}; +#else +/* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ +FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,}; +#endif + +uint8_t +rng_get_uint8(void) { +#if 1 + /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ + uint8_t j; + j = (PHY_RSSI>>6) | (PHY_RSSI>>4) | (PHY_RSSI>>4) | PHY_RSSI; +#else +/* Get a pseudo random number using the ADC */ + uint8_t i,j; + ADCSRA=1< +//#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) +// delay_us(50000); + } + clock_init(); +} +#endif + + PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); + +/* rtimers needed for radio cycling */ + rtimer_init(); + + /* Initialize process subsystem */ + process_init(); + + /* etimers must be started before ctimer_init */ + process_start(&etimer_process, NULL); + ctimer_init(); + + /* Start radio and radio receive process */ + NETSTACK_RADIO.init(); + +/* Get a random seed for the 802.15.4 packet sequence number. + * Some layers will ignore duplicates found in a history (e.g. Contikimac) + * causing the initial packets to be ignored after a short-cycle restart. + */ + random_init(rng_get_uint8()); + + /* Set addresses BEFORE starting tcpip process */ + + rimeaddr_t addr; + + if (params_get_eui64(addr.u8)) { + PRINTA("Random EUI64 address generated\n"); + } + +#if UIP_CONF_IPV6 + memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t)); +#elif WITH_NODE_ID + node_id=get_panaddr_from_eeprom(); + addr.u8[1]=node_id&0xff; + addr.u8[0]=(node_id&0xff00)>>8; + PRINTA("Node ID from eeprom: %X\n",node_id); +#endif + rimeaddr_set_node_addr(&addr); + + rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8); + rf230_set_channel(params_get_channel()); + rf230_set_txpower(params_get_txpower()); + +#if UIP_CONF_IPV6 + PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); +#else + PRINTA("MAC address "); + uint8_t i; + for (i=sizeof(rimeaddr_t); i>0; i--){ + PRINTA("%x:",addr.u8[i-1]); + } + PRINTA("\n"); +#endif + + /* Initialize stack protocols */ + queuebuf_init(); + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + +#if ANNOUNCE_BOOT + PRINTA("%s %s, channel %u power %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel(),rf230_get_txpower()); + if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac + unsigned short tmp; + tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ + NETSTACK_RDC.channel_check_interval()); + if (tmp<65535) PRINTA(", check rate %u Hz",tmp); + } + PRINTA("\n"); + +#if UIP_CONF_IPV6_RPL + PRINTA("RPL Enabled\n"); +#endif +#if UIP_CONF_ROUTER + PRINTA("Routing Enabled\n"); +#endif + +#endif /* ANNOUNCE_BOOT */ + + process_start(&tcpip_process, NULL); + +#ifdef RAVEN_LCD_INTERFACE + process_start(&raven_lcd_process, NULL); +#endif + + /* Autostart other processes */ + autostart_start(autostart_processes); + + /*---If using coffee file system create initial web content if necessary---*/ +#if COFFEE_FILES + int fa = cfs_open( "/index.html", CFS_READ); + if (fa<0) { //Make some default web content + PRINTA("No index.html file found, creating upload.html!\n"); + PRINTA("Formatting FLASH file system for coffee..."); + cfs_coffee_format(); + PRINTA("Done!\n"); + fa = cfs_open( "/index.html", CFS_WRITE); + int r = cfs_write(fa, &"It works!", 9); + if (r<0) PRINTA("Can''t create /index.html!\n"); + cfs_close(fa); +// fa = cfs_open("upload.html"), CFW_WRITE); +//
+ } +#endif /* COFFEE_FILES */ + +/* Add addresses for testing */ +#if 0 +{ + uip_ip6addr_t ipaddr; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +// uip_ds6_prefix_add(&ipaddr,64,0); +} +#endif + +/*--------------------------Announce the configuration---------------------*/ +#if ANNOUNCE_BOOT +#if AVR_WEBSERVER +{ uint8_t i; + char buf[80]; + unsigned int size; + + for (i=0;i>10); +#elif COFFEE_FILES==3 + PRINTA(".%s online with static %u byte program memory file system\n",buf,size); +#elif COFFEE_FILES==4 + PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); +#endif /* COFFEE_FILES */ +} +#else + PRINTA("Online\n"); +#endif +#endif /* ANNOUNCE_BOOT */ + +#if RF230BB_CONF_LEDONPORTE1 + /* NB: PORTE1 conflicts with UART0 */ + DDRE|=(1<u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0) PRINTF("::"); + } else { + if(f > 0) { + f = -1; + } else if(i > 0) { + PRINTF(":"); + } + PRINTF("%x",a); + } + } +} +#endif + +/*-------------------------------------------------------------------------*/ +/*------------------------- Main Scheduler loop----------------------------*/ +/*-------------------------------------------------------------------------*/ +int +main(void) +{ + + CLKPR=(1<"); + PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); + for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { + if(uip_ds6_routing_table[i].isused) { + ipaddr_add(&uip_ds6_routing_table[i].ipaddr); + PRINTF("/%u (via ", uip_ds6_routing_table[i].length); + ipaddr_add(&uip_ds6_routing_table[i].nexthop); + // if(uip_ds6_routing_table[i].state.lifetime < 600) { + PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); + // } else { + // PRINTF(")\n"); + // } + j=0; + } + } + if (j) PRINTF(" "); + PRINTF("\n---------\n"); +} +#endif + +#ifndef SM_PROJECT +#if STACKMONITOR +if ((clocktime%STACKMONITOR)==3) { + extern uint16_t __bss_end; + uint16_t p=(uint16_t)&__bss_end; + do { + if (*(uint16_t *)p != 0x4242) { + PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); + break; + } + p+=10; + } while (p +#include +#include +#include + +#if AVR_WEBSERVER +//#include "httpd-fs.h" +//#include "httpd-cgi.h" +#endif + +#include "contiki-net.h" +#include "params.h" + +#if WITH_NODE_ID +uint16_t node_id; +#endif + +#if CONTIKI_CONF_RANDOM_MAC +extern uint8_t rng_get_uint8(void); +static void +generate_new_eui64(uint8_t eui64[8]) { + eui64[0] = 0x02; + eui64[1] = rng_get_uint8(); + eui64[2] = rng_get_uint8(); + eui64[3] = 0xFF; + eui64[4] = 0xFE; + eui64[5] = rng_get_uint8(); + eui64[6] = rng_get_uint8(); + eui64[7] = rng_get_uint8(); +} +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ +extern uint8_t default_mac_address[8]; +extern uint8_t default_server_name[16]; +extern uint8_t default_domain_name[30]; +#else +uint8_t const default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; +uint8_t const default_server_name[] PROGMEM = PARAMS_SERVERNAME; +uint8_t const default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; +#endif + +#if PARAMETER_STORAGE==0 +/* 0 Hard coded, minmal program and eeprom usage. */ +uint8_t +params_get_eui64(uint8_t *eui64) { +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); + return 1; +#else + uint8_t i; + for (i=0;i 26)) x[1]=x[0]; +/* Do exclusive or test on the two values read */ + if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit +/* Verification fails, rewrite everything */ + uint8_t i,buffer[32]; + PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(&buffer); + randomeui64=1; +#else + for (i=0;iSet EEPROM RF channel to %d\n",x); + } + } + return x; +} +uint8_t +params_get_eui64(uint8_t *eui64) { + size_t size = sizeof(rimeaddr_t); + if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get EUI64 MAC\n"); + return 0; + } +#if CONTIKI_CONF_RANDOM_MAC + PRINTD("Generating random EUI64 MAC\n"); + generate_new_eui64(eui64); +#else + {uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this +#endif + if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM MAC address\n"); + } +#if CONTIKI_CONF_RANDOM_MAC + return 1; +#else + return 0; +#endif +} +uint16_t +params_get_panid(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN ID of %04x\n",x); + } else { + x=PARAMS_PANID; + if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN ID to %04x\n",x); + } + } + return x; +} +uint16_t +params_get_panaddr(void) { + uint16_t x; + size_t size = 2; + if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get PAN address of %04x\n",x); + } else { + x=PARAMS_PANADDR; + if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM PAN address to %04x\n",x); + } + } + return x; +} +uint8_t +params_get_txpower(void) { + uint8_t x; + size_t size = 1; + if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { + PRINTD("<-Get tx power of %d (0=max)\n",x); + } else { + x=PARAMS_TXPOWER; + if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { + PRINTD("->Set EEPROM tx power of %d (0=max)\n",x); + } + } + return x; +} +#endif /* CONTIKI_CONF_SETTINGS_MANAGER */ diff --git a/platform/avr-pluto/params.h b/platform/avr-pluto/params.h new file mode 100644 index 0000000..7a5e8aa --- /dev/null +++ b/platform/avr-pluto/params.h @@ -0,0 +1,108 @@ +#ifndef __PARAMS_H__ +#define __PARAMS_H__ +/* PARAMETER_STORAGE = + * 0 Hard coded, minmal program and eeprom usage. + * 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. + * This allows parameter changes using a hardware programmer or custom application code. + * Corruption test is based on channel verify so get the channel before anything else! + * 2 Obtained from eeprom using the general settings manager and read from program flash if not present. + * Useful for for testing builds without wearing out flash memory. + * 3 Obtained from eeprom using the settings manager and rewritten from flash if not present. + * This ensures all parameters are present in upper eeprom flash. + * + * Note the parameters in this file can be changed without forcing a complete rebuild. + */ +#define CONTIKI_CONF_RANDOM_MAC 0 //adds 78 bytes +#define CONTIKI_CONF_SETTINGS_MANAGER 0 //adds 1696 bytes + +#if CONTIKI_CONF_SETTINGS_MANAGER +//#define PARAMETER_STORAGE 2 +#define PARAMETER_STORAGE 2 +#else +#define PARAMETER_STORAGE 1 +#endif + +/* Include settings.h, then dummy out the write routines */ +#include "settings.h" +#if PARAMETER_STORAGE==2 +#define settings_add(...) 0 +#define settings_add_uint8(...) 0 +#define settings_add_uint16(...) 0 +#endif + +#if AVR_WEBSERVER +/* Webserver builds can set some defaults in httpd-fsdata.c via makefsdata.h */ +extern uint8_t eemem_mac_address[8]; +extern uint8_t eemem_server_name[16]; +extern uint8_t eemem_domain_name[30]; +#endif + +#ifdef SERVER_NAME +#define PARAMS_SERVERNAME SERVER_NAME +#else +#define PARAMS_SERVERNAME "ATMEGA128rfa1" +#endif +#ifdef DOMAIN_NAME +#define PARAMS_DOMAINNAME DOMAIN_NAME +#else +#define PARAMS_DOMAINNAME "localhost" +#endif +#ifdef NODE_ID +#define PARAMS_NODEID NODE_ID +#else +#define PARAMS_NODEID 0 +#endif +#ifdef CHANNEL_802_15_4 +#define PARAMS_CHANNEL CHANNEL_802_15_4 +#else +#define PARAMS_CHANNEL 26 +#endif +#ifdef IEEE802154_PANID +#define PARAMS_PANID IEEE802154_PANID +#else +#define PARAMS_PANID 0xABCD +#endif +#ifdef IEEE802154_PANADDR +#define PARAMS_PANADDR IEEE802154_PANADDR +#else +#define PARAMS_PANADDR 0 +#endif +#ifdef RF230_MAX_TX_POWER +#define PARAMS_TXPOWER RF230_MAX_TX_POWER +#else +#define PARAMS_TXPOWER 0 +#endif +#ifdef EUI64_ADDRESS +#define PARAMS_EUI64ADDR EUI64_ADDRESS +#else +/* This form of of EUI64 mac allows full 6LoWPAN header compression from mac address */ +#if UIP_CONF_LL_802154 +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN, 0xNN} +#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01} +#else +//#define PARAMS_EUI64ADDR {0x02, 0xNN, 0xNN, 0xff, 0xfe, 0xNN, 0xNN, 0xNN} +#define PARAMS_EUI64ADDR {0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01} +#endif +/* This form of of EUI64 mac allows 16 bit 6LoWPAN header compression on multihops */ +//#define PARAMS_EUI64ADDR {0x02, 0x00, 0x00, 0xff, 0xfe, 0x00, 0xNN, 0xNN} +#endif + +uint8_t params_get_eui64(uint8_t *eui64); +#if PARAMETER_STORAGE==0 +/* Hard coded program flash parameters */ +#define params_get_servername(...) +#define params_get_nodeid(...) PARAMS_NODEID +#define params_get_channel(...) PARAMS_CHANNEL +#define params_get_panid(...) PARAMS_PANID +#define params_get_panaddr(...) PARAMS_PANADDR +#define params_get_txpower(...) PARAMS_TXPOWER +#else +/* Parameters stored in eeprom */ +uint16_t params_get_nodeid(void); +uint8_t params_get_channel(void); +uint16_t params_get_panid(void); +uint16_t params_get_panaddr(void); +uint8_t params_get_txpower(void); +#endif + +#endif /* __PARAMS_H__ */ diff --git a/platform/avr-pluto/raven-lcd.h b/platform/avr-pluto/raven-lcd.h new file mode 100644 index 0000000..23c5eb2 --- /dev/null +++ b/platform/avr-pluto/raven-lcd.h @@ -0,0 +1,27 @@ +#ifndef raven_lcd_h +#define raven_lcd_h + +int raven_lcd_serial_input(unsigned char ch); +void raven_lcd_show_text(char *text); +PROCESS_NAME(raven_lcd_process); + +/* Serial protocol */ +#define SOF_CHAR 1 +#define EOF_CHAR 4 +#define NULL_CMD (0x00) +#define SERIAL_CMD (0x01) + +/* Messages from the 1284p to the 3290p */ +#define REPORT_PING (0xC0) +#define REPORT_PING_BEEP (0xC1) +#define REPORT_TEXT_MSG (0xC2) +#define REPORT_WAKE (0xC3) + +/* Messages from the 3290p to the 1284p */ +#define SEND_TEMP (0x80) +#define SEND_PING (0x81) +#define SEND_ADC2 (0x82) +#define SEND_SLEEP (0x83) +#define SEND_WAKE (0x84) + +#endif diff --git a/platform/avr-pluto/slip_uart0.c b/platform/avr-pluto/slip_uart0.c new file mode 100644 index 0000000..edff553 --- /dev/null +++ b/platform/avr-pluto/slip_uart0.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010, University of Colombo School of Computing + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$$ + */ + +/** + * \file + * Machine dependent AVR SLIP routines for UART0. + * \author + * Kasun Hewage + */ + +#include +#include "contiki.h" +#include "dev/rs232.h" +#include "slip.h" + +/*---------------------------------------------------------------------------*/ +static int +slip_putchar(char c, FILE *stream) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if (!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((unsigned char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if (c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} +/*---------------------------------------------------------------------------*/ +static FILE slip_stdout = FDEV_SETUP_STREAM(slip_putchar, NULL, + _FDEV_SETUP_WRITE); +/*---------------------------------------------------------------------------*/ +void +slip_arch_init(unsigned long ubr) +{ + rs232_set_input(SLIP_PORT, slip_input_byte); + stdout = &slip_stdout; +} +/*---------------------------------------------------------------------------*/ +/* + XXX: + Currently, the following function is in cpu/avr/dev/rs232.c file. this + should be moved to here from there hence this is a platform specific slip + related function. +void +slip_arch_writeb(unsigned char c) +{ + rs232_send(RS232_PORT_0, c); +} +*/