From fdd380e7ca815190b57f47c57ff625931bca2f38 Mon Sep 17 00:00:00 2001 From: Giovanni `evilaliv3` Pellerano Date: Mon, 17 Dec 2012 09:24:35 +0100 Subject: [PATCH] added support for SEED-EYE board (http://rtn.sssup.it/index.php/hardware/seed-eye) --- platform/seedeye/Makefile.seedeye | 37 + platform/seedeye/contiki-conf.h | 139 +++ platform/seedeye/contiki-seedeye-main.c | 180 ++++ platform/seedeye/dev/battery-sensor.c | 143 +++ platform/seedeye/dev/button-sensor.c | 138 +++ platform/seedeye/dev/leds-arch.c | 110 ++ platform/seedeye/dev/mrf24j40/mrf24j40.c | 945 ++++++++++++++++++ platform/seedeye/dev/mrf24j40/mrf24j40.h | 228 +++++ platform/seedeye/dev/mrf24j40/mrf24j40_arch.h | 128 +++ platform/seedeye/dev/radio-sensor.c | 98 ++ platform/seedeye/init-net.c | 178 ++++ platform/seedeye/init-net.h | 59 ++ platform/seedeye/platform-conf.h | 64 ++ 13 files changed, 2447 insertions(+) create mode 100644 platform/seedeye/Makefile.seedeye create mode 100644 platform/seedeye/contiki-conf.h create mode 100644 platform/seedeye/contiki-seedeye-main.c create mode 100644 platform/seedeye/dev/battery-sensor.c create mode 100644 platform/seedeye/dev/button-sensor.c create mode 100644 platform/seedeye/dev/leds-arch.c create mode 100644 platform/seedeye/dev/mrf24j40/mrf24j40.c create mode 100644 platform/seedeye/dev/mrf24j40/mrf24j40.h create mode 100644 platform/seedeye/dev/mrf24j40/mrf24j40_arch.h create mode 100644 platform/seedeye/dev/radio-sensor.c create mode 100644 platform/seedeye/init-net.c create mode 100644 platform/seedeye/init-net.h create mode 100644 platform/seedeye/platform-conf.h diff --git a/platform/seedeye/Makefile.seedeye b/platform/seedeye/Makefile.seedeye new file mode 100644 index 000000000..922d8868f --- /dev/null +++ b/platform/seedeye/Makefile.seedeye @@ -0,0 +1,37 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +ifdef SEEDEYE_ID +CFLAGS += -DSEEDEYE_ID=${SEEDEYE_ID} +endif + +ifdef UIP_CONF_IPV6 +CFLAGS += -DWITH_UIP6=1 +endif + +CONTIKI_TARGET_DIRS = . dev dev/mrf24j40 apps net +CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} + +CONTIKI_PLAT_DEFS += -D __USE_TIMER__ +CONTIKI_PLAT_DEFS += -D __USE_TIMER_1__ +CONTIKI_PLAT_DEFS += -D __USE_TIMER_23__ +CONTIKI_PLAT_DEFS += -D __USE_UART__ +CONTIKI_PLAT_DEFS += -D __USE_UART_PORT1A__ +CONTIKI_PLAT_DEFS += -D __USE_UART_PORT1B__ +CONTIKI_PLAT_DEFS += -D __USE_SPI__ +CONTIKI_PLAT_DEFS += -D __USE_SPI_PORT3A__ +CONTIKI_PLAT_DEFS += -D __USE_MRF24J40_SPI_PORT_3A__ +CONTIKI_PLAT_DEFS += -D __USE_UART_PORT1A_FOR_SLIP__ +CONTIKI_PLAT_DEFS += -D __USE_UART_PORT1B_FOR_DEBUG__ +CONTIKI_PLAT_DEFS += -D MRF24J40MB -D ADD_RSSI_AND_LQI_TO_PACKET + +CONTIKI_CORE_SOURCEFILES = leds.c sensors.c slip.c + +CONTIKI_TARGET_SOURCEFILES += contiki-seedeye-main.c init-net.c leds-arch.c battery-sensor.c button-sensor.c radio-sensor.c +CONTIKI_TARGET_SOURCEFILES += mrf24j40.c +CONTIKI_TARGET_SOURCEFILES += $(CONTIKI_CORE_SOURCEFILES) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +include $(CONTIKI)/cpu/pic32/Makefile.pic32 diff --git a/platform/seedeye/contiki-conf.h b/platform/seedeye/contiki-conf.h new file mode 100644 index 000000000..ceaff1cd6 --- /dev/null +++ b/platform/seedeye/contiki-conf.h @@ -0,0 +1,139 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \file contiki-conf.h + * \brief Contiki configuration file for the SEEDEYE port. + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include + +#include "platform-conf.h" + +#define CCIF +#define CLIF + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; +typedef uint16_t uip_stats_t; + +typedef uint32_t clock_time_t; + +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) + +#define RF_CHANNEL 13 + +#define PROFILE_CONF_ON 0 +#ifndef ENERGEST_CONF_ON +#define ENERGEST_CONF_ON 1 +#endif /* ENERGEST_CONF_ON */ + +#ifdef WITH_UIP6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RADIO mrf24j40_driver +#define RIMEADDR_CONF_SIZE 8 +#else +#define NETSTACK_CONF_NETWORK rime_driver +#define NETSTACK_CONF_FRAMER framer_802154 +#define NETSTACK_CONF_MAC nullmac_driver +#define NETSTACK_CONF_RDC nullrdc_driver +#define NETSTACK_CONF_RADIO mrf24j40_driver +#define RIMEADDR_CONF_SIZE 2 +#endif + +#define RDC_CONF_HARDWARE_CSMA 1 + +#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 + +#ifdef WITH_UIP6 +#define UIP_CONF_ROUTER 1 +#ifndef UIP_CONF_IPV6_RPL +#define UIP_CONF_IPV6_RPL 1 +#endif /* UIP_CONF_IPV6_RPL */ + +/* IPv6 configuration options */ +#define UIP_CONF_IPV6 1 +#define UIP_CONF_DS6_NBR_NBU 20 /* number of neighbors */ +#define UIP_CONF_DS6_ROUTE_NBU 20 /* number of routes */ +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif /* QUEUEBUF_CONF_NUM */ + +/* UDP configuration options */ +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_UDP_CONNS 10 + +/* 6lowpan options (for ipv6) */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ + +/* General configuration options */ +#define UIP_CONF_STATISTICS 0 +#define UIP_CONF_LOGGING 0 +#define UIP_CONF_BROADCAST 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_LL_802154 1 +#endif + +/* 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/seedeye/contiki-seedeye-main.c b/platform/seedeye/contiki-seedeye-main.c new file mode 100644 index 000000000..e1ec4c220 --- /dev/null +++ b/platform/seedeye/contiki-seedeye-main.c @@ -0,0 +1,180 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file contiki-seedeye-main.c + * \brief Main program for the SEEDEYE port. + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#include +#include +#include +#include +#include "dev/button-sensor.h" +#include "dev/battery-sensor.h" +#include + +#include +#include + +#include + +#include + +#include +#include + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if UIP_CONF_ROUTER +#ifndef UIP_ROUTER_MODULE +#ifdef UIP_CONF_ROUTER_MODULE +#define UIP_ROUTER_MODULE UIP_CONF_ROUTER_MODULE +#else /* UIP_CONF_ROUTER_MODULE */ +#define UIP_ROUTER_MODULE rimeroute +#endif /* UIP_CONF_ROUTER_MODULE */ +#endif /* UIP_ROUTER_MODULE */ +extern const struct uip_router UIP_ROUTER_MODULE; +#endif /* UIP_CONF_ROUTER */ + +SENSORS(&button_sensor); + +/*---------------------------------------------------------------------------*/ +static void +print_processes(struct process *const processes[]) +{ + PRINTF("Starting:\n"); + + while(*processes != NULL) { + PRINTF(" '%s'\n", (*processes)->name); + processes++; + } + + PRINTF("\n"); +} +/*---------------------------------------------------------------------------*/ +int +main(int argc, char **argv) +{ + int32_t r; + + /* Initalizing main hardware */ + pic32_init(); + watchdog_init(); + leds_init(); + + clock_init(); + + dbg_setup_uart(UART_DEBUG_BAUDRATE); + + PRINTF("Initialising Node: %d\n", SEEDEYE_ID); + + printf("CPU Clock: %uMhz\n", pic32_clock_get_system_clock() / 1000000); + printf("Peripheral Clock: %uMhz\n", pic32_clock_get_peripheral_clock() / 1000000); + + random_init(SEEDEYE_ID); + + process_init(); + process_start(&etimer_process, NULL); + ctimer_init(); + rtimer_init(); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + process_start(&sensors_process, NULL); + SENSORS_ACTIVATE(battery_sensor); + + leds_on(LEDS_RED); + + /* Inizialize Network! */ + + init_net(SEEDEYE_ID); + + leds_on(LEDS_RED); + + /* Starting autostarting process */ + print_processes(autostart_processes); + autostart_start(autostart_processes); + + PRINTF("Processes running\n"); + + leds_off(LEDS_ALL); + + watchdog_start(); + + /* + * This is the scheduler loop. + */ + while(1) { + + do { + /* Reset watchdog. */ + watchdog_periodic(); + r = process_run(); + } while(r > 0); + + ENERGEST_OFF(ENERGEST_TYPE_CPU); + ENERGEST_ON(ENERGEST_TYPE_LPM); + + watchdog_stop(); + asm volatile("wait"); + watchdog_start(); + + ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + } + + return 0; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/dev/battery-sensor.c b/platform/seedeye/dev/battery-sensor.c new file mode 100644 index 000000000..d1d268316 --- /dev/null +++ b/platform/seedeye/dev/battery-sensor.c @@ -0,0 +1,143 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file battery-sensor.c + * \brief Battery Sensor + * \author Giovanni Pellerano + * \date 2012-07-04 + */ + +#include + +#include + +/*---------------------------------------------------------------------------*/ +PROCESS(battery_process, "battery sensor"); +/*---------------------------------------------------------------------------*/ + +const struct sensors_sensor battery_sensor; + +#define BATTERY_SAMPLES 10 + +static uint16_t battery_samples[BATTERY_SAMPLES]; +static uint8_t counter = 0; + +static uint8_t sensor_status = 0; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint32_t tmp = 0; + uint8_t i; + for(i = 0; i < BATTERY_SAMPLES; ++i) { + tmp += battery_samples[i]; + } + + return tmp / BATTERY_SAMPLES; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + // all PORTB = Digital; RB10 = analog + AD1PCFG = 0b1111110111111111; + + // SSRC bit = 111 implies internal counter ends sampling and starts converting + AD1CON1 = 0b0000000011100000; + + AD1CHS = 0b00000000000010100000000000000000; + + AD1CSSL = 0; + + // Manual Sample, Tad = internal 6 TPB + AD1CON3 = 0x1F02; + + AD1CON2 = 0; + + // Turn ADC on + AD1CON1SET = 0b1000000000000000; + + process_start(&battery_process, NULL); + + sensor_status = 1; + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sensor_status; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(battery_process, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + static struct etimer et; + + etimer_set(&et, CLOCK_SECOND); + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + // start converting + AD1CON1SET = 0b0000000000000010; + + while (!(AD1CON1 & 0b0000000000000001)) { + ; // wait conversion finish + } + + // read the conversion result + battery_samples[counter] = ADC1BUF0; + + counter = (counter + 1) % BATTERY_SAMPLES; + } + + PROCESS_END(); +} + +/** @} */ diff --git a/platform/seedeye/dev/button-sensor.c b/platform/seedeye/dev/button-sensor.c new file mode 100644 index 000000000..d138ec8ad --- /dev/null +++ b/platform/seedeye/dev/button-sensor.c @@ -0,0 +1,138 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file button-sensor.c + * \brief Button Sensor + * \author Giovanni Pellerano + * \date 2012-04-24 + */ + +#include + +#include + +#include + +#define button_read PORTDbits.RD5 + +const struct sensors_sensor button_sensor; + +static struct timer debouncetimer; + +static int status(int type); + +static uint8_t sensor_status = 0; + +ISR(_CHANGE_NOTICE_VECTOR) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor); + } + + IFS1CLR = _IFS1_CNIF_MASK; + + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} + +/*---------------------------------------------------------------------------*/ +void +button_press(void) +{ + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return button_read || !timer_expired(&debouncetimer); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch (type) { + case SENSORS_ACTIVE: + if (value) { + if(!status(SENSORS_ACTIVE)) { + timer_set(&debouncetimer, 0); + + TRISDbits.TRISD5 = 1; + + CNCON = 0; + CNCONSET = 1 << _CNCON_ON_POSITION | 1 << _CNCON_SIDL_POSITION; + CNEN = 1 << _CNEN_CNEN14_POSITION; + CNPUE = 1 << _CNPUE_CNPUE14_POSITION; + + IEC1CLR = _IEC1_CNIE_MASK; + IFS1CLR = _IFS1_CNIF_MASK; + + IPC6CLR = _IPC6_CNIP_MASK; + IPC6SET = 6 << _IPC6_CNIP_POSITION; + + IEC1SET = 1 << _IEC1_CNIE_POSITION; + + sensor_status = 1; + } + } + return 1; + } + + sensor_status = 0; + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return sensor_status; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/dev/leds-arch.c b/platform/seedeye/dev/leds-arch.c new file mode 100644 index 000000000..c9fdbf1dc --- /dev/null +++ b/platform/seedeye/dev/leds-arch.c @@ -0,0 +1,110 @@ +/* + * Contiki PIC32 Port project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file leds-arch.c + * \brief LEDs Specific Arch Conf + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#include "contiki-conf.h" + +#include "dev/leds.h" + +#include "p32xxxx.h" + +/* + * IPM2 has 2 red LEDs, LED1 is mapped to the Contiki + * LEDS_RED and LED2 is mapped to LEDS_GREEN. + */ + +#define LEDS_CONF_GREEN 0x04 +#define LEDS_CONF_RED 0x08 + +#define SEEDEYE_BOARD_V2_CAT3(x,y,z) x ## y ## z + +/* NOTE: Led0 works in a negated logic. */ +#define led_0_on (LATCCLR = LEDS_CONF_RED) +#define led_0_off (LATCSET = LEDS_CONF_RED) +#define led_0_toggle (LATCINV = LEDS_CONF_RED) +#define led_1_on (LATCSET = LEDS_CONF_GREEN) +#define led_1_off (LATCCLR = LEDS_CONF_GREEN) +#define led_1_toggle (LATCINV = LEDS_CONF_GREEN) +#define led_on(n) SEEDEYE_BOARD_V2_CAT3(led_,n,_on) +#define led_off(n) SEEDEYE_BOARD_V2_CAT3(led_,n,_off) +#define led_toggle(n) SEEDEYE_BOARD_V2_CAT3(led_,n,_toggle) + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + TRISCCLR = 0x0C; + + led_0_off; + led_1_off; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return (PORTC & LEDS_CONF_RED ? 0 : LEDS_RED) | (~PORTC & LEDS_CONF_GREEN ? 0 : LEDS_GREEN); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + if(leds & LEDS_RED) { + led_0_on; + } else { + led_0_off; + } + + if(leds & LEDS_GREEN) { + led_1_on; + } else { + led_1_off; + } +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/dev/mrf24j40/mrf24j40.c b/platform/seedeye/dev/mrf24j40/mrf24j40.c new file mode 100644 index 000000000..d7dd3b04a --- /dev/null +++ b/platform/seedeye/dev/mrf24j40/mrf24j40.c @@ -0,0 +1,945 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup mrf24j40 MRF24J40 Driver + * + * @{ + */ + +/** + * \file mrf24j40.c + * + * \brief MRF24J40 Driver + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#include "contiki.h" + +#include "mrf24j40.h" +#include "mrf24j40_arch.h" + +#include +#include + +#include "net/packetbuf.h" +#include "net/netstack.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +PROCESS(mrf24j40_process, "MRF24J40 driver"); +/*---------------------------------------------------------------------------*/ + +static volatile uint8_t mrf24j40_last_lqi; +static volatile uint8_t mrf24j40_last_rssi; +static volatile uint8_t status_tx; +static volatile uint8_t pending; +static volatile uint8_t receive_on; + +/*---------------------------------------------------------------------------*/ +static void +set_short_add_mem(uint8_t addr, uint8_t val) +{ + const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT(); + uint8_t msg[2]; + + msg[0] = (addr << 1) | 0x01; + msg[1] = val; + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_CLR(); + } + + MRF24J40_CSn_LOW(); + MRF24J40_SPI_PORT_WRITE(msg, 2); + MRF24J40_CSn_HIGH(); + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_SET(); + } +} +/*---------------------------------------------------------------------------*/ +static void +set_long_add_mem(uint16_t addr, uint8_t val) +{ + const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT(); + uint8_t msg[3]; + + msg[0] = (((uint8_t) (addr >> 3)) & 0x7F) | 0x80; + msg[1] = (((uint8_t) (addr << 5)) & 0xE0) | 0x10; + msg[2] = val; + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_CLR(); + } + + MRF24J40_CSn_LOW(); + MRF24J40_SPI_PORT_WRITE(msg, 3); + MRF24J40_CSn_HIGH(); + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_SET(); + } +} +/*---------------------------------------------------------------------------*/ +static uint8_t +get_short_add_mem(uint8_t addr) +{ + const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT(); + uint8_t ret_val; + + addr <<= 1; + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_CLR(); + } + + MRF24J40_CSn_LOW(); + MRF24J40_SPI_PORT_WRITE(&addr, 1); + MRF24J40_SPI_PORT_READ(&ret_val, 1); + MRF24J40_CSn_HIGH(); + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_SET(); + } + + return ret_val; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +get_long_add_mem(uint16_t addr) +{ + const uint8_t tmp = MRF24J40_INTERRUPT_ENABLE_STAT(); + uint8_t ret_val; + uint8_t msg[2]; + + msg[0] = (((uint8_t) (addr >> 3)) & 0x7F) | 0x80; + msg[1] = ((uint8_t) (addr << 5)) & 0xE0; + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_CLR(); + } + + MRF24J40_CSn_LOW(); + MRF24J40_SPI_PORT_WRITE(msg, 2); + MRF24J40_SPI_PORT_READ(&ret_val, 1); + MRF24J40_CSn_HIGH(); + + if(tmp) { + MRF24J40_INTERRUPT_ENABLE_SET(); + } + + return ret_val; +} +/*---------------------------------------------------------------------------*/ +static void +reset_rf_state_machine(void) +{ + /* + * Reset RF state machine + */ + + const uint8_t rfctl = get_short_add_mem(MRF24J40_RFCTL); + + set_short_add_mem(MRF24J40_RFCTL, rfctl | 0b00000100); + set_short_add_mem(MRF24J40_RFCTL, rfctl & 0b11111011); + + clock_delay_usec(2500); +} +/*---------------------------------------------------------------------------*/ +void +flush_rx_fifo(void) +{ + set_short_add_mem(MRF24J40_RXFLUSH, get_short_add_mem(MRF24J40_RXFLUSH) | 0b00000001); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set the channel + * + * This routine sets the rx/tx channel + */ +void +mrf24j40_set_channel(uint16_t ch) +{ + set_long_add_mem(MRF24J40_RFCON0, ((ch - 11) << 4) | 0b00000011); + + reset_rf_state_machine(); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Store MAC PAN ID + * + * This routine sets the MAC PAN ID in the MRF24J40. + */ +void +mrf24j40_set_panid(uint16_t id) +{ + set_short_add_mem(MRF24J40_PANIDL, (uint8_t) id); + set_short_add_mem(MRF24J40_PANIDH, (uint8_t) (id >> 8)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Store short MAC address + * + * This routine sets the short MAC address in the MRF24J40. + */ +void +mrf24j40_set_short_mac_addr(uint16_t addr) +{ + set_short_add_mem(MRF24J40_SADRL, (uint8_t) addr); + set_short_add_mem(MRF24J40_SADRH, (uint8_t) (addr >> 8)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Store extended MAC address + * + * This routine sets the extended MAC address in the MRF24J40. + */ +void +mrf24j40_set_extended_mac_addr(uint64_t addr) +{ + set_short_add_mem(MRF24J40_EADR7, (uint8_t) addr); + set_short_add_mem(MRF24J40_EADR6, (uint8_t) (addr >> 8)); + set_short_add_mem(MRF24J40_EADR5, (uint8_t) (addr >> 16)); + set_short_add_mem(MRF24J40_EADR4, (uint8_t) (addr >> 24)); + set_short_add_mem(MRF24J40_EADR3, (uint8_t) (addr >> 32)); + set_short_add_mem(MRF24J40_EADR2, (uint8_t) (addr >> 40)); + set_short_add_mem(MRF24J40_EADR1, (uint8_t) (addr >> 48)); + set_short_add_mem(MRF24J40_EADR0, (uint8_t) (addr >> 56)); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get short MAC address + * + * This routine gets the short MAC address stored in the MRF24J40. + */ +void +mrf24j40_get_short_mac_addr(uint16_t *addr) +{ + *(((uint8_t *) & addr)) = get_short_add_mem(MRF24J40_SADRH); + *(((uint8_t *) & addr) + 1) = get_short_add_mem(MRF24J40_SADRL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Gets extended MAC address + * + * This routine gets the extended MAC address stored in the MRF24J40. + */ +void +mrf24j40_get_extended_mac_addr(uint64_t *addr) +{ + *(((uint8_t *) & addr)) = get_short_add_mem(MRF24J40_EADR7); + *(((uint8_t *) & addr) + 1) = get_short_add_mem(MRF24J40_EADR6); + *(((uint8_t *) & addr) + 2) = get_short_add_mem(MRF24J40_EADR5); + *(((uint8_t *) & addr) + 3) = get_short_add_mem(MRF24J40_EADR4); + *(((uint8_t *) & addr) + 4) = get_short_add_mem(MRF24J40_EADR3); + *(((uint8_t *) & addr) + 5) = get_short_add_mem(MRF24J40_EADR2); + *(((uint8_t *) & addr) + 6) = get_short_add_mem(MRF24J40_EADR1); + *(((uint8_t *) & addr) + 7) = get_short_add_mem(MRF24J40_EADR0); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set TX power + * + * This routine sets the transmission power of the MRF24J40. + */ +void +mrf24j40_set_tx_power(uint8_t pwr) +{ + set_long_add_mem(MRF24J40_RFCON3, pwr); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get radio status + * + * This routine returns the MRF24J40 status. + */ +uint8_t +mrf24j40_get_status(void) +{ + return get_long_add_mem(MRF24J40_RFSTATE); +} + +/*---------------------------------------------------------------------------*/ +/** + * \brief Get the RSSI + * + * This routine returns the rssi value mesured in dbm + * Note: to convert the returned value to dBm, use the table 3-8 available + * in the MRF24J40 datasheet. + */ +uint8_t +mrf24j40_get_rssi(void) +{ + /* + * 3.6.1 RSSI FIRMWARE REQUEST (RSSI MODE1) + * In this mode, the host microcontroller sends a request + * to calculate RSSI, then waits until it is done and then + * reads the RSSI value. The steps are: + * + * 1. + * Set RSSIMODE1 0x3E<7> – Initiate RSSI + * calculation. + * + * 2. + * Wait until RSSIRDY 0x3E<0> is set to ‘1’ – RSSI + * calculation is complete. + * + * 3. + * Read RSSI 0x210<7:0> – The RSSI register + * contains the averaged RSSI received power + * level for 8 symbol periods. + */ + + /* Initiate RSSI calculation */ + set_short_add_mem(MRF24J40_BBREG6, get_short_add_mem(MRF24J40_BBREG6) | 0b10000000); + + /* Wait until RSSI calculation is done */ + while(!(get_short_add_mem(MRF24J40_BBREG6) & 0b00000001)) { + ; + } + + mrf24j40_last_rssi = get_long_add_mem(MRF24J40_RSSI); + + return mrf24j40_last_rssi; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get the last read RSSI + * + * This routine returns the last rssi value mesured in dbm + * Note: to convert the returned value to dBm, use the table 3-8 available + * in the MRF24J40 datasheet. + */ +uint8_t +mrf24j40_get_last_rssi(void) +{ + return mrf24j40_last_rssi; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get the last read LQI + * + * This routine returns the last lqi + */ +uint8_t +mrf24j40_get_last_lqi(void) +{ + return mrf24j40_last_lqi; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Store message + * + * This routine stores a buffer of buf_len bytes in the TX_FIFO + * buffer of the MRF24J40. + */ +int32_t +mrf24j40_set_txfifo(const uint8_t *buf, uint8_t buf_len) +{ + uint8_t i; + + if((buf_len == 0) || (buf_len > 128)) { + return -1; + } + + set_long_add_mem(MRF24J40_NORMAL_TX_FIFO, 0); + + set_long_add_mem(MRF24J40_NORMAL_TX_FIFO + 1, buf_len); + + for(i = 0; i < buf_len; ++i) { + set_long_add_mem(MRF24J40_NORMAL_TX_FIFO + 2 + i, buf[i]); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get message + * + * This routine is used to retrieve a message stored in the RX_FIFO + */ +int32_t +mrf24j40_get_rxfifo(uint8_t *buf, uint8_t buf_len) +{ + uint8_t i, len; + + MRF24J40_INTERRUPT_ENABLE_CLR(); + + /* Disable packet reception */ + set_short_add_mem(MRF24J40_BBREG1, 0b00000100); + + /* Get packet length discarding 2 bytes (LQI, RSSI) */ + len = get_long_add_mem(MRF24J40_RX_FIFO) - 2; + + if(len <= buf_len) { + /* Get the packet */ + for(i = 0; i < len; ++i) { + buf[i] = get_long_add_mem(MRF24J40_RX_FIFO + i + 1); + } + + /* + * packet len includes = header + paylod + LQI + RSSI + */ +#ifdef ADD_RSSI_AND_LQI_TO_PACKET + mrf24j40_last_lqi = get_long_add_mem(MRF24J40_RX_FIFO + len + 3); + mrf24j40_last_rssi = get_long_add_mem(MRF24J40_RX_FIFO + len + 4); +#endif + } else { + len = 0; + } + + /* Enable packet reception */ + set_short_add_mem(MRF24J40_BBREG1, 0b00000000); + + pending = 0; + +#ifdef MRF24J40_PROMISCUOUS_MODE + /* + * Flush RX FIFO as suggested by the work around 1 in + * MRF24J40 Silicon Errata. + */ + flush_rx_fifo(); +#endif + + MRF24J40_INTERRUPT_ENABLE_SET(); + + return len == 0 ? -1 : len; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Start sleep + * + * This routine puts the radio in sleep mode. + */ +static void +put_to_sleep(void) +{ + /* Prepare WAKE pin: */ + MRF24J40_WAKE = 0; + + /* Enable Immediate Wake-up mode */ + set_short_add_mem(MRF24J40_WAKECON, 0b10000000); + + set_short_add_mem(MRF24J40_SOFTRST, 0b00000100); + + set_short_add_mem(MRF24J40_RXFLUSH, 0b01100000); + + /* Put to sleep */ + set_short_add_mem(MRF24J40_SLPACK, 0b10000000); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Awake the radio + * + * This routine turns on and sets the radio on receiving mode. + * Note: After performing this routine the radio is in the receiving state. + */ +static void +wake(void) +{ + /* Wake-up */ + MRF24J40_WAKE = 1; + + /* RF State Machine reset */ + set_short_add_mem(MRF24J40_RFCTL, 0b00000100); + set_short_add_mem(MRF24J40_RFCTL, 0b00000000); + + clock_delay_usec(2500); +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_on(void) +{ + if(!receive_on) { + wake(); + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + receive_on = 1; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_off(void) +{ + if(receive_on) { + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + receive_on = 0; + + put_to_sleep(); + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Init transceiver + * + * This routine initializes the radio transceiver + */ +int +mrf24j40_init(void) +{ + uint8_t i; + + /* Set the IO pins direction */ + MRF24J40_PINDIRECTION_INIT(); + + /* Set interrupt registers and reset flags */ + MRF24J40_INTERRUPT_INIT(6, 3); + + if(MRF24J40_SPI_PORT_INIT(10000000, SPI_DEFAULT) < 0) + return -1; + + PRINTF("MRF24J40 Initialization started\n"); + + MRF24J40_HARDRESET_LOW(); + + clock_delay_usec(2500); + + MRF24J40_HARDRESET_HIGH(); + + clock_delay_usec(2500); + + /* + * bit 7:3 reserved: Maintain as ‘0’ + * bit 2 RSTPWR: Power Management Reset bit + * 1 = Reset power management circuitry (bit is automatically cleared to ‘0’ by hardware) + * bit 1 RSTBB: Baseband Reset bit + * 1 = Reset baseband circuitry (bit is automatically cleared to ‘0’ by hardware) + * bit 0 RSTMAC: MAC Reset bit + * 1 = Reset MAC circuitry (bit is automatically cleared to ‘0’ by hardware) + */ + set_short_add_mem(MRF24J40_SOFTRST, 0b00000111); + + /* + * wait until the radio reset is completed + */ + do { + i = get_short_add_mem(MRF24J40_SOFTRST); + } while((i & 0b0000111) != 0); + + clock_delay_usec(2500); + + + /* + * bit 7 FIFOEN: FIFO Enable bit 1 = Enabled (default). Always maintain this bit as a ‘1’. + * bit 6 reserved: Maintain as ‘0’ + * bit 5:2 TXONTS<3:0>: Transmitter Enable On Time Symbol bits(1) + * Transmitter on time before beginning of packet. Units: symbol period (16 μs). + * Minimum value: 0x1. Default value: 0x2 (2 * 16 μs = 32 μs). Recommended value: 0x6 (6 * 16 μs = 96 μs). + * bit 1:0 TXONT<8:7>: Transmitter Enable On Time Tick bits(1) + * Transmitter on time before beginning of packet. TXONT is a 9-bit value. TXONT<6:0> bits are located + * in SYMTICKH<7:1>. Units: tick (50 ns). Default value = 0x028 (40 * 50 ns = 2 μs). + */ + set_short_add_mem(MRF24J40_PACON2, 0b10011000); + + mrf24j40_set_channel(MRF24J40_DEFAULT_CHANNEL); + + set_long_add_mem(MRF24J40_RFCON1, 0b00000010); /* program the RF and Baseband Register */ + /* as suggested by the datasheet */ + + set_long_add_mem(MRF24J40_RFCON2, 0b10000000); /* enable PLL */ + + mrf24j40_set_tx_power(0b00000000); /* set power 0dBm (plus 20db power amplifier 20dBm)*/ + + /* + * Set up + * + * bit 7 '1' as suggested by the datasheet + * bit 6:5 '00' reserved + * bit 4 '1' recovery from sleep 1 usec + * bit 3 '0' battery monitor disabled + * bit 2:0 '000' reserved + */ + set_long_add_mem(MRF24J40_RFCON6, 0b10010000); + + set_long_add_mem(MRF24J40_RFCON7, 0b10000000); /* Sleep clock = 100kHz */ + set_long_add_mem(MRF24J40_RFCON8, 0b00000010); /* as suggested by the datasheet */ + + set_long_add_mem(MRF24J40_SLPCON1, 0b00100001); /* as suggested by the datasheet */ + + /* Program CCA, RSSI threshold values */ + set_short_add_mem(MRF24J40_BBREG2, 0b01111000); /* Recommended value by the datashet */ + set_short_add_mem(MRF24J40_CCAEDTH, 0b01100000); /* Recommended value by the datashet */ + +#ifdef MRF24J40MB + /* Activate the external amplifier needed by the MRF24J40MB */ + set_long_add_mem(MRF24J40_TESTMODE, 0b0001111); + PRINTF("MRF24J40 Init Amplifier activated \n"); +#endif + +#ifdef ADD_RSSI_AND_LQI_TO_PACKET + /* Enable the packet RSSI */ + set_short_add_mem(MRF24J40_BBREG6, 0b01000000); + PRINTF("MRF24J40 Init append RSSI and LQI to packet\n"); +#endif + + /* + * Wait until the radio state machine is not on rx mode + */ + do { + i = get_long_add_mem(MRF24J40_RFSTATE); + } while((i & 0xA0) != 0xA0); + + i = 0; + +#ifdef MRF24J40_DISABLE_AUTOMATIC_ACK + i = i | 0b00100000; + PRINTF("MRF24J40 Init NO_AUTO_ACK\n"); +#endif + +#ifdef MRF24J40_PAN_COORDINATOR + i = i | 0b00001000; + PRINTF("MRF24J40 Init PAN COORD\n"); + set_short_add_mem(MRF24J40_ORDER, 0b11111111); +#endif + +#ifdef MRF24J40_COORDINATOR + i = i | 0b00000100; + PRINTF("MRF24J40 Init COORD\n"); +#endif + +#ifdef MRF24J40_ACCEPT_WRONG_CRC_PKT + i = i | 0b00000010; + PRINTF("MRF24J40 Init Accept Wrong CRC\n"); +#endif + +#ifdef MRF24J40_PROMISCUOUS_MODE + i = i | 0b00000001; + PRINTF("MRF24J40 Init PROMISCUOUS MODE\n"); +#endif + + /* + * Set the RXMCR register. + * Default setting i = 0x00, which means: + * - Automatic ACK; + * - Device is not a PAN coordinator; + * - Device is not a coordinator; + * - Accept only packets with good CRC + * - Discard packet when there is a MAC address mismatch, + * illegal frame type, dPAN/sPAN or MAC short address mismatch. + */ + set_short_add_mem(MRF24J40_RXMCR, i); + PRINTF("RXMCR 0x%X\n", i); + + /* + * Set the TXMCR register. + * bit 7 '0' Enable No Carrier Sense Multiple Access (CSMA) Algorithm. + * bit 6 '0' Disable Battery Life Extension Mode bit. + * bit 5 '0' Disable Slotted CSMA-CA Mode bit. + * bit 4:3 '11' MAC Minimum Backoff Exponent bits (macMinBE). + * bit 2:0 '100' CSMA Backoff bits (macMaxCSMABackoff) + */ + set_short_add_mem(MRF24J40_TXMCR, 0b00011100); + + i = get_short_add_mem(MRF24J40_TXMCR); + PRINTF("TXMCR 0x%X\n", i); + + /* + * Set TX turn around time as defined by IEEE802.15.4 standard + */ + set_short_add_mem(MRF24J40_TXSTBL, 0b10010101); + set_short_add_mem(MRF24J40_TXTIME, 0b00110000); + +#ifdef INT_POLARITY_HIGH + /* Set interrupt edge polarity high */ + set_long_add_mem(MRF24J40_SLPCON0, 0b00000011); + PRINTF("MRF24J40 Init INT Polarity High\n"); +#else + set_long_add_mem(MRF24J40_SLPCON0, 0b00000001); + PRINTF("MRF24J40 Init INT Polarity Low\n"); +#endif + + PRINTF("MRF24J40 Inititialization completed\n"); + + mrf24j40_last_lqi = 0; + mrf24j40_last_rssi = 0; + status_tx = MRF24J40_TX_ERR_NONE; + pending = 0; + + receive_on = 1; + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + reset_rf_state_machine(); + + /* Flush RX FIFO */ + flush_rx_fifo(); + + process_start(&mrf24j40_process, NULL); + + /* + * + * Setup interrupts. + * + * set INTCON + * bit 7 '1' Disables the sleep alert interrupt + * bit 6 '1' Disables the wake-up alert interrupt + * bit 5 '1' Disables the half symbol timer interrupt + * bit 4 '1' Disables the security key request interrupt + * bit 3 '0' Enables the RX FIFO reception interrupt + * bit 2 '1' Disables the TX GTS2 FIFO transmission interrupt + * bit 1 '1' Disables the TX GTS1 FIFO transmission interrupt + * bit 0 '0' Enables the TX Normal FIFO transmission interrupt + */ + set_short_add_mem(MRF24J40_INTCON, 0b11110110); + + return 0; +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_prepare(const void *data, unsigned short len) +{ + PRINTF("PREPARE %u bytes\n", len); + + uint8_t receive_was_on = receive_on; + + mrf24j40_on(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + mrf24j40_set_txfifo(data, len); + + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + + if(!receive_was_on) { + mrf24j40_off(); + } else { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_transmit(unsigned short len) +{ + PRINTF("TRANSMIT %u bytes\n", len); + + uint8_t receive_was_on = receive_on; + + mrf24j40_on(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + status_tx = MRF24J40_TX_WAIT; + + set_short_add_mem(MRF24J40_TXNCON, 0b00000001); + + /* Wait until the transmission has finished. */ + while(status_tx == MRF24J40_TX_WAIT) { + ; + } + + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + + if(!receive_was_on) { + mrf24j40_off(); + } else { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + switch(status_tx) { + case MRF24J40_TX_ERR_NONE: + return RADIO_TX_OK; + case MRF24J40_TX_ERR_COLLISION: + return RADIO_TX_COLLISION; + case MRF24J40_TX_ERR_MAXRETRY: + return RADIO_TX_NOACK; + default: + return RADIO_TX_ERR; + } +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_write(const void *data, uint16_t len) +{ + int ret = -1; + + PRINTF("PREPARE & TRANSMIT %u bytes\n", len); + + if(mrf24j40_prepare(data, len)) + return ret; + + ret = mrf24j40_transmit(len); + + return ret; +} + +/*---------------------------------------------------------------------------*/ +int +mrf24j40_read(void *data, uint16_t len) +{ + return mrf24j40_get_rxfifo(data, len); +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_cca(void) +{ + uint8_t ret; + + uint8_t receive_was_on = receive_on; + + mrf24j40_on(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + ret = mrf24j40_get_rssi() <= 95; /* -69dbm */ + + if(!receive_was_on) { + mrf24j40_off(); + } else { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_receiving_packet(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +mrf24j40_pending_packet(void) +{ + return pending; +} +/*---------------------------------------------------------------------------*/ +MRF24J40_ISR() +{ + INT_status int_status; + TX_status tx_status; + + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + int_status.val = get_short_add_mem(MRF24J40_INTSTAT); + + if(!int_status.val) { + return; + } + + if(int_status.bits.RXIF) { + + pending = 1; + + process_poll(&mrf24j40_process); + + } + + if(int_status.bits.TXNIF) { + + tx_status.val = get_short_add_mem(MRF24J40_TXSTAT); + + if(tx_status.bits.TXNSTAT) { + if(tx_status.bits.CCAFAIL) { + status_tx = MRF24J40_TX_ERR_COLLISION; + } else { + status_tx = MRF24J40_TX_ERR_MAXRETRY; + } + } else { + status_tx = MRF24J40_TX_ERR_NONE; + } + } + + MRF24J40_INTERRUPT_FLAG_CLR(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(mrf24j40_process, ev, data) +{ + PROCESS_BEGIN(); + + uint8_t ret; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + if(!pending) { + continue; + } + + packetbuf_clear(); + + ret = mrf24j40_read(packetbuf_dataptr(), PACKETBUF_SIZE); + + packetbuf_set_datalen(ret); + +#ifdef ADD_RSSI_AND_LQI_TO_PACKET + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, mrf24j40_last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, mrf24j40_last_lqi); +#endif + + NETSTACK_RDC.input(); + } + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +const struct radio_driver mrf24j40_driver = { + mrf24j40_init, + mrf24j40_prepare, + mrf24j40_transmit, + mrf24j40_write, + mrf24j40_read, + mrf24j40_cca, + mrf24j40_receiving_packet, + mrf24j40_pending_packet, + mrf24j40_on, + mrf24j40_off +}; +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/dev/mrf24j40/mrf24j40.h b/platform/seedeye/dev/mrf24j40/mrf24j40.h new file mode 100644 index 000000000..52b727891 --- /dev/null +++ b/platform/seedeye/dev/mrf24j40/mrf24j40.h @@ -0,0 +1,228 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \defgroup mrf24j40 MRF24J40 Driver + * + * @{ + */ + +/** + * \file mrf24j40.h + * \brief MRF24J40 Driver + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#ifndef __MRF24J40_H__ +#define __MRF24J40_H__ + +#include +#include + +extern const struct radio_driver mrf24j40_driver; + +#define MRF24J40_DEFAULT_CHANNEL 11 + +#define MRF24J40_TX_ERR_NONE 0 +#define MRF24J40_TX_ERR_NOTSPECIFIED 1 +#define MRF24J40_TX_ERR_COLLISION 2 +#define MRF24J40_TX_ERR_MAXRETRY 3 +#define MRF24J40_TX_WAIT 4 + +/* Functions prototypes */ +void mrf24j40_set_channel(uint16_t ch); +void mrf24j40_set_panid(uint16_t id); +void mrf24j40_set_short_mac_addr(uint16_t addr); +void mrf24j40_set_extended_mac_addr(uint64_t addr); +void mrf24j40_get_short_mac_addr(uint16_t * addr); +void mrf24j40_get_extended_mac_addr(uint64_t * addr); +void mrf24j40_set_tx_power(uint8_t pwr); +void mrf24j40_set_csma_par(uint8_t be, uint8_t nb); +uint8_t mrf24j40_get_status(void); +uint8_t mrf24j40_get_rssi(void); +uint8_t mrf24j40_get_last_rssi(void); +uint8_t mrf24j40_get_last_lqi(void); +int32_t mrf24j40_set_txfifo(const uint8_t * buf, uint8_t buf_len); +int32_t mrf24j40_get_rxfifo(uint8_t * buf, uint8_t buf_len); + +/* Long address registers */ +#define MRF24J40_RFCON0 (0x200) +#define MRF24J40_RFCON1 (0x201) +#define MRF24J40_RFCON2 (0x202) +#define MRF24J40_RFCON3 (0x203) +#define MRF24J40_RFCON5 (0x205) +#define MRF24J40_RFCON6 (0x206) +#define MRF24J40_RFCON7 (0x207) +#define MRF24J40_RFCON8 (0x208) +#define MRF24J40_SPCAL0 (0x209) +#define MRF24J40_SPCAL1 (0x20A) +#define MRF24J40_SPCAL2 (0x20B) +#define MRF24J40_RFSTATE (0x20F) +#define MRF24J40_RSSI (0x210) +#define MRF24J40_SLPCON0 (0x211) +#define MRF24J40_SLPCON1 (0x220) +#define MRF24J40_WAKETIMEL (0x222) +#define MRF24J40_WAKETIMEH (0x223) +#define MRF24J40_REMCNTL (0x224) +#define MRF24J40_REMCNTH (0x225) +#define MRF24J40_MAINCNT0 (0x226) +#define MRF24J40_MAINCNT1 (0x227) +#define MRF24J40_MAINCNT2 (0x228) +#define MRF24J40_MAINCNT3 (0x229) +#define MRF24J40_TESTMODE (0x22F) +#define MRF24J40_NORMAL_TX_FIFO (0x000) +#define MRF24J40_BEACON_TX_FIFO (0x080) +#define MRF24J40_GTS1_TX_FIFO (0x100) +#define MRF24J40_GTS2_TX_FIFO (0x180) +#define MRF24J40_RX_FIFO (0x300) +#define MRF24J40_SECURITY_FIFO (0x280) +#define MRF24J40_UPNONCE0 (0x240) + +/* Short address registers */ +#define MRF24J40_RXMCR (0x00) +#define MRF24J40_PANIDL (0x01) +#define MRF24J40_PANIDH (0x02) +#define MRF24J40_SADRL (0x03) +#define MRF24J40_SADRH (0x04) +#define MRF24J40_EADR0 (0x05) +#define MRF24J40_EADR1 (0x06) +#define MRF24J40_EADR2 (0x07) +#define MRF24J40_EADR3 (0x08) +#define MRF24J40_EADR4 (0x09) +#define MRF24J40_EADR5 (0x0A) +#define MRF24J40_EADR6 (0x0B) +#define MRF24J40_EADR7 (0x0C) +#define MRF24J40_RXFLUSH (0x0D) +#define MRF24J40_ORDER (0x10) +#define MRF24J40_TXMCR (0x11) +#define MRF24J40_ACKTMOUT (0x12) +#define MRF24J40_ESLOTG1 (0x13) +#define MRF24J40_SYMTICKL (0x14) +#define MRF24J40_SYMTICKH (0x15) +#define MRF24J40_PACON0 (0x16) +#define MRF24J40_PACON1 (0x17) +#define MRF24J40_PACON2 (0x18) +#define MRF24J40_TXBCON0 (0x1A) +#define MRF24J40_TXNCON (0x1B) +#define MRF24J40_TXG1CON (0x1C) +#define MRF24J40_TXG2CON (0x1D) +#define MRF24J40_ESLOTG23 (0x1E) +#define MRF24J40_ESLOTG45 (0x1F) +#define MRF24J40_ESLOTG87 (0x20) +#define MRF24J40_TXPEND (0x21) +#define MRF24J40_WAKECON (0x22) +#define MRF24J40_FRMOFFSET (0x23) +#define MRF24J40_TXSTAT (0x24) +#define MRF24J40_TXBCON1 (0x25) +#define MRF24J40_GATECLK (0x26) +#define MRF24J40_TXTIME (0x27) +#define MRF24J40_HSYMTMRL (0x28) +#define MRF24J40_HSYMTMRH (0x29) +#define MRF24J40_SOFTRST (0x2A) +#define MRF24J40_SECCON0 (0x2C) +#define MRF24J40_SECCON1 (0x2D) +#define MRF24J40_TXSTBL (0x2E) +#define MRF24J40_RXSR (0x30) +#define MRF24J40_INTSTAT (0x31) +#define MRF24J40_INTCON (0x32) +#define MRF24J40_GPIO (0x33) +#define MRF24J40_TRISGPIO (0x34) +#define MRF24J40_SLPACK (0x35) +#define MRF24J40_RFCTL (0x36) +#define MRF24J40_SECCR2 (0x37) +#define MRF24J40_BBREG0 (0x38) +#define MRF24J40_BBREG1 (0x39) +#define MRF24J40_BBREG2 (0x3A) +#define MRF24J40_BBREG3 (0x3B) +#define MRF24J40_BBREG4 (0x3C) +#define MRF24J40_BBREG6 (0x3E) +#define MRF24J40_CCAEDTH (0x3F) + +/* + * TX power setting generation: + * tx_pwr_set(large_val, small_val) computes the value for the RFCON3 register. + * Examples: + * - if we want to set tx power to -11,2 dB then: + * mrf24j40_tx_pwr_set(#define MRF24J40_PWR_H_MINUS_10dB, #define MRF24J40_PWR_L_MINUS_1.2dB). + */ + +#define MRF24J40_PWR_H_MINUS_30dB (0b11) +#define MRF24J40_PWR_H_MINUS_20dB (0b10) +#define MRF24J40_PWR_H_MINUS_10dB (0b01) +#define MRF24J40_PWR_H_0dB (0b00) + +#define MRF24J40_PWR_L_MINUS_6_3dB (0b111) +#define MRF24J40_PWR_L_MINUS_4_9dB (0b110) +#define MRF24J40_PWR_L_MINUS_3_7dB (0b101) +#define MRF24J40_PWR_L_MINUS_2_8dB (0b100) +#define MRF24J40_PWR_L_MINUS_1_9dB (0b011) +#define MRF24J40_PWR_L_MINUS_1_2dB (0b010) +#define MRF24J40_PWR_L_MINUS_0_5dB (0b001) +#define MRF24J40_PWR_L_0dB (0b000) + +#define MRF24J40_TX_PWR_SET(large_val, small_val) ((large_val << 6) | (small_val << 3)) + +typedef union _TX_status { + uint8_t val; + struct TX_bits { + uint8_t TXNSTAT:1; + uint8_t TXG1STAT:1; + uint8_t TXG2STAT:1; + uint8_t TXG1FNT:1; + uint8_t TXG2FNT:1; + uint8_t CCAFAIL:1; + uint8_t TXNRETRY:2; + } bits; +} TX_status; + +typedef union _INT_status { + uint8_t val; + struct INT_bits { + uint8_t TXNIF:1; + uint8_t TXG1IF:1; + uint8_t TXG2IF:1; + uint8_t RXIF:1; + uint8_t SECIF:1; + uint8_t HSYMTMRIF:1; + uint8_t WAKEIF:1; + uint8_t SLPIF:1; + } bits; +} INT_status; + +#endif /* __MRF24J40_H__ */ + +/** @} */ diff --git a/platform/seedeye/dev/mrf24j40/mrf24j40_arch.h b/platform/seedeye/dev/mrf24j40/mrf24j40_arch.h new file mode 100644 index 000000000..8a3cda91d --- /dev/null +++ b/platform/seedeye/dev/mrf24j40/mrf24j40_arch.h @@ -0,0 +1,128 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup mrf24j40 MRF24J40 Driver + * + * @{ + */ + +/** + * \file mrf24j40_arch.h + * \brief MRF24J40 Specific Arch Conf + * \author Giovanni Pellerano + * \date 2012-03-21 + */ + +#ifndef __MRF24J40_ARCH_H__ +#define __MRF24J40_ARCH_H__ + +#include "p32xxxx.h" + +#include + +#include "dev/radio.h" + +/* Pin Mapping */ +#define MRF24J40_RESETn PORTGbits.RG15 +#define MRF24J40_INT PORTAbits.RA15 +#define MRF24J40_CSn PORTFbits.RF12 +#define MRF24J40_WAKE PORTGbits.RG12 + +/* Pin Tri-States */ +#define MRF24J40_TRIS_RESETn TRISGbits.TRISG1 +#define MRF24J40_TRIS_INT TRISAbits.TRISA15 +#define MRF24J40_TRIS_CSn TRISFbits.TRISF12 +#define MRF24J40_TRIS_WAKE TRISGbits.TRISG12 + +/* RESET low/high */ +#define MRF24J40_HARDRESET_LOW() MRF24J40_RESETn = 0 +#define MRF24J40_HARDRESET_HIGH() MRF24J40_RESETn = 1 +#define MRF24J40_CSn_LOW() MRF24J40_CSn = 0 +#define MRF24J40_CSn_HIGH() MRF24J40_CSn = 1 + +/* Spi port Mapping */ +#ifdef __USE_MRF24J40_SPI_PORT_1__ +#define MRF24J40_SPI_PORT_INIT pic32_spi1_init +#define MRF24J40_SPI_PORT_WRITE pic32_spi1_write +#define MRF24J40_SPI_PORT_READ pic32_spi1_read +#elif defined __USE_MRF24J40_SPI_PORT_1A__ +#define MRF24J40_SPI_PORT_INIT pic32_spi1A_init +#define MRF24J40_SPI_PORT_WRITE pic32_spi1A_write +#define MRF24J40_SPI_PORT_READ pic32_spi1A_read +#elif defined __USE_MRF24J40_SPI_PORT_2A__ +#define MRF24J40_SPI_PORT_INIT pic32_spi2A_init +#define MRF24J40_SPI_PORT_WRITE pic32_spi2A_write +#define MRF24J40_SPI_PORT_READ pic32_spi2A_read +#elif defined __USE_MRF24J40_SPI_PORT_3A__ +#define MRF24J40_SPI_PORT_INIT pic32_spi3A_init +#define MRF24J40_SPI_PORT_WRITE pic32_spi3A_write +#define MRF24J40_SPI_PORT_READ pic32_spi3A_read +#else +#define MRF24J40_SPI_PORT_INIT pic32_spi3A_init +#define MRF24J40_SPI_PORT_WRITE pic32_spi3A_write +#define MRF24J40_SPI_PORT_READ pic32_spi3A_read +#endif + +/* IRC Configuration */ +#define MRF24J40_ISR() ISR(_EXTERNAL_4_VECTOR) +#define MRF24J40_INTERRUPT_FLAG_SET() IFS0SET = _IFS0_INT4IF_MASK +#define MRF24J40_INTERRUPT_FLAG_CLR() IFS0CLR = _IFS0_INT4IF_MASK +#define MRF24J40_INTERRUPT_ENABLE_SET() IEC0SET = _IEC0_INT4IE_MASK +#define MRF24J40_INTERRUPT_ENABLE_CLR() IEC0CLR = _IEC0_INT4IE_MASK +#define MRF24J40_INTERRUPT_ENABLE_STAT() IEC0bits.INT4IE + +#define MRF24J40_PINDIRECTION_INIT() \ +do { \ + MRF24J40_TRIS_RESETn = 0; \ + MRF24J40_TRIS_INT = 1; \ + MRF24J40_TRIS_CSn = 0; \ + MRF24J40_TRIS_WAKE = 0; \ +} while(0) + +#define MRF24J40_INTERRUPT_INIT(p, s) \ +do { \ + MRF24J40_INTERRUPT_ENABLE_CLR(); \ + MRF24J40_INTERRUPT_FLAG_CLR(); \ + INTCONCLR = _INTCON_INT4EP_MASK; \ + IPC4CLR = _IPC4_INT4IP_MASK | _IPC4_INT4IS_MASK; \ + IPC4SET = (p << _IPC4_INT4IP_POSITION) | (s << _IPC4_INT4IS_POSITION); \ + MRF24J40_INTERRUPT_ENABLE_SET(); \ +} while(0) + +#endif /* __MRF24J40_ARCH_H__ */ + +/** @} */ diff --git a/platform/seedeye/dev/radio-sensor.c b/platform/seedeye/dev/radio-sensor.c new file mode 100644 index 000000000..b13df4fa4 --- /dev/null +++ b/platform/seedeye/dev/radio-sensor.c @@ -0,0 +1,98 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file radio-sensor.c + * \brief RADIO Sensor + * \author Giovanni Pellerano + * \date 2012-04-24 + */ + +#include "lib/sensors.h" +#include "dev/radio-sensor.h" + +#include "mrf24j40.h" + +const struct sensors_sensor radio_sensor; + +static int active; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + case RADIO_SENSOR_LAST_PACKET: + return mrf24j40_get_last_lqi(); + case RADIO_SENSOR_LAST_VALUE: + default: + return mrf24j40_get_last_rssi(); + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + if(type == SENSORS_ACTIVE) { + active = c; + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return active; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(radio_sensor, RADIO_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/init-net.c b/platform/seedeye/init-net.c new file mode 100644 index 000000000..865fa4697 --- /dev/null +++ b/platform/seedeye/init-net.c @@ -0,0 +1,178 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file init-net.c + * \brief Network initialization for the SEEDEYE port. + * \author Giovanni Pellerano + * \date 2012-03-25 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +void +init_net(uint8_t node_id) +{ + uint16_t shortaddr; + uint64_t longaddr; + rimeaddr_t addr; +#if WITH_UIP6 + uip_ds6_addr_t *lladdr; + uip_ipaddr_t ipaddr; +#endif + + uint8_t i; + + memset(&shortaddr, 0, sizeof(shortaddr)); + memset(&longaddr, 0, sizeof(longaddr)); + *((uint8_t *) & shortaddr) = node_id >> 8; + *((uint8_t *) & shortaddr + 1) = node_id; + *((uint8_t *) & longaddr) = node_id >> 8; + *((uint8_t *) & longaddr + 1) = node_id; + for(i = 2; i < sizeof(longaddr); ++i) { + ((uint8_t *)&longaddr)[i] = random_rand(); + } + + PRINTF("SHORT MAC ADDRESS %02x:%02x\n", + *((uint8_t *) & shortaddr), *((uint8_t *) & shortaddr + 1)); + + PRINTF("EXTENDED MAC ADDRESS %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + *((uint8_t *) & longaddr), + *((uint8_t *) & longaddr + 1), + *((uint8_t *) & longaddr + 2), + *((uint8_t *) & longaddr + 3), + *((uint8_t *) & longaddr + 4), + *((uint8_t *) & longaddr + 5), + *((uint8_t *) & longaddr + 6), + *((uint8_t *) & longaddr + 7)); + + memset(&addr, 0, sizeof(rimeaddr_t)); + + for(i = 0; i < sizeof(addr.u8); ++i) { + addr.u8[i] = ((uint8_t *)&longaddr)[i]; + } + + rimeaddr_set_node_addr(&addr); + + PRINTF("Rime started with address: "); + for(i = 0; i < sizeof(addr.u8) - 1; ++i) { + PRINTF("%d.", addr.u8[i]); + } + PRINTF("%d\n", addr.u8[i]); + + queuebuf_init(); + + NETSTACK_RADIO.init(); + + mrf24j40_set_channel(RF_CHANNEL); + mrf24j40_set_panid(IEEE802154_PANID); + mrf24j40_set_short_mac_addr(shortaddr); + mrf24j40_set_extended_mac_addr(longaddr); + + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + + PRINTF("%s %s, channel check rate %d Hz, radio channel %u\n", + NETSTACK_MAC.name, NETSTACK_RDC.name, + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1 : + NETSTACK_RDC.channel_check_interval()), RF_CHANNEL); + +#if WITH_UIP6 + +#if RIMEADDR_CONF_SIZE == 2 + memset(&uip_lladdr.addr, 0, sizeof(uip_lladdr.addr)); + uip_lladdr.addr[3] = 0xff; + uip_lladdr.addr[4]= 0xfe; + memcpy(&uip_lladdr.addr[6], &shortaddr, sizeof(shortaddr)); +#else + memcpy(&uip_lladdr.addr, &longaddr, sizeof(uip_lladdr.addr)); +#endif + + process_start(&tcpip_process, NULL); + + lladdr = uip_ds6_get_link_local(-1); + + PRINTF("Tentative link-local IPv6 address "); + + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", lladdr->ipaddr.u8[i * 2], lladdr->ipaddr.u8[i * 2 + 1]); + } + + PRINTF("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + + if(!UIP_CONF_IPV6_RPL) { + uip_ip6addr(&ipaddr, 0x2001, 0x1418, 0x100, 0x823c, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + + PRINTF("Tentative global IPv6 address "); + + for(i = 0; i < 7; ++i) { + PRINTF("%02x%02x:", ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); + } + + PRINTF("%02x%02x\n", ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); + } +#endif +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/platform/seedeye/init-net.h b/platform/seedeye/init-net.h new file mode 100644 index 000000000..8f9bcbb27 --- /dev/null +++ b/platform/seedeye/init-net.h @@ -0,0 +1,59 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ + +/** + * \addtogroup SeedEye Contiki SEEDEYE Platform + * + * @{ + */ + +/** + * \file init-net.h + * \brief Network initialization for the SEEDEYE port. + * \author Giovanni Pellerano + * \date 2012-03-25 + */ + +#ifndef __INIT_NET_H__ +#define __INIT_NET_H__ + +#include + +void init_net(uint8_t ); + +#endif /* __INIT_NET_H__ */ + +/** @} */ diff --git a/platform/seedeye/platform-conf.h b/platform/seedeye/platform-conf.h new file mode 100644 index 000000000..37a3b90d1 --- /dev/null +++ b/platform/seedeye/platform-conf.h @@ -0,0 +1,64 @@ +/* + * Contiki SeedEye Platform project + * + * Copyright (c) 2012, + * Scuola Superiore Sant'Anna (http://www.sssup.it) and + * Consorzio Nazionale Interuniversitario per le Telecomunicazioni + * (http://www.cnit.it). + * + * 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. + * + */ +/** + * \file platform-conf.h + * \brief Platform configuration file for the SEEDEYE port. + * \author Giovanni Pellerano + * \date 2012-06-06 + */ + +#ifndef __PLATFORM_CONF_H__ +#define __PLATFORM_CONF_H__ + +#ifndef SEEDEYE_ID +#define SEEDEYE_ID 1 +#endif /* SEEDEYE_ID */ + +#if SEEDEYE_ID == 1 +#define MRF24J40_PAN_COORDINATOR +#endif /* SEEDEYE_ID == 1 */ + +#define UART_DEBUG_BAUDRATE 230400 +#define UART_SLIP_BAUDRATE 230400 + +#define PLATFORM_HAS_BATTERY 1 +#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_RADIO 1 + +#define CLOCK_CONF_SECOND 1024 + +#endif /* __PLATFORM_CONF_H__ */