Merge branch 'contiki'

master-01022017
Harald Pichler 2016-11-15 08:29:23 +01:00
commit b708fac68d
76 changed files with 2765 additions and 397 deletions

View File

@ -65,7 +65,7 @@
/*---------------------------------------------------------------------------*/
#define DEBUG 0
#if DEBUG
#define PRINTF(...) PRINTF(__VA_ARGS__)
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif

View File

@ -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);
}
}
}
/*---------------------------------------------------------------------------*/

View File

@ -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:

View File

@ -36,6 +36,7 @@
#include <dirent.h>
#include <string.h>
#define CFS_IMPL 1
#include "cfs/cfs.h"
struct cfs_posix_dir {

View File

@ -40,6 +40,7 @@
#include <unistd.h>
#endif
#define CFS_IMPL 1
#include "cfs/cfs.h"
/*---------------------------------------------------------------------------*/

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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 */

View File

@ -32,7 +32,6 @@
*
*/
#include <unistd.h>
#include <string.h>
#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 */
/*-----------------------------------------------------------------------------------*/

View File

@ -29,6 +29,7 @@
* This file is part of the Contiki operating system.
*
* Author: Oliver Schmidt <ol.sc@web.de>
* Author: Greg King <gregdk@users.sf.net>
*
*/
@ -37,11 +38,17 @@
#include <sys/types.h>
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_ */

View File

@ -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

View File

@ -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

View File

@ -40,6 +40,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "dev/ecc-algorithm.h"
#include "dev/ecc-driver.h"

View File

@ -40,6 +40,7 @@
#include "ieee-addr.h"
#include <stdint.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
void
ieee_addr_cpy_to(uint8_t *dst, uint8_t len)

View File

@ -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_ */

View File

@ -4,6 +4,7 @@
#include "usb-core.h"
#include <stdio.h>
#include <string.h>
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)

View File

@ -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;

View File

@ -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,
};
/*---------------------------------------------------------------------------*/

View File

@ -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,
};
/*---------------------------------------------------------------------------*/

View File

@ -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
*

View File

@ -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 */

View File

@ -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;

View File

@ -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.
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
DEFINES = WITH_LOGGING,WITH_80COL
DEFINES = WITH_LOGGING,WITH_PFS,WITH_80COL

View File

@ -35,6 +35,10 @@
#include <stdio.h>
#include <string.h>
#ifdef __CC65__
#include <cc65.h>
#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 <enter> to continue...");
getchar();
#ifdef __CC65__
if(doesclrscrafterexit()) {
puts("Press <enter> to continue...");
getchar();
}
#endif /* __CC65__ */
process_exit(&wget_process);
LOADER_UNLOAD();
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
TARGET = zoul

View File

@ -0,0 +1,54 @@
/*
* 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 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_ */
/**
* @}
* @}
*/

View File

@ -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 <amejias@zolertia.com>
* Antonio Lignan <alinan@zolertia.com>
*/
/*---------------------------------------------------------------------------*/
#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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/*---------------------------------------------------------------------------*/
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();
}
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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();
}

View File

@ -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 <alinan@zolertia.com>
@ -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();
}

View File

@ -33,6 +33,7 @@
*/
#include <stdlib.h>
#include <cc65.h>
#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);
}

View File

@ -33,6 +33,7 @@
*/
#include <stdlib.h>
#include <cc65.h>
#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);
}

View File

@ -31,7 +31,8 @@
# Author: Oliver Schmidt <ol.sc@web.de>
#
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

View File

@ -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

View File

@ -0,0 +1,5 @@
; 2016-04-28, Greg King
;
; The C128 function is the same as the C64 function.
.include "../../c64/lib/logscr.S"

View File

@ -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

171
platform/c128/lib/pfs-dir.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -31,7 +31,8 @@
# Author: Oliver Schmidt <ol.sc@web.de>
#
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

View File

@ -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

38
platform/c64/lib/logscr.S Normal file
View File

@ -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

View File

@ -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

171
platform/c64/lib/pfs-dir.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -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(&eth_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

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -99,5 +99,4 @@ static const ab080x_register_config_t ab080x_default_setting[] =
/**
* @}
* @}
*/
*/

View File

@ -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)

View File

@ -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

View File

@ -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 <alinan@zolertia.com>
@ -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);
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -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 <alinan@zolertia.com>
* Toni Lozano <tlozano@zolertia.com>
*/
/*---------------------------------------------------------------------------*/
#ifndef TSL2563_H_
#define TSL2563_H_
#ifndef TSL256X_H_
#define TSL256X_H_
#include <stdio.h>
#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
/* -------------------------------------------------------------------------- */

View File

@ -0,0 +1,2 @@
MOTELIST_ZOLERTIA = firefly
BOARD_SOURCEFILES += board.c leds-arch.c

View File

@ -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"

View File

@ -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 <stdint.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
static void
configure_unused_pins(void)
{
/* FIXME */
}
/*---------------------------------------------------------------------------*/
void
board_init()
{
configure_unused_pins();
}
/*---------------------------------------------------------------------------*/
/**
* @}
*/

View File

@ -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_ */
/**
* @}
* @}
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -29,7 +29,7 @@
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup remote-power-mgmt
* \addtogroup remote-power-mgmt-reva
* @{
*
* RE-Mote power management and shutdown mode

View File

@ -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);
/* -------------------------------------------------------------------------- */

View File

@ -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

View File

@ -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 <amejias@zolertia.com>
* Antonio Lignan <alinan@zolertia.com>
*/
/* -------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdint.h>
#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;
}
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/

View File

@ -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_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
* @}
*/

Binary file not shown.

View File

@ -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 */