diff --git a/apps/mqtt/mqtt.c b/apps/mqtt/mqtt.c index f56df3a16..64b2d9454 100644 --- a/apps/mqtt/mqtt.c +++ b/apps/mqtt/mqtt.c @@ -65,7 +65,7 @@ /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG -#define PRINTF(...) PRINTF(__VA_ARGS__) +#define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif diff --git a/apps/rest-engine/rest-engine.c b/apps/rest-engine/rest-engine.c index 67ac232a2..cec590012 100644 --- a/apps/rest-engine/rest-engine.c +++ b/apps/rest-engine/rest-engine.c @@ -113,6 +113,14 @@ rest_activate_resource(resource_t *resource, char *path) PRINTF("Periodic resource: %p (%s)\n", resource->periodic, resource->periodic->resource->url); list_add(restful_periodic_services, resource->periodic); + if(process_is_running(&rest_engine_process)) { + PRINTF("Periodic: Set timer for /%s to %lu\n", + resource->url, resource->periodic->period); + PROCESS_CONTEXT_BEGIN(&rest_engine_process); + etimer_set(&resource->periodic->periodic_timer, + resource->periodic->period); + PROCESS_CONTEXT_END(&rest_engine_process); + } } } /*---------------------------------------------------------------------------*/ diff --git a/apps/webbrowser/htmlparser.c b/apps/webbrowser/htmlparser.c index b0d8cfdc3..07653be8e 100644 --- a/apps/webbrowser/htmlparser.c +++ b/apps/webbrowser/htmlparser.c @@ -410,6 +410,7 @@ parse_tag(void) switch_majorstate(s.lastmajorstate); break; case TAG_BODY: + do_word(); s.majorstate = s.lastmajorstate = MAJORSTATE_BODY; break; case TAG_IMG: diff --git a/core/cfs/cfs-posix-dir.c b/core/cfs/cfs-posix-dir.c index 0eb2ba9cb..623471b29 100644 --- a/core/cfs/cfs-posix-dir.c +++ b/core/cfs/cfs-posix-dir.c @@ -36,6 +36,7 @@ #include #include +#define CFS_IMPL 1 #include "cfs/cfs.h" struct cfs_posix_dir { diff --git a/core/cfs/cfs-posix.c b/core/cfs/cfs-posix.c index 1ee1b99df..452ddbbbb 100644 --- a/core/cfs/cfs-posix.c +++ b/core/cfs/cfs-posix.c @@ -40,6 +40,7 @@ #include #endif +#define CFS_IMPL 1 #include "cfs/cfs.h" /*---------------------------------------------------------------------------*/ diff --git a/core/net/rpl/rpl-nbr-policy.c b/core/net/rpl/rpl-nbr-policy.c index 0af5a9041..d10de973e 100644 --- a/core/net/rpl/rpl-nbr-policy.c +++ b/core/net/rpl/rpl-nbr-policy.c @@ -203,13 +203,13 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio) if(dio->rank + instance->min_hoprankinc < worst_rank - instance->min_hoprankinc / 2) { /* Found *great* neighbor - add! */ PRINTF("Found better neighbor %d < %d - add to cache...\n", - rank, worst_rank); + dio->rank, worst_rank); return worst_rank_nbr; } PRINTF("Found worse neighbor with new %d and old %d - NOT add to cache.\n", - rank, worst_rank); + dio->rank, worst_rank); return NULL; } /*---------------------------------------------------------------------------*/ diff --git a/cpu/6502/6502def.h b/cpu/6502/6502def.h index 2da81b02e..c0f5c999a 100644 --- a/cpu/6502/6502def.h +++ b/cpu/6502/6502def.h @@ -74,6 +74,12 @@ typedef unsigned short uip_stats_t; #define LOADER_CONF_ARCH "lib/unload.h" +#ifdef HAVE_LOGSCR +void logscr(const void *msg, unsigned len); +#else +#define logscr(msg, len) write(STDERR_FILENO, msg, len) +#endif + #if MTU_SIZE #define UIP_CONF_BUFFER_SIZE (UIP_LLH_LEN + MTU_SIZE) #else /* MTU_SIZE */ diff --git a/cpu/6502/lib/log.c b/cpu/6502/lib/log.c index 93ed0eeda..a259c06d6 100644 --- a/cpu/6502/lib/log.c +++ b/cpu/6502/lib/log.c @@ -32,7 +32,6 @@ * */ -#include #include #include "net/ip/uip.h" @@ -43,8 +42,8 @@ void uip_log(char *message) { - write(STDERR_FILENO, message, strlen(message)); - write(STDERR_FILENO, "\n", 1); + logscr(message, strlen(message)); + logscr("\n", 1); } #endif /* UIP_LOGGING */ /*-----------------------------------------------------------------------------------*/ @@ -52,9 +51,9 @@ uip_log(char *message) void log_message(const char *part1, const char *part2) { - write(STDERR_FILENO, part1, strlen(part1)); - write(STDERR_FILENO, part2, strlen(part2)); - write(STDERR_FILENO, "\n", 1); + logscr(part1, strlen(part1)); + logscr(part2, strlen(part2)); + logscr("\n", 1); } #endif /* LOG_CONF_ENABLED */ /*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/lib/pfs.h b/cpu/6502/lib/pfs.h index 73102ce55..51fcd7c5b 100644 --- a/cpu/6502/lib/pfs.h +++ b/cpu/6502/lib/pfs.h @@ -29,6 +29,7 @@ * This file is part of the Contiki operating system. * * Author: Oliver Schmidt + * Author: Greg King * */ @@ -37,11 +38,17 @@ #include +struct cfs_dir; +struct cfs_dirent; + int __fastcall__ pfs_open(const char *name, int flags); void __fastcall__ pfs_close(int fd); int __fastcall__ pfs_read(int fd, void *buf, unsigned int len); int __fastcall__ pfs_write(int fd, const void *buf, unsigned int len); off_t __fastcall__ pfs_seek(int fd, off_t offset, int whence); int __fastcall__ pfs_remove(const char *name); +int __fastcall__ pfs_opendir(struct cfs_dir *dirp, const char *name); +void __fastcall__ pfs_closedir(struct cfs_dir *dirp); +int __fastcall__ pfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent); #endif /* PFS_H_ */ diff --git a/cpu/cc2538/dev/cc2538-rf.c b/cpu/cc2538/dev/cc2538-rf.c index 300ab7dee..66ff4694c 100644 --- a/cpu/cc2538/dev/cc2538-rf.c +++ b/cpu/cc2538/dev/cc2538-rf.c @@ -482,7 +482,7 @@ init(void) REG(SYS_CTRL_SCGCRFC) = 1; REG(SYS_CTRL_DCGCRFC) = 1; - REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE; + REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES; /* * Changes from default values diff --git a/cpu/cc2538/dev/cc2538-rf.h b/cpu/cc2538/dev/cc2538-rf.h index 5edb478ba..87fef3a59 100644 --- a/cpu/cc2538/dev/cc2538-rf.h +++ b/cpu/cc2538/dev/cc2538-rf.h @@ -71,7 +71,7 @@ #ifdef CC2538_RF_CONF_CCA_THRES #define CC2538_RF_CCA_THRES CC2538_RF_CONF_CCA_THRES #else -#define CC2538_RF_CCA_THRES CCA_THRES_USER_GUIDE /** User guide recommendation */ +#define CC2538_RF_CCA_THRES CC2538_RF_CCA_THRES_USER_GUIDE #endif /* CC2538_RF_CONF_CCA_THRES */ #ifdef CC2538_RF_CONF_CHANNEL diff --git a/cpu/cc2538/dev/ecc-algorithm.c b/cpu/cc2538/dev/ecc-algorithm.c index 9e389375f..b67f1220c 100644 --- a/cpu/cc2538/dev/ecc-algorithm.c +++ b/cpu/cc2538/dev/ecc-algorithm.c @@ -40,6 +40,7 @@ #include #include +#include #include "dev/ecc-algorithm.h" #include "dev/ecc-driver.h" diff --git a/cpu/cc2538/ieee-addr.c b/cpu/cc2538/ieee-addr.c index f45e4210d..bd9c481a5 100644 --- a/cpu/cc2538/ieee-addr.c +++ b/cpu/cc2538/ieee-addr.c @@ -40,6 +40,7 @@ #include "ieee-addr.h" #include +#include /*---------------------------------------------------------------------------*/ void ieee_addr_cpy_to(uint8_t *dst, uint8_t len) diff --git a/cpu/cc2538/lpm.h b/cpu/cc2538/lpm.h index 60dc46693..d9b9e8758 100644 --- a/cpu/cc2538/lpm.h +++ b/cpu/cc2538/lpm.h @@ -79,6 +79,9 @@ extern rtimer_clock_t lpm_stats[3]; #define LPM_PM2 2 /** @} */ /*---------------------------------------------------------------------------*/ +typedef bool (*lpm_periph_permit_pm1_func_t)(void); + +#if LPM_CONF_ENABLE /** * \brief Initialise the LPM module */ @@ -185,8 +188,6 @@ void lpm_exit(void); * \sa lpm_enter() */ void lpm_set_max_pm(uint8_t pm); -/*---------------------------------------------------------------------------*/ -typedef bool (*lpm_periph_permit_pm1_func_t)(void); /** * \brief Register a peripheral function which will get called by the LPM @@ -207,12 +208,18 @@ typedef bool (*lpm_periph_permit_pm1_func_t)(void); void lpm_register_peripheral(lpm_periph_permit_pm1_func_t permit_pm1_func); /*---------------------------------------------------------------------------*/ /* Disable the entire module if required */ -#if LPM_CONF_ENABLE==0 +#else #define lpm_init() #define lpm_enter() #define lpm_exit() -#define lpm_set_max_pm(...) -#define lpm_register_peripheral(...) +static inline void +lpm_set_max_pm(uint8_t pm) +{ +} +static inline void +lpm_register_peripheral(lpm_periph_permit_pm1_func_t permit_pm1_func) +{ +} #endif #endif /* LPM_H_ */ diff --git a/cpu/cc253x/usb/common/cdc-acm/cdc-acm.c b/cpu/cc253x/usb/common/cdc-acm/cdc-acm.c index 8c2808a13..444d6b0e3 100644 --- a/cpu/cc253x/usb/common/cdc-acm/cdc-acm.c +++ b/cpu/cc253x/usb/common/cdc-acm/cdc-acm.c @@ -4,6 +4,7 @@ #include "usb-core.h" #include +#include #ifdef DEBUG #define PRINTF(...) printf(__VA_ARGS__) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 8fc9541f6..4a974a8ea 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -97,6 +97,8 @@ #define cc26xx_rf_cpe0_isr RFCCPE0IntHandler #define cc26xx_rf_cpe1_isr RFCCPE1IntHandler /*---------------------------------------------------------------------------*/ +typedef ChipType_t chip_type_t; +/*---------------------------------------------------------------------------*/ /* Remember the last Radio Op issued to the radio */ static rfc_radioOp_t *last_radio_op = NULL; /*---------------------------------------------------------------------------*/ @@ -371,7 +373,7 @@ uint8_t rf_core_set_modesel() { uint8_t rv = RF_CORE_CMD_ERROR; - ChipType_t chip_type = ti_lib_chipinfo_get_chip_type(); + chip_type_t chip_type = ti_lib_chipinfo_get_chip_type(); if(chip_type == CHIP_TYPE_CC2650) { HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5; @@ -382,6 +384,9 @@ rf_core_set_modesel() } else if(chip_type == CHIP_TYPE_CC1310) { HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3; rv = RF_CORE_CMD_OK; + } else if(chip_type == CHIP_TYPE_CC1350) { + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5; + rv = RF_CORE_CMD_OK; } return rv; diff --git a/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c index 95fae730c..0fe452999 100644 --- a/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c +++ b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c @@ -47,8 +47,8 @@ /* Base frequency in kHz */ #define RF_CFG_CHAN_CENTER_F0 863125 -/* Channel spacing in kHz */ -#define RF_CFG_CHAN_SPACING 200 +/* Channel spacing in Hz */ +#define RF_CFG_CHAN_SPACING 200000 /* The minimum channel */ #define RF_CFG_MIN_CHANNEL 0 /* The maximum channel */ @@ -57,6 +57,8 @@ #define RF_CFG_MAX_TXPOWER CC1200_CONST_TX_POWER_MAX /* The carrier sense level used for CCA in dBm */ #define RF_CFG_CCA_THRESHOLD (-91) +/* The RSSI offset in dBm */ +#define RF_CFG_RSSI_OFFSET (-81) /*---------------------------------------------------------------------------*/ static const char rf_cfg_descriptor[] = "802.15.4g 863-870MHz MR-FSK mode #1"; /*---------------------------------------------------------------------------*/ @@ -156,11 +158,13 @@ const cc1200_rf_cfg_t cc1200_802154g_863_870_fsk_50kbps = { .register_settings = preferredSettings, .size_of_register_settings = sizeof(preferredSettings), .tx_pkt_lifetime = (RTIMER_SECOND / 20), + .tx_rx_turnaround = (RTIMER_SECOND / 100), .chan_center_freq0 = RF_CFG_CHAN_CENTER_F0, .chan_spacing = RF_CFG_CHAN_SPACING, .min_channel = RF_CFG_MIN_CHANNEL, .max_channel = RF_CFG_MAX_CHANNEL, .max_txpower = RF_CFG_MAX_TXPOWER, .cca_threshold = RF_CFG_CCA_THRESHOLD, + .rssi_offset = RF_CFG_RSSI_OFFSET, }; /*---------------------------------------------------------------------------*/ diff --git a/dev/cc1200/cc1200-868-fsk-1-2kbps.c b/dev/cc1200/cc1200-868-fsk-1-2kbps.c new file mode 100644 index 000000000..7c8d52cb4 --- /dev/null +++ b/dev/cc1200/cc1200-868-fsk-1-2kbps.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#include "cc1200-rf-cfg.h" +#include "cc1200-const.h" + +/* + * This is a setup for the following configuration: + * + * cc1200 at 1.2 kbps, 2-FSK, 12.5 kHz Channel Spacing (868 MHz). + */ + +/* Base frequency in kHz */ +#define RF_CFG_CHAN_CENTER_F0 867787 +/* Channel spacing in Hz */ +#define RF_CFG_CHAN_SPACING 12500 +/* The minimum channel */ +#define RF_CFG_MIN_CHANNEL 0 +/* The maximum channel */ +#define RF_CFG_MAX_CHANNEL 33 +/* The maximum output power in dBm */ +#define RF_CFG_MAX_TXPOWER CC1200_CONST_TX_POWER_MAX +/* The carrier sense level used for CCA in dBm */ +#define RF_CFG_CCA_THRESHOLD (-91) +/* The RSSI offset in dBm */ +#define RF_CFG_RSSI_OFFSET (-99) +/*---------------------------------------------------------------------------*/ +static const char rf_cfg_descriptor[] = "868MHz 2-FSK 1.2 kbps"; +/*---------------------------------------------------------------------------*/ +/* + * Register settings exported from SmartRF Studio using the standard template + * "trxEB RF Settings Performance Line". + */ + +// Modulation format = 2-FSK +// Whitening = false +// Symbol rate = 1.2 +// Deviation = 3.986359 +// Carrier frequency = 867.999878 +// Manchester enable = false +// Bit rate = 1.2 +// RX filter BW = 10.964912 + +static const registerSetting_t preferredSettings[]= +{ + {CC1200_IOCFG2, 0x06}, + {CC1200_DEVIATION_M, 0xD1}, + {CC1200_MODCFG_DEV_E, 0x00}, + {CC1200_DCFILT_CFG, 0x5D}, + {CC1200_PREAMBLE_CFG0, 0x8A}, + {CC1200_IQIC, 0xCB}, + {CC1200_CHAN_BW, 0xA6}, + {CC1200_MDMCFG1, 0x40}, + {CC1200_MDMCFG0, 0x05}, + {CC1200_SYMBOL_RATE2, 0x3F}, + {CC1200_SYMBOL_RATE1, 0x75}, + {CC1200_SYMBOL_RATE0, 0x10}, + {CC1200_AGC_REF, 0x20}, + {CC1200_AGC_CS_THR, 0xEC}, + {CC1200_AGC_CFG1, 0x51}, + {CC1200_AGC_CFG0, 0x87}, + {CC1200_FIFO_CFG, 0x00}, + {CC1200_FS_CFG, 0x12}, + {CC1200_PKT_CFG2, 0x00}, + {CC1200_PKT_CFG0, 0x20}, + {CC1200_PKT_LEN, 0xFF}, + {CC1200_IF_MIX_CFG, 0x1C}, + {CC1200_FREQOFF_CFG, 0x22}, + {CC1200_MDMCFG2, 0x0C}, + {CC1200_FREQ2, 0x56}, + {CC1200_FREQ1, 0xCC}, + {CC1200_FREQ0, 0xCC}, + {CC1200_IF_ADC1, 0xEE}, + {CC1200_IF_ADC0, 0x10}, + {CC1200_FS_DIG1, 0x07}, + {CC1200_FS_DIG0, 0xAF}, + {CC1200_FS_CAL1, 0x40}, + {CC1200_FS_CAL0, 0x0E}, + {CC1200_FS_DIVTWO, 0x03}, + {CC1200_FS_DSM0, 0x33}, + {CC1200_FS_DVC0, 0x17}, + {CC1200_FS_PFD, 0x00}, + {CC1200_FS_PRE, 0x6E}, + {CC1200_FS_REG_DIV_CML, 0x1C}, + {CC1200_FS_SPARE, 0xAC}, + {CC1200_FS_VCO0, 0xB5}, + {CC1200_XOSC5, 0x0E}, + {CC1200_XOSC1, 0x03}, +}; +/*---------------------------------------------------------------------------*/ +/* Global linkage: symbol name must be different in each exported file! */ +const cc1200_rf_cfg_t cc1200_868_fsk_1_2kbps = { + .cfg_descriptor = rf_cfg_descriptor, + .register_settings = preferredSettings, + .size_of_register_settings = sizeof(preferredSettings), + .tx_pkt_lifetime = (2 * RTIMER_SECOND), + .tx_rx_turnaround = (RTIMER_SECOND / 2), + .chan_center_freq0 = RF_CFG_CHAN_CENTER_F0, + .chan_spacing = RF_CFG_CHAN_SPACING, + .min_channel = RF_CFG_MIN_CHANNEL, + .max_channel = RF_CFG_MAX_CHANNEL, + .max_txpower = RF_CFG_MAX_TXPOWER, + .cca_threshold = RF_CFG_CCA_THRESHOLD, + .rssi_offset = RF_CFG_RSSI_OFFSET, +}; +/*---------------------------------------------------------------------------*/ diff --git a/dev/cc1200/cc1200-conf.h b/dev/cc1200/cc1200-conf.h index 9d28922a4..27dc6eb6e 100644 --- a/dev/cc1200/cc1200-conf.h +++ b/dev/cc1200/cc1200-conf.h @@ -121,18 +121,6 @@ #define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps #endif /*---------------------------------------------------------------------------*/ -/* - * The RSSI offset in dBm (int8_t) - * - * Might be hardware dependent, so we make it a configuration parameter. - * This parameter is written to AGC_GAIN_ADJUST.GAIN_ADJUSTMENT - */ -#ifdef CC1200_CONF_RSSI_OFFSET -#define CC1200_RSSI_OFFSET CC1200_CONF_RSSI_OFFSET -#else -#define CC1200_RSSI_OFFSET (-81) -#endif -/*---------------------------------------------------------------------------*/ /* * The frequency offset * diff --git a/dev/cc1200/cc1200-rf-cfg.h b/dev/cc1200/cc1200-rf-cfg.h index c7ba53527..4b206959b 100644 --- a/dev/cc1200/cc1200-rf-cfg.h +++ b/dev/cc1200/cc1200-rf-cfg.h @@ -67,10 +67,12 @@ typedef struct cc1200_rf_cfg { * synch word + phy header, payload + CRC. */ rtimer_clock_t tx_pkt_lifetime; + /* The maximum time it takes to switch from Tx to Rx */ + rtimer_clock_t tx_rx_turnaround; /* Base frequency in kHz */ uint32_t chan_center_freq0; - /* Channel spacing in kHz */ - uint16_t chan_spacing; + /* Channel spacing in Hz */ + uint32_t chan_spacing; /* The minimum channel */ uint8_t min_channel; /* The maximum channel */ @@ -82,6 +84,9 @@ typedef struct cc1200_rf_cfg { * CC1200_CONST_CCA_THRESHOLD_MIN and CC1200_CONST_CCA_THRESHOLD_MAX. */ int8_t cca_threshold; + /* The RSSI offset in dBm. + * -99 when MDMCFG1.DVGA_GAIN=00, -81 when MDMCFG1.DVGA_GAIN=01 */ + int8_t rssi_offset; } cc1200_rf_cfg_t; /*---------------------------------------------------------------------------*/ #endif /* CC1200_RF_CFG_H */ diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c index 013c54ee6..fef495e31 100644 --- a/dev/cc1200/cc1200.c +++ b/dev/cc1200/cc1200.c @@ -40,6 +40,7 @@ #include "net/netstack.h" #include "net/packetbuf.h" #include "net/rime/rimestats.h" +#include "dev/watchdog.h" #include "dev/leds.h" @@ -289,7 +290,9 @@ extern const cc1200_rf_cfg_t CC1200_RF_CFG; do { \ rtimer_clock_t t0; \ t0 = RTIMER_NOW(); \ - while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) {} \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) { \ + watchdog_periodic(); \ + } \ } while(0) /*---------------------------------------------------------------------------*/ #if CC1200_USE_GPIO2 @@ -799,7 +802,7 @@ transmit(unsigned short transmit_len) */ BUSYWAIT_UNTIL_STATE(STATE_RX, - RTIMER_SECOND / 100); + CC1200_RF_CFG.tx_rx_turnaround); ENABLE_GPIO_INTERRUPTS(); @@ -1459,7 +1462,7 @@ configure(void) #endif /* RSSI offset */ - single_write(CC1200_AGC_GAIN_ADJUST, (int8_t)CC1200_RSSI_OFFSET); + single_write(CC1200_AGC_GAIN_ADJUST, (int8_t)CC1200_RF_CFG.rssi_offset); /*************************************************************************** * RF test modes needed during hardware development @@ -2013,7 +2016,7 @@ calculate_freq(uint8_t channel) uint32_t freq; - freq = CC1200_RF_CFG.chan_center_freq0 + channel * CC1200_RF_CFG.chan_spacing; + freq = CC1200_RF_CFG.chan_center_freq0 + (channel * CC1200_RF_CFG.chan_spacing) / 1000 /* /1000 because chan_spacing is in Hz */; freq *= FREQ_MULTIPLIER; freq /= FREQ_DIVIDER; diff --git a/examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c index 691b48e40..afd81cad4 100644 --- a/examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c +++ b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-client.c @@ -176,13 +176,17 @@ set_global_address(void) uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -/* The choice of server address determines its 6LoPAN header compression. - * (Our address will be compressed Mode 3 since it is derived from our link-local address) +/* The choice of server address determines its 6LoWPAN header compression. + * (Our address will be compressed Mode 3 since it is derived from our + * link-local address) * Obviously the choice made here must also be selected in udp-server.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit + * compressed address of aaaa::1111:22ff:fe33:xxxx) * * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. */ diff --git a/examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c index 8e1ee552d..75ba90e71 100644 --- a/examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c +++ b/examples/avr-rss2/ipv6/dc-rpl-coap/coap-server.c @@ -220,13 +220,17 @@ PROCESS_THREAD(coap_server_process, ev, data) PRINTF("CoAP server started\n"); #if UIP_CONF_ROUTER -/* The choice of server address determines its 6LoPAN header compression. +/* The choice of server address determines its 6LoWPAN header compression. * Obviously the choice made here must also be selected in udp-client.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) - * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit + * compressed address of aaaa::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct + * uncompressed addresses. */ #if 0 diff --git a/examples/avr-rss2/ipv6/rpl-udp-report/report.c b/examples/avr-rss2/ipv6/rpl-udp-report/report.c index 7915dff2f..406c494ee 100644 --- a/examples/avr-rss2/ipv6/rpl-udp-report/report.c +++ b/examples/avr-rss2/ipv6/rpl-udp-report/report.c @@ -147,15 +147,19 @@ set_global_address(void) uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -/* The choice of server address determines its 6LoPAN header compression. +/* The choice of server address determines its 6LoWPAN header compression. * (Our address will be compressed Mode 3 since it is derived from our link-local address) * Obviously the choice made here must also be selected in udp-server.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit + * compressed address of aaaa::1111:22ff:fe33:xxxx) * - * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. + * Note the IPCMV6 checksum verification depends on the correct uncompressed + * addresses. */ #if 0 diff --git a/examples/avr-rss2/ipv6/rpl-udp-report/sink.c b/examples/avr-rss2/ipv6/rpl-udp-report/sink.c index cb8421943..babc14703 100644 --- a/examples/avr-rss2/ipv6/rpl-udp-report/sink.c +++ b/examples/avr-rss2/ipv6/rpl-udp-report/sink.c @@ -117,13 +117,17 @@ PROCESS_THREAD(udp_server_process, ev, data) #if UIP_CONF_ROUTER -/* The choice of server address determines its 6LoPAN header compression. +/* The choice of server address determines its 6LoWPAN header compression. * Obviously the choice made here must also be selected in udp-client.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx) - * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit + * compressed address of aaaa::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct + * uncompressed addresses. */ #if 0 diff --git a/examples/ipv6/rpl-udp/udp-client.c b/examples/ipv6/rpl-udp/udp-client.c index e5339fc3d..01f6d5c62 100644 --- a/examples/ipv6/rpl-udp/udp-client.c +++ b/examples/ipv6/rpl-udp/udp-client.c @@ -144,15 +144,20 @@ set_global_address(void) uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -/* The choice of server address determines its 6LoPAN header compression. - * (Our address will be compressed Mode 3 since it is derived from our link-local address) +/* The choice of server address determines its 6LoWPAN header compression. + * (Our address will be compressed Mode 3 since it is derived from our + * link-local address) * Obviously the choice made here must also be selected in udp-server.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx) + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit + * compressed address of fd00::1111:22ff:fe33:xxxx) * - * Note the IPCMV6 checksum verification depends on the correct uncompressed addresses. + * Note the IPCMV6 checksum verification depends on the correct uncompressed + * addresses. */ #if 0 diff --git a/examples/ipv6/rpl-udp/udp-server.c b/examples/ipv6/rpl-udp/udp-server.c index ce87d3b8f..56c5072ec 100644 --- a/examples/ipv6/rpl-udp/udp-server.c +++ b/examples/ipv6/rpl-udp/udp-server.c @@ -111,13 +111,17 @@ PROCESS_THREAD(udp_server_process, ev, data) NBR_TABLE_CONF_MAX_NEIGHBORS, UIP_CONF_MAX_ROUTES); #if UIP_CONF_ROUTER -/* The choice of server address determines its 6LoPAN header compression. +/* The choice of server address determines its 6LoWPAN header compression. * Obviously the choice made here must also be selected in udp-client.c. * - * For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences, - * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it. - * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx) - * Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses. + * For correct Wireshark decoding using a sniffer, add the /64 prefix to the + * 6LowPAN protocol preferences, + * e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and + * then overwrites it. + * (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit + * compressed address of fd00::1111:22ff:fe33:xxxx) + * Note Wireshark's IPCMV6 checksum verification depends on the correct + * uncompressed addresses. */ #if 0 diff --git a/examples/telnet-server/Makefile.c128.defines b/examples/telnet-server/Makefile.c128.defines index 062a12cd7..d8cd8baee 100644 --- a/examples/telnet-server/Makefile.c128.defines +++ b/examples/telnet-server/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_80COL +DEFINES = WITH_LOGGING,WITH_PFS,WITH_80COL diff --git a/examples/wget/wget.c b/examples/wget/wget.c index bdba5b25d..bf1daf141 100644 --- a/examples/wget/wget.c +++ b/examples/wget/wget.c @@ -35,6 +35,10 @@ #include #include +#ifdef __CC65__ +#include +#endif /* __CC65__ */ + #include "contiki-net.h" #include "webclient.h" #include "cfs/cfs.h" @@ -146,8 +150,12 @@ app_quit(void) if(file != -1) { cfs_close(file); } - puts("Press to continue..."); - getchar(); +#ifdef __CC65__ + if(doesclrscrafterexit()) { + puts("Press to continue..."); + getchar(); + } +#endif /* __CC65__ */ process_exit(&wget_process); LOADER_UNLOAD(); } diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index c06984c73..f0d8c6535 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,13 +1,13 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-servo.c +CONTIKI_PROJECT = zoul-demo test-tsl256x test-sht25 test-servo.c CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor CONTIKI_PROJECT += test-zonik test-dht22.c test-ac-dimmer.c -CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c +CONTIKI_TARGET_SOURCEFILES += tsl256x.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c ac-dimmer.c diff --git a/examples/zolertia/zoul/rev-b/Makefile b/examples/zolertia/zoul/rev-b/Makefile new file mode 100644 index 000000000..ddb6bda4b --- /dev/null +++ b/examples/zolertia/zoul/rev-b/Makefile @@ -0,0 +1,14 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + +CONTIKI_PROJECT = test-power-mgmt + +BOARD ?= remote-revb + +# Works in Linux and probably on OSX too (RTCC example) +CFLAGS = -DDATE="\"`date +"%02u %02d %02m %02y %02H %02M %02S"`\"" + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/zolertia/zoul/rev-b/Makefile.target b/examples/zolertia/zoul/rev-b/Makefile.target new file mode 100644 index 000000000..75430a6e4 --- /dev/null +++ b/examples/zolertia/zoul/rev-b/Makefile.target @@ -0,0 +1 @@ +TARGET = zoul diff --git a/examples/zolertia/zoul/rev-b/project-conf.h b/examples/zolertia/zoul/rev-b/project-conf.h new file mode 100644 index 000000000..39e389032 --- /dev/null +++ b/examples/zolertia/zoul/rev-b/project-conf.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, Zolertia + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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 remote-examples + * @{ + * + * \defgroup remote-power-mgmt-revb-test RE-Mote rev.B power management test + * + * Test the RE-Mote revision B power management implementation + * @{ + * + * \file + * Project specific configuration defines for the basic RE-Mote examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** + * @} + * @} + */ diff --git a/examples/zolertia/zoul/rev-b/test-power-mgmt.c b/examples/zolertia/zoul/rev-b/test-power-mgmt.c new file mode 100644 index 000000000..fb83c1e6f --- /dev/null +++ b/examples/zolertia/zoul/rev-b/test-power-mgmt.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 remote-power-mgmt-revb-test + * @{ + * + * Test the RE-Mote's power management features, shutdown mode and battery + * management. + * + * @{ + * + * \author + * Aitor Mejias + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/process.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "lib/list.h" +#include "power-mgmt.h" +#include "rtcc.h" +#include +#include +#include +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +/* RE-Mote revision B, low-power PIC version */ +#define PM_EXPECTED_VERSION 0x20 +/*---------------------------------------------------------------------------*/ +#ifndef DATE +#define DATE "Unknown" +#endif +/*---------------------------------------------------------------------------*/ +#define TEST_LEDS_FAIL leds_off(LEDS_ALL); \ + leds_on(LEDS_RED); \ + PROCESS_EXIT(); +/*---------------------------------------------------------------------------*/ +#define TEST_ALARM_SECOND 15 +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_pm, "RE-Mote rev.B Power Management Test"); +AUTOSTART_PROCESSES(&test_remote_pm); +/*---------------------------------------------------------------------------*/ +static uint8_t rtc_buffer[sizeof(simple_td_map)]; +static simple_td_map *simple_td = (simple_td_map *)rtc_buffer; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_pm, ev, data) +{ + static uint8_t aux; + static uint16_t voltage; + static uint32_t cycles; + static char *next; + + PROCESS_BEGIN(); + + aux = 0; + cycles = 0; + + /* Initialize the power management block and signal the low-power PIC */ + if(pm_enable() != PM_SUCCESS) { + printf("PM: Failed to initialize\n"); + TEST_LEDS_FAIL; + } + + printf("PM: enabled!\n"); + + /* Retrieve the firmware version and check expected */ + if((pm_get_fw_ver(&aux) == PM_ERROR) || + (aux != PM_EXPECTED_VERSION)) { + printf("PM: unexpected version 0x%02X\n", aux); + TEST_LEDS_FAIL; + } + + printf("PM: firmware version 0x%02X OK\n", aux); + + /* Read the battery voltage level */ + if(pm_get_voltage(&voltage) != PM_SUCCESS) { + printf("PM: error retrieving voltage\n"); + TEST_LEDS_FAIL; + } + + printf("PM: Voltage (raw) = %u\n", voltage); + + /* Note: if running the following test while the RE-Mote is powered over USB + * will show the command execution, but it will not put the board in shutdown + * mode. If powering the RE-Mote with an external battery the shutdown mode + * will operate as intended, and the RE-Mote will restart and run the tests + * from the start after waking-up off the shutdown mode. + * + * The first test shows how to use the "soft" shutdown mode, being the low + * power PIC the one counting cycles and restarting the system off shutdown + * mode. + * + * Each restart cycle is tracked by the low-power PIC, we can use this value + * to determine how many times we have entered shutdown mode, thus choosing + * a specific configuration or behaviour. For the next examples we are going + * to trigger a "soft" mode each even number, and "hard" if odd. + */ + + cycles = pm_get_num_cycles(); + printf("PM: cycle number %lu\n", cycles); + + if((cycles % 2) == 0) { + /* Set the timeout */ + if(pm_set_timeout(PM_SOFT_SHTDN_5_7_SEC) != PM_SUCCESS) { + printf("PM: error setting timeout for soft shutdown mode\n"); + TEST_LEDS_FAIL; + } + + printf("PM: Soft shutdown, timeout set to %lu\n", pm_get_timeout()); + + leds_off(LEDS_ALL); + leds_on(LEDS_PURPLE); + + /* Wait just enough to be able to check the LED result */ + etimer_set(&et, CLOCK_SECOND * 3); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Enter soft shut*/ + if(pm_shutdown_now(PM_SOFT_SLEEP_CONFIG) == PM_SUCCESS) { + printf("PM: Good night!\n"); + } else { + printf("PM: error shutting down the system!\n"); + TEST_LEDS_FAIL; + } + + /* Exit and wait the next cycle */ + PROCESS_EXIT(); + } + + /* Configure the RTCC to schedule a "hard" restart of the shutdown mode, + * waking up from a RTCC interrupt to the low-power PIC + */ + printf("PM: System date: %s\n", DATE); + if(strcmp("Unknown", DATE) == 0) { + printf("PM: could not retrieve date from system\n"); + TEST_LEDS_FAIL; + } + + /* Configure RTC and return structure with all parameters */ + rtcc_init(); + + /* Configure the RTC with the current values */ + simple_td->weekdays = (uint8_t)strtol(DATE, &next, 10); + simple_td->day = (uint8_t)strtol(next, &next, 10); + simple_td->months = (uint8_t)strtol(next, &next, 10); + simple_td->years = (uint8_t)strtol(next, &next, 10); + simple_td->hours = (uint8_t)strtol(next, &next, 10); + simple_td->minutes = (uint8_t)strtol(next, &next, 10); + simple_td->seconds = (uint8_t)strtol(next, NULL, 10); + + simple_td->miliseconds = 0; + simple_td->mode = RTCC_24H_MODE; + simple_td->century = RTCC_CENTURY_20XX; + + if(rtcc_set_time_date(simple_td) == AB08_ERROR) { + printf("PM: Time and date configuration failed\n"); + TEST_LEDS_FAIL; + } else { + if(rtcc_get_time_date(simple_td) == AB08_ERROR) { + printf("PM: Couldn't read time and date\n"); + TEST_LEDS_FAIL; + } + } + + printf("PM: Configured time: "); + rtcc_print(RTCC_PRINT_DATE_DEC); + + /* Configure the RTCC to trigger an alarm tick */ + printf("\nPM: Setting an alarm to tick in %u seconds\n", TEST_ALARM_SECOND); + if(rtcc_date_increment_seconds(simple_td, TEST_ALARM_SECOND) == AB08_ERROR) { + printf("PM: could not increment the next alarm date\n"); + TEST_LEDS_FAIL; + } + + /* Set the timeout to zero to avoid the PIC being awake while waiting for the + * RTCC system to kick-in + */ + if(pm_set_timeout(0x00) != PM_SUCCESS) { + printf("PM: couldn't clear the shutdown period\n"); + TEST_LEDS_FAIL; + } + + /* We use the RTCC_REPEAT_DAY as we want the RTCC to match the given date */ + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, RTCC_REPEAT_DAY, + RTCC_TRIGGER_INT2) == AB08_ERROR) { + printf("PM: couldn't set the alarm\n"); + TEST_LEDS_FAIL; + } + + printf("PM: Alarm set to match: "); + rtcc_print(RTCC_PRINT_ALARM_DEC); + + leds_off(LEDS_ALL); + leds_on(LEDS_BLUE); + + etimer_set(&et, CLOCK_SECOND * 3); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + if(pm_shutdown_now(PM_HARD_SLEEP_CONFIG) == PM_SUCCESS) { + printf("PM: good night!\n"); + } else { + printf("PM: error shutting down the system!\n"); + TEST_LEDS_FAIL; + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** +* @} +* @} +*/ diff --git a/examples/zolertia/zoul/rtcc/test-rtcc.c b/examples/zolertia/zoul/rtcc/test-rtcc.c index 9b8895c09..b2c7ce937 100644 --- a/examples/zolertia/zoul/rtcc/test-rtcc.c +++ b/examples/zolertia/zoul/rtcc/test-rtcc.c @@ -59,9 +59,14 @@ #define DATE "Unknown" #endif /*---------------------------------------------------------------------------*/ -#define LOOP_PERIOD 60L -#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) -#define TEST_ALARM_SECOND 30 +#define LOOP_PERIOD 60L +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define TEST_ALARM_SECOND 15 +/*---------------------------------------------------------------------------*/ +/* Enable to match a given second number every minute, else it will trigger an + * interrupt every TEST_ALARM_SECOND + */ +#define TEST_ALARM_MATCH_MIN 0 /*---------------------------------------------------------------------------*/ PROCESS(test_remote_rtcc_process, "Test RTC driver process"); AUTOSTART_PROCESSES(&test_remote_rtcc_process); @@ -72,11 +77,34 @@ static simple_td_map *simple_td = (simple_td_map *)rtc_buffer; static struct etimer et; /*---------------------------------------------------------------------------*/ void +configure_new_alarm(void) +{ + if(rtcc_date_increment_seconds(simple_td, TEST_ALARM_SECOND) == AB08_ERROR) { + printf("Fail: could not increment the next alarm date\n"); + return; + } + + /* We use the RTCC_REPEAT_DAY as we want the RTCC to match the given date */ + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, RTCC_REPEAT_DAY, + RTCC_TRIGGER_INT1) == AB08_ERROR) { + printf("Fail: couldn't set the alarm\n"); + return; + } + + printf("Alarm set to match: "); + rtcc_print(RTCC_PRINT_ALARM_DEC); +} +/*---------------------------------------------------------------------------*/ +void rtcc_interrupt_callback(uint8_t value) { printf("A RTCC interrupt just happened! time/date: "); rtcc_print(RTCC_PRINT_DATE_DEC); - leds_toggle(LEDS_PURPLE); + leds_toggle(LEDS_ALL); + +#if !TEST_ALARM_MATCH_MIN + configure_new_alarm(); +#endif } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_remote_rtcc_process, ev, data) @@ -149,9 +177,10 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) printf("Configured time: "); rtcc_print(RTCC_PRINT_DATE_DEC); - /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */ - printf("Setting an alarm to tick every minute matching %u seconds\n", - TEST_ALARM_SECOND); +#if TEST_ALARM_MATCH_MIN + /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND match */ + printf("Setting an alarm to tick every %u seconds match\n", TEST_ALARM_SECOND); + simple_td->seconds = TEST_ALARM_SECOND; /* Notice the arguments, we want to trigger the alarm every time the clock @@ -159,14 +188,18 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) * minute. In case we would want to trigger the alarm on a specific time, * then we would want to set a daily repeat interval */ - if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, - RTCC_REPEAT_MINUTE) == AB08_ERROR) { + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, RTCC_REPEAT_MINUTE, + RTCC_TRIGGER_INT1) == AB08_ERROR) { printf("Fail: couldn't set the alarm\n"); PROCESS_EXIT(); } - printf("Alarm set to match: "); - rtcc_print(RTCC_PRINT_ALARM_DEC); +#else + /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */ + printf("Setting an alarm to tick every %u seconds\n", TEST_ALARM_SECOND); + + configure_new_alarm(); +#endif PROCESS_END(); } diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl256x.c similarity index 78% rename from examples/zolertia/zoul/test-tsl2563.c rename to examples/zolertia/zoul/test-tsl256x.c index b6296b3e5..ed6f72327 100644 --- a/examples/zolertia/zoul/test-tsl2563.c +++ b/examples/zolertia/zoul/test-tsl256x.c @@ -32,13 +32,13 @@ * \addtogroup zoul-examples * @{ * - * \defgroup zoul-tsl2563-test TSL2563 light sensor test + * \defgroup zoul-tsl256x-test TSL256X light sensor test (TSL2561/TSL2563) * - * Demonstrates the use of the TSL2563 digital ambient light sensor + * Demonstrates the use of the TSL256X digital ambient light sensor * @{ * * \file - * Test file for the external TSL2563 light sensor + * Test file for the external TSL256X light sensor * * \author * Antonio Lignan @@ -49,13 +49,13 @@ #include "contiki.h" #include "dev/i2c.h" #include "dev/leds.h" -#include "dev/tsl2563.h" +#include "dev/tsl256x.h" /*---------------------------------------------------------------------------*/ /* Default sensor's integration cycle is 402ms */ #define SENSOR_READ_INTERVAL (CLOCK_SECOND) /*---------------------------------------------------------------------------*/ -PROCESS(remote_tsl2563_process, "TSL2563 test process"); -AUTOSTART_PROCESSES(&remote_tsl2563_process); +PROCESS(remote_tsl256x_process, "TSL256X test process"); +AUTOSTART_PROCESSES(&remote_tsl256x_process); /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ @@ -66,21 +66,31 @@ light_interrupt_callback(uint8_t value) leds_toggle(LEDS_PURPLE); } /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(remote_tsl2563_process, ev, data) +PROCESS_THREAD(remote_tsl256x_process, ev, data) { PROCESS_BEGIN(); static uint16_t light; + /* Print the sensor used, teh default is the TSL2561 (from Grove) */ + if(TSL256X_REF == TSL2561_SENSOR_REF) { + printf("Light sensor test --> TSL2561\n"); + } else if(TSL256X_REF == TSL2563_SENSOR_REF) { + printf("Light sensor test --> TSL2563\n"); + } else { + printf("Unknown light sensor reference, aborting\n"); + PROCESS_EXIT(); + } + /* Use Contiki's sensor macro to enable the sensor */ - SENSORS_ACTIVATE(tsl2563); + SENSORS_ACTIVATE(tsl256x); /* Default integration time is 402ms with 1x gain, use the below call to * change the gain and timming, see tsl2563.h for more options */ - /* tsl2563.configure(TSL2563_TIMMING_CFG, TSL2563_G16X_402MS); */ + /* tsl256x.configure(TSL256X_TIMMING_CFG, TSL256X_G16X_402MS); */ /* Register the interrupt handler */ - TSL2563_REGISTER_INT(light_interrupt_callback); + TSL256X_REGISTER_INT(light_interrupt_callback); /* Enable the interrupt source for values over the threshold. The sensor * compares against the value of CH0, one way to find out the required @@ -89,18 +99,18 @@ PROCESS_THREAD(remote_tsl2563_process, ev, data) * calculations done in the calculate_lux() function. The below value roughly * represents a 2500 lux threshold, same as pointing a flashlight directly */ - tsl2563.configure(TSL2563_INT_OVER, 0x15B8); + tsl256x.configure(TSL256X_INT_OVER, 0x15B8); /* And periodically poll the sensor */ while(1) { etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - light = tsl2563.value(TSL2563_VAL_READ); - if(light != TSL2563_ERROR) { + light = tsl256x.value(TSL256X_VAL_READ); + if(light != TSL256X_ERROR) { printf("Light = %u\n", (uint16_t)light); } else { - printf("Error, enable the DEBUG flag in the tsl2563 driver for info, "); + printf("Error, enable the DEBUG flag in the tsl256x driver for info, "); printf("or check if the sensor is properly connected\n"); PROCESS_EXIT(); } diff --git a/platform/apple2enh/lib/error.c b/platform/apple2enh/lib/error.c index b030d5877..39f3b0d7b 100644 --- a/platform/apple2enh/lib/error.c +++ b/platform/apple2enh/lib/error.c @@ -33,6 +33,7 @@ */ #include +#include #include "sys/log.h" @@ -43,8 +44,10 @@ void error_exit(void) { #if LOG_CONF_ENABLED - log_message("Press any key to continue ...", ""); - ctk_arch_getkey(); + if(doesclrscrafterexit()) { + log_message("Press any key to continue ...", ""); + ctk_arch_getkey(); + } #endif /* LOG_CONF_ENABLED */ exit(EXIT_FAILURE); } diff --git a/platform/atarixl/lib/error.c b/platform/atarixl/lib/error.c index b030d5877..39f3b0d7b 100644 --- a/platform/atarixl/lib/error.c +++ b/platform/atarixl/lib/error.c @@ -33,6 +33,7 @@ */ #include +#include #include "sys/log.h" @@ -43,8 +44,10 @@ void error_exit(void) { #if LOG_CONF_ENABLED - log_message("Press any key to continue ...", ""); - ctk_arch_getkey(); + if(doesclrscrafterexit()) { + log_message("Press any key to continue ...", ""); + ctk_arch_getkey(); + } #endif /* LOG_CONF_ENABLED */ exit(EXIT_FAILURE); } diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128 index 0c674ee38..c1adbaf08 100644 --- a/platform/c128/Makefile.c128 +++ b/platform/c128/Makefile.c128 @@ -31,7 +31,8 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c logscr.S lseek.c \ + pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c128/contiki-conf.h b/platform/c128/contiki-conf.h index 057d6473d..9ee7cc2b7 100644 --- a/platform/c128/contiki-conf.h +++ b/platform/c128/contiki-conf.h @@ -35,8 +35,16 @@ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ +#define HAVE_LOGSCR + #include "6502def.h" +#if (WITH_PFS && !CFS_IMPL) +#define cfs_opendir pfs_opendir +#define cfs_closedir pfs_closedir +#define cfs_readdir pfs_readdir +#endif + #define CTK_CONF_MENU_KEY CH_F1 #define CTK_CONF_WINDOWSWITCH_KEY CH_F3 #define CTK_CONF_WIDGETUP_KEY CH_F5 diff --git a/platform/c128/lib/logscr.S b/platform/c128/lib/logscr.S new file mode 100644 index 000000000..e87e2aa17 --- /dev/null +++ b/platform/c128/lib/logscr.S @@ -0,0 +1,5 @@ +; 2016-04-28, Greg King +; +; The C128 function is the same as the C64 function. + + .include "../../c64/lib/logscr.S" diff --git a/platform/c128/lib/pfs-dir-asm.S b/platform/c128/lib/pfs-dir-asm.S new file mode 100644 index 000000000..dbc1c956f --- /dev/null +++ b/platform/c128/lib/pfs-dir-asm.S @@ -0,0 +1,114 @@ +; +; Helper functions for pfs_opendir() and pfs_readdir() +; +; Close a directory listing that had been openned by pfs_opendir(). +; +; 2012-06-01, Ullrich von Bassewitz +; 2016-04-10, Greg King +; + + .importzp sp, ptr1, tmp1 + .import pushax, _pfs_read, _pfs_close + .export __pfs_dirread1, __pfs_dirread + + .export _pfs_closedir + +;--------------------------------------------------------------------------- +; Data structure + +.struct DIR + fd .word +.endstruct + +;--------------------------------------------------------------------------- +; /* Read one byte from the directory into the supplied buffer. +; ** Return true if the read was successful, and false otherwise. +; */ +; unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf); + +__pfs_dirread1: + jsr pushax ; Push buf + lda #1 ; Load count = 1 + +; Run directly into __dirread + +;--------------------------------------------------------------------------- +; /* Read characters from the directory into the supplied buffer. +; ** Return true if the read was successful, and false otherwise. +; */ +; unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf, + +__pfs_dirread: + pha ; Save count + +; Replace dir by ((DIR*)dir)->fd. + + ldy #$02 + lda (sp),y + sta ptr1 + iny + lda (sp),y + sta ptr1+1 + ldy #DIR::fd+1 + lda (ptr1),y + pha + dey + lda (ptr1),y + ldy #$02 + sta (sp),y + pla + iny + sta (sp),y + +; Get count, save it again, clear the high byte, and call pfs_read(). +; By the previous actions, the stack frame is as pfs_read() needs it; +; and, pfs_read() also will drop it. + + pla + pha + ldx #>$0000 + jsr _pfs_read + +; Check for errors. + + cpx #>-1 + beq L3 + +; pfs_read() was successful; check number of bytes read. We assume that +; pfs_read() will not return more than count; so, .X is zero if we come here. + + sta tmp1 ; Save returned count + pla ; Our count + cmp tmp1 + beq L2 ; OK, return count + +; Didn't read enough bytes. That is an error for us. + + bne L1 ; Branch always + +; pfs_read() returned an error. + +L3: pla ; Drop count + inx ; .X = 0 +L1: txa ; Return zero +L2: rts + +;--------------------------------------------------------------------------- +; void __fastcall__ pfs_closedir(struct cfs_dir *dirp); + +.proc _pfs_closedir + sta ptr1 + stx ptr1+1 + +; Load ((DIR *)dirp)->fd. + + ldy #DIR::fd+1 + lda (ptr1),y + tax + dey + lda (ptr1),y + +; Close the directory file. + + jmp _pfs_close +.endproc diff --git a/platform/c128/lib/pfs-dir.c b/platform/c128/lib/pfs-dir.c new file mode 100644 index 000000000..2b9d959f9 --- /dev/null +++ b/platform/c128/lib/pfs-dir.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016, Greg King + * + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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 a part of the Contiki operating system. + */ + +/* +** Open a directory listing, so that it can be read by pfs_readdir(). +** +** Read one file-name from a directory listing that was opened by pfs_opendir(). +** +** 2012-05-30, Ullrich von Bassewitz +** 2016-04-22, Greg King +*/ + +#include "cfs.h" + +typedef struct { + int fd; /* File descriptor for a directory */ +} DIR; + +/*---------------------------------------------------------------------------*/ +/* +** Read characters from the directory into the supplied buffer. +** Return true if the read was successful, and false otherwise. +*/ +extern unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf, + unsigned char count); + +/* +** Read one byte from the directory into the supplied buffer. +** Return true if the read was successful, and false otherwise. +*/ +extern unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf); +/*---------------------------------------------------------------------------*/ +int __fastcall__ +pfs_opendir(struct cfs_dir *dirp, register const char *name) +{ + static int fd; + static char buf[2 + 1] = "$"; + + /* Set up the actual file name that is sent to the DOS. + ** We accept "0:", "1:", "/", and "." as directory names. + */ + if(name == NULL || name[0] == '\0' || (name[0] == '.' || name[0] == '/') && name[1] == '\0') { + buf[1] = '\0'; + } else if((name[0] == '0' || name[0] == '1') && name[1] == ':' && name[2] == '\0') { + buf[1] = name[0]; + buf[2] = '\0'; + } else { + return -1; + } + + /* Open the directory on a disk, for reading. */ + fd = pfs_open(buf, CFS_READ); + if(fd >= 0) { + ((DIR *)dirp)->fd = fd; + + /* Skip the load address. */ + if(_pfs_dirread(dirp, buf + 1, 2)) { + return 0; + } else { + pfs_close(fd); + } + } + + return -1; +} +/*---------------------------------------------------------------------------*/ +int __fastcall__ +pfs_readdir(struct cfs_dir *dirp, register struct cfs_dirent *dirent) +{ + register unsigned char *b; + register unsigned char i; + register unsigned char count; + unsigned char buffer[0x40]; + static unsigned char s; + static unsigned char j; + + /* Skip the BASIC line-link. */ + if(!_pfs_dirread(dirp, buffer, 2)) { + return -1; + } + + /* Read the number of blocks. It's a two-byte number; but, the size is + ** a four-byte number. Zero the size; then, put the block number in + ** the first two bytes. It works because the 6502 CPU's numbers are + ** little-endian. + */ + dirent->size = 0; + if(!_pfs_dirread(dirp, &dirent->size, 2)) { + return -1; + } + + /* Read the next file entry into a buffer. */ + for(count = 0, b = buffer; count < sizeof(buffer); ++b) { + if(!_pfs_dirread1(dirp, b)) { + return -1; + } + ++count; + if(*b == '\0') { + break; + } + } + + /* The end of the directory was reached if the buffer contains "blocks free." + ** It is sufficient here to check for the leading 'b'. The buffer will have + ** at least one byte if we come here. + */ + if(buffer[0] == 'b') { + return -1; + } + + /* Parse the buffer for the file-name. */ + b = buffer; + j = 0; + s = 0; + i = 0; + while(i < count) { + switch(s) { + case 0: + /* Search for the start of the file-name. */ + if(*b == '"') { + s = 1; + } + break; + case 1: + /* Within the file-name. */ + if(*b == '"') { + /* The end of the file-name was found. */ + dirent->name[j] = '\0'; + return 0; + } else if(j < sizeof(dirent->name) - 1) { + dirent->name[j] = *b; + ++j; + } + break; + } + ++b; + ++i; + } + + /* The file-name is too long for the buffer. Return what could be read. */ + dirent->name[j] = '\0'; + return 0; +} diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S index 7947b67d8..b835f613e 100644 --- a/platform/c128/lib/pfs.S +++ b/platform/c128/lib/pfs.S @@ -36,7 +36,7 @@ .constructor init_pfs .destructor done_pfs - .importzp sp, ptr1, ptr2, ptr3 + .importzp sp, ptr1, ptr2, ptr3, tmp1 .import curunit, __filetype, popax, addysp, subysp .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend .if F_IDE64 @@ -46,6 +46,7 @@ .export pfs_makename, pfs_scratch .export _pfs_open, _pfs_read, _pfs_close + ;--------------------------------------------------------------------- MAXLEN = 80 ;maximum filename length @@ -107,7 +108,14 @@ _pfs_open: lda FNL beq error ;must have a filename - lda #2 - 1 ;file number + ; A directory listing needs a special secondary address + ldy tmp1 + bne open1 ;branch if not directory + lda #2 - 1 + dey ;.Y = 0 - 1 + bne open2 ;branch always + +open1: lda #2 - 1 ;file number tay ;secondary address open2: sta ptr2 sty ptr2 + 1 @@ -118,10 +126,6 @@ next: inc ptr2 ;next file number bcs error ;no more files lda flags - 1,x bne next ;already used - lda ptr2 + 1 - bne nextsa - inx - stx ptr2 + 1 nextsa: inc ptr2 + 1 ;next channel retr: lda ptr2 ;file number ldx curunit @@ -209,7 +213,7 @@ pfs_makename: ; Validate the name; and, find its length ldy #<-1 - sty ptr3 + sty ptr3 ;init. the count of retries sty ptr1 @L10: iny cpy #MAXLEN @@ -227,9 +231,17 @@ pfs_makename: bne @L10 cpy #0 beq badchr ;no name + sty FNL ;save original length tay ;zero index reg. - lda #'0' ;drive 0 or current partition + lda (FN),y + sta tmp1 ;preset not-directory flag to true + cmp #'$' + bne @L9 + sty tmp1 ;set not-directory flag to false + rts + +@L9: lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 diff --git a/platform/c64/Makefile.c64 b/platform/c64/Makefile.c64 index f78dcf717..7fcb4d19f 100644 --- a/platform/c64/Makefile.c64 +++ b/platform/c64/Makefile.c64 @@ -31,7 +31,8 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += exec.c lseek.c pfs.S pfs_remove.S pfs_seek.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += exec.c logscr.S lseek.c \ + pfs.S pfs-dir.c pfs-dir-asm.S pfs_remove.S pfs_seek.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h index 7d5a8d070..21ea459bd 100644 --- a/platform/c64/contiki-conf.h +++ b/platform/c64/contiki-conf.h @@ -35,8 +35,16 @@ #ifndef CONTIKI_CONF_H_ #define CONTIKI_CONF_H_ +#define HAVE_LOGSCR + #include "6502def.h" +#if (WITH_PFS && !CFS_IMPL) +#define cfs_opendir pfs_opendir +#define cfs_closedir pfs_closedir +#define cfs_readdir pfs_readdir +#endif + #define CTK_CONF_MENU_KEY CH_F1 #define CTK_CONF_WINDOWSWITCH_KEY CH_F3 #define CTK_CONF_WIDGETUP_KEY CH_F5 diff --git a/platform/c64/lib/logscr.S b/platform/c64/lib/logscr.S new file mode 100644 index 000000000..e9f297be7 --- /dev/null +++ b/platform/c64/lib/logscr.S @@ -0,0 +1,38 @@ +; 2002-11-16, Ullrich von Bassewitz +; 2016-04-28, Greg King +; +; void logscr(const void *msg, unsigned len); + + .export _logscr + + .import BSOUT + .import popax + .importzp ptr1, ptr2 + +;-------------------------------------------------------------------------- + +.proc _logscr + eor #$FF + sta ptr2 + txa + eor #$FF + sta ptr2+1 ; remember -count-1 + + jsr popax ; get buf + sta ptr1 + stx ptr1+1 + +L1: inc ptr2 ; count the char that will be printed + bne L2 + inc ptr2+1 + beq L9 +L2: ldy #$00 + lda (ptr1),y + jsr BSOUT + inc ptr1 + bne L1 + inc ptr1+1 + bne L1 ; branch always + +L9: rts +.endproc diff --git a/platform/c64/lib/pfs-dir-asm.S b/platform/c64/lib/pfs-dir-asm.S new file mode 100644 index 000000000..dbc1c956f --- /dev/null +++ b/platform/c64/lib/pfs-dir-asm.S @@ -0,0 +1,114 @@ +; +; Helper functions for pfs_opendir() and pfs_readdir() +; +; Close a directory listing that had been openned by pfs_opendir(). +; +; 2012-06-01, Ullrich von Bassewitz +; 2016-04-10, Greg King +; + + .importzp sp, ptr1, tmp1 + .import pushax, _pfs_read, _pfs_close + .export __pfs_dirread1, __pfs_dirread + + .export _pfs_closedir + +;--------------------------------------------------------------------------- +; Data structure + +.struct DIR + fd .word +.endstruct + +;--------------------------------------------------------------------------- +; /* Read one byte from the directory into the supplied buffer. +; ** Return true if the read was successful, and false otherwise. +; */ +; unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf); + +__pfs_dirread1: + jsr pushax ; Push buf + lda #1 ; Load count = 1 + +; Run directly into __dirread + +;--------------------------------------------------------------------------- +; /* Read characters from the directory into the supplied buffer. +; ** Return true if the read was successful, and false otherwise. +; */ +; unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf, + +__pfs_dirread: + pha ; Save count + +; Replace dir by ((DIR*)dir)->fd. + + ldy #$02 + lda (sp),y + sta ptr1 + iny + lda (sp),y + sta ptr1+1 + ldy #DIR::fd+1 + lda (ptr1),y + pha + dey + lda (ptr1),y + ldy #$02 + sta (sp),y + pla + iny + sta (sp),y + +; Get count, save it again, clear the high byte, and call pfs_read(). +; By the previous actions, the stack frame is as pfs_read() needs it; +; and, pfs_read() also will drop it. + + pla + pha + ldx #>$0000 + jsr _pfs_read + +; Check for errors. + + cpx #>-1 + beq L3 + +; pfs_read() was successful; check number of bytes read. We assume that +; pfs_read() will not return more than count; so, .X is zero if we come here. + + sta tmp1 ; Save returned count + pla ; Our count + cmp tmp1 + beq L2 ; OK, return count + +; Didn't read enough bytes. That is an error for us. + + bne L1 ; Branch always + +; pfs_read() returned an error. + +L3: pla ; Drop count + inx ; .X = 0 +L1: txa ; Return zero +L2: rts + +;--------------------------------------------------------------------------- +; void __fastcall__ pfs_closedir(struct cfs_dir *dirp); + +.proc _pfs_closedir + sta ptr1 + stx ptr1+1 + +; Load ((DIR *)dirp)->fd. + + ldy #DIR::fd+1 + lda (ptr1),y + tax + dey + lda (ptr1),y + +; Close the directory file. + + jmp _pfs_close +.endproc diff --git a/platform/c64/lib/pfs-dir.c b/platform/c64/lib/pfs-dir.c new file mode 100644 index 000000000..2b9d959f9 --- /dev/null +++ b/platform/c64/lib/pfs-dir.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016, Greg King + * + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 AUTHOR 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 a part of the Contiki operating system. + */ + +/* +** Open a directory listing, so that it can be read by pfs_readdir(). +** +** Read one file-name from a directory listing that was opened by pfs_opendir(). +** +** 2012-05-30, Ullrich von Bassewitz +** 2016-04-22, Greg King +*/ + +#include "cfs.h" + +typedef struct { + int fd; /* File descriptor for a directory */ +} DIR; + +/*---------------------------------------------------------------------------*/ +/* +** Read characters from the directory into the supplied buffer. +** Return true if the read was successful, and false otherwise. +*/ +extern unsigned char __fastcall__ _pfs_dirread(struct cfs_dir *dir, void *buf, + unsigned char count); + +/* +** Read one byte from the directory into the supplied buffer. +** Return true if the read was successful, and false otherwise. +*/ +extern unsigned char __fastcall__ _pfs_dirread1(struct cfs_dir *dir, void *buf); +/*---------------------------------------------------------------------------*/ +int __fastcall__ +pfs_opendir(struct cfs_dir *dirp, register const char *name) +{ + static int fd; + static char buf[2 + 1] = "$"; + + /* Set up the actual file name that is sent to the DOS. + ** We accept "0:", "1:", "/", and "." as directory names. + */ + if(name == NULL || name[0] == '\0' || (name[0] == '.' || name[0] == '/') && name[1] == '\0') { + buf[1] = '\0'; + } else if((name[0] == '0' || name[0] == '1') && name[1] == ':' && name[2] == '\0') { + buf[1] = name[0]; + buf[2] = '\0'; + } else { + return -1; + } + + /* Open the directory on a disk, for reading. */ + fd = pfs_open(buf, CFS_READ); + if(fd >= 0) { + ((DIR *)dirp)->fd = fd; + + /* Skip the load address. */ + if(_pfs_dirread(dirp, buf + 1, 2)) { + return 0; + } else { + pfs_close(fd); + } + } + + return -1; +} +/*---------------------------------------------------------------------------*/ +int __fastcall__ +pfs_readdir(struct cfs_dir *dirp, register struct cfs_dirent *dirent) +{ + register unsigned char *b; + register unsigned char i; + register unsigned char count; + unsigned char buffer[0x40]; + static unsigned char s; + static unsigned char j; + + /* Skip the BASIC line-link. */ + if(!_pfs_dirread(dirp, buffer, 2)) { + return -1; + } + + /* Read the number of blocks. It's a two-byte number; but, the size is + ** a four-byte number. Zero the size; then, put the block number in + ** the first two bytes. It works because the 6502 CPU's numbers are + ** little-endian. + */ + dirent->size = 0; + if(!_pfs_dirread(dirp, &dirent->size, 2)) { + return -1; + } + + /* Read the next file entry into a buffer. */ + for(count = 0, b = buffer; count < sizeof(buffer); ++b) { + if(!_pfs_dirread1(dirp, b)) { + return -1; + } + ++count; + if(*b == '\0') { + break; + } + } + + /* The end of the directory was reached if the buffer contains "blocks free." + ** It is sufficient here to check for the leading 'b'. The buffer will have + ** at least one byte if we come here. + */ + if(buffer[0] == 'b') { + return -1; + } + + /* Parse the buffer for the file-name. */ + b = buffer; + j = 0; + s = 0; + i = 0; + while(i < count) { + switch(s) { + case 0: + /* Search for the start of the file-name. */ + if(*b == '"') { + s = 1; + } + break; + case 1: + /* Within the file-name. */ + if(*b == '"') { + /* The end of the file-name was found. */ + dirent->name[j] = '\0'; + return 0; + } else if(j < sizeof(dirent->name) - 1) { + dirent->name[j] = *b; + ++j; + } + break; + } + ++b; + ++i; + } + + /* The file-name is too long for the buffer. Return what could be read. */ + dirent->name[j] = '\0'; + return 0; +} diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S index 49ef496ec..eae0838d4 100644 --- a/platform/c64/lib/pfs.S +++ b/platform/c64/lib/pfs.S @@ -36,7 +36,7 @@ .constructor init_pfs .destructor done_pfs - .importzp sp, ptr1, ptr2, ptr3 + .importzp sp, ptr1, ptr2, ptr3, tmp1 .import curunit, __filetype, popax, addysp, subysp .export pfs_rwcommon, pfs_rwsetflags, pfs_rwcommonend .if F_IDE64 @@ -46,6 +46,7 @@ .export pfs_makename, pfs_scratch .export _pfs_open, _pfs_read, _pfs_close + ;--------------------------------------------------------------------- MAXLEN = 80 ;maximum filename length @@ -107,7 +108,14 @@ _pfs_open: lda FNL beq error ;must have a filename - lda #2 - 1 ;file number + ; A directory listing needs a special secondary address + ldy tmp1 + bne open1 ;branch if not directory + lda #2 - 1 + dey ;.Y = 0 - 1 + bne open2 ;branch always + +open1: lda #2 - 1 ;file number tay ;secondary address open2: sta ptr2 sty ptr2 + 1 @@ -118,10 +126,6 @@ next: inc ptr2 ;next file number bcs error ;no more files lda flags - 1,x bne next ;already used - lda ptr2 + 1 - bne nextsa - inx - stx ptr2 + 1 nextsa: inc ptr2 + 1 ;next channel retr: lda ptr2 ;file number ldx curunit @@ -209,7 +213,7 @@ pfs_makename: ; Validate the name; and, find its length ldy #<-1 - sty ptr3 + sty ptr3 ;init. the count of retries sty ptr1 @L10: iny cpy #MAXLEN @@ -227,9 +231,17 @@ pfs_makename: bne @L10 cpy #0 beq badchr ;no name + sty FNL ;save original length tay ;zero index reg. - lda #'0' ;drive 0 or current partition + lda (FN),y + sta tmp1 ;preset not-directory flag to true + cmp #'$' + bne @L9 + sty tmp1 ;set not-directory flag to false + rts + +@L9: lda #'0' ;drive 0 or current partition sta (sp),y iny inc ptr1 diff --git a/platform/galileo/drivers/galileo-gen2-pinmux.c b/platform/galileo/drivers/galileo-gen2-pinmux.c index f4ea5be30..37d37cb3e 100644 --- a/platform/galileo/drivers/galileo-gen2-pinmux.c +++ b/platform/galileo/drivers/galileo-gen2-pinmux.c @@ -576,7 +576,7 @@ int galileo_brd_to_cpu_gpio_pin(unsigned pin, bool *sus) { static const int SUS = 0x100; - unsigned pins[GALILEO_NUM_PINS] = { + unsigned pins[GALILEO_NUM_DIGITAL_PINS] = { 3, 4, 5, 6, SUS | 4, 8, 9, SUS | 0, SUS | 1, SUS | 2, 2, SUS | 3, diff --git a/platform/galileo/net/eth-conf.c b/platform/galileo/net/eth-conf.c index 3afb8f211..f36d6e8aa 100644 --- a/platform/galileo/net/eth-conf.c +++ b/platform/galileo/net/eth-conf.c @@ -44,9 +44,8 @@ const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0 } }; #define HOST_IP SUBNET_IP, 2 #define GATEWAY_IP SUBNET_IP, 1 #define NAMESERVER_IP GATEWAY_IP -#endif - PROCESS(dhcp_process, "DHCP"); +#endif /*---------------------------------------------------------------------------*/ void @@ -74,11 +73,14 @@ eth_init(void) #endif process_start(ð_process, NULL); +#if !NETSTACK_CONF_WITH_IPV6 /* Comment out the following line to disable DHCP and simply use the static * IP configuration setup above. */ process_start(&dhcp_process, NULL); +#endif } +#if !NETSTACK_CONF_WITH_IPV6 /*---------------------------------------------------------------------------*/ PROCESS_THREAD(dhcp_process, ev, data) { @@ -123,3 +125,4 @@ dhcpc_unconfigured(const struct dhcpc_state *s) printf("DHCP unconfigured.\n"); } /*---------------------------------------------------------------------------*/ +#endif diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index 980038593..b95f3e9cd 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -13,7 +13,8 @@ platform supports two different boards: The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx-cc13xx`. The port was developed and tested with CC2650s, but the intention is for it to work with the CC2630 as well. Thus, bug reports are welcome for both chips. -Bear in mind that the CC2630 does not have BLE capability. +Bear in mind that the CC2630 does not have BLE capability. Similar rules apply +in terms of CC13xx chips. This port is only meant to work with 7x7mm chips @@ -186,6 +187,15 @@ the jumper configuration on P408 as discussed in [this thread](https://e2e.ti.com/support/wireless_connectivity/f/158/p/411992/1483824#1483824) on E2E. For this to work, you need to set `BOARD_CONF_DEBUGGER_DEVPACK` to 0. +IEEE vs Sub-GHz operation +========================= +The platform supports both modes of operation, provided the chip also has the +respective capability. If you specify nothing, the platform will default to +Sub-GHz mode for CC13xx devices, IEEE mode otherwise. To force IEEE mode, you +need to add this line to your `project-conf.h`. + + #define CC13XX_CONF_PROP_MODE 0 + Low Power Operation =================== The platform takes advantage of the CC26xx's power saving features. In a diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index 6342bce99..d12224201 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -89,7 +89,18 @@ #define NETSTACK_CONF_FRAMER framer_802154 #endif +/* + * Auto-configure Prop-mode radio if we are running on CC13xx, unless the + * project has specified otherwise. Depending on the final mode, determine a + * default channel (again, if unspecified) and configure RDC params + */ #if CPU_FAMILY_CC13XX +#ifndef CC13XX_CONF_PROP_MODE +#define CC13XX_CONF_PROP_MODE 1 +#endif /* CC13XX_CONF_PROP_MODE */ +#endif /* CPU_FAMILY_CC13XX */ + +#if CC13XX_CONF_PROP_MODE #define NETSTACK_CONF_RADIO prop_mode_driver #ifndef RF_CORE_CONF_CHANNEL diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index 3992ff9e0..0aa1c4526 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -190,6 +190,11 @@ main(void) printf("With DriverLib v%u.%u\n", DRIVERLIB_RELEASE_GROUP, DRIVERLIB_RELEASE_BUILD); printf(BOARD_STRING "\n"); + printf("IEEE 802.15.4: %s, Sub-GHz: %s, BLE: %s, Prop: %s\n", + ti_lib_chipinfo_supports_ieee_802_15_4() == true ? "Yes" : "No", + ti_lib_chipinfo_chip_family_is_cc13xx() == true ? "Yes" : "No", + ti_lib_chipinfo_supports_ble() == true ? "Yes" : "No", + ti_lib_chipinfo_supports_proprietary() == true ? "Yes" : "No"); process_start(&etimer_process, NULL); ctimer_init(); diff --git a/platform/wismote/dev/battery-sensor.c b/platform/wismote/dev/battery-sensor.c index faf53402f..7111256f3 100644 --- a/platform/wismote/dev/battery-sensor.c +++ b/platform/wismote/dev/battery-sensor.c @@ -29,10 +29,10 @@ * * ----------------------------------------------------------------- * - * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne, Sumankumar Panchal * Created : 2005-11-01 - * Updated : $Date: 2010/02/03 20:30:07 $ - * $Revision: 1.10 $ + * Updated : $Date: 2016/09/17 11:30:00 $ + * $Revision: 1.11 $ */ #include "dev/battery-sensor.h" @@ -44,11 +44,18 @@ static uint8_t active; static void activate(void) { + /* Setup ADC12, ref., sampling time */ + ADC12CTL0 = ADC12REF2_5V + ADC12SHT0_6 + ADC12SHT1_6 + ADC12MSC + ADC12REFON; + /* Use sampling timer, repeat-sequence-of-channels */ + ADC12CTL1 = ADC12SHP + ADC12CONSEQ_3 + ADC12CSTARTADD_1; + /* Configure ADC12_2 to sample channel 11 (voltage) and use */ /* the Vref+ as reference (SREF_1) since it is a stable reference */ -// ADC12MCTL2 = (INCH_11 + SREF_1); + ADC12MCTL2 = (ADC12INCH_11 + ADC12SREF_1); -// sky_sensors_activate(0x80); + ADC12CTL0 |= ADC12ON; + ADC12CTL0 |= ADC12ENC; /* enable conversion */ + ADC12CTL0 |= ADC12SC; /* sample & convert */ active = 1; } @@ -56,14 +63,13 @@ activate(void) static void deactivate(void) { -// sky_sensors_deactivate(0x80); active = 0; } /*---------------------------------------------------------------------------*/ static int value(int type) { - return 0;//ADC12MEM2/*battery_value*/; + return ADC12MEM2; /*battery_value*/ } /*---------------------------------------------------------------------------*/ static int @@ -92,4 +98,4 @@ status(int type) } /*---------------------------------------------------------------------------*/ SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, - value, configure, status); + value, configure, status); diff --git a/platform/zoul/dev/rtcc-config.h b/platform/zoul/dev/rtcc-config.h index de39d5ec8..cf5f92135 100644 --- a/platform/zoul/dev/rtcc-config.h +++ b/platform/zoul/dev/rtcc-config.h @@ -99,5 +99,4 @@ static const ab080x_register_config_t ab080x_default_setting[] = /** * @} * @} - */ - + */ \ No newline at end of file diff --git a/platform/zoul/dev/rtcc.c b/platform/zoul/dev/rtcc.c index e27bdc555..30049156f 100644 --- a/platform/zoul/dev/rtcc.c +++ b/platform/zoul/dev/rtcc.c @@ -388,10 +388,17 @@ rtcc_get_time_date(simple_td_map *data) } /*---------------------------------------------------------------------------*/ int8_t -rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) +rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat, + uint8_t trigger) { uint8_t aux[4], buf[RTCC_ALARM_MAP_SIZE]; + if((trigger != RTCC_TRIGGER_INT2) && (trigger != RTCC_TRIGGER_INT1) && + (trigger != RTCC_TRIGGER_BOTH)) { + PRINTF("RTC: invalid trigger pin\n"); + return AB08_ERROR; + } + if(state == RTCC_ALARM_OFF) { if(ab08_read_reg((INT_MASK_ADDR + CONFIG_MAP_OFFSET), &aux[0], 1) == AB08_ERROR) { @@ -505,12 +512,25 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) /* Clear the AIE alarm bit */ aux[INT_MASK_ADDR] &= ~INTMASK_AIE; - /* Configure Interrupt parameters for Alarm Interrupt Mode in nIRQ pin, - * and fixed level until interrupt flag is cleared + /* Configure Interrupt parameters for Alarm Interrupt Mode in nIRQ + * or nAIRQ pins and fixed level until interrupt flag is cleared + * RTC_INT1 is connected to the CC2538 + * RTC_INT2 is connected to the power management PIC in revision B */ + if (trigger == RTCC_TRIGGER_INT2) { + aux[CTRL_2_ADDR] |= CTRL2_OUT2S_NAIRQ_OUTB; + /* Only options left enable the INT1 interrupt pin */ + } else { + GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(RTC_INT1_VECTOR); + } - /* Enable nIRQ if at least one interrupt is enabled */ - aux[CTRL_2_ADDR] |= CTRL2_OUT1S_NIRQ_NAIRQ_OUT; + if (trigger == RTCC_TRIGGER_INT1) { + aux[CTRL_2_ADDR] |= CTRL2_OUT1S_NIRQ_NAIRQ_OUT; + } else if (trigger == RTCC_TRIGGER_BOTH) { + aux[CTRL_2_ADDR] |= (CTRL2_OUT1S_NIRQ_NAIRQ_OUT + CTRL2_OUT2S_NAIRQ_OUTB); + } if(repeat != RTCC_REPEAT_NONE) { aux[INT_MASK_ADDR] &= ~INTMASK_IM_LOW; @@ -523,11 +543,6 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) return AB08_ERROR; } - /* Enable interrupts */ - GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); - ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE); - nvic_interrupt_enable(RTC_INT1_VECTOR); - /* Write to the alarm counters */ if(ab08_write_reg((HUNDREDTHS_ALARM_ADDR + ALARM_MAP_OFFSET), buf, RTCC_ALARM_MAP_SIZE) == AB08_ERROR) { @@ -549,6 +564,75 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) return AB08_SUCCESS; } /*---------------------------------------------------------------------------*/ +int8_t +rtcc_date_increment_seconds(simple_td_map *data, uint16_t seconds) +{ + uint16_t aux; + + if(data == NULL) { + PRINTF("RTC: invalid argument\n"); + return AB08_ERROR; + } + + if(rtcc_get_time_date(data) == AB08_ERROR) { + return AB08_ERROR; + } + + /* Nothing to do here but congratulate the user */ + if(!seconds) { + return AB08_SUCCESS; + } + + aux = data->seconds + seconds; + data->seconds = (uint8_t)(aux % 60); + + /* Add the remainder seconds to the minutes counter */ + if(aux > 59) { + aux /= 60; + aux += data->minutes; + data->minutes = (uint8_t)(aux % 60); + } + + /* Add the remainder minutes to the hours counter */ + if(aux > 59) { + aux /= 60; + aux += data->hours; + data->hours = (uint8_t)(aux % 24); + } + + if(aux > 23) { + aux /= 24; + aux += data->day; + + if(data->months == 2) { + if(check_leap_year(data->years)) { + if(aux > 29) { + data->day = (uint8_t)(aux % 29); + data->months++; + } + } else if(aux > 28) { + data->day = (uint8_t)(aux % 28); + data->months++; + } + } else if((data->months == 4) || (data->months == 6) || + (data->months == 9) || (data->months == 11)) { + if(aux > 30) { + data->day = (uint8_t)(aux % 30); + data->months++; + } + } else if(aux > 31) { + data->day = (uint8_t)(aux % 31); + data->months++; + } + } + + if(data->months > 12) { + data->months = data->months % 12; + data->years++; + } + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ PROCESS(rtcc_int_process, "RTCC interruption process handler"); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(rtcc_int_process, ev, data) diff --git a/platform/zoul/dev/rtcc.h b/platform/zoul/dev/rtcc.h index 4bbcbfe4f..898e9c264 100644 --- a/platform/zoul/dev/rtcc.h +++ b/platform/zoul/dev/rtcc.h @@ -275,6 +275,13 @@ enum { RTCC_AUTOCAL_17_MIN, RTCC_AUTOCAL_9_MIN, }; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_TRIGGER_INT1 = 0, + RTCC_TRIGGER_INT2, + RTCC_TRIGGER_BOTH, +}; + /** @} */ /* -------------------------------------------------------------------------- */ /** \name Readable Date and time memory map implementation @@ -337,12 +344,23 @@ int8_t rtcc_print(uint8_t value); * \param data date and time values (in decimal) to match against * \param state set on/off the alarm interruption * \param repeat set the frequency of the alarm (minute, hourly, daily, etc.) + * \param trigger interrupt trigger (INT1, INT2 or both) * \return * \ AB08_SUCCESS date/time set * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) */ int8_t rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, - uint8_t repeat); + uint8_t repeat, uint8_t trigger); + +/** + * \brief Increments the current date by a number of seconds + * \param data structure to store the date + * \param seconds the numberof seconds to increment the date + * \return + * \ AB08_SUCCESS updated date values + * \ AB08_ERROR failed to return the values + */ +int8_t rtcc_date_increment_seconds(simple_td_map *data, uint16_t seconds); /** * \brief Manually calibrate the RTCC diff --git a/platform/zoul/dev/tsl2563.c b/platform/zoul/dev/tsl256x.c similarity index 55% rename from platform/zoul/dev/tsl2563.c rename to platform/zoul/dev/tsl256x.c index e35698bec..3eceb925d 100644 --- a/platform/zoul/dev/tsl2563.c +++ b/platform/zoul/dev/tsl256x.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup zoul-tsl2563-sensor + * \addtogroup zoul-tsl256x-sensor * @{ * * \file - * Driver for the external TSL2563 light sensor + * Driver for the external TSL256X light sensor * * \author * Antonio Lignan @@ -45,7 +45,7 @@ #include "dev/gpio.h" #include "dev/zoul-sensors.h" #include "lib/sensors.h" -#include "tsl2563.h" +#include "tsl256x.h" /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG @@ -54,14 +54,14 @@ #define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -#define TSL2563_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT) -#define TSL2563_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN) +#define TSL256X_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT) +#define TSL256X_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN) /*---------------------------------------------------------------------------*/ static uint8_t enabled; static uint8_t gain; static uint8_t timming; /*---------------------------------------------------------------------------*/ -void (*tsl2563_int_callback)(uint8_t value); +void (*tsl256x_int_callback)(uint8_t value); /*---------------------------------------------------------------------------*/ static uint16_t calculate_lux(uint8_t *buf) @@ -80,13 +80,13 @@ calculate_lux(uint8_t *buf) buffer[1] = (buf[3] << 8 | (buf[2])); switch(timming) { - case TSL2563_TIMMING_INTEG_402MS: + case TSL256X_TIMMING_INTEG_402MS: chscale = (1 << CH_SCALE); break; - case TSL2563_TIMMING_INTEG_101MS: + case TSL256X_TIMMING_INTEG_101MS: chscale = CHSCALE_TINT1; break; - case TSL2563_TIMMING_INTEG_13_7MS: + case TSL256X_TIMMING_INTEG_13_7MS: chscale = CHSCALE_TINT0; break; } @@ -132,135 +132,135 @@ calculate_lux(uint8_t *buf) } /*---------------------------------------------------------------------------*/ static int -tsl2563_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) +tsl256x_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) { i2c_master_enable(); - if(i2c_single_send(TSL2563_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_single_send(TSL256X_ADDR, reg) == I2C_MASTER_ERR_NONE) { while(i2c_master_busy()); - if(i2c_burst_receive(TSL2563_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { - return TSL2563_SUCCESS; + if(i2c_burst_receive(TSL256X_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { + return TSL256X_SUCCESS; } } - return TSL2563_ERROR; + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ static int -tsl2563_write_reg(uint8_t *buf, uint8_t num) +tsl256x_write_reg(uint8_t *buf, uint8_t num) { if((buf == NULL) || (num <= 0)) { - PRINTF("TSL2563: invalid write values\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: invalid write values\n"); + return TSL256X_ERROR; } i2c_master_enable(); - if(i2c_burst_send(TSL2563_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { - return TSL2563_SUCCESS; + if(i2c_burst_send(TSL256X_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return TSL256X_SUCCESS; } - return TSL2563_ERROR; + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ static int -tsl2563_on(void) +tsl256x_on(void) { uint8_t buf[2]; - buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); - buf[1] = TSL2563_CONTROL_POWER_ON; + buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL); + buf[1] = TSL256X_CONTROL_POWER_ON; - if(tsl2563_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { - if(i2c_single_receive(TSL2563_ADDR, &buf[0]) == I2C_MASTER_ERR_NONE) { - if((buf[0] & 0x0F) == TSL2563_CONTROL_POWER_ON) { - PRINTF("TSL2563: powered on\n"); - return TSL2563_SUCCESS; + if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { + if(i2c_single_receive(TSL256X_ADDR, &buf[0]) == I2C_MASTER_ERR_NONE) { + if((buf[0] & 0x0F) == TSL256X_CONTROL_POWER_ON) { + PRINTF("TSL256X: powered on\n"); + return TSL256X_SUCCESS; } } } - PRINTF("TSL2563: failed to power on\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: failed to power on\n"); + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ static int -tsl2563_id_register(uint8_t *buf) +tsl256x_id_register(uint8_t *buf) { - if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_ID_REG), - buf, 1) == TSL2563_SUCCESS) { - PRINTF("TSL2563: partnum/revnum 0x%02X\n", *buf); - return TSL2563_SUCCESS; + if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_ID_REG), + buf, 1) == TSL256X_SUCCESS) { + PRINTF("TSL256X: partnum/revnum 0x%02X\n", *buf); + return TSL256X_SUCCESS; } - return TSL2563_ERROR; + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ static int -tsl2563_off(void) +tsl256x_off(void) { uint8_t buf[2]; - buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); - buf[1] = TSL2563_CONTROL_POWER_OFF; + buf[0] = (TSL256X_COMMAND + TSL256X_CONTROL); + buf[1] = TSL256X_CONTROL_POWER_OFF; - if(tsl2563_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { - PRINTF("TSL2563: powered off\n"); - return TSL2563_SUCCESS; + if(tsl256x_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { + PRINTF("TSL256X: powered off\n"); + return TSL256X_SUCCESS; } - PRINTF("TSL2563: failed to power off\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: failed to power off\n"); + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ static int -tsl2563_clear_interrupt(void) +tsl256x_clear_interrupt(void) { - uint8_t buf = (TSL2563_COMMAND + TSL2563_CLEAR_INTERRUPT); - if(tsl2563_write_reg(&buf, 1) != I2C_MASTER_ERR_NONE) { - PRINTF("TSL2563: failed to clear the interrupt\n"); - return TSL2563_ERROR; + uint8_t buf = (TSL256X_COMMAND + TSL256X_CLEAR_INTERRUPT); + if(tsl256x_write_reg(&buf, 1) != I2C_MASTER_ERR_NONE) { + PRINTF("TSL256X: failed to clear the interrupt\n"); + return TSL256X_ERROR; } - return TSL2563_SUCCESS; + return TSL256X_SUCCESS; } /*---------------------------------------------------------------------------*/ static int -tsl2563_read_sensor(uint16_t *lux) +tsl256x_read_sensor(uint16_t *lux) { uint8_t buf[4]; /* This is hardcoded to use word write/read operations */ - if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_D0LOW), - &buf[0], 2) == TSL2563_SUCCESS) { - if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_D1LOW), - &buf[2], 2) == TSL2563_SUCCESS) { + if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_D0LOW), + &buf[0], 2) == TSL256X_SUCCESS) { + if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_D1LOW), + &buf[2], 2) == TSL256X_SUCCESS) { - PRINTF("TSL2563: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0], + PRINTF("TSL256X: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0], buf[3], buf[2]); *lux = calculate_lux(buf); - return TSL2563_SUCCESS; + return TSL256X_SUCCESS; } } - PRINTF("TSL2563: failed to read\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: failed to read\n"); + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ -PROCESS(tsl2563_int_process, "TSL2563 interrupt process handler"); +PROCESS(tsl256x_int_process, "TSL256X interrupt process handler"); /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(tsl2563_int_process, ev, data) +PROCESS_THREAD(tsl256x_int_process, ev, data) { PROCESS_EXITHANDLER(); PROCESS_BEGIN(); while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - tsl2563_clear_interrupt(); - tsl2563_int_callback(0); + tsl256x_clear_interrupt(); + tsl256x_int_callback(0); } PROCESS_END(); } /*---------------------------------------------------------------------------*/ static void -tsl2563_interrupt_handler(uint8_t port, uint8_t pin) +tsl256x_interrupt_handler(uint8_t port, uint8_t pin) { /* There's no alert/interruption flag to check, clear the interruption by * writting to the CLEAR bit in the COMMAND register */ - process_poll(&tsl2563_int_process); + process_poll(&tsl256x_int_process); } /*---------------------------------------------------------------------------*/ static int @@ -268,185 +268,185 @@ configure(int type, int value) { uint8_t buf[3]; - if((type != TSL2563_ACTIVE) && (type != TSL2563_INT_OVER) && - (type != TSL2563_INT_BELOW) && (type != TSL2563_INT_DISABLE) && - (type != TSL2563_TIMMING_CFG)) { - PRINTF("TSL2563: invalid start value\n"); - return TSL2563_ERROR; + if((type != TSL256X_ACTIVE) && (type != TSL256X_INT_OVER) && + (type != TSL256X_INT_BELOW) && (type != TSL256X_INT_DISABLE) && + (type != TSL256X_TIMMING_CFG)) { + PRINTF("TSL256X: invalid start value\n"); + return TSL256X_ERROR; } /* As default the power-on values of the sensor are gain 1X, 402ms integration * time (not nominal), with manual control disabled */ - if(type == TSL2563_ACTIVE) { + if(type == TSL256X_ACTIVE) { if(value) { i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); /* Initialize interrupts handlers */ - tsl2563_int_callback = NULL; + tsl256x_int_callback = NULL; /* Power on the sensor and check for the part number */ - if(tsl2563_on() == TSL2563_SUCCESS) { - if(tsl2563_id_register(&buf[0]) == TSL2563_SUCCESS) { - if((buf[0] & TSL2563_ID_PARTNO_MASK) == TSL2563_EXPECTED_PARTNO) { + if(tsl256x_on() == TSL256X_SUCCESS) { + if(tsl256x_id_register(&buf[0]) == TSL256X_SUCCESS) { + if((buf[0] & TSL256X_ID_PARTNO_MASK) == TSL256X_EXPECTED_PARTNO) { /* Read the timming/gain configuration */ - if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_TIMMING), - &buf[0], 1) == TSL2563_SUCCESS) { - gain = buf[0] & TSL2563_TIMMING_GAIN; - timming = buf[0] & TSL2563_TIMMING_INTEG_MASK; - PRINTF("TSL2563: enabled, timming %u gain %u\n", timming, gain); + if(tsl256x_read_reg((TSL256X_COMMAND + TSL256X_TIMMING), + &buf[0], 1) == TSL256X_SUCCESS) { + gain = buf[0] & TSL256X_TIMMING_GAIN; + timming = buf[0] & TSL256X_TIMMING_INTEG_MASK; + PRINTF("TSL256X: enabled, timming %u gain %u\n", timming, gain); /* Restart the over interrupt threshold */ - buf[0] = (TSL2563_COMMAND + TSL2563_THRHIGHLOW); + buf[0] = (TSL256X_COMMAND + TSL256X_THRHIGHLOW); buf[1] = 0xFF; buf[2] = 0xFF; - if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { - PRINTF("TSL2563: failed to clear over interrupt\n"); - return TSL2563_ERROR; + if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) { + PRINTF("TSL256X: failed to clear over interrupt\n"); + return TSL256X_ERROR; } /* Restart the below interrupt threshold */ - buf[0] = (TSL2563_COMMAND + TSL2563_THRLOWLOW); + buf[0] = (TSL256X_COMMAND + TSL256X_THRLOWLOW); buf[1] = 0x00; buf[2] = 0x00; - if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { - PRINTF("TSL2563: failed to clear below interrupt\n"); - return TSL2563_ERROR; + if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) { + PRINTF("TSL256X: failed to clear below interrupt\n"); + return TSL256X_ERROR; } /* Clear any pending interrupt */ - if(tsl2563_clear_interrupt() == TSL2563_SUCCESS) { + if(tsl256x_clear_interrupt() == TSL256X_SUCCESS) { enabled = 1; - return TSL2563_SUCCESS; + return TSL256X_SUCCESS; } } } } } - return TSL2563_ERROR; + return TSL256X_ERROR; } else { - if(tsl2563_off() == TSL2563_SUCCESS) { - PRINTF("TSL2563: stopped\n"); + if(tsl256x_off() == TSL256X_SUCCESS) { + PRINTF("TSL256X: stopped\n"); enabled = 0; - return TSL2563_SUCCESS; + return TSL256X_SUCCESS; } - return TSL2563_ERROR; + return TSL256X_ERROR; } } if(!enabled) { - PRINTF("TSL2563: sensor not started\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: sensor not started\n"); + return TSL256X_ERROR; } - if(type == TSL2563_INT_DISABLE) { + if(type == TSL256X_INT_DISABLE) { /* Ensure the GPIO doesn't generate more interrupts, this may affect others * I2C digital sensors using the bus and sharing this pin, so an user may * comment the line below */ - GPIO_DISABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_DISABLE_INTERRUPT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); /* This also wipes out the persistance value, to be reconfigured when * enabling back the interruption */ - buf[0] = (TSL2563_COMMAND + TSL2563_INTERRUPT); - buf[1] = TSL2563_INTR_DISABLED; + buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT); + buf[1] = TSL256X_INTR_DISABLED; - if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { - PRINTF("TSL2563: failed to disable the interrupt\n"); - return TSL2563_ERROR; + if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) { + PRINTF("TSL256X: failed to disable the interrupt\n"); + return TSL256X_ERROR; } - return TSL2563_SUCCESS; + return TSL256X_SUCCESS; } /* Configure the timming and gain */ - if(type == TSL2563_TIMMING_CFG) { - if((value != TSL2563_G16X_402MS) && (value != TSL2563_G1X_402MS) && - (value != TSL2563_G1X_101MS) && (value != TSL2563_G1X_13_7MS)) { - PRINTF("TSL2563: invalid timming configuration values\n"); - return TSL2563_ERROR; + if(type == TSL256X_TIMMING_CFG) { + if((value != TSL256X_G16X_402MS) && (value != TSL256X_G1X_402MS) && + (value != TSL256X_G1X_101MS) && (value != TSL256X_G1X_13_7MS)) { + PRINTF("TSL256X: invalid timming configuration values\n"); + return TSL256X_ERROR; } - buf[0] = (TSL2563_COMMAND + TSL2563_TIMMING); + buf[0] = (TSL256X_COMMAND + TSL256X_TIMMING); buf[1] = value; - if(tsl2563_write_reg(buf, 2) == TSL2563_SUCCESS) { - if(value == TSL2563_G16X_402MS) { + if(tsl256x_write_reg(buf, 2) == TSL256X_SUCCESS) { + if(value == TSL256X_G16X_402MS) { gain = 1; } switch(value) { - case TSL2563_G16X_402MS: - case TSL2563_G1X_402MS: - timming = TSL2563_TIMMING_INTEG_402MS; + case TSL256X_G16X_402MS: + case TSL256X_G1X_402MS: + timming = TSL256X_TIMMING_INTEG_402MS; break; - case TSL2563_G1X_101MS: - timming = TSL2563_TIMMING_INTEG_101MS; + case TSL256X_G1X_101MS: + timming = TSL256X_TIMMING_INTEG_101MS; break; - case TSL2563_G1X_13_7MS: - timming = TSL2563_TIMMING_INTEG_13_7MS; + case TSL256X_G1X_13_7MS: + timming = TSL256X_TIMMING_INTEG_13_7MS; break; } - PRINTF("TSL2563: new timming %u gain %u\n", timming, gain); - return TSL2563_SUCCESS; + PRINTF("TSL256X: new timming %u gain %u\n", timming, gain); + return TSL256X_SUCCESS; } - PRINTF("TSL2563: failed to configure timming\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: failed to configure timming\n"); + return TSL256X_ERROR; } /* From here we handle the interrupt configuration, it requires the interrupt - * callback handler to have been previously set using the TSL2563_REGISTER_INT + * callback handler to have been previously set using the TSL256X_REGISTER_INT * macro */ buf[1] = ((uint8_t *)&value)[0]; buf[2] = ((uint8_t *)&value)[1]; - if(type == TSL2563_INT_OVER) { - buf[0] = (TSL2563_COMMAND + TSL2563_THRHIGHLOW); - } else if(type == TSL2563_INT_BELOW) { - buf[0] = (TSL2563_COMMAND + TSL2563_THRLOWLOW); + if(type == TSL256X_INT_OVER) { + buf[0] = (TSL256X_COMMAND + TSL256X_THRHIGHLOW); + } else if(type == TSL256X_INT_BELOW) { + buf[0] = (TSL256X_COMMAND + TSL256X_THRLOWLOW); } - if(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { - PRINTF("TSL2563: failed to set interrupt level\n"); - return TSL2563_ERROR; + if(tsl256x_write_reg(buf, 3) != TSL256X_SUCCESS) { + PRINTF("TSL256X: failed to set interrupt level\n"); + return TSL256X_ERROR; } /* Now configure the interruption register (level interrupt, 2 integration * cycles after threshold has been reached (roughly 804ms if timming is 402ms) */ - buf[0] = (TSL2563_COMMAND + TSL2563_INTERRUPT); - buf[1] = (TSL2563_INTR_LEVEL << TSL2563_INTR_SHIFT); - buf[1] += TSL2563_INT_PERSIST_2_CYCLES; + buf[0] = (TSL256X_COMMAND + TSL256X_INTERRUPT); + buf[1] = (TSL256X_INTR_LEVEL << TSL256X_INTR_SHIFT); + buf[1] += TSL256X_INT_PERSIST_2_CYCLES; - if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { - PRINTF("TSL2563: failed to enable interrupt\n"); - return TSL2563_ERROR; + if(tsl256x_write_reg(buf, 2) != TSL256X_SUCCESS) { + PRINTF("TSL256X: failed to enable interrupt\n"); + return TSL256X_ERROR; } /* Configure the interrupts pins */ - GPIO_SOFTWARE_CONTROL(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); - GPIO_SET_INPUT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_SOFTWARE_CONTROL(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); + GPIO_SET_INPUT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); /* Pull-up resistor, detect falling edge */ - GPIO_DETECT_EDGE(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); - GPIO_TRIGGER_SINGLE_EDGE(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); - GPIO_DETECT_FALLING(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); - gpio_register_callback(tsl2563_interrupt_handler, I2C_INT_PORT, I2C_INT_PIN); + GPIO_DETECT_EDGE(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); + GPIO_DETECT_FALLING(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); + gpio_register_callback(tsl256x_interrupt_handler, I2C_INT_PORT, I2C_INT_PIN); /* Spin process until an interrupt is received */ - process_start(&tsl2563_int_process, NULL); + process_start(&tsl256x_int_process, NULL); /* Enable interrupts */ - GPIO_ENABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + GPIO_ENABLE_INTERRUPT(TSL256X_INT_PORT_BASE, TSL256X_INT_PIN_MASK); /* The RE-Mote revision A has this pin shared and with a pull-down resistor, * for other platforms (like the firefly), change to enable pull-up internal @@ -455,8 +455,8 @@ configure(int type, int value) ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); nvic_interrupt_enable(I2C_INT_VECTOR); - PRINTF("TSL2563: Interrupt configured\n"); - return TSL2563_SUCCESS; + PRINTF("TSL256X: Interrupt configured\n"); + return TSL256X_SUCCESS; } /*---------------------------------------------------------------------------*/ static int @@ -476,19 +476,19 @@ value(int type) uint16_t lux; if(!enabled) { - PRINTF("TSL2563: sensor not started\n"); - return TSL2563_ERROR; + PRINTF("TSL256X: sensor not started\n"); + return TSL256X_ERROR; } - if(type == TSL2563_VAL_READ) { - if(tsl2563_read_sensor(&lux) != TSL2563_ERROR) { + if(type == TSL256X_VAL_READ) { + if(tsl256x_read_sensor(&lux) != TSL256X_ERROR) { return lux; } - PRINTF("TSL2563: fail to read\n"); + PRINTF("TSL256X: fail to read\n"); } - return TSL2563_ERROR; + return TSL256X_ERROR; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(tsl2563, TSL2563_SENSOR, value, configure, status); +SENSORS_SENSOR(tsl256x, TSL256X_SENSOR, value, configure, status); /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/zoul/dev/tsl2563.h b/platform/zoul/dev/tsl256x.h similarity index 52% rename from platform/zoul/dev/tsl2563.h rename to platform/zoul/dev/tsl256x.h index f8619140e..b21337f11 100644 --- a/platform/zoul/dev/tsl2563.h +++ b/platform/zoul/dev/tsl256x.h @@ -34,98 +34,125 @@ * \addtogroup zoul-sensors * @{ * - * \defgroup zoul-tsl2563-sensor TSL2563 Sensor + * \defgroup zoul-tsl256x-sensor TSL256X Sensor * - * Driver for the TSL2563 sensor + * Driver for the TSL256X sensor * - * The TSL2563 driver returns the converted light value value in lux + * The TSL256X driver returns the converted light value value in lux * @{ * * \file - * Header file for the external TSL2563 Sensor Driver + * Header file for the external TSL256X Sensor Driver * * \author * Antonio Lignan * Toni Lozano */ /*---------------------------------------------------------------------------*/ -#ifndef TSL2563_H_ -#define TSL2563_H_ +#ifndef TSL256X_H_ +#define TSL256X_H_ #include #include "lib/sensors.h" #include "dev/zoul-sensors.h" #include "i2c.h" /* -------------------------------------------------------------------------- */ /** - * \name TSL2563 digital Light sensor address and registers + * \name TSL256x digital Light sensor specific model information * @{ */ -/* -------------------------------------------------------------------------- */ -#define TSL2563_ADDR 0x39 -/* -------------------------------------------------------------------------- */ -#define TSL2563_CONTROL 0x00 -#define TSL2563_TIMMING 0x01 -#define TSL2563_THRLOWLOW 0x02 -#define TSL2563_THRLOWHIGH 0x03 -#define TSL2563_THRHIGHLOW 0x04 -#define TSL2563_THRHIGHHIGH 0x05 -#define TSL2563_INTERRUPT 0x06 -#define TSL2563_CRC 0x08 -#define TSL2563_ID_REG 0x0A -#define TSL2563_D0LOW 0x0C -#define TSL2563_D0HIGH 0x0D -#define TSL2563_D1LOW 0x0E -#define TSL2563_D1HIGH 0x0F -/* -------------------------------------------------------------------------- */ -/* Uses the word read/write operation protocol */ -#define TSL2563_COMMAND 0xA0 -#define TSL2563_CLEAR_INTERRUPT 0x40 -/* -------------------------------------------------------------------------- */ -#define TSL2563_CONTROL_POWER_ON 0x03 -#define TSL2563_CONTROL_POWER_OFF 0x00 -#define TSL2563_TIMMING_GAIN 0x10 -#define TSL2563_TIMMING_MANUAL 0x08 -#define TSL2563_TIMMING_INTEG_MANUAL 0x03 -#define TSL2563_TIMMING_INTEG_402MS 0x02 -#define TSL2563_TIMMING_INTEG_101MS 0x01 -#define TSL2563_TIMMING_INTEG_13_7MS 0x00 -#define TSL2563_TIMMING_INTEG_MASK 0x03 +/* This driver supports the TSL2563 (Zolertia) and the TSL2561 (Grove) */ +#define TSL2561_SENSOR_REF 0 +#define TSL2563_SENSOR_REF 1 -#define TSL2563_G16X_402MS (TSL2563_TIMMING_INTEG_402MS + TSL2563_TIMMING_GAIN) -#define TSL2563_G1X_402MS TSL2563_TIMMING_INTEG_402MS -#define TSL2563_G1X_101MS TSL2563_TIMMING_INTEG_101MS -#define TSL2563_G1X_13_7MS TSL2563_TIMMING_INTEG_13_7MS - -#define TSL2563_INTR_SHIFT 0x04 -#define TSL2563_INTR_DISABLED 0x00 -#define TSL2563_INTR_LEVEL 0x01 -#define TSL2563_INTR_SMB_ALERT 0x02 -#define TSL2563_INTR_TEST 0x03 - -#define TSL2563_INT_PERSIST_EVERY 0x00 -#define TSL2563_INT_PERSIST_ANY 0x01 -#define TSL2563_INT_PERSIST_2_CYCLES 0x02 -#define TSL2563_INT_PERSIST_3_CYCLES 0x03 -#define TSL2563_INT_PERSIST_4_CYCLES 0x04 -#define TSL2563_INT_PERSIST_5_CYCLES 0x05 -#define TSL2563_INT_PERSIST_6_CYCLES 0x06 -#define TSL2563_INT_PERSIST_7_CYCLES 0x07 -#define TSL2563_INT_PERSIST_8_CYCLES 0x08 -#define TSL2563_INT_PERSIST_9_CYCLES 0x09 -#define TSL2563_INT_PERSIST_10_CYCLES 0x0A -#define TSL2563_INT_PERSIST_11_CYCLES 0x0B -#define TSL2563_INT_PERSIST_12_CYCLES 0x0C -#define TSL2563_INT_PERSIST_13_CYCLES 0x0D -#define TSL2563_INT_PERSIST_14_CYCLES 0x0E -#define TSL2563_INT_PERSIST_15_CYCLES 0x0F - -#define TSL2563_ID_PARTNO_MASK 0xF0 -#define TSL2563_ID_REV_MASK 0x0F +/* The TSL2563 (from Zolertia) has a different part number than the TSL2561 from + * Grove (digital light sensor) + */ #define TSL2563_EXPECTED_PARTNO 0x30 +#define TSL2561_EXPECTED_PARTNO 0x50 + +#ifndef TSL256X_CONF_REF +#define TSL256X_REF TSL2561_SENSOR_REF +#else +#define TSL256X_REF TSL256X_CONF_REF +#endif + +#if TSL256X_CONF_REF == TSL2561_SENSOR +#define TSL256X_ADDR 0x29 +#define TSL256X_EXPECTED_PARTNO TSL2561_EXPECTED_PARTNO +#else +#define TSL256X_ADDR 0x39 +#define TSL256X_EXPECTED_PARTNO TSL2563_EXPECTED_PARTNO +#endif + /** @} */ /* -------------------------------------------------------------------------- */ /** - * \name TSL2563 convertion and calibration values + * \name TSL256X digital Light registers + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define TSL256X_CONTROL 0x00 +#define TSL256X_TIMMING 0x01 +#define TSL256X_THRLOWLOW 0x02 +#define TSL256X_THRLOWHIGH 0x03 +#define TSL256X_THRHIGHLOW 0x04 +#define TSL256X_THRHIGHHIGH 0x05 +#define TSL256X_INTERRUPT 0x06 +#define TSL256X_CRC 0x08 +#define TSL256X_ID_REG 0x0A +#define TSL256X_D0LOW 0x0C +#define TSL256X_D0HIGH 0x0D +#define TSL256X_D1LOW 0x0E +#define TSL256X_D1HIGH 0x0F +/* -------------------------------------------------------------------------- */ +/* Uses the word read/write operation protocol */ +#define TSL256X_COMMAND 0xA0 +#define TSL256X_CLEAR_INTERRUPT 0x40 +/* -------------------------------------------------------------------------- */ +#define TSL256X_CONTROL_POWER_ON 0x03 +#define TSL256X_CONTROL_POWER_OFF 0x00 +#define TSL256X_TIMMING_GAIN 0x10 +#define TSL256X_TIMMING_MANUAL 0x08 +#define TSL256X_TIMMING_INTEG_MANUAL 0x03 +#define TSL256X_TIMMING_INTEG_402MS 0x02 +#define TSL256X_TIMMING_INTEG_101MS 0x01 +#define TSL256X_TIMMING_INTEG_13_7MS 0x00 +#define TSL256X_TIMMING_INTEG_MASK 0x03 + +#define TSL256X_G16X_402MS (TSL256X_TIMMING_INTEG_402MS + TSL256X_TIMMING_GAIN) +#define TSL256X_G1X_402MS TSL256X_TIMMING_INTEG_402MS +#define TSL256X_G1X_101MS TSL256X_TIMMING_INTEG_101MS +#define TSL256X_G1X_13_7MS TSL256X_TIMMING_INTEG_13_7MS + +#define TSL256X_INTR_SHIFT 0x04 +#define TSL256X_INTR_DISABLED 0x00 +#define TSL256X_INTR_LEVEL 0x01 +#define TSL256X_INTR_SMB_ALERT 0x02 +#define TSL256X_INTR_TEST 0x03 + +#define TSL256X_INT_PERSIST_EVERY 0x00 +#define TSL256X_INT_PERSIST_ANY 0x01 +#define TSL256X_INT_PERSIST_2_CYCLES 0x02 +#define TSL256X_INT_PERSIST_3_CYCLES 0x03 +#define TSL256X_INT_PERSIST_4_CYCLES 0x04 +#define TSL256X_INT_PERSIST_5_CYCLES 0x05 +#define TSL256X_INT_PERSIST_6_CYCLES 0x06 +#define TSL256X_INT_PERSIST_7_CYCLES 0x07 +#define TSL256X_INT_PERSIST_8_CYCLES 0x08 +#define TSL256X_INT_PERSIST_9_CYCLES 0x09 +#define TSL256X_INT_PERSIST_10_CYCLES 0x0A +#define TSL256X_INT_PERSIST_11_CYCLES 0x0B +#define TSL256X_INT_PERSIST_12_CYCLES 0x0C +#define TSL256X_INT_PERSIST_13_CYCLES 0x0D +#define TSL256X_INT_PERSIST_14_CYCLES 0x0E +#define TSL256X_INT_PERSIST_15_CYCLES 0x0F + +#define TSL256X_ID_PARTNO_MASK 0xF0 +#define TSL256X_ID_REV_MASK 0x0F +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL256X convertion and calibration values * @{ */ @@ -163,33 +190,33 @@ /** @} */ /* -------------------------------------------------------------------------- */ /** - * \name Callback function to handle the TSL2563 alarm interrupt and macro + * \name Callback function to handle the TSL256X alarm interrupt and macro * @{ */ -#define TSL2563_REGISTER_INT(ptr) tsl2563_int_callback = ptr; -extern void (*tsl2563_int_callback)(uint8_t value); +#define TSL256X_REGISTER_INT(ptr) tsl256x_int_callback = ptr; +extern void (*tsl256x_int_callback)(uint8_t value); /** @} */ /* -------------------------------------------------------------------------- */ /** - * \name TSL2563 return and command values + * \name TSL256X return and command values * @{ */ -#define TSL2563_SUCCESS 0x00 -#define TSL2563_LIGHT 0x01 -#define TSL2563_ERROR -1 +#define TSL256X_SUCCESS 0x00 +#define TSL256X_LIGHT 0x01 +#define TSL256X_ERROR -1 -#define TSL2563_ACTIVE SENSORS_ACTIVE -#define TSL2563_INT_OVER HW_INT_OVER_THRS -#define TSL2563_INT_BELOW HW_INT_BELOW_THRS -#define TSL2563_INT_DISABLE HW_INT_DISABLE -#define TSL2563_TIMMING_CFG (HW_INT_DISABLE + 1) +#define TSL256X_ACTIVE SENSORS_ACTIVE +#define TSL256X_INT_OVER HW_INT_OVER_THRS +#define TSL256X_INT_BELOW HW_INT_BELOW_THRS +#define TSL256X_INT_DISABLE HW_INT_DISABLE +#define TSL256X_TIMMING_CFG (HW_INT_DISABLE + 1) -#define TSL2563_VAL_READ 0x01 +#define TSL256X_VAL_READ 0x01 /** @} */ /* -------------------------------------------------------------------------- */ -#define TSL2563_SENSOR "TSL2563 Light Sensor" +#define TSL256X_SENSOR "TSL256X Light Sensor" /* -------------------------------------------------------------------------- */ -extern const struct sensors_sensor tsl2563; +extern const struct sensors_sensor tsl256x; /* -------------------------------------------------------------------------- */ #endif /* -------------------------------------------------------------------------- */ diff --git a/platform/zoul/firefly-reva/Makefile.firefly-reva b/platform/zoul/firefly-reva/Makefile.firefly-reva new file mode 100644 index 000000000..50cb71997 --- /dev/null +++ b/platform/zoul/firefly-reva/Makefile.firefly-reva @@ -0,0 +1,2 @@ +MOTELIST_ZOLERTIA = firefly +BOARD_SOURCEFILES += board.c leds-arch.c diff --git a/platform/zoul/firefly-reva/README.md b/platform/zoul/firefly-reva/README.md new file mode 100644 index 000000000..bfec06091 --- /dev/null +++ b/platform/zoul/firefly-reva/README.md @@ -0,0 +1,41 @@ +Zolertia Firefly Revision A platform +============================================ + +![Zolertia Firefly Revision A breakout board][firefly-reva] + +The Firefly is a breakout board designed to inspire. + +It exposes the most basic Zoul features, sporting only the most down-to-core features to work with the Zoul, providing the following: + +* ARM Cortex-M3 with 512KB flash and 32KB RAM (16KB retention), 32MHz. +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* On-board printed PCB sub-1GHz antenna and 2.4Ghz ceramic chip antenna. +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Compatible with breadboards and protoboards. +* On-board CP2104/PIC to flash over USB-A connector. +* User and reset buttons. +* RGB LED to allow more than 7 colour combinations. +* Small form factor (68.78 x 25.80mm). + +The Firefly can be seen as the "small brother" of the RE-Mote, with a slick design and a lower cost. + +To work out of the box, the firefly includes a PCB antenna for the Sub-1GHz interface, and a ceramic chip antenna for the 2.4GHz radio interface. Optionally 2 x u.Fl connectors for 2.4GHz and sub-1GHz external antennas can be mounted. + +The firefly can be programmed and debugged over JTAG and USB. The board has a CP2104 USB to serial converter with a PIC, it allows to program the CC2538 without having to manually to put the device in bootloader mode. + +The most prominent changes respect to the previous Firefly release are: + +* On-board ceramic chip 2.4GHz antenna +* Pin-out changes and CC1200 GPIO2 pin is exposed +* RF matching improvements +* Printed PCB USB A connector instead of Micro-USB connector + +Firefly pin-out +============= + +![Firefly Revision A pin-out (front)][firefly-reva-pinout-front] + +[firefly-reva-pinout-front]: ../images/firefly-pinout-front.png "Firefly Revision A pin-out (front)" +[firefly-reva]: ../images/firefly-reva.png "Zolertia Firefly Revision A breakout board" diff --git a/platform/zoul/firefly-reva/board.c b/platform/zoul/firefly-reva/board.c new file mode 100644 index 000000000..f00c82000 --- /dev/null +++ b/platform/zoul/firefly-reva/board.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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 firefly + * @{ + * + * \file + * Board-initialisation for the Zolertia's Firefly platform + * + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include +#include +/*---------------------------------------------------------------------------*/ +static void +configure_unused_pins(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +void +board_init() +{ + configure_unused_pins(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/firefly-reva/board.h b/platform/zoul/firefly-reva/board.h new file mode 100644 index 000000000..2cac08d01 --- /dev/null +++ b/platform/zoul/firefly-reva/board.h @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia + * 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 copyright holder 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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 zoul-platforms + * @{ + * + * \defgroup firefly-reva Firefly platform + * + * The Zolertia Firefly is the most down-to-core development platform, exposing + * the Zoul core functionalities and features, with a slick design to allow a + * flexible and easier user experience. + * + * Defines related to the Firefly platform: a Zoul-based breakout board + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * Firefly platform, Zoul-based + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Connector headers + * + * The Firefly features two 2.54 mm header rows over which exposes the following + * pins (facing up, Zolertia logo above and USB connector below): + * -----------------------------+---+---+-------------------------------------- + * PIN_NAME |JP3|JP2| PIN_NAME + * -----------------------------+---+---+-------------------------------------- + * PB5/CC1200.CS |-01|15-| PD2/SPI1.MISO + * PB2/SPI0.SCLK/CC1200.SCLK |-02|16-| PD0/SPI1.SCLK + * PB1/SPIO0.MOSI/CC1200.MOSI |-03|17-| ADC5/AIN7/PA7 + * PB3/SPIO0.MISO/CC1200.MISO |-04|18-| ADC4/AIN6/PA6 + * PB4/CC1200.GPIO0 |-05|19-| DGND + * PB0/CC1200.GPIO2 |-06|20-| +VDD + * PD1/I2C.INT |-07|21-| ADC1/AIN5/PA5 + * PC2/I2C.SDA |-08|22-| ADC2/AIN4/PA4 + * PC3/I2C.SCL |-09|23-| BUTTON.USER/ADC6/AIN3/PA3 + * DGND |-10|24-| ADC3/AIN2/PA2 + * +VDD |-11|25-| PC0/UART1.TX + * PC6/SPI1.MOSI |-12|26-| PC1/UART1.RX + * USB.D+ |-13|27-| PC4 + * USB.D- |-14|28-| PC5 + * ---------------------------+-+---+---+-+------------------------------------ + */ +/*---------------------------------------------------------------------------*/ +/** \name Firefly LED configuration + * + * LEDs on the Firefly are connected as follows: + * - LED1 (Red) -> PD5 + * - LED2 (Green) -> PD4 + * - LED3 (Blue) -> PD3 + * + * LED1 pin exposed in JP2 connector + * LED2 pin exposed in JP2 connector + * LED3 pin exposed in JP2 connector + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +/* In leds.h the LEDS_BLUE is defined by LED_YELLOW definition */ +#define LEDS_GREEN (1 << 4) /**< LED1 (Green) -> PD4 */ +#define LEDS_BLUE (1 << 3) /**< LED2 (Blue) -> PD3 */ +#define LEDS_RED (1 << 5) /**< LED3 (Red) -> PD5 */ + +#define LEDS_CONF_ALL (LEDS_GREEN | LEDS_BLUE | LEDS_RED) + +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /**< Green + Blue (24) */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /**< Green + Red (48) */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /**< Blue + Red (40) */ +#define LEDS_WHITE LEDS_ALL /**< Green + Blue + Red (56) */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is to be enabled by an external resistor, as it is not mapped + * to a GPIO. + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the Firefly, the UARTs are connected to the following ports/pins: + * + * - UART0: + * - RX: PA0, connected to CP2104 serial-to-usb converter TX pin + * - TX: PA1, connected to CP2104 serial-to-usb converter RX pin + * - UART1: + * - RX: PC1 + * - TX: PC0 + * - CTS: not used, one suggestion however is to use PC4 + * - RTS: not used, one suggestion however is to use PC5 + * + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor. + * UART0 is not exposed anywhere, UART1 pins are exposed over the JP3 connector. + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 1 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 0 +#define UART1_CTS_PORT (-1) /**< GPIO_D_NUM */ +#define UART1_CTS_PIN (-1) /**< 1 */ +#define UART1_RTS_PORT (-1) /**< GPIO_D_NUM */ +#define UART1_RTS_PIN (-1) /**< 0 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. There pins are suggested as they can be changed, but note that only + * pins from PA can be configured as ADC. + * + * - ADC1: up to 3.3V. + * - ADC2: up to 3.3V. + * - ADC3: up to 3.3V. + * - ADC4: up to 3.3V. + * - ADC5: up to 3.3V. + * - ADC6: up to 3.3V, shared with user button. + * + * The internal ADC reference is 1190mV, use either a voltage divider as input, + * or a different voltage reference, like AVDD5 or other externally (AIN7 or + * AIN6). + * + * Warning: if using ADC6 (PA3), you will need to disable the bootloader by + * making FLASH_CCA_CONF_BOOTLDR_BACKDOOR equal to zero + * @{ + */ +#define ADC_SENSORS_PORT GPIO_A_NUM /**< ADC GPIO control port */ + +#ifndef ADC_SENSORS_CONF_ADC1_PIN +#define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5 */ +#else +#if ((ADC_SENSORS_CONF_ADC1_PIN != -1) && (ADC_SENSORS_CONF_ADC1_PIN != 5)) +#error "ADC1 channel should be mapped to PA5 or disabled with -1" +#else +#define ADC_SENSORS_ADC1_PIN ADC_SENSORS_CONF_ADC1_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC2_PIN +#define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4 */ +#else +#if ((ADC_SENSORS_CONF_ADC2_PIN != -1) && (ADC_SENSORS_CONF_ADC2_PIN != 4)) +#error "ADC2 channel should be mapped to PA4 or disabled with -1" +#else +#define ADC_SENSORS_ADC2_PIN ADC_SENSORS_CONF_ADC2_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC3_PIN +#define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2 */ +#else +#if ((ADC_SENSORS_CONF_ADC3_PIN != -1) && (ADC_SENSORS_CONF_ADC3_PIN != 2)) +#error "ADC3 channel should be mapped to PA2 or disabled with -1" +#else +#define ADC_SENSORS_ADC3_PIN ADC_SENSORS_CONF_ADC3_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC4_PIN +#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6 */ +#else +#if ((ADC_SENSORS_CONF_ADC4_PIN != -1) && (ADC_SENSORS_CONF_ADC4_PIN != 6)) +#error "ADC4 channel should be mapped to PA6 or disabled with -1" +#else +#define ADC_SENSORS_ADC4_PIN ADC_SENSORS_CONF_ADC4_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC5_PIN +#define ADC_SENSORS_ADC5_PIN 7 /**< ADC5 to PA7 */ +#else +#if ((ADC_SENSORS_CONF_ADC5_PIN != -1) && (ADC_SENSORS_CONF_ADC5_PIN != 7)) +#error "ADC5 channel should be mapped to PA7 or disabled with -1" +#else +#define ADC_SENSORS_ADC5_PIN ADC_SENSORS_CONF_ADC5_PIN +#endif +#endif + +#ifndef ADC_SENSORS_CONF_ADC6_PIN +#define ADC_SENSORS_ADC6_PIN (-1) /**< ADC6 not declared */ +#else +#define ADC_SENSORS_ADC6_PIN 3 /**< Hard-coded to PA3 */ +#endif + +#ifndef ADC_SENSORS_CONF_MAX +#define ADC_SENSORS_MAX 5 /**< Maximum sensors */ +#else +#define ADC_SENSORS_MAX ADC_SENSORS_CONF_MAX +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Firefly Button configuration + * + * Buttons on the Firefly are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader + * - BUTTON_RESET -> RESET_N line + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have an user button. + * If ADC6 channel is used, then disable the user button + */ +#ifdef PLATFORM_CONF_WITH_BUTTON +#if (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) +#error "The ADC6 (PA3) and user button cannot be enabled at the same time" +#else +#define PLATFORM_HAS_BUTTON (PLATFORM_CONF_WITH_BUTTON && \ + !(ADC_SENSORS_ADC6_PIN == 3)) +#endif /* (PLATFORM_CONF_WITH_BUTTON && (ADC_SENSORS_ADC6_PIN == 3)) */ +#else +#define PLATFORM_HAS_BUTTON !(ADC_SENSORS_ADC6_PIN == 3) +#endif /* PLATFORM_CONF_WITH_BUTTON */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * reserved exclusively for the CC1200 RF transceiver. These pins are exposed + * to the JP3 connector. To disable the CC1200 and use these pins, just + * remove the R10 resistor (0 ohm), which powers both the CC2538 and CC1200 to + * only power the SoC. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_B_NUM +#define SPI0_CLK_PIN 2 +#define SPI0_TX_PORT GPIO_B_NUM +#define SPI0_TX_PIN 1 +#define SPI0_RX_PORT GPIO_B_NUM +#define SPI0_RX_PIN 3 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * exposed over JP3 connector. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_D_NUM +#define SPI1_CLK_PIN 0 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 6 +#define SPI1_RX_PORT GPIO_D_NUM +#define SPI1_RX_PIN 2 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines, exposed + * over JP3 connector. + * @{ + */ +#define I2C_SCL_PORT GPIO_C_NUM +#define I2C_SCL_PIN 3 +#define I2C_SDA_PORT GPIO_C_NUM +#define I2C_SDA_PIN 2 +#define I2C_INT_PORT GPIO_D_NUM +#define I2C_INT_PIN 1 +#define I2C_INT_VECTOR NVIC_INT_GPIO_PORT_D +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Dual RF interface support + * + * Enables support for dual band operation (both CC1200 and 2.4GHz enabled). + * Unlike the RE-Mote, the Firefly doesn't have a RF switch, so both interfaces + * should be always enabled if the R10 resistor is mounted. If only using the + * 2.4GHz RF interface, the resistor can be removed to power-off the CC1200. + * @{ + */ +#define REMOTE_DUAL_RF_ENABLED 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1200 configuration + * + * These values configure the required pins to drive the CC1200 + * None of the following pins are exposed to any connector, kept for internal + * use only + * @{ + */ +#define CC1200_SPI_INSTANCE 0 +#define CC1200_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1200_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1200_SPI_MOSI_PORT SPI0_TX_PORT +#define CC1200_SPI_MOSI_PIN SPI0_TX_PIN +#define CC1200_SPI_MISO_PORT SPI0_RX_PORT +#define CC1200_SPI_MISO_PIN SPI0_RX_PIN +#define CC1200_SPI_CSN_PORT GPIO_B_NUM +#define CC1200_SPI_CSN_PIN 5 +#define CC1200_GDO0_PORT GPIO_B_NUM +#define CC1200_GDO0_PIN 4 +#define CC1200_GDO2_PORT GPIO_B_NUM +#define CC1200_GDO2_PIN 0 +#define CC1200_RESET_PORT GPIO_C_NUM +#define CC1200_RESET_PIN 7 +#define CC1200_GPIOx_VECTOR NVIC_INT_GPIO_PORT_B +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia Firefly revision A platform" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/zoul/images/firefly-reva-pinout-front.png b/platform/zoul/images/firefly-reva-pinout-front.png new file mode 100644 index 000000000..7e70c1f94 Binary files /dev/null and b/platform/zoul/images/firefly-reva-pinout-front.png differ diff --git a/platform/zoul/images/firefly-reva.jpg b/platform/zoul/images/firefly-reva.jpg new file mode 100755 index 000000000..32e4f6eb6 Binary files /dev/null and b/platform/zoul/images/firefly-reva.jpg differ diff --git a/platform/zoul/images/zoul-pinout-back.png b/platform/zoul/images/zoul-pinout-back.png index e0fe2e36e..215075222 100755 Binary files a/platform/zoul/images/zoul-pinout-back.png and b/platform/zoul/images/zoul-pinout-back.png differ diff --git a/platform/zoul/images/zoul-pinout-front.png b/platform/zoul/images/zoul-pinout-front.png index c1d8a6c91..c18bee7b3 100755 Binary files a/platform/zoul/images/zoul-pinout-front.png and b/platform/zoul/images/zoul-pinout-front.png differ diff --git a/platform/zoul/remote-reva/power-mgmt.c b/platform/zoul/remote-reva/power-mgmt.c index b0a09100b..43a4f84c7 100644 --- a/platform/zoul/remote-reva/power-mgmt.c +++ b/platform/zoul/remote-reva/power-mgmt.c @@ -29,7 +29,7 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup remote-power-mgmt + * \addtogroup remote-power-mgmt-reva * @{ * * RE-Mote power management and shutdown mode diff --git a/platform/zoul/remote-reva/power-mgmt.h b/platform/zoul/remote-reva/power-mgmt.h index 0504f9dba..6659fdb8c 100644 --- a/platform/zoul/remote-reva/power-mgmt.h +++ b/platform/zoul/remote-reva/power-mgmt.h @@ -32,7 +32,7 @@ * \addtogroup remote * @{ * - * \defgroup remote-power-mgmt RE-Mote power management driver + * \defgroup remote-power-mgmt-reva RE-Mote power management driver * * The power management module is composed by a nano-watt (gating) timer and an * ultra-low power MCU, driving the RE-Mote power supply when connected to an @@ -152,29 +152,29 @@ typedef enum { * @{ */ /** \brief Initializes the Power Management driver - * \return \c PM_SUCCESS if initialized, else \c PM_ERROR + * \return PM_SUCCESS if initialized, else PM_ERROR */ int8_t pm_init(void); /* -------------------------------------------------------------------------- */ /** \brief Enable the shutdown mode, periodically driven by the Nano Timer - * \return \c PM_SUCCESS if successful, else \c PM_ERROR + * \return PM_SUCCESS if successful, else PM_ERROR */ int8_t pm_enable_timer(void); /* -------------------------------------------------------------------------- */ /** \brief Disable the Nano Timer - * \return \c PM_SUCCESS if successful, else \c PM_ERROR + * \return PM_SUCCESS if successful, else PM_ERROR */ int8_t pm_disable_timer(void); /* -------------------------------------------------------------------------- */ /** \brief Get the current state of the power management module * \param state Pointer to a variable to save the state - * \return \c PM_SUCCESS if successful, else \c PM_ERROR + * \return PM_SUCCESS if successful, else PM_ERROR */ int8_t pm_get_state(uint8_t *state); /* -------------------------------------------------------------------------- */ /** \brief Get the firmware version of the power management module * \param state Pointer to a variable to save the state - * \return \c PM_SUCCESS if successful, else \c PM_ERROR + * \return PM_SUCCESS if successful, else PM_ERROR */ int8_t pm_get_firmware_version(uint8_t *state); /* -------------------------------------------------------------------------- */ diff --git a/platform/zoul/remote-revb/Makefile.remote-revb b/platform/zoul/remote-revb/Makefile.remote-revb index 34f526c65..ce4070ecf 100644 --- a/platform/zoul/remote-revb/Makefile.remote-revb +++ b/platform/zoul/remote-revb/Makefile.remote-revb @@ -1,2 +1,2 @@ MOTELIST_ZOLERTIA = remote -BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c leds-res-arch.c +BOARD_SOURCEFILES += board.c antenna-sw.c rtcc.c leds-res-arch.c power-mgmt.c diff --git a/platform/zoul/remote-revb/power-mgmt.c b/platform/zoul/remote-revb/power-mgmt.c new file mode 100644 index 000000000..0de8a8903 --- /dev/null +++ b/platform/zoul/remote-revb/power-mgmt.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 remote-power-mgmt-revb + * @{ + * RE-Mote power management functions. + * + * @{ + * + * \author + * Aitor Mejias + * Antonio Lignan + */ +/* -------------------------------------------------------------------------- */ +#include +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "sys/rtimer.h" +#include "power-mgmt.h" +#include "dev/i2c.h" +/* -------------------------------------------------------------------------- */ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/* -------------------------------------------------------------------------- */ +#define PM_ENABLE_LINE_SET GPIO_SET_PIN(PM_ENABLE_PORT_BASE, \ + PM_ENABLE_PIN_MASK) +#define PM_ENABLE_LINE_CLR GPIO_CLR_PIN(PM_ENABLE_PORT_BASE, \ + PM_ENABLE_PIN_MASK) +#define PM_ENABLE_AS_OUTPUT GPIO_SET_OUTPUT(PM_ENABLE_PORT_BASE, \ + PM_ENABLE_PIN_MASK) +#define PM_ENABLE_LINE_CMD PM_ENABLE_LINE_SET; \ + clock_delay_usec(100); + +/* -------------------------------------------------------------------------- */ +#define PM_NUMBITS(X) (1 << ((X)-1)) +/* -------------------------------------------------------------------------- */ +static uint8_t initialized = 0; +static uint8_t lbuf[5]; +/* -------------------------------------------------------------------------- */ +int8_t +pm_enable(void) +{ + /* Set as output/low to set IDLE state */ + GPIO_SOFTWARE_CONTROL(PM_ENABLE_PORT_BASE, PM_ENABLE_PIN_MASK); + PM_ENABLE_AS_OUTPUT; + + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + initialized = 1; + return PM_SUCCESS; +} +/* -------------------------------------------------------------------------- */ +static int +pm_write_byte(uint8_t reg, uint8_t val) +{ + if(!initialized) { + return PM_ERROR; + } + lbuf[0] = reg; + lbuf[1] = val; + PM_ENABLE_LINE_CMD; + + if(i2c_burst_send(PWR_MNGMT_ADDR, lbuf, 2) == I2C_MASTER_ERR_NONE) { + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + PM_ENABLE_LINE_CLR; + return PM_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +pm_read_byte(uint8_t reg, uint8_t *val, uint8_t len) +{ + /* Detect valid register parameter */ + if((reg < PM_VBAT) || (reg >= PM_MAX_COMMANDS) || (!len)) { + PRINTF("PM: invalid settings/not initialized\n"); + return PM_ERROR; + } + + PM_ENABLE_LINE_CMD; + + if(i2c_single_send(PWR_MNGMT_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(PWR_MNGMT_ADDR, val, len) == I2C_MASTER_ERR_NONE) { + printf("PM: Data 0x%02X\n", *val); + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + } + PRINTF("PM: Error reading the registers\n"); + PM_ENABLE_LINE_CLR; + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_reset_system(void) +{ + if(!initialized) { + return PM_ERROR; + } + + /* Reset the low-power PIC and the whole board as a bonus */ + lbuf[0] = PM_CMD_RST_HARD; + lbuf[1] = 1; + PM_ENABLE_LINE_CMD; + + if(i2c_burst_send(PWR_MNGMT_ADDR, lbuf, 2) == I2C_MASTER_ERR_NONE) { + clock_delay_usec(1000); + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + PM_ENABLE_LINE_CLR; + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_set_timeout(uint32_t time) +{ + if(!initialized) { + return PM_ERROR; + } + + if(time > PM_SOFT_SHTDN_28_DAYS) { + PRINTF("PM: maximum timeout is %u\n", (uint32_t)PM_SOFT_SHTDN_28_DAYS); + return PM_ERROR; + } + + lbuf[0] = PM_SOFT_TIME; + lbuf[1] = (uint8_t)(time >> 24); + lbuf[2] = (uint8_t)(time >> 16) & 0xFF; + lbuf[3] = (uint8_t)(time >> 8) & 0xFF; + lbuf[4] = (uint8_t)(time & 0xFF); + PRINTF("PM: Timeout 0x%02x%02x%02x%02x\n", lbuf[1], lbuf[2], lbuf[3], lbuf[4]); + + PM_ENABLE_LINE_CMD; + + if(i2c_burst_send(PWR_MNGMT_ADDR, lbuf, 5) == I2C_MASTER_ERR_NONE) { + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + + PRINTF("PM: error setting the timeout\n"); + PM_ENABLE_LINE_CLR; + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +uint32_t +pm_get_timeout(void) +{ + uint32_t retval = 0; + PM_ENABLE_LINE_CMD; + + if(i2c_single_send(PWR_MNGMT_ADDR, PM_SOFT_TIME) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(PWR_MNGMT_ADDR, lbuf, 4) == I2C_MASTER_ERR_NONE) { + retval |= ((uint32_t)lbuf[0] << 24); + retval |= ((uint32_t)lbuf[1] << 16); + retval |= ((uint32_t)lbuf[2] << 8); + retval |= lbuf[3]; + } + } + + PM_ENABLE_LINE_CLR; + PRINTF("PM: Timeout 0x%02x%02x%02x%02x\n", lbuf[0], lbuf[1], lbuf[2], lbuf[3]); + + retval *= PM_SOFT_SHTDN_INTERVAL; + retval /= 100; + return retval; +} +/* -------------------------------------------------------------------------- */ +uint32_t +pm_get_num_cycles(void) +{ + uint32_t retval = 0; + PM_ENABLE_LINE_CMD; + + if(i2c_single_send(PWR_MNGMT_ADDR, PM_GET_NUM_CYCLES) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(PWR_MNGMT_ADDR, lbuf, 4) == I2C_MASTER_ERR_NONE) { + retval |= ((uint32_t)lbuf[0] << 24); + retval |= ((uint32_t)lbuf[1] << 16); + retval |= ((uint32_t)lbuf[2] << 8); + retval |= lbuf[3]; + } + } + PM_ENABLE_LINE_CLR; + PRINTF("PM: Sleep cycles: 0x%02x%02x%02x%02x\n", lbuf[0], lbuf[1], lbuf[2], + lbuf[3]); + return retval; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_shutdown_now(uint8_t type) +{ + if(!initialized) { + PRINTF("PM: Not initialized\n"); + return PM_ERROR; + } + + if((type != PM_HARD_SLEEP_CONFIG) && (type != PM_SOFT_SLEEP_CONFIG)) { + PRINTF("PM: Invalid shutdown mode type\n"); + return PM_ERROR; + } + + PM_ENABLE_LINE_CMD; + + if(type == PM_HARD_SLEEP_CONFIG) { + pm_write_byte(PM_HARD_SLEEP_CONFIG, PM_ENABLE); + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + + /* Soft sleep */ + pm_write_byte(PM_SOFT_SLEEP_CONFIG, PM_ENABLE); + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_get_voltage(uint16_t *state) +{ + if(!initialized) { + return PM_ERROR; + } + + PM_ENABLE_LINE_CMD; + if(i2c_single_send(PWR_MNGMT_ADDR, PM_GET_VDD) == I2C_MASTER_ERR_NONE) { + /* Read two bytes only */ + if(i2c_burst_receive(PWR_MNGMT_ADDR, lbuf, 2) == I2C_MASTER_ERR_NONE) { + *state = (uint16_t)lbuf[0] << 8; + *state += lbuf[1]; + + /* Delay required for the command to finish */ + clock_delay_usec(3000); + + PRINTF("PM: Voltage %u [%u][%u]\n", *state, lbuf[0], lbuf[1]); + PM_ENABLE_LINE_CLR; + return PM_SUCCESS; + } + } + PM_ENABLE_LINE_CLR; + return PM_ERROR; +} +/* -------------------------------------------------------------------------- */ +int8_t +pm_get_fw_ver(uint8_t *fwver) +{ + if((!initialized) || (fwver == NULL)) { + return PM_ERROR; + } + + if(pm_read_byte(PM_FW_VERSION, fwver, 1) == PM_SUCCESS) { + return PM_SUCCESS; + } + return PM_ERROR; +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/zoul/remote-revb/power-mgmt.h b/platform/zoul/remote-revb/power-mgmt.h new file mode 100644 index 000000000..de4ece3cd --- /dev/null +++ b/platform/zoul/remote-revb/power-mgmt.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * 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 remote + * @{ + * + * \defgroup remote-power-mgmt-revb RE-Mote power management driver + * + * Driver control the power management of the RE-Mote rev B platform. This + * driver is an I2C communication with external power manager chip + * that controls few functions of the board. Note the driver will work if + * powered both over USB and external battery, but the shutdown mode will only + * be actually working with external battery + * + * @{ + * + * \file + * Header file for the RE-Mote Power Management driver + * + * \ingroup remote-power-mgmt-revb + * @{ + */ +/* -------------------------------------------------------------------------- */ +#ifndef POWER_MGMT_H_ +#define POWER_MGMT_H_ +#include "dev/gpio.h" +/* -------------------------------------------------------------------------- */ +/** + * \name Power management controller + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define PWR_MNGMT_ADDR 0x7F /**< Power Management slave address */ +/** @} */ +/* -------------------------------------------------------------------------- */ +#define PM_ENABLE_PORT_BASE GPIO_PORT_TO_BASE(PM_ENABLE_PORT) +#define PM_ENABLE_PIN_MASK GPIO_PIN_MASK(PM_ENABLE_PIN) +/* -------------------------------------------------------------------------- */ +/** \name Power Management return values + * @{ + */ +#define PM_SUCCESS 0 +#define PM_ERROR (-1) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management Registers + * @{ + */ +typedef enum { + PM_VBAT = 34, /* Connect/Disconnect battery, it can be "1" (ON) or "0" (OFF) */ + PM_CURRENT_CHARGE, /* register with pm_charge_current_states options */ + PM_CHARGE_ENABLE, /* Enable the current charge mode on the battery */ + PM_SYSOFF, /* Control SYSOFF pin on the battery charger */ + PM_EXTERNAL_REFERENCE, /* Use reference fot vdd. 0: internal 1:External */ + PM_HARD_SLEEP_CONFIG, /* Disconnect Battery until event ext2 on RTCC. */ + PM_SOFT_SLEEP_CONFIG, /* Disconnect Batt without RTCC until PM_SOFT_TIME val */ + PM_SOFT_TIME, /* Time Out used by system time on hard/soft config */ + PM_GET_VDD, /* Command to get the current VDD on the system */ + PM_FW_VERSION, /* Get the Firmware version */ + PM_GET_NUM_CYCLES, /* Obtain the current sleep cycles at moment */ + PM_CMD_RST_HARD, /* Disconnect and reconnect the battery */ + PM_MAX_COMMANDS /* Maximum register commands. Register not valid */ +} pm_registers_t; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management status and masks + * @{ + */ +#define PM_ENABLE 1 /* Pin status on */ +#define PM_DISABLE 0 /* Pin status off */ + +#define BATT_CHARGED_VAL 0 +#define BATT_UNCHARGED_VAL 1 + +#define PM_REFERENCE_INTERNAL 0 +#define PM_REFERENCE_EXTERNAL 1 + +/* The PIC interval time is 57.20ms given in PM_SOFT_SHTDN_INTERVAL, to set a + * timeout period (using the soft shutdown mode) then calculate the time using + * this value as base, i.e 10 minutes would be roughly 600000/57.20 ~10490. + * The maximum value is 28 days! + */ +#define PM_SOFT_SHTDN_INTERVAL 5720 + +#define PM_SOFT_SHTDN_0_5_SEC 8 +#define PM_SOFT_SHTDN_1_SEC 17 +#define PM_SOFT_SHTDN_1_4_SEC 25 +#define PM_SOFT_SHTDN_5_7_SEC 100 +#define PM_SOFT_SHTDN_30_SEC 524 +#define PM_SOFT_SHTDN_1_MIN 1049 +#define PM_SOFT_SHTDN_5_MIN 5245 +#define PM_SOFT_SHTDN_10_MIN 10490 +#define PM_SOFT_SHTDN_1_H 62937 +#define PM_SOFT_SHTDN_24_H 1510490 +#define PM_SOFT_SHTDN_7_DAYS 10573427 +#define PM_SOFT_SHTDN_14_DAYS 21146853 +#define PM_SOFT_SHTDN_28_DAYS 42383709 +#define PM_SOFT_SHTDN_TEST 0xCC00FFEE + +typedef enum { + PM_USB100 = 0, /* 100mA chage */ + PM_USB500, /* 500mA chage */ + PM_USBEXT, /* USB set by external resistor to ILIM (1K) */ + PM_USBSUSPEND /* USB in suspend mode */ +} pm_charge_current_states; + +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Power Management functions + * @{ + */ +/** \brief Initializes the Power Management driver + * \return PM_SUCCESS if initialized, else PM_ERROR + */ +int8_t pm_enable(void); + +/** \brief Gets the current firmware version of power management module + * \param fwver pointer to get the value of firmware + * \return PM_SUCCESS if success, else PM_ERROR + */ +int8_t pm_get_fw_ver(uint8_t *fwver); + +/** \brief Disconnects the board battery and enter shutdown mode + * PM_SOFT/HARD_SLEEP_CONFIG + * \param type Hard shutdown (RTCC based) or soft (PIC-governed) + * \return Value byte of the register requested. + */ +int8_t pm_shutdown_now(uint8_t type); + +/** \brief Configure Internal Timeout for Hard and Soft shutdown modes. + * In Hard mode, any positive value counts as internal security timeout. + * In Soft mode, this value is needed. + * \param time value as timeout maximum + * \return PM_SUCCESS if success, else PM_ERROR + */ +int8_t pm_set_timeout(uint32_t time); + +/** \brief Gets the current timeout value configured in power management module + * \return value with timeout. + */ +uint32_t pm_get_timeout(void); + +/** \brief Gets current cycles. incremented each shutdown cycle + * \return Number of shutdown cycles + */ +uint32_t pm_get_num_cycles(void); + +/** \brief Reads the voltage of the external battery if connected to VIN pin + * \param state pointer to get the voltage value + * \return PM_SUCCESS if success, else PM_ERROR + */ +int8_t pm_get_voltage(uint16_t *state); + +/** \brief Restarts the on-board low-power PIC, provoking a board reset + * \return PM_SUCCESS if success, else PM_ERROR + */ +int8_t pm_reset_system(void); +/* -------------------------------------------------------------------------- */ +/** @} */ +#endif /* POWER_MGMT_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/tools/apple2enh/prodos.po b/tools/apple2enh/prodos.po index ed32e7a38..af35b8c45 100644 Binary files a/tools/apple2enh/prodos.po and b/tools/apple2enh/prodos.po differ diff --git a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java index 57d1fb4f6..84d31ae46 100644 --- a/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java +++ b/tools/cooja/java/org/contikios/cooja/util/ExecuteJAR.java @@ -222,13 +222,20 @@ public class ExecuteJAR { /* Check dependencies: mote type */ for (MoteType t: simulation.getMoteTypes()) { - if (!t.getClass().getName().contains("SkyMoteType")) { - throw new RuntimeException( - "You simulation contains the mote type: " + Cooja.getDescriptionOf(t.getClass()) + "\n" + - "Only the Sky Mote Type is currently supported.\n" - ); - } logger.info("Checking mote types: '" + Cooja.getDescriptionOf(t.getClass()) + "'"); + if (t.getClass().getName().endsWith("SkyMoteType")) { + continue; + } + if (t.getClass().getName().endsWith("WismoteMoteType")) { + continue; + } + if (t.getClass().getName().endsWith("Z1MoteType")) { + continue; + } + throw new RuntimeException( + "Your simulation contains the mote type: " + Cooja.getDescriptionOf(t.getClass()) + "\n" + + "Only the Sky, Wismote, and Z1 mote types are currently supported.\n" + ); } /* Check dependencies: Contiki Control Plugin */