From 4ce6d215e8f1fa88f683408f23c5b8cb4df42920 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 4 Sep 2015 17:59:25 +0100 Subject: [PATCH 01/94] Use volatile access for CMD_IEEE_TX --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index b5b5cf4c1..4d5b187ee 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -766,7 +766,7 @@ transmit(unsigned short transmit_len) uint16_t stat; uint8_t tx_active = 0; rtimer_clock_t t0; - rfc_CMD_IEEE_TX_t cmd; + volatile rfc_CMD_IEEE_TX_t cmd; if(!rf_is_on()) { was_off = 1; From 8636a282484ef25a39b3020a6020685baeb397be Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 24 Oct 2015 20:01:31 +0100 Subject: [PATCH 02/94] Clear interrupt flags selectively As discussed in #1294, every time a CC13xx/CC26xx RF interrupt fires, we clear all interrupt flags unconditionally. This may result in missed events. This patch fixes this bug by clearing only the flag that triggered the interrupt in the first place. Fixes #1294 --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 45387ab42..0553c58f6 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -478,8 +478,8 @@ cc26xx_rf_cpe1_isr(void) } } - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + /* Clear INTERNAL_ERROR interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF; ENERGEST_OFF(ENERGEST_TYPE_IRQ); } @@ -500,17 +500,25 @@ cc26xx_rf_cpe0_isr(void) ti_lib_int_master_disable(); if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) { + /* Clear the RX_ENTRY_DONE interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF; process_poll(&rf_core_process); } if(RF_CORE_DEBUG_CRC) { if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) { + /* Clear the RX_NOK interrupt flag */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF; rx_nok_isr(); } } - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & + (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) { + /* Clear the two TX-related interrupt flags */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5; + } + ti_lib_int_master_enable(); ENERGEST_OFF(ENERGEST_TYPE_IRQ); From 55b41863d584bf6f9efba374bcb8f9c7b0ab54c7 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 24 Oct 2015 20:54:33 +0100 Subject: [PATCH 03/94] Remove redundant function calls in CC26xx RFC code As discussed in #1279, the current CC13xx/CC26xx rf-core code makes some unnecessary power domain-related reads. This commit removes them. Closes #1279 --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 45387ab42..ee4a03971 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -114,9 +114,7 @@ PROCESS(rf_core_process, "CC13xx / CC26xx RF driver"); uint8_t rf_core_is_accessible() { - if(ti_lib_prcm_rf_ready() && - ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) == - PRCM_DOMAIN_POWER_ON) { + if(ti_lib_prcm_rf_ready()) { return RF_CORE_ACCESSIBLE; } return RF_CORE_NOT_ACCESSIBLE; @@ -221,10 +219,6 @@ rf_core_power_up() ti_lib_prcm_load_set(); while(!ti_lib_prcm_load_get()); - while(!rf_core_is_accessible()) { - PRINTF("rf_core_power_up: Not ready\n"); - } - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; ti_lib_int_enable(INT_RF_CPE0); From 946b72a58dc21569cd173e10b96318b1c10f0728 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 1 Nov 2015 20:46:46 +0000 Subject: [PATCH 04/94] Mask CMDSTA when waiting for a command to get accepted --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 45387ab42..248d66a73 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -159,7 +159,7 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status) HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd; do { - *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA); + *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA) & 0xFF; if(++timeout_count > 50000) { PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd); if(!interrupts_disabled) { From 1ee40ef02166339a38e7fe6746f8d4c2f67f17c6 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 1 Nov 2015 20:48:28 +0000 Subject: [PATCH 05/94] Fix the logic that detects whether a command is a Radio OP --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 14 +++++++++++--- cpu/cc26xx-cc13xx/rf-core/rf-core.h | 1 - 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 248d66a73..791fa1f53 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -129,10 +129,18 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status) bool interrupts_disabled; bool is_radio_op = false; - /* If cmd is 4-byte aligned, then it's a radio OP. Clear the status field */ + /* + * If cmd is 4-byte aligned, then it's either a radio OP or an immediate + * command. Clear the status field if it's a radio OP + */ if((cmd & 0x03) == 0) { - is_radio_op = true; - ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + uint32_t cmd_type; + cmd_type = ((rfc_command_t *)cmd)->commandNo & RF_CORE_COMMAND_TYPE_MASK; + if(cmd_type == RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP || + cmd_type == RF_CORE_COMMAND_TYPE_RADIO_OP) { + is_radio_op = true; + ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + } } /* diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h index 7cf0b10e8..42c6edb90 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.h +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -218,7 +218,6 @@ typedef struct rf_core_primary_mode_s { /*---------------------------------------------------------------------------*/ /* Command Types */ #define RF_CORE_COMMAND_TYPE_MASK 0x0C00 -#define RF_CORE_COMMAND_TYPE_IMMEDIATE 0x0000 #define RF_CORE_COMMAND_TYPE_RADIO_OP 0x0800 #define RF_CORE_COMMAND_TYPE_IEEE_BG_RADIO_OP 0x0800 #define RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP 0x0C00 From f401c7cc607882082ef6219fe2bbf76ef9e9b034 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 1 Nov 2015 20:48:53 +0000 Subject: [PATCH 06/94] Save new TX power setting even if the RFC is powered off. The current logic attempts to send `CMD_SET_TX_POWER` before saving the new power setting. If `CMD_SET_TX_POWER` fails the power setting will not get saved. As a result, when the RFC is powered off, all attempts to change TX power will fail. This commit changes this logic to always save the new TX setting as requested by the user. If the RFC is powered up, we apply it immediately. If it is powered down, the new setting will automatically be applied next time we send `CMD_RADIO_SETUP`. Fixes #1340 --- cpu/cc26xx-cc13xx/rf-core/ieee-mode.c | 39 ++++++++++++++++----------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c index b5b5cf4c1..4cfeb3a3e 100644 --- a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -401,26 +401,33 @@ set_tx_power(radio_value_t power) int i; rfc_CMD_SET_TX_POWER_t cmd; - /* Send a CMD_SET_TX_POWER command to the RF */ - memset(&cmd, 0x00, sizeof(cmd)); - - cmd.commandNo = CMD_SET_TX_POWER; - + /* First, find the correct setting and save it */ for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { if(power <= output_power[i].dbm) { - cmd.txPower.IB = output_power[i].register_ib; - cmd.txPower.GC = output_power[i].register_gc; - cmd.txPower.tempCoeff = output_power[i].temp_coeff; - - if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { - /* Success: Remember the new setting */ - tx_power_current = &output_power[i]; - } else { - PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status); - } - return; + tx_power_current = &output_power[i]; + break; } } + + /* + * If the core is not accessible, the new setting will be applied next + * time we send CMD_RADIO_SETUP, so we don't need to do anything further. + * If the core is accessible, we can apply the new setting immediately with + * CMD_SET_TX_POWER + */ + if(rf_core_is_accessible() == RF_CORE_NOT_ACCESSIBLE) { + return; + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_SET_TX_POWER; + cmd.txPower.IB = output_power[i].register_ib; + cmd.txPower.GC = output_power[i].register_gc; + cmd.txPower.tempCoeff = output_power[i].temp_coeff; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status); + } } /*---------------------------------------------------------------------------*/ static uint8_t From 08fddb6598aacb3f7a5424ff79bfe548407c4d37 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 9 Nov 2015 13:28:52 +0000 Subject: [PATCH 07/94] Always set a valid time for the next AON RTC CH1 compare event The AON RTC CH1 event handler aims to schedule the next compare event on the next 512 RTC counter boundary. However, the current calculation of "now" takes place too early within the interrupt handler. In some cases, this results in the next event getting scheduled too soon in the future or on some extreme cases even in the past. AON RTC compare events cannot happen within 2 SCLK_LF cycles after a clearance (4 RTC ticks in the 16.16 format). Thus, if the next 512 boundary is too soon (5 ticks for margin), we skip it altogether. When this happens, etimers that would have expired on the skipped tick will expire 1 tick later instead. Skipping a tick has no negative impact on our s/w clock counter, since this is always derived directly from the hardware counter. --- cpu/cc26xx-cc13xx/dev/soc-rtc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpu/cc26xx-cc13xx/dev/soc-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c index fb5394947..08d9a7cce 100644 --- a/cpu/cc26xx-cc13xx/dev/soc-rtc.c +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -142,14 +142,12 @@ soc_rtc_last_isr_time(void) void soc_rtc_isr(void) { - uint32_t now, next; + uint32_t next; ENERGEST_ON(ENERGEST_TYPE_IRQ); last_isr_time = RTIMER_NOW(); - now = ti_lib_aon_rtc_current_compare_value_get(); - /* Adjust the s/w tick counter irrespective of which event trigger this */ clock_update(); @@ -161,7 +159,8 @@ soc_rtc_isr(void) * event on the next 512 tick boundary. If we drop to deep sleep before it * happens, lpm_drop() will reschedule us in the 'distant' future */ - next = (now + COMPARE_INCREMENT) & MULTIPLE_512_MASK; + next = ((ti_lib_aon_rtc_current_compare_value_get() + 5) + + COMPARE_INCREMENT) & MULTIPLE_512_MASK; ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next); } From 571cf9364a4e640c956b5a110876c453dd698062 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Mon, 9 Nov 2015 13:36:11 +0000 Subject: [PATCH 08/94] Improve CC13xx/CC26xx LPM logic This commit applies a number of improvements to the logic used when trying to drop to a CC13xx/CC26xx low-power mode: * We identify whether there are any pending etimers by using `etimer_pending()` instead of `etimer_next_expiration_time()`. This subsequently allows us to also identify whether an etimer is set to fire at time 0. * We run a larger portion of the code with the global interrupt disabled. This prevents a number of messy conditions that can occur if an interrupt fires after we have started the low-power sequence. * We check whether there are pending events earlier in the sequence. * We make sure to schedule a next wakeup event even when an LPM module prohibits deep sleep and forces sleep instead. This fixes some of the issues discussed in #1236 --- cpu/cc26xx-cc13xx/lpm.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cpu/cc26xx-cc13xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c index c9e874824..6af58e899 100644 --- a/cpu/cc26xx-cc13xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -244,8 +244,18 @@ lpm_drop() uint32_t domains = LOCKABLE_DOMAINS; + /* Critical. Don't get interrupted! */ + ti_lib_int_master_disable(); + + /* Check if any events fired before we turned interrupts off. If so, abort */ + if(process_nevents()) { + ti_lib_int_master_enable(); + return; + } + if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(), RTIMER_NOW() + STANDBY_MIN_DURATION)) { + ti_lib_int_master_enable(); lpm_sleep(); return; } @@ -261,30 +271,20 @@ lpm_drop() } } - /* Check if any events fired during this process. Last chance to abort */ - if(process_nevents()) { - return; + /* Reschedule AON RTC CH1 to fire just in time for the next etimer event */ + next_event = etimer_next_expiration_time(); + + if(etimer_pending()) { + next_event = next_event - clock_time(); + soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() + + (next_event * (RTIMER_SECOND / CLOCK_SECOND))); } /* Drop */ if(max_pm == LPM_MODE_SLEEP) { + ti_lib_int_master_enable(); lpm_sleep(); } else { - /* Critical. Don't get interrupted! */ - ti_lib_int_master_disable(); - - /* - * Reschedule AON RTC CH1 to fire an event N ticks before the next etimer - * event - */ - next_event = etimer_next_expiration_time(); - - if(next_event) { - next_event = next_event - clock_time(); - soc_rtc_schedule_one_shot(AON_RTC_CH1, soc_rtc_last_isr_time() + - (next_event * (RTIMER_SECOND / CLOCK_SECOND))); - } - /* * Notify all registered modules that we are dropping to mode X. We do not * need to do this for simple sleep. From 576d04a8b0d10fa8b81b1d286506c1c84e826518 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 29 Nov 2015 12:55:48 +0100 Subject: [PATCH 09/94] CI simexec: print stdout from java run, which includes the Cooja log and possible JVM error logs --- regression-tests/simexec.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests/simexec.sh b/regression-tests/simexec.sh index 66f81fd6a..b4bc91e16 100755 --- a/regression-tests/simexec.sh +++ b/regression-tests/simexec.sh @@ -55,13 +55,13 @@ while (( "$#" )); do #Verbose output when using CI if [ "$CI" = "true" ]; then - echo "==== COOJA.log ====" ; cat COOJA.log; + echo "==== $BASENAME.log ====" ; cat $BASENAME.log; echo "==== COOJA.testlog ====" ; cat COOJA.testlog; echo "==== Files used for simulation (sha1sum) ====" grep "Loading firmware from:" COOJA.log | cut -d " " -f 10 | uniq | xargs -r sha1sum grep "Creating core communicator between Java class" COOJA.log | cut -d " " -f 17 | uniq | xargs -r sha1sum else - tail -50 COOJA.log ; + tail -50 $BASENAME.log ; fi; mv COOJA.testlog $BASENAME.$RANDOMSEED.faillog From 1b8c889e41f4c48a15613c7b23ba9ff62e54fd40 Mon Sep 17 00:00:00 2001 From: Amit Geron Date: Mon, 30 Nov 2015 00:18:16 +0200 Subject: [PATCH 10/94] Add route_discovery_explicit_open() For route discovery connections, 2 logical channels are used: One channel for netflood messages, and one for unicast. When opening a route discovery connection using route_discovery_open(), only the netflood channel number is specified, and the unicast channel number is hard-coded to be the next channel (+1). This commit adds an alternative function for opening route-discovery connections, allowing the user to specify both channels independently, to gain improved control and readability. --- core/net/rime/route-discovery.c | 16 +++++++++++++--- core/net/rime/route-discovery.h | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/net/rime/route-discovery.c b/core/net/rime/route-discovery.c index 21afceaa9..4a471bbbc 100644 --- a/core/net/rime/route-discovery.c +++ b/core/net/rime/route-discovery.c @@ -271,14 +271,24 @@ static const struct unicast_callbacks rrep_callbacks = {rrep_packet_received}; static const struct netflood_callbacks rreq_callbacks = {rreq_packet_received, NULL, NULL}; /*---------------------------------------------------------------------------*/ void +route_discovery_expicit_open(struct route_discovery_conn *c, + clock_time_t time, + uint16_t netflood_channel, + uint16_t unicast_channel, + const struct route_discovery_callbacks *callbacks) +{ + netflood_open(&c->rreqconn, time, netflood_channel, &rreq_callbacks); + unicast_open(&c->rrepconn, unicast_channel, &rrep_callbacks); + c->cb = callbacks; +} +/*---------------------------------------------------------------------------*/ +void route_discovery_open(struct route_discovery_conn *c, clock_time_t time, uint16_t channels, const struct route_discovery_callbacks *callbacks) { - netflood_open(&c->rreqconn, time, channels + 0, &rreq_callbacks); - unicast_open(&c->rrepconn, channels + 1, &rrep_callbacks); - c->cb = callbacks; + route_discovery_expicit_open(c, time, channels + 0, channels + 1, callbacks); } /*---------------------------------------------------------------------------*/ void diff --git a/core/net/rime/route-discovery.h b/core/net/rime/route-discovery.h index 81d454d5f..09ce984c2 100644 --- a/core/net/rime/route-discovery.h +++ b/core/net/rime/route-discovery.h @@ -83,6 +83,10 @@ struct route_discovery_conn { void route_discovery_open(struct route_discovery_conn *c, clock_time_t time, uint16_t channels, const struct route_discovery_callbacks *callbacks); +void route_discovery_explicit_open(struct route_discovery_conn *c, clock_time_t time, + uint16_t netflood_channel, + uint16_t unicast_channel, + const struct route_discovery_callbacks *callbacks); int route_discovery_discover(struct route_discovery_conn *c, const linkaddr_t *dest, clock_time_t timeout); From 3dd11603a7c5e739b8fb6a96afca51003f392334 Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Tue, 1 Dec 2015 04:14:46 +0100 Subject: [PATCH 11/94] Implementation of OMA LWM2M Engine / IPSO Objects --- apps/ipso-objects/Makefile.ipso-objects | 3 + apps/ipso-objects/ipso-button.c | 163 +++ apps/ipso-objects/ipso-leds-control.c | 191 ++++ apps/ipso-objects/ipso-light-control.c | 202 ++++ apps/ipso-objects/ipso-objects.c | 66 ++ apps/ipso-objects/ipso-objects.h | 122 ++ apps/ipso-objects/ipso-temperature.c | 159 +++ apps/oma-lwm2m/Makefile.oma-lwm2m | 5 + apps/oma-lwm2m/lwm2m-device.c | 152 +++ apps/oma-lwm2m/lwm2m-device.h | 62 + apps/oma-lwm2m/lwm2m-engine.c | 1017 +++++++++++++++++ apps/oma-lwm2m/lwm2m-engine.h | 82 ++ apps/oma-lwm2m/lwm2m-object.c | 336 ++++++ apps/oma-lwm2m/lwm2m-object.h | 359 ++++++ apps/oma-lwm2m/lwm2m-plain-text.c | 248 ++++ apps/oma-lwm2m/lwm2m-plain-text.h | 62 + apps/oma-lwm2m/lwm2m-security.c | 112 ++ apps/oma-lwm2m/lwm2m-server.c | 93 ++ apps/oma-lwm2m/oma-tlv-reader.c | 114 ++ apps/oma-lwm2m/oma-tlv-reader.h | 50 + apps/oma-lwm2m/oma-tlv-writer.c | 89 ++ apps/oma-lwm2m/oma-tlv-writer.h | 50 + apps/oma-lwm2m/oma-tlv.c | 296 +++++ apps/oma-lwm2m/oma-tlv.h | 89 ++ examples/ipso-objects/Makefile | 29 + .../cooja-example-ipso-objects.csc | 171 +++ .../cooja-example-router-node.csc | 187 +++ examples/ipso-objects/example-ipso-objects.c | 100 ++ .../ipso-objects/example-ipso-temperature.c | 59 + examples/ipso-objects/example-server.c | 392 +++++++ examples/ipso-objects/project-conf.h | 75 ++ examples/ipso-objects/serial-protocol.c | 126 ++ examples/ipso-objects/serial-protocol.h | 43 + 33 files changed, 5304 insertions(+) create mode 100644 apps/ipso-objects/Makefile.ipso-objects create mode 100644 apps/ipso-objects/ipso-button.c create mode 100644 apps/ipso-objects/ipso-leds-control.c create mode 100644 apps/ipso-objects/ipso-light-control.c create mode 100644 apps/ipso-objects/ipso-objects.c create mode 100644 apps/ipso-objects/ipso-objects.h create mode 100644 apps/ipso-objects/ipso-temperature.c create mode 100644 apps/oma-lwm2m/Makefile.oma-lwm2m create mode 100644 apps/oma-lwm2m/lwm2m-device.c create mode 100644 apps/oma-lwm2m/lwm2m-device.h create mode 100644 apps/oma-lwm2m/lwm2m-engine.c create mode 100644 apps/oma-lwm2m/lwm2m-engine.h create mode 100644 apps/oma-lwm2m/lwm2m-object.c create mode 100644 apps/oma-lwm2m/lwm2m-object.h create mode 100644 apps/oma-lwm2m/lwm2m-plain-text.c create mode 100644 apps/oma-lwm2m/lwm2m-plain-text.h create mode 100644 apps/oma-lwm2m/lwm2m-security.c create mode 100644 apps/oma-lwm2m/lwm2m-server.c create mode 100644 apps/oma-lwm2m/oma-tlv-reader.c create mode 100644 apps/oma-lwm2m/oma-tlv-reader.h create mode 100644 apps/oma-lwm2m/oma-tlv-writer.c create mode 100644 apps/oma-lwm2m/oma-tlv-writer.h create mode 100644 apps/oma-lwm2m/oma-tlv.c create mode 100644 apps/oma-lwm2m/oma-tlv.h create mode 100644 examples/ipso-objects/Makefile create mode 100644 examples/ipso-objects/cooja-example-ipso-objects.csc create mode 100644 examples/ipso-objects/cooja-example-router-node.csc create mode 100644 examples/ipso-objects/example-ipso-objects.c create mode 100644 examples/ipso-objects/example-ipso-temperature.c create mode 100644 examples/ipso-objects/example-server.c create mode 100644 examples/ipso-objects/project-conf.h create mode 100644 examples/ipso-objects/serial-protocol.c create mode 100644 examples/ipso-objects/serial-protocol.h diff --git a/apps/ipso-objects/Makefile.ipso-objects b/apps/ipso-objects/Makefile.ipso-objects new file mode 100644 index 000000000..8de44f196 --- /dev/null +++ b/apps/ipso-objects/Makefile.ipso-objects @@ -0,0 +1,3 @@ +ipso-objects_src = ipso-temperature.c ipso-button.c ipso-leds-control.c \ + ipso-light-control.c ipso-objects.c +CFLAGS += -DWITH_IPSO=1 diff --git a/apps/ipso-objects/ipso-button.c b/apps/ipso-objects/ipso-button.c new file mode 100644 index 000000000..f40410ea0 --- /dev/null +++ b/apps/ipso-objects/ipso-button.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 ipso-objects + * @{ + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO button as a digital input + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if PLATFORM_HAS_BUTTON +#include "dev/button-sensor.h" + +PROCESS(ipso_button_process, "ipso-button"); +#endif /* PLATFORM_HAS_BUTTON */ + +static int input_state = 0; +static int polarity = 0; +static int32_t counter = 0; +static int32_t edge_selection = 3; +static int32_t debounce_time = 10; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + int value; + if(polarity == 0) { + value = input_state ? 1 : 0; + } else { + value = input_state ? 0 : 1; + } + PRINTF("Read button state (polarity=%d, state=%d): %d\n", + polarity, input_state, value); + return ctx->writer->write_boolean(ctx, outbuf, outsize, value); +} +/*---------------------------------------------------------------------------*/ +static int +reset_counter(lwm2m_context_t *ctx, const uint8_t *arg, size_t len, + uint8_t *outbuf, size_t outlen) +{ + counter = 0; + return 0; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(button_resources, + LWM2M_RESOURCE_CALLBACK(5500, { read_state, NULL, NULL }), + LWM2M_RESOURCE_INTEGER_VAR(5501, &counter), + LWM2M_RESOURCE_BOOLEAN_VAR(5502, &polarity), + LWM2M_RESOURCE_INTEGER_VAR(5503, &debounce_time), + LWM2M_RESOURCE_INTEGER_VAR(5504, &edge_selection), + LWM2M_RESOURCE_CALLBACK(5505, { NULL, NULL, reset_counter }), + LWM2M_RESOURCE_STRING(5751, "Button") + ); +LWM2M_INSTANCES(button_instances, + LWM2M_INSTANCE(0, button_resources)); +LWM2M_OBJECT(button, 3200, button_instances); +/*---------------------------------------------------------------------------*/ +void +ipso_button_init(void) +{ + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&button); + +#if PLATFORM_HAS_BUTTON + process_start(&ipso_button_process, NULL); +#endif /* PLATFORM_HAS_BUTTON */ +} +/*---------------------------------------------------------------------------*/ +#if PLATFORM_HAS_BUTTON +PROCESS_THREAD(ipso_button_process, ev, data) +{ + static struct etimer timer; + int32_t time; + + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(button_sensor); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == sensors_event && data == &button_sensor) { + if(!input_state) { + input_state = 1; + counter++; + if((edge_selection & 2) != 0) { + lwm2m_object_notify_observers(&button, "/0/5500"); + } + lwm2m_object_notify_observers(&button, "/0/5501"); + + time = (debounce_time * CLOCK_SECOND / 1000); + if(time < 1) { + time = 1; + } + etimer_set(&timer, (clock_time_t)time); + } + } else if(ev == PROCESS_EVENT_TIMER && data == &timer) { + if(!input_state) { + /* Button is not in pressed state */ + } else if(button_sensor.value(0) != 0) { + /* Button is still pressed */ + etimer_reset(&timer); + } else { + input_state = 0; + if((edge_selection & 1) != 0) { + lwm2m_object_notify_observers(&button, "/0/5500"); + } + } + } + } + + PROCESS_END(); +} +#endif /* PLATFORM_HAS_BUTTON */ +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-leds-control.c b/apps/ipso-objects/ipso-leds-control.c new file mode 100644 index 000000000..fea620602 --- /dev/null +++ b/apps/ipso-objects/ipso-leds-control.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 ipso-objects + * @{ + * + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Light Control for LEDs + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" +#include "dev/leds.h" +#include + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if LEDS_ALL > 3 +#define LEDS_CONTROL_NUMBER 3 +#elif LEDS_ALL > 1 +#define LEDS_CONTROL_NUMBER 2 +#else +#define LEDS_CONTROL_NUMBER 1 +#endif + +struct led_state { + unsigned long last_on_time; + uint32_t total_on_time; + uint8_t is_on; +}; + +static struct led_state states[LEDS_CONTROL_NUMBER]; +static lwm2m_instance_t leds_control_instances[LEDS_CONTROL_NUMBER]; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + return ctx->writer->write_boolean(ctx, outbuf, outsize, + states[idx].is_on ? 1 : 0); +} +/*---------------------------------------------------------------------------*/ +static int +write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int value; + size_t len; + + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + len = ctx->reader->read_boolean(ctx, inbuf, insize, &value); + if(len > 0) { + if(value) { + if(!states[idx].is_on) { + states[idx].is_on = 1; + states[idx].last_on_time = clock_seconds(); +#if PLATFORM_HAS_LEDS + leds_on(1 << idx); +#endif /* PLATFORM_HAS_LEDS */ + } + } else if(states[idx].is_on) { + states[idx].total_on_time += clock_seconds() - states[idx].last_on_time; + states[idx].is_on = 0; +#if PLATFORM_HAS_LEDS + leds_off(1 << idx); +#endif /* PLATFORM_HAS_LEDS */ + } + } else { + PRINTF("IPSO leds control - ignored illegal write to on/off\n"); + } + return len; +} +/*---------------------------------------------------------------------------*/ +static int +read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + unsigned long now; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + if(states[idx].is_on) { + /* Update the on time */ + now = clock_seconds(); + states[idx].total_on_time += now - states[idx].last_on_time; + states[idx].last_on_time = now; + } + return ctx->writer->write_int(ctx, outbuf, outsize, + (int32_t)states[idx].total_on_time); +} +/*---------------------------------------------------------------------------*/ +static int +write_on_time(lwm2m_context_t *ctx, + const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0 && value == 0) { + PRINTF("IPSO leds control - reset On Time\n"); + states[idx].total_on_time = 0; + if(states[idx].is_on) { + states[idx].last_on_time = clock_seconds(); + } + } else { + PRINTF("IPSO leds control - ignored illegal write to On Time\n"); + } + return len; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(leds_control_resources, + LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }), + LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }) + ); +LWM2M_OBJECT(leds_control, 3311, leds_control_instances); +/*---------------------------------------------------------------------------*/ +void +ipso_leds_control_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE(0, leds_control_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < LEDS_CONTROL_NUMBER; i++) { + leds_control_instances[i] = template; + leds_control_instances[i].id = i; + } + + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&leds_control); + PRINTF("IPSO leds control initialized with %u instances\n", + LEDS_CONTROL_NUMBER); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-light-control.c b/apps/ipso-objects/ipso-light-control.c new file mode 100644 index 000000000..02c4b9be2 --- /dev/null +++ b/apps/ipso-objects/ipso-light-control.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 ipso-objects + * @{ + * + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Light Control + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "ipso-objects.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#ifdef IPSO_LIGHT_CONTROL +extern const struct ipso_objects_actuator IPSO_LIGHT_CONTROL; +#endif /* IPSO_LIGHT_CONTROL */ +/*---------------------------------------------------------------------------*/ +static unsigned long last_on_time; +static uint32_t total_on_time; +static int dim_level = 0; +static uint8_t is_on = 0; +/*---------------------------------------------------------------------------*/ +static int +read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_boolean(ctx, outbuf, outsize, is_on ? 1 : 0); +} +/*---------------------------------------------------------------------------*/ +static int +write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int value; + size_t len; + + len = ctx->reader->read_boolean(ctx, inbuf, insize, &value); + if(len > 0) { + if(value) { + if(!is_on) { + is_on = 1; + last_on_time = clock_seconds(); + } + } else { + if(is_on) { + total_on_time += clock_seconds() - last_on_time; + is_on = 0; + } + } +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.set_on) { + IPSO_LIGHT_CONTROL.set_on(value); + } else if(IPSO_LIGHT_CONTROL.set_dim_level) { + dim_level = value ? 100 : 0; + IPSO_LIGHT_CONTROL.set_dim_level(dim_level); + } +#endif /* IPSO_LIGHT_CONTROL */ + } + return len; +} +/*---------------------------------------------------------------------------*/ +static int +read_dim(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_int(ctx, outbuf, outsize, dim_level); +} +/*---------------------------------------------------------------------------*/ +static int +write_dim(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0) { + if(value < 0) { + value = 0; + } else if(value > 100) { + value = 100; + } + + dim_level = value; + if(value > 0) { + if(!is_on) { + is_on = 1; + last_on_time = clock_seconds(); + } + } else { + if(is_on) { + total_on_time += clock_seconds() - last_on_time; + is_on = 0; + } + } +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.set_dim_level) { + IPSO_LIGHT_CONTROL.set_dim_level(dim_level); + } else if(IPSO_LIGHT_CONTROL.set_on) { + IPSO_LIGHT_CONTROL.set_on(is_on); + } +#endif /* IPSO_LIGHT_CONTROL */ + } + return len; +} +/*---------------------------------------------------------------------------*/ +static int +read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + unsigned long now; + if(is_on) { + /* Update the on time */ + now = clock_seconds(); + total_on_time += now - last_on_time; + last_on_time = now; + } + return ctx->writer->write_int(ctx, outbuf, outsize, (int32_t)total_on_time); +} +/*---------------------------------------------------------------------------*/ +static int +write_on_time(lwm2m_context_t *ctx, + const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + int32_t value; + size_t len; + + len = ctx->reader->read_int(ctx, inbuf, insize, &value); + if(len > 0 && value == 0) { + total_on_time = 0; + if(is_on) { + last_on_time = clock_seconds(); + } + } + return len; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(light_control_resources, + LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }), + LWM2M_RESOURCE_CALLBACK(5851, { read_dim, write_dim, NULL }), + LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }), + ); +LWM2M_INSTANCES(light_control_instances, + LWM2M_INSTANCE(0, light_control_resources)); +LWM2M_OBJECT(light_control, 3311, light_control_instances); +/*---------------------------------------------------------------------------*/ +void +ipso_light_control_init(void) +{ +#ifdef IPSO_LIGHT_CONTROL + if(IPSO_LIGHT_CONTROL.init) { + IPSO_LIGHT_CONTROL.init(); + } + if(IPSO_LIGHT_CONTROL.is_on) { + is_on = IPSO_LIGHT_CONTROL.is_on(); + } + if(IPSO_LIGHT_CONTROL.get_dim_level) { + dim_level = IPSO_LIGHT_CONTROL.get_dim_level(); + if(dim_level > 0 && IPSO_LIGHT_CONTROL.is_on == NULL) { + is_on = 1; + } + } +#endif /* IPSO_LIGHT_CONTROL */ + last_on_time = clock_seconds(); + + lwm2m_engine_register_object(&light_control); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-objects.c b/apps/ipso-objects/ipso-objects.c new file mode 100644 index 000000000..1e8243f94 --- /dev/null +++ b/apps/ipso-objects/ipso-objects.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the IPSO Objects + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "ipso-objects.h" +/*---------------------------------------------------------------------------*/ +void +ipso_objects_init(void) +{ + /* initialize any relevant object for the IPSO Objects */ +#ifdef IPSO_TEMPERATURE + ipso_temperature_init(); +#endif + +#if PLATFORM_HAS_BUTTON + ipso_button_init(); +#endif + +#ifdef IPSO_LIGHT_CONTROL + ipso_light_control_init(); +#elif PLATFORM_HAS_LEDS + ipso_leds_control_init(); +#endif +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/ipso-objects/ipso-objects.h b/apps/ipso-objects/ipso-objects.h new file mode 100644 index 000000000..13cfecae6 --- /dev/null +++ b/apps/ipso-objects/ipso-objects.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 apps + * @{ + */ + +/** + * \defgroup ipso-objects An implementation of IPSO Objects + * @{ + * + * This application is an implementation of IPSO Objects for + * OMA Lightweight M2M. + */ + +/** + * \file + * Header file for the Contiki IPSO Objects for OMA LWM2M + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef IPSO_OBJECTS_H_ +#define IPSO_OBJECTS_H_ + +#include "contiki-conf.h" + +void ipso_temperature_init(void); +void ipso_button_init(void); +void ipso_light_control_init(void); +void ipso_leds_control_init(void); + +/* the init function to register the IPSO objects */ +void ipso_objects_init(void); + +struct ipso_objects_actuator { + /** + * \brief Initialize the driver. + */ + void (* init)(void); + + /** + * \brief Check if the actuator is on or off. + * + * \return Zero if the actuator is off and non-zero otherwise. + */ + int (* is_on)(void); + + /** + * \brief Set the actuator to on or off. + * + * \param onoroff Zero to set the actuator to off and non-zero otherwise. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* set_on)(int onoroff); + + /** + * \brief Set the actuator to on or off. + * + * \param onoroff Zero to set the actuator to off and non-zero otherwise. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* get_dim_level)(void); + + /** + * \brief Set the dim level of the actuator. + * + * \param level The dim level between 0% and 100%. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* set_dim_level)(int level); +}; + +struct ipso_objects_sensor { + /** + * \brief Initialize the driver. + */ + void (* init)(void); + + /** + * \brief Read the sensor value in 1/1000 units. + * + * \param value A pointer to the variable to hold the sensor value. + * \return Zero if ok and a non-zero error code otherwise. + */ + int (* read_value)(int32_t *value); +}; + +#endif /* IPSO_OBJECTS_H_ */ +/** + * @} + * @} + */ diff --git a/apps/ipso-objects/ipso-temperature.c b/apps/ipso-objects/ipso-temperature.c new file mode 100644 index 000000000..61c87554a --- /dev/null +++ b/apps/ipso-objects/ipso-temperature.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 ipso-objects + * @{ + */ + +/** + * \file + * Implementation of OMA LWM2M / IPSO Temperature + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "ipso-objects.h" +#include "lwm2m-object.h" +#include "lwm2m-engine.h" +#include "er-coap-engine.h" + +#ifdef IPSO_TEMPERATURE +extern const struct ipso_objects_sensor IPSO_TEMPERATURE; +#endif /* IPSO_TEMPERATURE */ + +#ifndef IPSO_TEMPERATURE_MIN +#define IPSO_TEMPERATURE_MIN (-50 * LWM2M_FLOAT32_FRAC) +#endif + +#ifndef IPSO_TEMPERATURE_MAX +#define IPSO_TEMPERATURE_MAX (80 * LWM2M_FLOAT32_FRAC) +#endif + +static struct ctimer periodic_timer; +static int32_t min_temp; +static int32_t max_temp; +static int read_temp(int32_t *value); +/*---------------------------------------------------------------------------*/ +static int +temp(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + int32_t value; + if(read_temp(&value)) { + return ctx->writer->write_float32fix(ctx, outbuf, outsize, + value, LWM2M_FLOAT32_BITS); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(temperature_resources, + /* Temperature (Current) */ + LWM2M_RESOURCE_CALLBACK(5700, { temp, NULL, NULL }), + /* Units */ + LWM2M_RESOURCE_STRING(5701, "Celcius"), + /* Min Range Value */ + LWM2M_RESOURCE_FLOATFIX(5603, IPSO_TEMPERATURE_MIN), + /* Max Range Value */ + LWM2M_RESOURCE_FLOATFIX(5604, IPSO_TEMPERATURE_MAX), + /* Min Measured Value */ + LWM2M_RESOURCE_FLOATFIX_VAR(5601, &min_temp), + /* Max Measured Value */ + LWM2M_RESOURCE_FLOATFIX_VAR(5602, &max_temp), + ); +LWM2M_INSTANCES(temperature_instances, + LWM2M_INSTANCE(0, temperature_resources)); +LWM2M_OBJECT(temperature, 3303, temperature_instances); +/*---------------------------------------------------------------------------*/ +static int +read_temp(int32_t *value) +{ +#ifdef IPSO_TEMPERATURE + int32_t temp; + if(IPSO_TEMPERATURE.read_value == NULL || + IPSO_TEMPERATURE.read_value(&temp) != 0) { + return 0; + } + + /* Convert milliCelsius to fix float */ + *value = (temp * LWM2M_FLOAT32_FRAC) / 1000; + + if(*value < min_temp) { + min_temp = *value; + lwm2m_object_notify_observers(&temperature, "/0/5601"); + } + if(*value > max_temp) { + max_temp = *value; + lwm2m_object_notify_observers(&temperature, "/0/5602"); + } + return 1; +#else /* IPSO_TEMPERATURE */ + return 0; +#endif /* IPSO_TEMPERATURE */ +} +/*---------------------------------------------------------------------------*/ +static void +handle_periodic_timer(void *ptr) +{ + static int32_t last_value = IPSO_TEMPERATURE_MIN; + int32_t v; + + /* Only notify when the value has changed since last */ + if(read_temp(&v) && v != last_value) { + last_value = v; + lwm2m_object_notify_observers(&temperature, "/0/5700"); + } + ctimer_reset(&periodic_timer); +} +/*---------------------------------------------------------------------------*/ +void +ipso_temperature_init(void) +{ + int32_t v; + min_temp = IPSO_TEMPERATURE_MAX; + max_temp = IPSO_TEMPERATURE_MIN; + +#ifdef IPSO_TEMPERATURE + if(IPSO_TEMPERATURE.init) { + IPSO_TEMPERATURE.init(); + } +#endif /* IPSO_TEMPERATURE */ + + /* register this device and its handlers - the handlers automatically + sends in the object to handle */ + lwm2m_engine_register_object(&temperature); + + /* update temp and min/max + notify any listeners */ + read_temp(&v); + ctimer_set(&periodic_timer, CLOCK_SECOND * 10, handle_periodic_timer, NULL); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/Makefile.oma-lwm2m b/apps/oma-lwm2m/Makefile.oma-lwm2m new file mode 100644 index 000000000..8445530ed --- /dev/null +++ b/apps/oma-lwm2m/Makefile.oma-lwm2m @@ -0,0 +1,5 @@ +oma-lwm2m_src = lwm2m-object.c lwm2m-engine.c \ + lwm2m-device.c lwm2m-server.c lwm2m-security.c \ + oma-tlv.c oma-tlv-reader.c oma-tlv-writer.c \ + lwm2m-plain-text.c +CFLAGS += -DHAVE_OMA_LWM2M=1 diff --git a/apps/oma-lwm2m/lwm2m-device.c b/apps/oma-lwm2m/lwm2m-device.c new file mode 100644 index 000000000..a911c7c4a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-device.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M device + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-device.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +static int32_t time_offset = 0; +/*---------------------------------------------------------------------------*/ +static int +read_lwtime(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + return ctx->writer->write_int(ctx, outbuf, outsize, + time_offset + clock_seconds()); +} +/*---------------------------------------------------------------------------*/ +static int +set_lwtime(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, + uint8_t *outbuf, size_t outsize) +{ + /* assume that this only read one TLV value */ + int32_t lw_time; + size_t len = ctx->reader->read_int(ctx, inbuf, insize, &lw_time); + if(len == 0) { + PRINTF("FAIL: could not read time '%*.s'\n", (int)insize, inbuf); + } else { + PRINTF("Got: time: %*.s => %" PRId32 "\n", (int)insize, inbuf, lw_time); + + time_offset = lw_time - clock_seconds(); + PRINTF("Write time...%" PRId32 " => offset = %" PRId32 "\n", + lw_time, time_offset); + } + /* return the number of bytes read */ + return len; +} +/*---------------------------------------------------------------------------*/ +#ifdef PLATFORM_REBOOT +static struct ctimer reboot_timer; +static void +do_the_reboot(void *ptr) +{ + PLATFORM_REBOOT(); +} +static int +reboot(lwm2m_context_t *ctx, const uint8_t *arg, size_t argsize, + uint8_t *outbuf, size_t outsize) +{ + PRINTF("Device will reboot!\n"); + ctimer_set(&reboot_timer, CLOCK_SECOND / 2, do_the_reboot, NULL); + return 0; +} +#endif /* PLATFORM_REBOOT */ +/*---------------------------------------------------------------------------*/ +#ifdef PLATFORM_FACTORY_DEFAULT +static int +factory_reset(lwm2m_context_t *ctx, const uint8_t *arg, size_t arg_size, + uint8_t *outbuf, size_t outsize) +{ + PRINTF("Device will do factory default!\n"); + PLATFORM_FACTORY_DEFAULT(); + return 0; +} +#endif /* PLATFORM_FACTORY_DEFAULT */ +/*---------------------------------------------------------------------------*/ +LWM2M_RESOURCES(device_resources, +#ifdef LWM2M_DEVICE_MANUFACTURER + LWM2M_RESOURCE_STRING(0, LWM2M_DEVICE_MANUFACTURER), +#endif /* LWM2M_DEVICE_MANUFACTURER */ +#ifdef LWM2M_DEVICE_TYPE + LWM2M_RESOURCE_STRING(17, LWM2M_DEVICE_TYPE), +#endif /* LWM2M_DEVICE_TYPE */ +#ifdef LWM2M_DEVICE_MODEL_NUMBER + LWM2M_RESOURCE_STRING(1, LWM2M_DEVICE_MODEL_NUMBER), +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ +#ifdef LWM2M_DEVICE_SERIAL_NO + LWM2M_RESOURCE_STRING(2, LWM2M_DEVICE_SERIAL_NO), +#endif /* LWM2M_DEVICE_SERIAL_NO */ +#ifdef LWM2M_DEVICE_FIRMWARE_VERSION + LWM2M_RESOURCE_STRING(3, LWM2M_DEVICE_FIRMWARE_VERSION), +#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */ +#ifdef PLATFORM_REBOOT + LWM2M_RESOURCE_CALLBACK(4, { NULL, NULL, reboot }), +#endif /* PLATFORM_REBOOT */ +#ifdef PLATFORM_FACTORY_DEFAULT + LWM2M_RESOURCE_CALLBACK(5, { NULL, NULL, factory_reset }), +#endif /* PLATFORM_FACTORY_DEFAULT */ + /* Current Time */ + LWM2M_RESOURCE_CALLBACK(13, { read_lwtime, set_lwtime, NULL }), + ); +LWM2M_INSTANCES(device_instances, LWM2M_INSTANCE(0, device_resources)); +LWM2M_OBJECT(device, 3, device_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_device_init(void) +{ + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle. + */ + PRINTF("*** Init lwm2m-device\n"); + lwm2m_engine_register_object(&device); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-device.h b/apps/oma-lwm2m/lwm2m-device.h new file mode 100644 index 000000000..5e80c786a --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-device.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M device + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_DEVICE_H_ +#define LWM2M_DEVICE_H_ + +#include "contiki-conf.h" + +#ifndef LWM2M_DEVICE_MODEL_NUMBER +#ifdef BOARD_STRING +#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING +#endif /* BOARD_STRING */ +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ + +#ifndef LWM2M_DEVICE_FIRMWARE_VERSION +#define LWM2M_DEVICE_FIRMWARE_VERSION CONTIKI_VERSION_STRING +#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */ + +void lwm2m_device_init(void); + +#endif /* LWM2M_DEVICE_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-engine.c b/apps/oma-lwm2m/lwm2m-engine.c new file mode 100644 index 000000000..62f549db4 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-engine.c @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M engine + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "lwm2m-engine.h" +#include "lwm2m-object.h" +#include "lwm2m-device.h" +#include "lwm2m-plain-text.h" +#include "rest-engine.h" +#include "er-coap-constants.h" +#include "er-coap-engine.h" +#include "oma-tlv.h" +#include "oma-tlv-writer.h" +#include "net/ipv6/uip-ds6.h" +#include +#include +#include + +#if UIP_CONF_IPV6_RPL +#include "net/rpl/rpl.h" +#endif /* UIP_CONF_IPV6_RPL */ + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX +#ifdef LWM2M_DEVICE_MODEL_NUMBER +#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX LWM2M_DEVICE_MODEL_NUMBER +#else /* LWM2M_DEVICE_MODEL_NUMBER */ +#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX "Contiki-" +#endif /* LWM2M_DEVICE_MODEL_NUMBER */ +#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX */ + +#ifdef LWM2M_ENGINE_CONF_MAX_OBJECTS +#define MAX_OBJECTS LWM2M_ENGINE_CONF_MAX_OBJECTS +#else /* LWM2M_ENGINE_CONF_MAX_OBJECTS */ +#define MAX_OBJECTS 10 +#endif /* LWM2M_ENGINE_CONF_MAX_OBJECTS */ + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) +#define BS_REMOTE_PORT UIP_HTONS(5685) + +static const lwm2m_object_t *objects[MAX_OBJECTS]; +static char endpoint[32]; +static char rd_data[128]; /* allocate some data for the RD */ + +PROCESS(lwm2m_rd_client, "LWM2M Engine"); + +static uip_ipaddr_t server_ipaddr; +static uint16_t server_port = REMOTE_PORT; +static uip_ipaddr_t bs_server_ipaddr; +static uint16_t bs_server_port = BS_REMOTE_PORT; + +static uint8_t use_bootstrap = 0; +static uint8_t has_bootstrap_server_info = 0; +static uint8_t use_registration = 0; +static uint8_t has_registration_server_info = 0; +static uint8_t registered = 0; +static uint8_t bootstrapped = 0; /* bootstrap made... */ + +void lwm2m_device_init(void); +void lwm2m_security_init(void); +void lwm2m_server_init(void); + +static const lwm2m_instance_t *get_first_instance_of_object(uint16_t id, lwm2m_context_t *context); +static const lwm2m_instance_t *get_instance(const lwm2m_object_t *object, lwm2m_context_t *context, int depth); +static const lwm2m_resource_t *get_resource(const lwm2m_instance_t *instance, lwm2m_context_t *context); +/*---------------------------------------------------------------------------*/ +static void +client_chunk_handler(void *response) +{ +#if (DEBUG) & DEBUG_PRINT + const uint8_t *chunk; + + int len = coap_get_payload(response, &chunk); + + PRINTF("|%.*s\n", len, (char *)chunk); +#endif /* (DEBUG) & DEBUG_PRINT */ +} +/*---------------------------------------------------------------------------*/ +static int +index_of(const uint8_t *data, int offset, int len, uint8_t c) +{ + if(offset < 0) { + return offset; + } + for(; offset < len; offset++) { + if(data[offset] == c) { + return offset; + } + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static int +has_network_access(void) +{ +#if UIP_CONF_IPV6_RPL + if(rpl_get_any_dag() == NULL) { + return 0; + } +#endif /* UIP_CONF_IPV6_RPL */ + return 1; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_use_bootstrap_server(int use) +{ + use_bootstrap = use != 0; + if(use_bootstrap) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_use_registration_server(int use) +{ + use_registration = use != 0; + if(use_registration) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port) +{ + uip_ipaddr_copy(&server_ipaddr, server); + if(port != 0) { + server_port = port; + } else { + server_port = REMOTE_PORT; + } + has_registration_server_info = 1; + registered = 0; + if(use_registration) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +static int +update_registration_server(void) +{ + if(has_registration_server_info) { + return 1; + } + +#if UIP_CONF_IPV6_RPL + { + rpl_dag_t *dag; + + /* Use the DAG id as server address if no other has been specified */ + dag = rpl_get_any_dag(); + if(dag != NULL) { + uip_ipaddr_copy(&server_ipaddr, &dag->dag_id); + server_port = REMOTE_PORT; + return 1; + } + } +#endif /* UIP_CONF_IPV6_RPL */ + + return 0; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, + uint16_t port) +{ + uip_ipaddr_copy(&bs_server_ipaddr, server); + if(port != 0) { + bs_server_port = port; + } else { + bs_server_port = BS_REMOTE_PORT; + } + has_bootstrap_server_info = 1; + bootstrapped = 0; + registered = 0; + if(use_bootstrap) { + process_poll(&lwm2m_rd_client); + } +} +/*---------------------------------------------------------------------------*/ +static int +update_bootstrap_server(void) +{ + if(has_bootstrap_server_info) { + return 1; + } + +#if UIP_CONF_IPV6_RPL + { + rpl_dag_t *dag; + + /* Use the DAG id as server address if no other has been specified */ + dag = rpl_get_any_dag(); + if(dag != NULL) { + uip_ipaddr_copy(&bs_server_ipaddr, &dag->dag_id); + bs_server_port = REMOTE_PORT; + return 1; + } + } +#endif /* UIP_CONF_IPV6_RPL */ + + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(lwm2m_rd_client, ev, data) +{ + static coap_packet_t request[1]; /* This way the packet can be treated as pointer as usual. */ + static struct etimer et; + + PROCESS_BEGIN(); + + printf("RD Client started with endpoint '%s'\n", endpoint); + + etimer_set(&et, 15 * CLOCK_SECOND); + + while(1) { + PROCESS_YIELD(); + + if(etimer_expired(&et)) { + if(!has_network_access()) { + /* Wait until for a network to join */ + } else if(use_bootstrap && bootstrapped == 0) { + if(update_bootstrap_server()) { + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); + coap_set_header_uri_path(request, "/bs"); + coap_set_header_uri_query(request, endpoint); + + printf("Registering ID with bootstrap server ["); + uip_debug_ipaddr_print(&bs_server_ipaddr); + printf("]:%u as '%s'\n", uip_ntohs(bs_server_port), endpoint); + + COAP_BLOCKING_REQUEST(&bs_server_ipaddr, bs_server_port, request, + client_chunk_handler); + bootstrapped++; + } + } else if(use_bootstrap && bootstrapped == 1) { + lwm2m_context_t context; + const lwm2m_instance_t *instance = NULL; + const lwm2m_resource_t *rsc; + const uint8_t *first; + int len; + + PRINTF("*** Bootstrap - checking for server info...\n"); + + /* get the security object */ + instance = get_first_instance_of_object(LWM2M_OBJECT_SECURITY_ID, &context); + if(instance != NULL) { + /* get the server URI */ + context.resource_id = LWM2M_SECURITY_SERVER_URI; + rsc = get_resource(instance, &context); + first = lwm2m_object_get_resource_string(rsc, &context); + len = lwm2m_object_get_resource_strlen(rsc, &context); + if(first != NULL && len > 0) { + int start, end; + uip_ipaddr_t addr; + int32_t port; + uint8_t secure = 0; + + PRINTF("**** Found security instance using: %.*s\n", len, first); + /* TODO Should verify it is a URI */ + + /* Check if secure */ + secure = strncmp((const char *)first, "coaps:", 6) == 0; + + /* Only IPv6 supported */ + start = index_of(first, 0, len, '['); + end = index_of(first, start, len, ']'); + if(start > 0 && end > start && + uiplib_ipaddrconv((const char *)&first[start], &addr)) { + if(first[end + 1] == ':' && + lwm2m_plain_text_read_int(first + end + 2, len - end - 2, &port)) { + } else if(secure) { + /** + * Secure CoAP should use a different port but for now + * the same port is used. + */ + port = COAP_DEFAULT_PORT; + } else { + port = COAP_DEFAULT_PORT; + } + PRINTF("Server address "); + PRINT6ADDR(&addr); + PRINTF(" port %" PRId32 "%s\n", port, secure ? " (secure)" : ""); + if(secure) { + printf("Secure CoAP requested but not supported - can not bootstrap\n"); + } else { + lwm2m_engine_register_with_server(&addr, + UIP_HTONS((uint16_t)port)); + bootstrapped++; + } + } else { + printf("** failed to parse URI %.*s\n", len, first); + } + } + } + + if(bootstrapped == 1) { + /* Not ready. Lets retry with the bootstrap server again */ + bootstrapped = 0; + } + + } else if(use_registration && !registered && + update_registration_server()) { + int pos; + int len, i, j; + registered = 1; + + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0); + coap_set_header_uri_path(request, "/rd"); + coap_set_header_uri_query(request, endpoint); + + /* generate the rd data */ + pos = 0; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] != NULL) { + for(j = 0; j < objects[i]->count; j++) { + if(objects[i]->instances[j].flag & LWM2M_INSTANCE_FLAG_USED) { + len = snprintf(&rd_data[pos], sizeof(rd_data) - pos, + "%s<%d/%d>", pos > 0 ? "," : "", + objects[i]->id, objects[i]->instances[j].id); + if(len > 0 && len < sizeof(rd_data) - pos) { + pos += len; + } + } + } + } + } + + coap_set_payload(request, (uint8_t *)rd_data, pos); + + printf("Registering with ["); + uip_debug_ipaddr_print(&server_ipaddr); + printf("]:%u lwm2m endpoint '%s': '%.*s'\n", uip_ntohs(server_port), + endpoint, pos, rd_data); + COAP_BLOCKING_REQUEST(&server_ipaddr, server_port, request, + client_chunk_handler); + } + /* for now only register once... registered = 0; */ + etimer_set(&et, 15 * CLOCK_SECOND); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_init(void) +{ +#ifdef LWM2M_ENGINE_CLIENT_ENDPOINT_NAME + + snprintf(endpoint, sizeof(endpoint) - 1, + "?ep=" LWM2M_ENGINE_CLIENT_ENDPOINT_NAME); + +#else /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */ + + int len, i; + uint8_t state; + uip_ipaddr_t *ipaddr; + char client[sizeof(endpoint)]; + + len = strlen(LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX); + /* ensure that this fits with the hex-nums */ + if(len > sizeof(client) - 13) { + len = sizeof(client) - 13; + } + memcpy(client, LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX, len); + + /* pick an IP address that is PREFERRED or TENTATIVE */ + ipaddr = NULL; + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + ipaddr = &(uip_ds6_if.addr_list[i]).ipaddr; + break; + } + } + + if(ipaddr != NULL) { + for(i = 0; i < 6; i++) { + /* assume IPv6 for now */ + uint8_t b = ipaddr->u8[10 + i]; + client[len++] = (b >> 4) > 9 ? 'A' - 10 + (b >> 4) : '0' + (b >> 4); + client[len++] = (b & 0xf) > 9 ? 'A' - 10 + (b & 0xf) : '0' + (b & 0xf); + } + } + + /* a zero at end of string */ + client[len] = 0; + /* create endpoint */ + snprintf(endpoint, sizeof(endpoint) - 1, "?ep=%s", client); + +#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */ + + rest_init_engine(); + process_start(&lwm2m_rd_client, NULL); +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_register_default_objects(void) +{ + lwm2m_security_init(); + lwm2m_server_init(); + lwm2m_device_init(); +} +/*---------------------------------------------------------------------------*/ +static int +parse_next(const char **path, int *path_len, uint16_t *value) +{ + char c; + *value = 0; + /* printf("parse_next: %p %d\n", *path, *path_len); */ + if(*path_len == 0) { + return 0; + } + while(*path_len > 0) { + c = **path; + (*path)++; + *path_len = *path_len - 1; + if(c >= '0' && c <= '9') { + *value = *value * 10 + (c - '0'); + } else if(c == '/') { + return 1; + } else { + /* error */ + return -4; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_engine_parse_context(const lwm2m_object_t *object, + const char *path, int path_len, + lwm2m_context_t *context) +{ + int ret; + if(context == NULL || object == NULL || path == NULL) { + return 0; + } + memset(context, 0, sizeof(lwm2m_context_t)); + /* get object id */ + ret = 0; + ret += parse_next(&path, &path_len, &context->object_id); + ret += parse_next(&path, &path_len, &context->object_instance_id); + ret += parse_next(&path, &path_len, &context->resource_id); + + /* Set default reader/writer */ + context->reader = &lwm2m_plain_text_reader; + context->writer = &oma_tlv_writer; + + return ret; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_object_t * +lwm2m_engine_get_object(uint16_t id) +{ + int i; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] != NULL && objects[i]->id == id) { + return objects[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_engine_register_object(const lwm2m_object_t *object) +{ + int i; + int found = 0; + for(i = 0; i < MAX_OBJECTS; i++) { + if(objects[i] == NULL) { + objects[i] = object; + found = 1; + break; + } + } + rest_activate_resource(lwm2m_object_get_coap_resource(object), + (char *)object->path); + return found; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_instance_t * +get_first_instance_of_object(uint16_t id, lwm2m_context_t *context) +{ + const lwm2m_object_t *object; + int i; + + object = lwm2m_engine_get_object(id); + if(object == NULL) { + /* No object with the specified id found */ + return NULL; + } + + /* Initialize the context */ + memset(context, 0, sizeof(lwm2m_context_t)); + context->object_id = id; + + for(i = 0; i < object->count; i++) { + if(object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) { + context->object_instance_id = object->instances[i].id; + context->object_instance_index = i; + return &object->instances[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_instance_t * +get_instance(const lwm2m_object_t *object, lwm2m_context_t *context, int depth) +{ + int i; + if(depth > 1) { + PRINTF("lwm2m: searching for instance %u\n", context->object_instance_id); + for(i = 0; i < object->count; i++) { + PRINTF(" Instance %d -> %u (used: %d)\n", i, object->instances[i].id, + (object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) != 0); + if(object->instances[i].id == context->object_instance_id && + object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) { + context->object_instance_index = i; + return &object->instances[i]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static const lwm2m_resource_t * +get_resource(const lwm2m_instance_t *instance, lwm2m_context_t *context) +{ + int i; + if(instance != NULL) { + PRINTF("lwm2m: searching for resource %u\n", context->resource_id); + for(i = 0; i < instance->count; i++) { + PRINTF(" Resource %d -> %u\n", i, instance->resources[i].id); + if(instance->resources[i].id == context->resource_id) { + context->resource_index = i; + return &instance->resources[i]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +write_rd_link_data(const lwm2m_object_t *object, + const lwm2m_instance_t *instance, + char *buffer, size_t size) +{ + const lwm2m_resource_t *resource; + int len, rdlen, i; + + PRINTF("<%d/%d>", object->id, instance->id); + rdlen = snprintf(buffer, size, "<%d/%d>", + object->id, instance->id); + if(rdlen < 0 || rdlen >= size) { + return -1; + } + + for(i = 0; i < instance->count; i++) { + resource = &instance->resources[i]; + PRINTF(",<%d/%d/%d>", object->id, instance->id, resource->id); + + len = snprintf(&buffer[rdlen], size - rdlen, + ",<%d/%d/%d>", object->id, instance->id, resource->id); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + } + return rdlen; +} +/*---------------------------------------------------------------------------*/ +static int +write_rd_json_data(const lwm2m_context_t *context, + const lwm2m_object_t *object, + const lwm2m_instance_t *instance, + char *buffer, size_t size) +{ + const lwm2m_resource_t *resource; + const char *s = ""; + int len, rdlen, i; + + PRINTF("{\"e\":["); + rdlen = snprintf(buffer, size, "{\"e\":["); + if(rdlen < 0 || rdlen >= size) { + return -1; + } + + for(i = 0, len = 0; i < instance->count; i++) { + resource = &instance->resources[i]; + len = 0; + if(lwm2m_object_is_resource_string(resource)) { + const uint8_t *value; + uint16_t slen; + value = lwm2m_object_get_resource_string(resource, context); + slen = lwm2m_object_get_resource_strlen(resource, context); + if(value != NULL) { + PRINTF("%s{\"n\":\"%u\",\"vs\":\"%.*s\"}", s, + resource->id, slen, value); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"vs\":\"%.*s\"}", s, + resource->id, slen, value); + } + } else if(lwm2m_object_is_resource_int(resource)) { + int32_t value; + if(lwm2m_object_get_resource_int(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, + resource->id, value); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, + resource->id, value); + } + } else if(lwm2m_object_is_resource_floatfix(resource)) { + int32_t value; + if(lwm2m_object_get_resource_floatfix(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"v\":%" PRId32 "}", s, resource->id, + value / LWM2M_FLOAT32_FRAC); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"v\":", s, resource->id); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + + len = lwm2m_plain_text_write_float32fix((uint8_t *)&buffer[rdlen], + size - rdlen, + value, LWM2M_FLOAT32_BITS); + if(len == 0) { + return -1; + } + rdlen += len; + + if(rdlen < size) { + buffer[rdlen] = '}'; + } + len = 1; + } + } else if(lwm2m_object_is_resource_boolean(resource)) { + int value; + if(lwm2m_object_get_resource_boolean(resource, context, &value)) { + PRINTF("%s{\"n\":\"%u\",\"v\":%s}", s, resource->id, + value ? "true" : "false"); + len = snprintf(&buffer[rdlen], size - rdlen, + "%s{\"n\":\"%u\",\"v\":%s}", s, resource->id, + value ? "true" : "false"); + } + } + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + if(len > 0) { + s = ","; + } + } + PRINTF("]}\n"); + len = snprintf(&buffer[rdlen], size - rdlen, "]}"); + rdlen += len; + if(len < 0 || rdlen >= size) { + return -1; + } + + return rdlen; +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset) +{ + int len; + const char *url; + unsigned int format; + int depth; + lwm2m_context_t context; + rest_resource_flags_t method; + const lwm2m_instance_t *instance; +#if (DEBUG) & DEBUG_PRINT + const char *method_str; +#endif /* (DEBUG) & DEBUG_PRINT */ + + method = REST.get_method_type(request); + + len = REST.get_url(request, &url); + if(!REST.get_header_content_type(request, &format)) { + PRINTF("No format given. Assume text plain...\n"); + format = LWM2M_TEXT_PLAIN; + } else if(format == TEXT_PLAIN) { + /* CoAP content format text plain - assume LWM2M text plain */ + format = LWM2M_TEXT_PLAIN; + } + + depth = lwm2m_engine_parse_context(object, url, len, &context); + PRINTF("Context: %u/%u/%u found: %d\n", context.object_id, + context.object_instance_id, context.resource_id, depth); + +#if (DEBUG) & DEBUG_PRINT + /* for debugging */ + if(method == METHOD_GET) { + method_str = "GET"; + } else if(method == METHOD_POST) { + method_str = "POST"; + } else if(method == METHOD_PUT) { + method_str = "PUT"; + } else if(method == METHOD_DELETE) { + method_str = "DELETE"; + } else { + method_str = "UNKNOWN"; + } + PRINTF("%s Called Path:%.*s Format:%d ID:%d bsize:%u\n", method_str, len, + url, format, object->id, preferred_size); + if(format == LWM2M_TEXT_PLAIN) { + /* a string */ + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + if(plen > 0) { + PRINTF("Data: '%.*s'\n", plen, (char *)data); + } + } +#endif /* (DEBUG) & DEBUG_PRINT */ + + instance = get_instance(object, &context, depth); + + /* from POST */ + if(depth > 1 && instance == NULL) { + if(method != METHOD_PUT && method != METHOD_POST) { + PRINTF("Error - do not have instance %d\n", context.object_instance_id); + REST.set_response_status(response, NOT_FOUND_4_04); + return; + } else { + const uint8_t *data; + int i, len, plen, pos; + oma_tlv_t tlv; + PRINTF(">>> CREATE ? %d/%d\n", context.object_id, + context.object_instance_id); + + for(i = 0; i < object->count; i++) { + if((object->instances[i].flag & LWM2M_INSTANCE_FLAG_USED) == 0) { + /* allocate this instance */ + object->instances[i].flag |= LWM2M_INSTANCE_FLAG_USED; + object->instances[i].id = context.object_instance_id; + context.object_instance_index = i; + PRINTF("Created instance: %d\n", context.object_instance_id); + REST.set_response_status(response, CREATED_2_01); + instance = &object->instances[i]; + break; + } + } + + if(instance == NULL) { + /* could for some reason not create the instance */ + REST.set_response_status(response, NOT_ACCEPTABLE_4_06); + return; + } + + plen = REST.get_request_payload(request, &data); + if(plen == 0) { + /* do nothing more */ + return; + } + PRINTF("Payload: "); + for(i = 0; i < plen; i++) { + PRINTF("%02x", data[i]); + } + PRINTF("\n"); + + pos = 0; + do { + len = oma_tlv_read(&tlv, (uint8_t *)&data[pos], plen - pos); + PRINTF("Found TLV type=%u id=%u len=%lu\n", + tlv.type, tlv.id, (unsigned long)tlv.length); + /* here we need to do callbacks or write value */ + if(tlv.type == OMA_TLV_TYPE_RESOURCE) { + context.resource_id = tlv.id; + const lwm2m_resource_t *rsc = get_resource(instance, &context); + if(rsc != NULL) { + /* write the value to the resource */ + if(lwm2m_object_is_resource_string(rsc)) { + PRINTF(" new string value for /%d/%d/%d = %.*s\n", + context.object_id, context.object_instance_id, + context.resource_id, (int)tlv.length, tlv.value); + lwm2m_object_set_resource_string(rsc, &context, + tlv.length, tlv.value); + } else if(lwm2m_object_is_resource_int(rsc)) { + PRINTF(" new int value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, oma_tlv_get_int32(&tlv)); + lwm2m_object_set_resource_int(rsc, &context, + oma_tlv_get_int32(&tlv)); + } else if(lwm2m_object_is_resource_floatfix(rsc)) { + int32_t value; + if(oma_tlv_float32_to_fix(&tlv, &value, LWM2M_FLOAT32_BITS)) { + PRINTF(" new float value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, value >> LWM2M_FLOAT32_BITS); + lwm2m_object_set_resource_floatfix(rsc, &context, value); + } else { + PRINTF(" new float value for /%d/%d/%d: FAILED\n", + context.object_id, context.object_instance_id, + context.resource_id); + } + } else if(lwm2m_object_is_resource_boolean(rsc)) { + PRINTF(" new boolean value for /%d/%d/%d = %" PRId32 "\n", + context.object_id, context.object_instance_id, + context.resource_id, oma_tlv_get_int32(&tlv)); + lwm2m_object_set_resource_boolean(rsc, &context, + oma_tlv_get_int32(&tlv) != 0); + } + } + } + pos = pos + len; + } while(len > 0 && pos < plen); + } + return; + } + + if(depth == 3) { + const lwm2m_resource_t *resource = get_resource(instance, &context); + size_t tlvlen = 0; + if(resource == NULL) { + PRINTF("Error - do not have resource %d\n", context.resource_id); + REST.set_response_status(response, NOT_FOUND_4_04); + return; + } + /* HANDLE PUT */ + if(method == METHOD_PUT) { + if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.write != NULL) { + /* pick a reader ??? */ + if(format == LWM2M_TEXT_PLAIN) { + /* a string */ + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + context.reader = &lwm2m_plain_text_reader; + PRINTF("PUT Callback with data: '%.*s'\n", plen, data); + /* no specific reader for plain text */ + tlvlen = resource->value.callback.write(&context, data, plen, + buffer, preferred_size); + PRINTF("tlvlen:%u\n", (unsigned int)tlvlen); + REST.set_response_status(response, CHANGED_2_04); + } else { + PRINTF("PUT callback with format %d\n", format); + REST.set_response_status(response, NOT_ACCEPTABLE_4_06); + } + } else { + PRINTF("PUT - no write callback\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } else { + PRINTF("PUT on non-callback resource!\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + /* HANDLE GET */ + } else if(method == METHOD_GET) { + if(lwm2m_object_is_resource_string(resource)) { + const uint8_t *value; + uint16_t len; + value = lwm2m_object_get_resource_string(resource, &context); + len = lwm2m_object_get_resource_strlen(resource, &context); + if(value != NULL) { + PRINTF("Get string value: %.*s\n", (int)len, (char *)value); + /* TODO check format */ + REST.set_response_payload(response, value, len); + REST.set_header_content_type(response, LWM2M_TEXT_PLAIN); + /* Done */ + return; + } + } else if(lwm2m_object_is_resource_int(resource)) { + int32_t value; + if(lwm2m_object_get_resource_int(resource, &context, &value)) { + /* export INT as TLV */ + tlvlen = oma_tlv_write_int32(resource->id, value, buffer, preferred_size); + PRINTF("Exporting int as TLV: %" PRId32 ", len: %u\n", + value, (unsigned int)tlvlen); + } + } else if(lwm2m_object_is_resource_floatfix(resource)) { + int32_t value; + if(lwm2m_object_get_resource_floatfix(resource, &context, &value)) { + /* export FLOATFIX as TLV */ + PRINTF("Exporting %d-bit fix as float: %" PRId32 "\n", + LWM2M_FLOAT32_BITS, value); + tlvlen = oma_tlv_write_float32(resource->id, + value, LWM2M_FLOAT32_BITS, + buffer, preferred_size); + PRINTF("Exporting as TLV: len:%u\n", (unsigned int)tlvlen); + } + } else if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.read != NULL) { + tlvlen = resource->value.callback.read(&context, + buffer, preferred_size); + } else { + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + return; + } + } + if(tlvlen > 0) { + REST.set_response_payload(response, buffer, tlvlen); + REST.set_header_content_type(response, LWM2M_TLV); + } else { + /* failed to produce output - it is an internal error */ + REST.set_response_status(response, INTERNAL_SERVER_ERROR_5_00); + } + /* Handle POST */ + } else if(method == METHOD_POST) { + if(lwm2m_object_is_resource_callback(resource)) { + if(resource->value.callback.exec != NULL) { + const uint8_t *data; + int plen = REST.get_request_payload(request, &data); + PRINTF("Execute Callback with data: '%.*s'\n", plen, data); + tlvlen = resource->value.callback.exec(&context, + data, plen, + buffer, preferred_size); + REST.set_response_status(response, CHANGED_2_04); + } else { + PRINTF("Execute callback - no exec callback\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } else { + PRINTF("Resource post but no callback resource\n"); + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } + } + } else if(depth == 2) { + /* produce an instance response */ + if(method != METHOD_GET) { + REST.set_response_status(response, METHOD_NOT_ALLOWED_4_05); + } else if(instance == NULL) { + REST.set_response_status(response, NOT_FOUND_4_04); + } else { + int rdlen; + if(format == APPLICATION_LINK_FORMAT) { + rdlen = write_rd_link_data(object, instance, + (char *)buffer, preferred_size); + } else { + rdlen = write_rd_json_data(&context, object, instance, + (char *)buffer, preferred_size); + } + if(rdlen < 0) { + PRINTF("Failed to generate instance response\n"); + REST.set_response_status(response, SERVICE_UNAVAILABLE_5_03); + return; + } + REST.set_response_payload(response, buffer, rdlen); + if(format == APPLICATION_LINK_FORMAT) { + REST.set_header_content_type(response, REST.type.APPLICATION_LINK_FORMAT); + } else { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +lwm2m_engine_delete_handler(const lwm2m_object_t *object, void *request, + void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + int len; + const char *url; + lwm2m_context_t context; + + len = REST.get_url(request, &url); + PRINTF("*** DELETE URI:'%.*s' called... - responding with DELETED.\n", + len, url); + len = lwm2m_engine_parse_context(object, url, len, &context); + PRINTF("Context: %u/%u/%u found: %d\n", context.object_id, + context.object_instance_id, context.resource_id, len); + + REST.set_response_status(response, DELETED_2_02); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-engine.h b/apps/oma-lwm2m/lwm2m-engine.h new file mode 100644 index 000000000..5512a326d --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-engine.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M engine + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_ENGINE_H +#define LWM2M_ENGINE_H + +#include "lwm2m-object.h" + +#define LWM2M_FLOAT32_BITS 10 +#define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS) + +/* LWM2M / CoAP Content-Formats */ +typedef enum { + LWM2M_TEXT_PLAIN = 1541, + LWM2M_TLV = 1542, + LWM2M_JSON = 1543, + LWM2M_OPAQUE = 1544 +} lwm2m_content_format_t; + +void lwm2m_engine_init(void); +void lwm2m_engine_register_default_objects(void); +void lwm2m_engine_use_bootstrap_server(int use); +void lwm2m_engine_use_registration_server(int use); +void lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port); +void lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, uint16_t port); + +const lwm2m_object_t *lwm2m_engine_get_object(uint16_t id); + +int lwm2m_engine_register_object(const lwm2m_object_t *object); + +void lwm2m_engine_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); + +void lwm2m_engine_delete_handler(const lwm2m_object_t *object, + void *request, void *response, + uint8_t *buffer, uint16_t preferred_size, + int32_t *offset); + +#endif /* LWM2M_ENGINE_H */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-object.c b/apps/oma-lwm2m/lwm2m-object.c new file mode 100644 index 000000000..2f5ddb6ed --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-object.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M object API + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_string(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const uint8_t * +lwm2m_object_get_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context) +{ + if(resource == NULL || context == NULL) { + return NULL; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) { + return resource->value.string.value; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + return *(resource->value.stringvar.var); + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count) { + return resource->value.stringvararr.var + + resource->value.stringvararr.size * context->object_instance_index; + } + return NULL; + } + /* Not a string */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +uint16_t +lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource, + const lwm2m_context_t *context) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) { + return resource->value.string.len; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + return *(resource->value.stringvar.len); + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count) { + return resource->value.stringvararr.len[context->object_instance_index]; + } + return 0; + } + /* Not a string */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + uint16_t len, const uint8_t *string) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) { + if(len > resource->value.stringvar.size) { + /* Too large */ + return 0; + } + memcpy(resource->value.stringvar.var, string, len); + *(resource->value.stringvar.len) = len; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.stringvararr.count && + len <= resource->value.stringvararr.size) { + memcpy(resource->value.stringvararr.var + + resource->value.stringvararr.size * context->object_instance_index, + string, len); + resource->value.stringvararr.len[context->object_instance_index] = len; + return 1; + } + return 0; + } + /* Not a string variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_int(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE) { + *value = resource->value.integer.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) { + *value = *(resource->value.integervar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.integervararr.count) { + *value = resource->value.integervararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not an integer */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) { + *(resource->value.integervar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.integervararr.count) { + resource->value.integervararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not an integer variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE) { + *value = resource->value.floatfix.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) { + *value = *(resource->value.floatfixvar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.floatfixvararr.count) { + *value = resource->value.floatfixvararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not an float */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) { + *(resource->value.floatfixvar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.floatfixvararr.count) { + resource->value.floatfixvararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not an float variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource) +{ + if(resource == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE || + resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE || + resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int *value) +{ + if(resource == NULL || context == NULL || value == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE) { + *value = resource->value.boolean.value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) { + *value = *(resource->value.booleanvar.var); + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.booleanvararr.count) { + *value = resource->value.booleanvararr.var[context->object_instance_index]; + return 1; + } + return 0; + } + /* Not a boolean */ + return 0; +} +/*---------------------------------------------------------------------------*/ +int +lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int value) +{ + if(resource == NULL || context == NULL) { + return 0; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) { + *(resource->value.booleanvar.var) = value; + return 1; + } + if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) { + if(context->object_instance_index < resource->value.booleanvararr.count) { + resource->value.booleanvararr.var[context->object_instance_index] = + value; + return 1; + } + return 0; + } + /* Not a boolean variable */ + return 0; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-object.h b/apps/oma-lwm2m/lwm2m-object.h new file mode 100644 index 000000000..5c391cb41 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-object.h @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 apps + * @{ + */ + +/** + * \defgroup oma-lwm2m An implementation of OMA LWM2M + * @{ + * + * This application is an implementation of OMA Lightweight M2M. + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M object API + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_OBJECT_H_ +#define LWM2M_OBJECT_H_ + +#include "rest-engine.h" +#include "er-coap-observe.h" + +#define LWM2M_OBJECT_SECURITY_ID 0 +#define LWM2M_OBJECT_SERVER_ID 1 +#define LWM2M_OBJECT_ACCESS_CONTROL_ID 2 +#define LWM2M_OBJECT_DEVICE_ID 3 +#define LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID 4 +#define LWM2M_OBJECT_FIRMWARE_ID 5 +#define LWM2M_OBJECT_LOCATION_ID 6 +#define LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID 7 + +#define LWM2M_SECURITY_SERVER_URI 0 +#define LWM2M_SECURITY_BOOTSTRAP_SERVER 1 +#define LWM2M_SECURITY_MODE 2 +#define LWM2M_SECURITY_CLIENT_PKI 3 +#define LWM2M_SECURITY_SERVER_PKI 4 +#define LWM2M_SECURITY_KEY 5 +#define LWM2M_SECURITY_SHORT_SERVER_ID 10 + +/* Pre-shared key mode */ +#define LWM2M_SECURITY_MODE_PSK 0 +/* Raw Public Key mode */ +#define LWM2M_SECURITY_MODE_RPK 1 +/* Certificate mode */ +#define LWM2M_SECURITY_MODE_CERTIFICATE 2 +/* NoSec mode */ +#define LWM2M_SECURITY_MODE_NOSEC 3 + +#define LWM2M_OBJECT_STR_HELPER(x) (uint8_t *) #x +#define LWM2M_OBJECT_STR(x) LWM2M_OBJECT_STR_HELPER(x) + +#define LWM2M_OBJECT_PATH_STR_HELPER(x) #x +#define LWM2M_OBJECT_PATH_STR(x) LWM2M_OBJECT_PATH_STR_HELPER(x) + +struct lwm2m_reader; +struct lwm2m_writer; +/* Data model for OMA LWM2M objects */ +typedef struct lwm2m_context { + uint16_t object_id; + uint16_t object_instance_id; + uint16_t resource_id; + uint8_t object_instance_index; + uint8_t resource_index; + /* TODO - add uint16_t resource_instance_id */ + + const struct lwm2m_reader *reader; + const struct lwm2m_writer *writer; +} lwm2m_context_t; + +/* LWM2M format writer for the various formats supported */ +typedef struct lwm2m_writer { + size_t (* write_int)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value); + size_t (* write_string)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, const char *value, size_t strlen); + size_t (* write_float32fix)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value, int bits); + size_t (* write_boolean)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int value); +} lwm2m_writer_t; + +typedef struct lwm2m_reader { + size_t (* read_int)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value); + size_t (* read_string)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, uint8_t *value, size_t strlen); + size_t (* read_float32fix)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value, int bits); + size_t (* read_boolean)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int *value); +} lwm2m_reader_t; + +typedef struct lwm2m_value_callback { + int (* read)(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen); + int (* write)(lwm2m_context_t *ctx, + const uint8_t *buffer, size_t len, + uint8_t *outbuf, size_t outlen); + int (* exec)(lwm2m_context_t *ctx, const uint8_t *arg, size_t len, + uint8_t *outbuf, size_t outlen); +} lwm2m_value_callback_t; + +#define LWM2M_RESOURCE_TYPE_STR_VALUE 1 +#define LWM2M_RESOURCE_TYPE_STR_VARIABLE 2 +#define LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY 3 +#define LWM2M_RESOURCE_TYPE_INT_VALUE 4 +#define LWM2M_RESOURCE_TYPE_INT_VARIABLE 5 +#define LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY 6 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE 7 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE 8 +#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY 9 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE 10 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE 11 +#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY 12 +#define LWM2M_RESOURCE_TYPE_CALLBACK 16 +#define LWM2M_RESOURCE_TYPE_INSTANCES 17 + +typedef struct lwm2m_resource { + uint16_t id; + uint8_t type; /* indicate value type and multi-instance resource */ + union { + struct { + uint16_t len; + const uint8_t *value; + } string; + struct { + uint16_t size; + uint16_t *len; + uint8_t **var; + } stringvar; + struct { + uint16_t count; + uint16_t size; + /* string var array with counting entries */ + uint16_t *len; + uint8_t *var; + } stringvararr; + struct { + int32_t value; + } integer; + struct { + int32_t *var; + } integervar; + struct { + /* used for multiple instances (dynamic) NOTE: this is an index into + the instance so having two instances means that there is need for + allocation of two ints here */ + uint16_t count; + int32_t *var; /* used as an array? */ + } integervararr; + struct { + int32_t value; + } floatfix; + struct { + int32_t *var; + } floatfixvar; + struct { + uint16_t count; + int32_t *var; + } floatfixvararr; + struct { + int value; + } boolean; + struct { + int *var; + } booleanvar; + struct { + uint16_t count; + int *var; + } booleanvararr; + lwm2m_value_callback_t callback; + /* lwm2m_resource *resources[]; TO BE ADDED LATER*/ + } value; +} lwm2m_resource_t; + +#define LWM2M_INSTANCE_FLAG_USED 1 + +typedef struct lwm2m_instance { + uint16_t id; + uint16_t count; + uint16_t flag; + const lwm2m_resource_t *resources; +} lwm2m_instance_t; + +typedef struct lwm2m_object { + uint16_t id; + uint16_t count; + const char *path; + resource_t *coap_resource; + lwm2m_instance_t *instances; +} lwm2m_object_t; + +#define LWM2M_RESOURCES(name, ...) \ + static const lwm2m_resource_t name[] = { __VA_ARGS__ } + +#define LWM2M_RESOURCE_STRING(id, s) \ + { id, LWM2M_RESOURCE_TYPE_STR_VALUE, .value.string.len = sizeof(s) - 1, .value.string.value = (uint8_t *) s } + +#define LWM2M_RESOURCE_STRING_VAR(id, s, l, v) \ + { id, LWM2M_RESOURCE_TYPE_STR_VARIABLE, .value.stringvar.size = (s), .value.stringvar.len = (l), .value.stringvar.var = (v) } + +#define LWM2M_RESOURCE_STRING_VAR_ARR(id, c, s, l, v) \ + { id, LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY, .value.stringvararr.count = c, .value.stringvararr.size = s, .value.stringvararr.len = l, .value.stringvararr.var = (uint8_t *) v } + +#define LWM2M_RESOURCE_INTEGER(id, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VALUE, .value.integer.value = (v) } + +#define LWM2M_RESOURCE_INTEGER_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VARIABLE, .value.integervar.var = (v) } + +#define LWM2M_RESOURCE_INTEGER_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY, .value.integervararr.count = (c), .value.integervararr.var = (v) } + +#define LWM2M_RESOURCE_FLOATFIX(id, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE, .value.floatfix.value = (v) } + +#define LWM2M_RESOURCE_FLOATFIX_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE, .value.floatfixvar.var = (v) } + +#define LWM2M_RESOURCE_FLOATFIX_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY, .value.floatfixvararr.count = (c), .value.floatfixvararr.var = (v) } + +#define LWM2M_RESOURCE_BOOLEAN(id, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE, .value.boolean.value = (v) } + +#define LWM2M_RESOURCE_BOOLEAN_VAR(id, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE, .value.booleanvar.var = (v) } + +#define LWM2M_RESOURCE_BOOLEAN_VAR_ARR(id, c, v) \ + { id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY, .value.booleanvararr.count = (c), .value.booleanvararr.var = (v) } + +#define LWM2M_RESOURCE_CALLBACK(id, ...) \ + { id, LWM2M_RESOURCE_TYPE_CALLBACK, .value.callback = __VA_ARGS__ } + +#define LWM2M_INSTANCE(id, resources) \ + { id, sizeof(resources)/sizeof(lwm2m_resource_t), LWM2M_INSTANCE_FLAG_USED, resources } + +#define LWM2M_INSTANCE_UNUSED(id, resources) \ + { id, sizeof(resources)/sizeof(lwm2m_resource_t), 0, resources } + +#define LWM2M_INSTANCES(name, ...) \ + static lwm2m_instance_t name[] = { __VA_ARGS__ } + +#define LWM2M_OBJECT(name, id, instances) \ + static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \ + static resource_t rest_rsc_##name = { NULL, NULL, HAS_SUB_RESOURCES | IS_OBSERVABLE, NULL, lwm2m_get_h_##name, lwm2m_post_h_##name, lwm2m_put_h_##name, lwm2m_delete_h_##name, { NULL } }; \ + static const lwm2m_object_t name = { id, sizeof(instances)/sizeof(lwm2m_instance_t), LWM2M_OBJECT_PATH_STR(id), &rest_rsc_##name, instances}; \ + static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \ + static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \ + lwm2m_engine_delete_handler(&name, request, response, buffer, preferred_size, offset); } + +/* how do we register attributes in the above resource here ??? */ + +int lwm2m_object_is_resource_string(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_int(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource); +int lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource); + +static inline int +lwm2m_object_is_resource_callback(const lwm2m_resource_t *resource) +{ + return resource != NULL && resource->type == LWM2M_RESOURCE_TYPE_CALLBACK; +} + +const uint8_t * +lwm2m_object_get_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context); + +uint16_t +lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource, + const lwm2m_context_t *context); + +int +lwm2m_object_set_resource_string(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + uint16_t len, const uint8_t *string); + +int +lwm2m_object_get_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value); + +int +lwm2m_object_set_resource_int(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value); + +int +lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t *value); + +int +lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int32_t value); + +int +lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int *value); + +int +lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource, + const lwm2m_context_t *context, + int value); + +static inline resource_t * +lwm2m_object_get_coap_resource(const lwm2m_object_t *object) +{ + return (resource_t *)object->coap_resource; +} + +static inline void +lwm2m_object_notify_observers(const lwm2m_object_t *object, char *path) +{ + coap_notify_observers_sub(lwm2m_object_get_coap_resource(object), path); +} + +#include "lwm2m-engine.h" + +#endif /* LWM2M_OBJECT_H_ */ +/** + * @} + * @} + */ diff --git a/apps/oma-lwm2m/lwm2m-plain-text.c b/apps/oma-lwm2m/lwm2m-plain-text.c new file mode 100644 index 000000000..34b7f2318 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-plain-text.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M plain text reader / writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "lwm2m-plain-text.h" +#include +#include +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, int32_t *value) +{ + int i, neg = 0; + *value = 0; + for(i = 0; i < len; i++) { + if(inbuf[i] >= '0' && inbuf[i] <= '9') { + *value = *value * 10 + (inbuf[i] - '0'); + } else if(inbuf[i] == '-' && i == 0) { + neg = 1; + } else { + break; + } + } + if(neg) { + *value = -*value; + } + return i; +} +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + int i, dot = 0, neg = 0; + int32_t counter, integerpart, frac; + + integerpart = 0; + counter = 0; + frac = 0; + for(i = 0; i < len; i++) { + if(inbuf[i] >= '0' && inbuf[i] <= '9') { + counter = counter * 10 + (inbuf[i] - '0'); + frac = frac * 10; + } else if(inbuf[i] == '.' && dot == 0) { + integerpart = counter; + counter = 0; + frac = 1; + dot = 1; + } else if(inbuf[i] == '-' && i == 0) { + neg = 1; + } else { + break; + } + } + *value = integerpart << bits; + if(frac > 1) { + *value += ((counter << bits) / frac); + } + PRINTF("READ FLOATFIX: \"%.*s\" => int(%ld) frac(%ld) f=%ld Value=%ld\n", + (int)len, (char *)inbuf, + (long)integerpart, + (long)counter, + (long)frac, + (long)*value); + if(neg) { + *value = -*value; + } + return i; +} +/*---------------------------------------------------------------------------*/ +size_t +lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + int64_t v; + unsigned long integer_part; + unsigned long frac_part; + int n, o = 0; + + if(outlen == 0) { + return 0; + } + if(value < 0) { + *outbuf++ = '-'; + outlen--; + o = 1; + value = -value; + } + + integer_part = (unsigned long)(value >> bits); + v = value - (integer_part << bits); + v = (v * 100) >> bits; + frac_part = (unsigned long)v; + + n = snprintf((char *)outbuf, outlen, "%lu.%02lu", integer_part, frac_part); + if(n < 0 || n >= outlen) { + return 0; + } + return n + o; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + if(outlen > 0) { + if(value) { + *outbuf = '1'; + } else { + *outbuf = '0'; + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + int n = snprintf((char *)outbuf, outlen, "%ld", (long)value); + if(n < 0 || n >= outlen) { + return 0; + } + return n; +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value, int bits) +{ + return lwm2m_plain_text_write_float32fix(outbuf, outlen, value, bits); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + int n = snprintf((char *)outbuf, outlen, "%.*s", (int) stringlen, value); + if(n < 0 || n >= outlen) { + return 0; + } + return n; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t lwm2m_plain_text_writer = { + write_int, + write_string, + write_float32fix, + write_boolean +}; +/*---------------------------------------------------------------------------*/ +static size_t +read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value) +{ + return lwm2m_plain_text_read_int(inbuf, len, value); +} +/*---------------------------------------------------------------------------*/ +static size_t +read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + uint8_t *value, size_t stringlen) +{ + if(stringlen <= len) { + /* The outbuffer can not contain the full string including ending zero */ + return 0; + } + memcpy(value, inbuf, len); + value[len] = '\0'; + return len; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + return lwm2m_plain_text_read_float32fix(inbuf, len, value, bits); +} +/*---------------------------------------------------------------------------*/ +static size_t +read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int *value) +{ + if(len > 0) { + if(*inbuf == '1' || *inbuf == '0') { + *value = *inbuf == '1' ? 1 : 0; + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_reader_t lwm2m_plain_text_reader = { + read_int, + read_string, + read_float32fix, + read_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-plain-text.h b/apps/oma-lwm2m/lwm2m-plain-text.h new file mode 100644 index 000000000..bf12a118c --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-plain-text.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + */ + +/** + * \file + * Header file for the Contiki OMA LWM2M plain text reader / writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef LWM2M_PLAIN_TEXT_H_ +#define LWM2M_PLAIN_TEXT_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_reader_t lwm2m_plain_text_reader; +extern const lwm2m_writer_t lwm2m_plain_text_writer; + +size_t lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, + int32_t *value); + +size_t lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len, + int32_t *value, int bits); + +size_t lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen, + int32_t value, int bits); + +#endif /* LWM2M_PLAIN_TEXT_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-security.c b/apps/oma-lwm2m/lwm2m-security.c new file mode 100644 index 000000000..953279b4d --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-security.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M security + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifdef LWM2M_CONF_SERVER_MAX_COUNT +#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT +#else +#define MAX_COUNT 2 +#endif + +/* hoping that we do not get more than 64 bytes... */ +#define MAX_SIZE 64 + +static int32_t bs_arr[MAX_COUNT]; +static int32_t secmode_arr[MAX_COUNT]; +static int32_t sid_arr[MAX_COUNT]; + +static char server_uri[MAX_COUNT][MAX_SIZE]; +static uint16_t su_len[MAX_COUNT]; +static char client_id[MAX_COUNT][MAX_SIZE]; +static uint16_t client_id_len[MAX_COUNT]; +static char server_id[MAX_COUNT][MAX_SIZE]; +static uint16_t server_id_len[MAX_COUNT]; +static char psk_key[MAX_COUNT][MAX_SIZE]; +static uint16_t psk_key_len[MAX_COUNT]; +static lwm2m_instance_t security_instances[MAX_COUNT]; + +LWM2M_RESOURCES(security_resources, + LWM2M_RESOURCE_STRING_VAR_ARR(0, MAX_COUNT, MAX_SIZE, su_len, server_uri), + LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, bs_arr), + LWM2M_RESOURCE_INTEGER_VAR_ARR(2, MAX_COUNT, secmode_arr), + LWM2M_RESOURCE_STRING_VAR_ARR(3, MAX_COUNT, MAX_SIZE, client_id_len, client_id), + LWM2M_RESOURCE_STRING_VAR_ARR(4, MAX_COUNT, MAX_SIZE, server_id_len, server_id), + /* TODO This should not be readable! */ + LWM2M_RESOURCE_STRING_VAR_ARR(5, MAX_COUNT, MAX_SIZE, psk_key_len, psk_key), + LWM2M_RESOURCE_INTEGER_VAR_ARR(10, MAX_COUNT, sid_arr) + ); +LWM2M_OBJECT(security, 0, security_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_security_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, security_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < MAX_COUNT; i++) { + security_instances[i] = template; + security_instances[i].id = i; + } + + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle. + */ + PRINTF("*** Init lwm2m-security\n"); + lwm2m_engine_register_object(&security); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/lwm2m-server.c b/apps/oma-lwm2m/lwm2m-server.c new file mode 100644 index 000000000..9de678682 --- /dev/null +++ b/apps/oma-lwm2m/lwm2m-server.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M server + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include "lwm2m-object.h" +#include "lwm2m-engine.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#ifdef LWM2M_CONF_SERVER_MAX_COUNT +#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT +#else +#define MAX_COUNT 2 +#endif + +static int32_t sid_arr[MAX_COUNT]; +static int32_t lifetime_arr[MAX_COUNT]; +static lwm2m_instance_t server_instances[MAX_COUNT]; + +LWM2M_RESOURCES(server_resources, + LWM2M_RESOURCE_INTEGER_VAR_ARR(0, MAX_COUNT, sid_arr), + LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, lifetime_arr), + ); +LWM2M_OBJECT(server, 1, server_instances); +/*---------------------------------------------------------------------------*/ +void +lwm2m_server_init(void) +{ + lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, server_resources); + int i; + + /* Initialize the instances */ + for(i = 0; i < MAX_COUNT; i++) { + server_instances[i] = template; + server_instances[i].id = i; + } + + /** + * Register this device and its handlers - the handlers + * automatically sends in the object to handle + */ + PRINTF("*** Init lwm2m-server\n"); + lwm2m_engine_register_object(&server); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-reader.c b/apps/oma-lwm2m/oma-tlv-reader.c new file mode 100644 index 000000000..58e1dcc54 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-reader.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV reader + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "oma-tlv-reader.h" +#include "oma-tlv.h" + +/*---------------------------------------------------------------------------*/ +static size_t +read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + *value = oma_tlv_get_int32(&tlv); + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + uint8_t *value, size_t stringlen) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + if(stringlen <= tlv.length) { + /* The outbuffer can not contain the full string including ending zero */ + return 0; + } + memcpy(value, tlv.value, tlv.length); + value[tlv.length] = '\0'; + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int32_t *value, int bits) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + oma_tlv_float32_to_fix(&tlv, value, bits); + } + return size; +} +/*---------------------------------------------------------------------------*/ +static size_t +read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, + int *value) +{ + oma_tlv_t tlv; + size_t size; + size = oma_tlv_read(&tlv, inbuf, len); + if(size > 0) { + *value = oma_tlv_get_int32(&tlv) != 0; + } + return size; +} +/*---------------------------------------------------------------------------*/ +const lwm2m_reader_t oma_tlv_reader = { + read_int, + read_string, + read_float32fix, + read_boolean +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-reader.h b/apps/oma-lwm2m/oma-tlv-reader.h new file mode 100644 index 000000000..7e6540c18 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-reader.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV reader + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OMA_TLV_READER_H_ +#define OMA_TLV_READER_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_reader_t oma_tlv_reader; + +#endif /* OMA_TLV_READER_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-writer.c b/apps/oma-lwm2m/oma-tlv-writer.c new file mode 100644 index 000000000..2f26a69f6 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-writer.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "lwm2m-object.h" +#include "oma-tlv.h" +/*---------------------------------------------------------------------------*/ +static size_t +write_boolean_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int value) +{ + return oma_tlv_write_int32(ctx->resource_id, value != 0 ? 1 : 0, + outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_int_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + int32_t value) +{ + return oma_tlv_write_int32(ctx->resource_id, value, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_float32fix_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, + size_t outlen, int32_t value, int bits) +{ + return oma_tlv_write_float32(ctx->resource_id, value, bits, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +static size_t +write_string_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, + const char *value, size_t stringlen) +{ + oma_tlv_t tlv; + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.value = (uint8_t *) value; + tlv.length = (uint32_t) stringlen; + tlv.id = ctx->resource_id; + return oma_tlv_write(&tlv, outbuf, outlen); +} +/*---------------------------------------------------------------------------*/ +const lwm2m_writer_t oma_tlv_writer = { + write_int_tlv, + write_string_tlv, + write_float32fix_tlv, + write_boolean_tlv +}; +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv-writer.h b/apps/oma-lwm2m/oma-tlv-writer.h new file mode 100644 index 000000000..6ae5edd14 --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv-writer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV writer + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OMA_TLV_WRITER_H_ +#define OMA_TLV_WRITER_H_ + +#include "lwm2m-object.h" + +extern const lwm2m_writer_t oma_tlv_writer; + +#endif /* OMA_TLV_WRITER_H_ */ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv.c b/apps/oma-lwm2m/oma-tlv.c new file mode 100644 index 000000000..c07df31cc --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ + * + */ + +/** + * \file + * Implementation of the Contiki OMA LWM2M TLV + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include +#include +#include "oma-tlv.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/*---------------------------------------------------------------------------*/ +static inline uint8_t +get_len_type(const oma_tlv_t *tlv) +{ + if(tlv->length < 8) { + return 0; + } else if(tlv->length < 256) { + return 1; + } else if(tlv->length < 0x10000) { + return 2; + } else { + return 3; + } +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len) +{ + uint8_t len_type; + uint8_t len_pos = 1; + size_t tlv_len; + + tlv->type = (buffer[0] >> 6) & 3; + len_type = (buffer[0] >> 3) & 3; + len_pos = 1 + (((buffer[0] & (1 << 5)) != 0) ? 2 : 1); + + tlv->id = buffer[1]; + /* if len_pos is larger than two it means that there is more ID to read */ + if(len_pos > 2) { + tlv->id = (tlv->id << 8) + buffer[2]; + } + + if(len_type == 0) { + tlv_len = buffer[0] & 7; + } else { + /* read the length */ + tlv_len = 0; + while(len_type > 0) { + tlv_len = tlv_len << 8 | buffer[len_pos++]; + len_type--; + } + } + /* and read out the data??? */ + tlv->length = tlv_len; + tlv->value = &buffer[len_pos]; + + return len_pos + tlv_len; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_get_size(const oma_tlv_t *tlv) +{ + size_t size; + /* first hdr + len size */ + size = 1 + get_len_type(tlv); + /* id size */ + size += (tlv->id > 255) ? 2 : 1; + + /* and the length */ + size += tlv->length; + return size; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len) +{ + int pos; + uint8_t len_type; + + /* len type is the same as number of bytes required for length */ + len_type = get_len_type(tlv); + pos = 1 + len_type; + /* ensure that we do not write too much */ + if(len < tlv->length + pos) { + PRINTF("OMA-TLV: Could not write the TLV - buffer overflow.\n"); + return 0; + } + + /* first type byte in TLV header */ + buffer[0] = (tlv->type << 6) | + (tlv->id > 255 ? (1 << 5) : 0) | + (len_type << 3) | + (len_type == 0 ? tlv->length : 0); + + pos = 1; + /* The ID */ + if(tlv->id > 255) { + buffer[pos++] = (tlv->id >> 8) & 0xff; + } + buffer[pos++] = tlv->id & 0xff; + /* Add length if needed - unrolled loop ? */ + if(len_type > 2) { + buffer[pos++] = (tlv->length >> 16) & 0xff; + } + if(len_type > 1) { + buffer[pos++] = (tlv->length >> 8) & 0xff; + } + if(len_type > 0) { + buffer[pos++] = tlv->length & 0xff; + } + + /* finally add the value */ + memcpy(&buffer[pos], tlv->value, tlv->length); + + if(DEBUG) { + int i; + PRINTF("TLV:"); + for(i = 0; i < pos + tlv->length; i++) { + PRINTF("%02x", buffer[i]); + } + PRINTF("\n"); + } + + return pos + tlv->length; +} +/*---------------------------------------------------------------------------*/ +int32_t +oma_tlv_get_int32(const oma_tlv_t *tlv) +{ + int i; + int32_t value = 0; + /* will probably need to handle MSB as a sign bit? */ + for(i = 0; i < tlv->length; i++) { + value = (value << 8) | tlv->value[i]; + } + return value; +} +/*---------------------------------------------------------------------------*/ +size_t +oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len) +{ + oma_tlv_t tlv; + size_t tlvlen = 0; + uint8_t buf[4]; + int i; + PRINTF("Exporting int32 %d %ld ", id, (long)value); + + buf[3] = value & 0xff; + value = value >> 8; + for(i = 1; value > 0 && i < 4; i++) { + buf[3 - i] = value & 0xff; + value = value >> 8; + } + tlvlen = i; + + /* export INT as TLV */ + PRINTF("len: %zu\n", tlvlen); + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.length = tlvlen; + tlv.value = &buf[3 - (tlvlen - 1)]; + tlv.id = id; + return oma_tlv_write(&tlv, buffer, len); +} +/*---------------------------------------------------------------------------*/ +/* convert fixpoint 32-bit to a IEEE Float in the byte array*/ +size_t +oma_tlv_write_float32(int16_t id, int32_t value, int bits, + uint8_t *buffer, size_t len) +{ + int i; + int e = 0; + int32_t val = 0; + int32_t v; + uint8_t b[4]; + oma_tlv_t tlv; + + v = value; + if(v < 0) { + v = -v; + } + + while(v > 1) { + val = (val >> 1); + if (v & 1) { + val = val | (1L << 22); + } + v = (v >> 1); + e++; + } + + PRINTF("Sign: %d, Fraction: %06lx 0b", value < 0, (long)val); + for(i = 0; i < 23; i++) { + PRINTF("%d", (int)((val >> (22 - i)) & 1)); + } + PRINTF("\nExp:%d\n", e); + + /* convert to the thing we should have */ + e = e - bits + 127; + + /* is this the right byte order? */ + b[0] = (value < 0 ? 0x80 : 0) | (e >> 1); + b[1] = ((e & 1) << 7) | ((val >> 16) & 0x7f); + b[2] = (val >> 8) & 0xff; + b[3] = val & 0xff; + + /* construct the TLV */ + tlv.type = OMA_TLV_TYPE_RESOURCE; + tlv.length = 4; + tlv.value = b; + tlv.id = id; + + return oma_tlv_write(&tlv, buffer, len); +} +/*---------------------------------------------------------------------------*/ +/* convert float to fixpoint */ +size_t +oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits) +{ + /* TLV needs to be 4 bytes */ + int e, i; + int32_t val; + int sign = (tlv->value[0] & 0x80) != 0; + e = ((tlv->value[0] << 1) & 0xff) | (tlv->value[1] >> 7); + val = (((long)tlv->value[1] & 0x7f) << 16) | (tlv->value[2] << 8) | tlv->value[3]; + + PRINTF("Sign: %d, Fraction: %06lx 0b", val < 0, (long)val); + for(i = 0; i < 23; i++) { + PRINTF("%d", (int)((val >> (22 - i)) & 1)); + } + PRINTF("\nExp:%d => %d\n", e, e - 127); + + e = e - 127 + bits; + + /* e corresponds to the number of times we need to roll the number */ + + PRINTF("Actual e=%d\n", e); + e = e - 23; + PRINTF("E after sub %d\n", e); + val = val | 1L << 23; + if(e > 0) { + val = val << e; + } else { + val = val >> -e; + } + + *value = sign ? -val : val; + return 4; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/apps/oma-lwm2m/oma-tlv.h b/apps/oma-lwm2m/oma-tlv.h new file mode 100644 index 000000000..1bd5fd94a --- /dev/null +++ b/apps/oma-lwm2m/oma-tlv.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 oma-lwm2m + * @{ */ + +/** + * \file + * Header file for the Contiki OMA LWM2M TLV + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef OAM_TLV_H_ +#define OAM_TLV_H_ + +#include "contiki.h" + +enum { + OMA_TLV_TYPE_OBJECT_INSTANCE = 0, + OMA_TLV_TYPE_RESOURCE_INSTANCE = 1, + OMA_TLV_TYPE_MULTI_RESOURCE = 2, + OMA_TLV_TYPE_RESOURCE = 3 +}; +typedef uint8_t oma_tlv_type_t; + +typedef enum { + OMA_TLV_LEN_TYPE_NO_LEN = 0, + OMA_TLV_LEN_TYPE_8BIT_LEN = 1, + OMA_TLV_LEN_TYPE_16BIT_LEN = 2, + OMA_TLV_LEN_TYPE_24BIT_LEN = 3 +} oma_tlv_len_type_t; + +typedef struct { + oma_tlv_type_t type; + uint16_t id; /* can be 8-bit or 16-bit when serialized */ + uint32_t length; + const uint8_t *value; +} oma_tlv_t; + +size_t oma_tlv_get_size(const oma_tlv_t *tlv); + +/* read a TLV from the buffer */ +size_t oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len); + +/* write a TLV to the buffer */ +size_t oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len); + +int32_t oma_tlv_get_int32(const oma_tlv_t *tlv); + +/* write a int as a TLV to the buffer */ +size_t oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len); + +/* write a float converted from fixpoint as a TLV to the buffer */ +size_t oma_tlv_write_float32(int16_t id, int32_t value, int bits, uint8_t *buffer, size_t len); + +/* convert TLV with float32 to fixpoint */ +size_t oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits); + +#endif /* OAM_TLV_H_ */ +/** @} */ diff --git a/examples/ipso-objects/Makefile b/examples/ipso-objects/Makefile new file mode 100644 index 000000000..8f620741c --- /dev/null +++ b/examples/ipso-objects/Makefile @@ -0,0 +1,29 @@ +CONTIKI_PROJECT = example-ipso-objects + +CONTIKI_SOURCEFILES += serial-protocol.c example-ipso-temperature.c + +all: $(CONTIKI_PROJECT) + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +APPS += rest-engine +APPS += er-coap +APPS += oma-lwm2m +APPS += ipso-objects + +CONTIKI=../.. +CONTIKI_WITH_IPV6 = 1 +include $(CONTIKI)/Makefile.include + +# border router rules +$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c + (cd $(CONTIKI)/tools && $(MAKE) tunslip6) + +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64 + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64 + +connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native + sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64 diff --git a/examples/ipso-objects/cooja-example-ipso-objects.csc b/examples/ipso-objects/cooja-example-ipso-objects.csc new file mode 100644 index 000000000..d8dc44876 --- /dev/null +++ b/examples/ipso-objects/cooja-example-ipso-objects.csc @@ -0,0 +1,171 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + LWM2M & IPSO Objects Example + 1.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote1 + Wismote Border Router #border-router + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c + make border-router.wismote TARGET=wismote DEFINES=NETSTACK_RDC=nullrdc_driver,NETSTACK_MAC=nullmac_driver + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote2 + Wismote IPSO Objects #ipso-example + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c + make example-ipso-objects.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 56.362361976162035 + 11.826023799100883 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + wismote1 + + + + + org.contikios.cooja.interfaces.Position + 60.1539674439426 + 11.827942168467365 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + wismote2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + 53.336918739504526 0.0 0.0 53.336918739504526 -2924.9161170527295 -473.3614543395965 + + 400 + 4 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + ID:2 + + + + 1286 + 1 + 240 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + OMA LWM2M & IPSO Object example + +1. Start a LWM2M server, for example Leshan +2. Run the example and bridge Cooja using tunslip with the prefix aaaa::1/64: + (cd contiki/examples/ipso-objects && make connect-router-cooja) + +After a short time, the example node should register with the LWM2M server at [aaaa::1]:5683. + true + + 1006 + 0 + 160 + 680 + 0 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 3 + 116 + 1 + 399 + + + diff --git a/examples/ipso-objects/cooja-example-router-node.csc b/examples/ipso-objects/cooja-example-router-node.csc new file mode 100644 index 000000000..a261b1747 --- /dev/null +++ b/examples/ipso-objects/cooja-example-router-node.csc @@ -0,0 +1,187 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + OMA LWM2M and IPSO Object example + 2.0 + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 500.0 + 500.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote1 + Wismote Router #wismote1 + [CONTIKI_DIR]/examples/ipso-objects/example-server.c + make example-server.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-server.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + org.contikios.cooja.mspmote.WismoteMoteType + wismote2 + Wismote Mote Type #wismote2 + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c + make example-ipso-objects.wismote TARGET=wismote + [CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.interfaces.IPAddress + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + org.contikios.cooja.mspmote.interfaces.MspClock + org.contikios.cooja.mspmote.interfaces.MspMoteID + org.contikios.cooja.mspmote.interfaces.MspButton + org.contikios.cooja.mspmote.interfaces.Msp802154Radio + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + org.contikios.cooja.mspmote.interfaces.MspLED + org.contikios.cooja.mspmote.interfaces.MspDebugOutput + + + + + org.contikios.cooja.interfaces.Position + 30.243188653185154 + 29.963547412144486 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 1 + + + org.contikios.cooja.mspmote.interfaces.MspDefaultSerial + s aaaa::200:0:0:3 /3311/0/5850 0~;s aaaa::200:0:0:3 /3311/0/5850 1~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;s aaaa::200:0:0:3 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 1~;h~;s aaaa::200:0:0:2 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 0~;g aaaa::200:0:0:2 /3311/0/5850~;g aaaa::200:0:0:2 /3311/1/5850~;g aaaa::200:0:0:2 /3311/2/5850~;l~; + + wismote1 + + + + + org.contikios.cooja.interfaces.Position + 59.75123136831088 + 29.84506209179908 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 2 + + wismote2 + + + + + org.contikios.cooja.interfaces.Position + 60.30742753391745 + 59.35092511889063 + 0.0 + + + org.contikios.cooja.mspmote.interfaces.MspClock + 1.0 + + + org.contikios.cooja.mspmote.interfaces.MspMoteID + 3 + + wismote2 + + + + org.contikios.cooja.plugins.SimControl + 280 + 0 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + 4.593848158957425 0.0 0.0 4.593848158957425 13.734375417550426 -121.37641081710846 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + + + + + 959 + 2 + 447 + 400 + 160 + + + org.contikios.cooja.plugins.Notes + + Enter notes here + true + + 679 + 1 + 160 + 680 + 0 + + + org.contikios.cooja.plugins.MoteInterfaceViewer + 0 + + Serial port + 0,0 + + 579 + 4 + 300 + 49 + 414 + + + diff --git a/examples/ipso-objects/example-ipso-objects.c b/examples/ipso-objects/example-ipso-objects.c new file mode 100644 index 000000000..66a31a0bb --- /dev/null +++ b/examples/ipso-objects/example-ipso-objects.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * OMA LWM2M and IPSO Objects example. + * \author + * Joakim Eriksson, joakime@sics.se + * Niclas Finne, nfi@sics.se + */ + +#include "contiki.h" +#include "lwm2m-engine.h" +#include "ipso-objects.h" + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER +#define REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER 0 +#endif + +#ifndef REGISTER_WITH_LWM2M_SERVER +#define REGISTER_WITH_LWM2M_SERVER 1 +#endif + +#ifndef LWM2M_SERVER_ADDRESS +#define LWM2M_SERVER_ADDRESS "aaaa::1" +#endif + +PROCESS(example_ipso_objects, "IPSO object example"); +AUTOSTART_PROCESSES(&example_ipso_objects); +/*---------------------------------------------------------------------------*/ +static void +setup_lwm2m_servers(void) +{ +#ifdef LWM2M_SERVER_ADDRESS + uip_ipaddr_t addr; + if(uiplib_ipaddrconv(LWM2M_SERVER_ADDRESS, &addr)) { + lwm2m_engine_register_with_bootstrap_server(&addr, 0); + lwm2m_engine_register_with_server(&addr, 0); + } +#endif /* LWM2M_SERVER_ADDRESS */ + + lwm2m_engine_use_bootstrap_server(REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER); + lwm2m_engine_use_registration_server(REGISTER_WITH_LWM2M_SERVER); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_ipso_objects, ev, data) +{ + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + PRINTF("Starting IPSO objects example\n"); + + /* Initialize the OMA LWM2M engine */ + lwm2m_engine_init(); + + /* Register default LWM2M objects */ + lwm2m_engine_register_default_objects(); + + /* Register default IPSO objects */ + ipso_objects_init(); + + setup_lwm2m_servers(); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} diff --git a/examples/ipso-objects/example-ipso-temperature.c b/examples/ipso-objects/example-ipso-temperature.c new file mode 100644 index 000000000..30f320640 --- /dev/null +++ b/examples/ipso-objects/example-ipso-temperature.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * An dummy temperature driver as example + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "ipso-objects.h" +#include "lib/random.h" + +static int32_t last_value = 27000; +/*---------------------------------------------------------------------------*/ +static int +read_value(int32_t *value) +{ + last_value = last_value + (random_rand() % 1000) - 500; + if(last_value < 18000) { + last_value = 18000; + } else if(last_value > 35000) { + last_value = 35000; + } + *value = last_value; + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct ipso_objects_sensor example_ipso_temperature = { + .read_value = read_value +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/example-server.c b/examples/ipso-objects/example-server.c new file mode 100644 index 000000000..2d48c738b --- /dev/null +++ b/examples/ipso-objects/example-server.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * IPSO Objects and OMA LWM2M example. + * \author + * Joakim Eriksson, joakime@sics.se + * Niclas Finne, nfi@sics.se + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include "net/netstack.h" +#include "er-coap-constants.h" +#include "er-coap-engine.h" +#include "lwm2m-engine.h" +#include "oma-tlv.h" +#include "dev/serial-line.h" +#include "serial-protocol.h" + +#if CONTIKI_TARGET_WISMOTE +#include "dev/uart1.h" +#endif + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT) + +#define URL_WELL_KNOWN ".well-known/core" +#define URL_DEVICE_MODEL "/3/0/1" +#define URL_DEVICE_FIRMWARE_VERSION "/3/0/3" +#define URL_LIGHT_CONTROL "/3311/0/5850" +#define URL_POWER_CONTROL "/3312/0/5850" + +#define MAX_NODES 10 + +#define NODE_HAS_TYPE (1 << 0) + +struct node { + uip_ipaddr_t ipaddr; + char type[32]; + uint8_t flags; + uint8_t retries; +}; + +static struct node nodes[MAX_NODES]; +static uint8_t node_count; + +static struct node *current_target; +static char current_uri[32] = URL_LIGHT_CONTROL; +static char current_value[32] = "1"; +static int current_request = COAP_PUT; +static uint8_t fetching_type = 0; + +PROCESS(router_process, "router process"); +AUTOSTART_PROCESSES(&router_process); +/*---------------------------------------------------------------------------*/ +static struct node * +add_node(const uip_ipaddr_t *addr) +{ + int i; + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* Node already added */ + return &nodes[i]; + } + } + if(node_count < MAX_NODES) { + uip_ipaddr_copy(&nodes[node_count].ipaddr, addr); + return &nodes[node_count++]; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +set_value(const uip_ipaddr_t *addr, char *uri, char *value) +{ + int i; + printf("#set value "); + uip_debug_ipaddr_print(addr); + printf(" URI: %s Value: %s\n", uri, value); + + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* setup command */ + current_target = &nodes[i]; + current_request = COAP_PUT; + strncpy(current_uri, uri, sizeof(current_uri) - 1); + strncpy(current_value, value, sizeof(current_value) - 1); + process_poll(&router_process); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +void +get_value(const uip_ipaddr_t *addr, char *uri) +{ + int i; + printf("#get value "); + uip_debug_ipaddr_print(addr); + printf(" URI: %s\n", uri); + + for(i = 0; i < node_count; i++) { + if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) { + /* setup command */ + current_target = &nodes[i]; + current_request = COAP_GET; + strncpy(current_uri, uri, sizeof(current_uri) - 1); + current_value[0] = 0; + process_poll(&router_process); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +void +print_node_list(void) +{ + int i; + int out = 0; + for(i = 0; i < node_count; i++) { + if(nodes[i].flags & NODE_HAS_TYPE) { + if(out++) { + printf(";"); + } + printf("%s,", nodes[i].type); + uip_debug_ipaddr_print(&nodes[i].ipaddr); + } + } + printf("\n"); +} +/*---------------------------------------------------------------------------*/ +/** + * This function is will be passed to COAP_BLOCKING_REQUEST() to + * handle responses. + */ +static void +client_chunk_handler(void *response) +{ + const uint8_t *chunk; + unsigned int format; + int len = coap_get_payload(response, &chunk); + coap_get_header_content_format(response, &format); + + /* if(len > 0) { */ + /* printf("|%.*s (%d,%d)", len, (char *)chunk, len, format); */ + /* } */ + if(current_target != NULL && fetching_type) { + if(len > sizeof(current_target->type) - 1) { + len = sizeof(current_target->type) - 1; + } + memcpy(current_target->type, chunk, len); + current_target->type[len] = 0; + current_target->flags |= NODE_HAS_TYPE; + + PRINTF("\nNODE "); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF(" HAS TYPE %s\n", current_target->type); + } else { + /* otherwise update the current value */ + if(format == LWM2M_TLV) { + oma_tlv_t tlv; + /* we can only read int32 for now ? */ + if(oma_tlv_read(&tlv, chunk, len) > 0) { + /* printf("TLV.type=%d len=%d id=%d value[0]=%d\n", */ + /* tlv.type, tlv.length, tlv.id, tlv.value[0]); */ + + int value = oma_tlv_get_int32(&tlv); + snprintf(current_value, sizeof(current_value), "%d", value); + } + } else { + if(len > sizeof(current_value) - 1) { + len = sizeof(current_value) - 1; + } + memcpy(current_value, chunk, len); + current_value[len] = 0; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +setup_network(void) +{ + uip_ipaddr_t ipaddr; + struct uip_ds6_addr *root_if; + rpl_dag_t *dag; + int i; + uint8_t state; + +#if CONTIKI_TARGET_WISMOTE + uart1_set_input(serial_line_input_byte); + serial_line_init(); +#endif + +#if UIP_CONF_ROUTER +/** + * 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. + */ +#if 0 +/* Mode 1 - 64 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1); +#elif 1 +/* Mode 2 - 16 bits inline */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1); +#else +/* Mode 3 - derived from link local (MAC) address */ + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); +#endif + + uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); + root_if = uip_ds6_addr_lookup(&ipaddr); + if(root_if != NULL) { + dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &ipaddr, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +#endif /* UIP_CONF_ROUTER */ + + PRINTF("IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + /* hack to make address "final" */ + if (state == ADDR_TENTATIVE) { + uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; + } + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_process, ev, data) +{ + /* This way the packet can be treated as pointer as usual. */ + static coap_packet_t request[1]; + static struct etimer timer; + uip_ds6_route_t *r; + uip_ipaddr_t *nexthop; + int n; + + PROCESS_BEGIN(); + + PROCESS_PAUSE(); + + /* receives all CoAP messages */ + coap_init_engine(); + + setup_network(); + + /* The data sink runs with a 100% duty cycle in order to ensure high + packet reception rates. */ + NETSTACK_MAC.off(1); + + while(1) { + etimer_set(&timer, CLOCK_SECOND * 5); + PROCESS_YIELD(); + + /* Handle serial line input */ + if(ev == serial_line_event_message) { + serial_protocol_input((char *) data); + } + + if(etimer_expired(&timer)) { + current_target = NULL; + n = 0; + for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { + current_target = add_node(&r->ipaddr); + if(current_target == NULL || + (current_target->flags & NODE_HAS_TYPE) != 0 || + current_target->retries > 5) { + continue; + } + PRINTF(" "); + PRINT6ADDR(&r->ipaddr); + PRINTF(" -> "); + nexthop = uip_ds6_route_nexthop(r); + if(nexthop != NULL) { + PRINT6ADDR(nexthop); + PRINTF("\n"); + } else { + PRINTF("-"); + } + PRINTF("\n"); + n++; + break; + } + } + + /* This is a node type discovery */ + if(current_target != NULL && + (current_target->flags & NODE_HAS_TYPE) == 0 && + current_target->retries < 6) { + + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0); + coap_set_header_uri_path(request, URL_DEVICE_MODEL); + + current_target->retries++; + + PRINTF("CoAP request to ["); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT), + current_target->retries); + + fetching_type = 1; + COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request, + client_chunk_handler); + fetching_type = 0; + strncpy(current_uri, URL_LIGHT_CONTROL, sizeof(current_uri)); + printf("\n--Done--\n"); + } + + /* If having a type this is another type of request */ + if(current_target != NULL && + (current_target->flags & NODE_HAS_TYPE) && strlen(current_uri) > 0) { + /* prepare request, TID is set by COAP_BLOCKING_REQUEST() */ + coap_init_message(request, COAP_TYPE_CON, current_request, 0); + coap_set_header_uri_path(request, current_uri); + + if(strlen(current_value) > 0) { + coap_set_payload(request, (uint8_t *)current_value, + strlen(current_value)); + } + + PRINTF("CoAP request to ["); + PRINT6ADDR(¤t_target->ipaddr); + PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri); + + COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request, + client_chunk_handler); + + /* print out result of command */ + if(current_request == COAP_PUT) { + printf("s "); + } else { + printf("g "); + } + uip_debug_ipaddr_print(¤t_target->ipaddr); + printf(" %s %s\n", current_uri, current_value); + + current_target = NULL; + current_uri[0] = 0; + current_value[0] = 0; + + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/project-conf.h b/examples/ipso-objects/project-conf.h new file mode 100644 index 000000000..49e049bbd --- /dev/null +++ b/examples/ipso-objects/project-conf.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 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. + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#ifdef BOARD_STRING +#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING +#elif defined(CONTIKI_TARGET_WISMOTE) +#include "dev/watchdog.h" +#define LWM2M_DEVICE_MODEL_NUMBER "wismote" +#define LWM2M_DEVICE_MANUFACTURER "Arago Systems" +#define LWM2M_DEVICE_SERIAL_NO "001" +#define PLATFORM_REBOOT watchdog_reboot +#endif + +#define IPSO_TEMPERATURE example_ipso_temperature + +/** + * Disabling RDC and CSMA to save memory on constrained devices. + */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC nullmac_driver + +/* Disabling TCP on CoAP nodes. */ +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Filtering .well-known/core per query can be disabled to save space. */ +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +#undef COAP_PROXY_OPTION_PROCESSING +#define COAP_PROXY_OPTION_PROCESSING 0 + +/* Enable client-side support for COAP observe */ +#define COAP_OBSERVE_CLIENT 1 + +#endif /* PROJECT_CONF_H_ */ diff --git a/examples/ipso-objects/serial-protocol.c b/examples/ipso-objects/serial-protocol.c new file mode 100644 index 000000000..f0c2cb1a0 --- /dev/null +++ b/examples/ipso-objects/serial-protocol.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Simple serial protocol to list and interact with devices + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#include "contiki.h" +#include "net/ip/uip.h" +#include "net/ip/uiplib.h" +#include + +void print_node_list(void); +void set_value(const uip_ipaddr_t *addr, char *uri, char *value); +void get_value(const uip_ipaddr_t *addr, char *uri); +/*---------------------------------------------------------------------------*/ +int +find_next_sep(const char *str, char sep, int pos) +{ + char c; + while((c = str[pos]) != 0) { + if(c == sep) { + return pos + 1; + } + pos++; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +/* + * l - list all discovered devices + * s - set + * d - get + */ +void +serial_protocol_input(char *data) +{ + /* We assume that we have a string here */ + char cmd = data[0]; + int pos = 0; + + switch(cmd) { + case 'l': + /* list devices */ + print_node_list(); + break; + case 's': { + uip_ip6addr_t ipaddr; + char *uri; + char *value; + pos = find_next_sep(data, ' ', pos); + if(pos > 0) { + /* start of IP */ + int start = pos; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) { + return; + } + data[pos - 1] = 0; + if(uiplib_ip6addrconv(&data[start], &ipaddr) == 0) { + printf("* Error not valid IP\n"); + } + uri = &data[pos]; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) return; + data[pos - 1] = 0; + value = &data[pos]; + /* set the value at the specified node */ + set_value(&ipaddr, uri, value); + } + break; + } + case 'g': { + uip_ip6addr_t ipaddr; + char *uri; + pos = find_next_sep(data, ' ', pos); + if(pos > 0) { + /* start of IP */ + int start = pos; + pos = find_next_sep(data, ' ', pos); + if(pos == -1) return; + data[pos - 1] = 0; + if(uiplib_ip6addrconv((const char *) &data[start], &ipaddr) == 0) { + printf("* Error not valid IP\n"); + } + uri = &data[pos]; + /* get the value at the specified node */ + get_value(&ipaddr, uri); + } + break; + } + default: + printf("Unknown command\n"); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipso-objects/serial-protocol.h b/examples/ipso-objects/serial-protocol.h new file mode 100644 index 000000000..a6dfcc129 --- /dev/null +++ b/examples/ipso-objects/serial-protocol.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Yanzi Networks AB. + * 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 HOLDER 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 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Simple serial protocol to list and interact with devices + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#ifndef SERIAL_PROTOCOL_H_ +#define SERIAL_PROTOCOL_H_ + +void serial_protocol_input(char *data); + +#endif /* SERIAL_PROTOCOL_H_ */ From a90ff6691aa698fec6c9cbd94c96e1eba0efefa9 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 21 Dec 2015 13:02:34 +0100 Subject: [PATCH 12/94] fixed leds control to work with red,green and blue LED - tested with remote. --- apps/ipso-objects/ipso-leds-control.c | 57 ++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/apps/ipso-objects/ipso-leds-control.c b/apps/ipso-objects/ipso-leds-control.c index fea620602..578dac3d2 100644 --- a/apps/ipso-objects/ipso-leds-control.c +++ b/apps/ipso-objects/ipso-leds-control.c @@ -56,10 +56,8 @@ #define PRINTF(...) #endif -#if LEDS_ALL > 3 -#define LEDS_CONTROL_NUMBER 3 -#elif LEDS_ALL > 1 -#define LEDS_CONTROL_NUMBER 2 +#if LEDS_ALL & LEDS_BLUE || LEDS_ALL & LEDS_RED || LEDS_ALL & LEDS_BLUE +#define LEDS_CONTROL_NUMBER (((LEDS_ALL & LEDS_BLUE) ? 1 : 0) + ((LEDS_ALL & LEDS_RED) ? 1 : 0) + ((LEDS_ALL & LEDS_GREEN) ? 1 : 0)) #else #define LEDS_CONTROL_NUMBER 1 #endif @@ -68,6 +66,7 @@ struct led_state { unsigned long last_on_time; uint32_t total_on_time; uint8_t is_on; + uint8_t led_value; }; static struct led_state states[LEDS_CONTROL_NUMBER]; @@ -103,14 +102,14 @@ write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, states[idx].is_on = 1; states[idx].last_on_time = clock_seconds(); #if PLATFORM_HAS_LEDS - leds_on(1 << idx); + leds_on(states[idx].led_value); #endif /* PLATFORM_HAS_LEDS */ } } else if(states[idx].is_on) { states[idx].total_on_time += clock_seconds() - states[idx].last_on_time; states[idx].is_on = 0; #if PLATFORM_HAS_LEDS - leds_off(1 << idx); + leds_off(states[idx].led_value); #endif /* PLATFORM_HAS_LEDS */ } } else { @@ -119,6 +118,32 @@ write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize, return len; } /*---------------------------------------------------------------------------*/ +static char * +get_color(int value) { + switch(value) { + case LEDS_GREEN: + return "Green"; + case LEDS_RED: + return "Red"; + case LEDS_BLUE: + return "Blue"; + } + return "None"; +} + +static int +read_color(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) +{ + char *value; + uint8_t idx = ctx->object_instance_index; + if(idx >= LEDS_CONTROL_NUMBER) { + return 0; + } + value = get_color(states[idx].led_value); + return ctx->writer->write_string(ctx, outbuf, outsize, + value, strlen(value)); +} +/*---------------------------------------------------------------------------*/ static int read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize) { @@ -165,10 +190,29 @@ write_on_time(lwm2m_context_t *ctx, /*---------------------------------------------------------------------------*/ LWM2M_RESOURCES(leds_control_resources, LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }), + LWM2M_RESOURCE_CALLBACK(5706, { read_color, NULL, NULL }), LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }) ); LWM2M_OBJECT(leds_control, 3311, leds_control_instances); /*---------------------------------------------------------------------------*/ +static int +bit_no(int bit) +{ + int i; + for(i = 0; i < 8; i++) { + if(LEDS_ALL & (1 << i)) { + if(bit == 0) { + /* matching bit */ + return 1 << i; + } else { + /* matching but used */ + bit--; + } + } + } + return 0; +} + void ipso_leds_control_init(void) { @@ -179,6 +223,7 @@ ipso_leds_control_init(void) for(i = 0; i < LEDS_CONTROL_NUMBER; i++) { leds_control_instances[i] = template; leds_control_instances[i].id = i; + states[i].led_value = bit_no(i); } /* register this device and its handlers - the handlers automatically From 5da887c35f298c32ac95403de580e6707fe9662c Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 21 Dec 2015 14:39:16 +0100 Subject: [PATCH 13/94] added readme for ipso-objects --- examples/ipso-objects/README.md | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 examples/ipso-objects/README.md diff --git a/examples/ipso-objects/README.md b/examples/ipso-objects/README.md new file mode 100644 index 000000000..6d1eb5871 --- /dev/null +++ b/examples/ipso-objects/README.md @@ -0,0 +1,48 @@ +IPSO Objects Example +============================================ + +This is an example of how to make use of the IPSO Object and LWM2M +implementation in Contiki. + +The LWM2M implementation is based on the Erbium CoAP implementation +and consists of two apps: lwm2m-engine and ipso-objects. The +lwm2m-engine handle the specifics of LWM2M including bootstrapping and +how read/writes of objects and resources are handled. The ipso-objects +contains implementations of some of the IPSO Smart Objects. + +The implementation was used during the IPSO Interop in May 2015, +Kista, Sweden, and was successfully tested with other +implementations. + +The examples use some of the basic IPSO object for controlling LEDs on +Contiki devices and for reading out temperature. + +##Testing IPSO-objects with Leshan + +First program a device with the examples/ipso-objects/example-ipso-objects.c + +```bash +>make example-ipso-objects.upload TARGET=zoul +>... +``` + +After that start up a native-border router or other border router on aaaa::1/64 +or another prefix - NOTE: if you use another prefix you will need to change LWM2M_SERVER_ADDRESS for which the device will register - in project-conf.h: +``` +#define LWM2M_SERVER_ADDRESS "aaaa::1" +``` + +Then when everything is setup you can download a Leshan and use that to +test controlling LEDs of the device. + +###Starting Leshan +```bash +wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-standalone.jar +java -jar ./leshan-standalone.jar +``` +Browse to leshans device page with http://127.0.0.1:8080 . + +When you have started the border-router and also Leshan you should now +start (or reboot) your IPSO Object enabled device. Within 30 seconds +you should be able to see it on the Leshan device page. + From cef3c39b7cda03c4c8ed2933265c871a67c76d9c Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Mon, 21 Dec 2015 14:57:45 +0100 Subject: [PATCH 14/94] Added compilation test of OMA LMW2M to the regression tests --- regression-tests/01-compile-base/Makefile | 1 + regression-tests/18-compile-arm-ports/Makefile | 2 ++ 2 files changed, 3 insertions(+) diff --git a/regression-tests/01-compile-base/Makefile b/regression-tests/01-compile-base/Makefile index ae70727ba..8ae34a04c 100644 --- a/regression-tests/01-compile-base/Makefile +++ b/regression-tests/01-compile-base/Makefile @@ -14,6 +14,7 @@ hello-world/z1 \ eeprom-test/native \ collect/sky \ er-rest-example/wismote \ +ipso-objects/wismote \ example-shell/native \ netperf/sky \ powertrace/sky \ diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index a3b47cddd..3331937a8 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -12,6 +12,7 @@ cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ er-rest-example/cc2538dk \ +ipso-objects/cc2538dk \ webserver-ipv6/cc2538dk \ cc2538dk/cc2538dk \ cc2538dk/udp-ipv6-echo-server/cc2538dk \ @@ -21,6 +22,7 @@ ipv6/multicast/cc2538dk \ zolertia/zoul/zoul \ zolertia/zoul/cc1200-demo/zoul \ er-rest-example/zoul \ +ipso-objects/zoul \ hello-world/zoul \ cc2538dk/mqtt-demo/zoul \ er-rest-example/stm32nucleo-spirit1 \ From fcc87ddce83ce7a78494457f0128b07812fe0ca2 Mon Sep 17 00:00:00 2001 From: Jeff Kent Date: Mon, 28 Dec 2015 09:45:09 -0600 Subject: [PATCH 15/94] jsontree: add JSONTREE_CONF_PRETTY option --- apps/json/jsontree.c | 26 ++++++++++++++++++++++++++ apps/json/jsontree.h | 6 ++++++ 2 files changed, 32 insertions(+) diff --git a/apps/json/jsontree.c b/apps/json/jsontree.c index 45f305869..e397ae47b 100644 --- a/apps/json/jsontree.c +++ b/apps/json/jsontree.c @@ -132,6 +132,9 @@ jsontree_print_next(struct jsontree_context *js_ctx) { struct jsontree_value *v; int index; +#if JSONTREE_PRETTY + int indent; +#endif v = js_ctx->values[js_ctx->depth]; @@ -145,10 +148,19 @@ jsontree_print_next(struct jsontree_context *js_ctx) index = js_ctx->index[js_ctx->depth]; if(index == 0) { js_ctx->putchar(v->type); +#if JSONTREE_PRETTY js_ctx->putchar('\n'); +#endif } if(index >= o->count) { +#if JSONTREE_PRETTY js_ctx->putchar('\n'); + indent = js_ctx->depth; + while (indent--) { + js_ctx->putchar(' '); + js_ctx->putchar(' '); + } +#endif js_ctx->putchar(v->type + 2); /* Default operation: back up one level! */ break; @@ -156,12 +168,26 @@ jsontree_print_next(struct jsontree_context *js_ctx) if(index > 0) { js_ctx->putchar(','); +#if JSONTREE_PRETTY js_ctx->putchar('\n'); +#endif } + +#if JSONTREE_PRETTY + indent = js_ctx->depth + 1; + while (indent--) { + js_ctx->putchar(' '); + js_ctx->putchar(' '); + } +#endif + if(v->type == JSON_TYPE_OBJECT) { jsontree_write_string(js_ctx, ((struct jsontree_object *)o)->pairs[index].name); js_ctx->putchar(':'); +#if JSONTREE_PRETTY + js_ctx->putchar(' '); +#endif ov = ((struct jsontree_object *)o)->pairs[index].value; } else { ov = o->values[index]; diff --git a/apps/json/jsontree.h b/apps/json/jsontree.h index 491e29ac9..b378d36b5 100644 --- a/apps/json/jsontree.h +++ b/apps/json/jsontree.h @@ -49,6 +49,12 @@ #define JSONTREE_MAX_DEPTH 10 #endif /* JSONTREE_CONF_MAX_DEPTH */ +#ifdef JSONTREE_CONF_PRETTY +#define JSONTREE_PRETTY JSONTREE_CONF_PRETTY +#else +#define JSONTREE_PRETTY 0 +#endif /* JSONTREE_CONF_PRETTY */ + struct jsontree_context { struct jsontree_value *values[JSONTREE_MAX_DEPTH]; uint16_t index[JSONTREE_MAX_DEPTH]; From bcc7d0a1eb7b1ac87ba5f0e0707bdcb6391adfac Mon Sep 17 00:00:00 2001 From: Jeff Kent Date: Mon, 28 Dec 2015 09:45:23 -0600 Subject: [PATCH 16/94] jsontree: add uint type --- apps/json/json.h | 1 + apps/json/jsontree.c | 22 ++++++++++++++++------ apps/json/jsontree.h | 7 +++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/json/json.h b/apps/json/json.h index a698464a5..d91cf93ef 100644 --- a/apps/json/json.h +++ b/apps/json/json.h @@ -45,6 +45,7 @@ #define JSON_TYPE_PAIR ':' #define JSON_TYPE_PAIR_NAME 'N' /* for N:V pairs */ #define JSON_TYPE_STRING '"' +#define JSON_TYPE_UINT 'U' #define JSON_TYPE_INT 'I' #define JSON_TYPE_NUMBER '0' #define JSON_TYPE_ERROR 0 diff --git a/apps/json/jsontree.c b/apps/json/jsontree.c index e397ae47b..4ffe68161 100644 --- a/apps/json/jsontree.c +++ b/apps/json/jsontree.c @@ -79,16 +79,11 @@ jsontree_write_string(const struct jsontree_context *js_ctx, const char *text) } /*---------------------------------------------------------------------------*/ void -jsontree_write_int(const struct jsontree_context *js_ctx, int value) +jsontree_write_uint(const struct jsontree_context *js_ctx, unsigned int value) { char buf[10]; int l; - if(value < 0) { - js_ctx->putchar('-'); - value = -value; - } - l = sizeof(buf) - 1; do { buf[l--] = '0' + (value % 10); @@ -101,6 +96,17 @@ jsontree_write_int(const struct jsontree_context *js_ctx, int value) } /*---------------------------------------------------------------------------*/ void +jsontree_write_int(const struct jsontree_context *js_ctx, int value) +{ + if(value < 0) { + js_ctx->putchar('-'); + value = -value; + } + + jsontree_write_uint(js_ctx, value); +} +/*---------------------------------------------------------------------------*/ +void jsontree_setup(struct jsontree_context *js_ctx, struct jsontree_value *root, int (* putchar)(int)) { @@ -203,6 +209,10 @@ jsontree_print_next(struct jsontree_context *js_ctx) jsontree_write_string(js_ctx, ((struct jsontree_string *)v)->value); /* Default operation: back up one level! */ break; + case JSON_TYPE_UINT: + jsontree_write_uint(js_ctx, ((struct jsontree_uint *)v)->value); + /* Default operation: back up one level! */ + break; case JSON_TYPE_INT: jsontree_write_int(js_ctx, ((struct jsontree_int *)v)->value); /* Default operation: back up one level! */ diff --git a/apps/json/jsontree.h b/apps/json/jsontree.h index b378d36b5..3434565a2 100644 --- a/apps/json/jsontree.h +++ b/apps/json/jsontree.h @@ -74,6 +74,11 @@ struct jsontree_string { const char *value; }; +struct jsontree_uint { + uint8_t type; + unsigned int value; +}; + struct jsontree_int { uint8_t type; int value; @@ -136,6 +141,8 @@ void jsontree_reset(struct jsontree_context *js_ctx); const char *jsontree_path_name(const struct jsontree_context *js_ctx, int depth); +void jsontree_write_uint(const struct jsontree_context *js_ctx, + unsigned int value); void jsontree_write_int(const struct jsontree_context *js_ctx, int value); void jsontree_write_atom(const struct jsontree_context *js_ctx, const char *text); From a65d566dee9b4a82dff0969d9e6e7cd91e11183d Mon Sep 17 00:00:00 2001 From: Jeff Kent Date: Mon, 28 Dec 2015 09:45:29 -0600 Subject: [PATCH 17/94] jsontree: add int pointer types --- apps/json/json.h | 8 ++++++++ apps/json/jsontree.c | 24 ++++++++++++++++++++++++ apps/json/jsontree.h | 5 +++++ 3 files changed, 37 insertions(+) diff --git a/apps/json/json.h b/apps/json/json.h index d91cf93ef..51ef652f8 100644 --- a/apps/json/json.h +++ b/apps/json/json.h @@ -57,6 +57,14 @@ #define JSON_TYPE_CALLBACK 'C' +/* integer pointer types */ +#define JSON_TYPE_S8PTR 'b' +#define JSON_TYPE_U8PTR 'B' +#define JSON_TYPE_S16PTR 'w' +#define JSON_TYPE_U16PTR 'W' +#define JSON_TYPE_S32PTR 'd' +#define JSON_TYPE_U32PTR 'D' + enum { JSON_ERROR_OK, JSON_ERROR_SYNTAX, diff --git a/apps/json/jsontree.c b/apps/json/jsontree.c index 4ffe68161..13d7d8604 100644 --- a/apps/json/jsontree.c +++ b/apps/json/jsontree.c @@ -234,6 +234,30 @@ jsontree_print_next(struct jsontree_context *js_ctx) } /* Default operation: back up one level! */ break; + case JSON_TYPE_S8PTR: + jsontree_write_int(js_ctx, *((int8_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U8PTR: + jsontree_write_uint(js_ctx, *((uint8_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_S16PTR: + jsontree_write_int(js_ctx, *((int16_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U16PTR: + jsontree_write_uint(js_ctx, *((uint16_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_S32PTR: + jsontree_write_int(js_ctx, *((int32_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; + case JSON_TYPE_U32PTR: + jsontree_write_uint(js_ctx, *((uint32_t *)((struct jsontree_ptr *)v)->value)); + /* Default operation: back up one level! */ + break; } default: PRINTF("\nError: Illegal json type:'%c'\n", v->type); diff --git a/apps/json/jsontree.h b/apps/json/jsontree.h index 3434565a2..a6c349d80 100644 --- a/apps/json/jsontree.h +++ b/apps/json/jsontree.h @@ -109,6 +109,11 @@ struct jsontree_array { struct jsontree_value **values; }; +struct jsontree_ptr { + uint8_t type; + const void *value; +}; + #define JSONTREE_STRING(text) {JSON_TYPE_STRING, (text)} #define JSONTREE_PAIR(name, value) {(name), (struct jsontree_value *)(value)} #define JSONTREE_CALLBACK(output, set) {JSON_TYPE_CALLBACK, (output), (set)} From cf5e9557f8b30b77131f0391d16f44d8837444f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 27 Dec 2015 01:18:45 +0100 Subject: [PATCH 18/94] cc2538: Add crypto driver and example for AES-CBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/Makefile.cc2538 | 2 +- cpu/cc2538/dev/cbc.c | 66 +++ cpu/cc2538/dev/cbc.h | 92 ++++ cpu/cc2538/dev/ccm.h | 2 +- examples/cc2538dk/crypto/Makefile | 2 +- examples/cc2538dk/crypto/cbc-test.c | 696 ++++++++++++++++++++++++++++ platform/cc2538dk/README.md | 2 +- platform/zoul/README.md | 2 +- 8 files changed, 859 insertions(+), 5 deletions(-) create mode 100644 cpu/cc2538/dev/cbc.c create mode 100644 cpu/cc2538/dev/cbc.h create mode 100644 examples/cc2538dk/crypto/cbc-test.c diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index fe6c06263..ae8f91729 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -53,7 +53,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c -CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c ccm.c sha256.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ccm.c sha256.c CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c diff --git a/cpu/cc2538/dev/cbc.c b/cpu/cc2538/dev/cbc.c new file mode 100644 index 000000000..c73a0f416 --- /dev/null +++ b/cpu/cc2538/dev/cbc.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-cbc + * @{ + * + * \file + * Implementation of the cc2538 AES-CBC driver + */ +#include "contiki.h" +#include "dev/cbc.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *mdata_in, void *mdata_out, uint16_t mdata_len, + struct process *process) +{ + uint32_t ctrl; + + /* Program AES-CBC crypto operation */ + ctrl = AES_AES_CTRL_CBC | /* CBC */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata_in, mdata_out, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +int8_t +cbc_crypt_check_status(void) +{ + return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) : + CRYPTO_PENDING; +} + +/** @} */ diff --git a/cpu/cc2538/dev/cbc.h b/cpu/cc2538/dev/cbc.h new file mode 100644 index 000000000..920708af3 --- /dev/null +++ b/cpu/cc2538/dev/cbc.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-aes + * @{ + * + * \defgroup cc2538-cbc cc2538 AES-CBC + * + * Driver for the cc2538 AES-CBC mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CBC driver + */ +#ifndef CBC_H_ +#define CBC_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC constants + * @{ + */ +#define CBC_IV_LEN AES_IV_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC functions + * @{ + */ + +/** \brief Starts a CBC crypto operation + * \param encrypt \c true to encrypt, or \c false to decrypt + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 128-bit initialization vector + * \param mdata_in Pointer to input message in SRAM + * \param mdata_out Pointer to output message in SRAM (may be \p mdata_in) + * \param mdata_len Length of message in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC error code + */ +uint8_t cbc_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *mdata_in, void *mdata_out, + uint16_t mdata_len, struct process *process); + +/** \brief Checks the status of the CBC crypto operation + * \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if + * successful, or CRYPTO/AES/CBC error code + * \note This function must be called only after \c cbc_crypt_start(). + */ +int8_t cbc_crypt_check_status(void); + +/** @} */ + +#endif /* CBC_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ccm.h b/cpu/cc2538/dev/ccm.h index 8bb1f533b..156cd1a6f 100644 --- a/cpu/cc2538/dev/ccm.h +++ b/cpu/cc2538/dev/ccm.h @@ -54,7 +54,7 @@ #include #include /*---------------------------------------------------------------------------*/ -/** \name CCM constants +/** \name AES-CCM constants * @{ */ #define CCM_FLAGS_LEN 1 diff --git a/examples/cc2538dk/crypto/Makefile b/examples/cc2538dk/crypto/Makefile index 4f397d8d4..b11a2165c 100644 --- a/examples/cc2538dk/crypto/Makefile +++ b/examples/cc2538dk/crypto/Makefile @@ -1,4 +1,4 @@ -CONTIKI_PROJECT = ecb-test ccm-test sha256-test +CONTIKI_PROJECT = ecb-test cbc-test ccm-test sha256-test all: $(CONTIKI_PROJECT) diff --git a/examples/cc2538dk/crypto/cbc-test.c b/examples/cc2538dk/crypto/cbc-test.c new file mode 100644 index 000000000..ff7c429f3 --- /dev/null +++ b/examples/cc2538dk/crypto/cbc-test.c @@ -0,0 +1,696 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-examples + * @{ + * + * \defgroup cc2538-cbc-test cc2538dk AES-CBC Test Project + * + * AES-CBC access example for CC2538 on SmartRF06EB. + * + * This example shows how AES-CBC should be used. The example also verifies + * the AES-CBC functionality. + * + * @{ + * + * \file + * Example demonstrating AES-CBC on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/cbc.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define MDATA_MAX_LEN 160 +/*---------------------------------------------------------------------------*/ +PROCESS(cbc_test_process, "cbc test process"); +AUTOSTART_PROCESSES(&cbc_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cbc_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error", + "keystore read error", + "keystore write error", + "authentication failed" + }; + static const uint8_t keys128[][128 / 8] = { + { 0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0, + 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17 }, + { 0xb7, 0xf3, 0xc9, 0x57, 0x6e, 0x12, 0xdd, 0x0d, + 0xb6, 0x3e, 0x8f, 0x8f, 0xac, 0x2b, 0x9a, 0x39 }, + { 0x89, 0xa5, 0x53, 0x73, 0x04, 0x33, 0xf7, 0xe6, + 0xd6, 0x7d, 0x16, 0xd3, 0x73, 0xbd, 0x53, 0x60 }, + { 0x2c, 0x14, 0x41, 0x37, 0x51, 0xc3, 0x1e, 0x27, + 0x30, 0x57, 0x0b, 0xa3, 0x36, 0x1c, 0x78, 0x6b }, + { 0x6a, 0x70, 0x82, 0xcf, 0x8c, 0xda, 0x13, 0xef, + 0xf4, 0x8c, 0x81, 0x58, 0xdd, 0xa2, 0x06, 0xae }, + { 0x7b, 0x1a, 0xb9, 0x14, 0x4b, 0x02, 0x39, 0x31, + 0x5c, 0xd5, 0xee, 0xc6, 0xc7, 0x56, 0x63, 0xbd }, + { 0xba, 0xb0, 0xcc, 0xed, 0xdc, 0x0a, 0xbd, 0x63, + 0xe3, 0xf8, 0x2e, 0x9f, 0xbf, 0xf7, 0xb8, 0xaa }, + { 0x97, 0xa1, 0x02, 0x55, 0x29, 0xb9, 0x92, 0x5e, + 0x25, 0xbb, 0xe7, 0x87, 0x70, 0xca, 0x2f, 0x99 } + }; + static const uint8_t keys192[][192 / 8] = { + { 0xba, 0x75, 0xf4, 0xd1, 0xd9, 0xd7, 0xcf, 0x7f, + 0x55, 0x14, 0x45, 0xd5, 0x6c, 0xc1, 0xa8, 0xab, + 0x2a, 0x07, 0x8e, 0x15, 0xe0, 0x49, 0xdc, 0x2c }, + { 0x16, 0x2a, 0xd5, 0x0e, 0xe6, 0x4a, 0x07, 0x02, + 0xaa, 0x55, 0x1f, 0x57, 0x1d, 0xed, 0xc1, 0x6b, + 0x2c, 0x1b, 0x6a, 0x1e, 0x4d, 0x4b, 0x5e, 0xee }, + { 0x8e, 0x27, 0x40, 0xfb, 0xa1, 0x57, 0xae, 0xf2, + 0x42, 0x2e, 0x44, 0x23, 0x12, 0xd1, 0x5c, 0x14, + 0xd3, 0x12, 0x55, 0x36, 0x84, 0xfc, 0xdc, 0x15 }, + { 0x50, 0x9b, 0xaf, 0x46, 0xfb, 0x9d, 0xe3, 0x42, + 0x81, 0xda, 0xfc, 0xc3, 0xdb, 0x79, 0x59, 0x3b, + 0xff, 0xa8, 0x42, 0x69, 0x04, 0x30, 0x26, 0x88 } + }; + static const uint8_t keys256[][256 / 8] = { + { 0x6e, 0xd7, 0x6d, 0x2d, 0x97, 0xc6, 0x9f, 0xd1, + 0x33, 0x95, 0x89, 0x52, 0x39, 0x31, 0xf2, 0xa6, + 0xcf, 0xf5, 0x54, 0xb1, 0x5f, 0x73, 0x8f, 0x21, + 0xec, 0x72, 0xdd, 0x97, 0xa7, 0x33, 0x09, 0x07 }, + { 0x48, 0xbe, 0x59, 0x7e, 0x63, 0x2c, 0x16, 0x77, + 0x23, 0x24, 0xc8, 0xd3, 0xfa, 0x1d, 0x9c, 0x5a, + 0x9e, 0xcd, 0x01, 0x0f, 0x14, 0xec, 0x5d, 0x11, + 0x0d, 0x3b, 0xfe, 0xc3, 0x76, 0xc5, 0x53, 0x2b }, + { 0x43, 0xe9, 0x53, 0xb2, 0xae, 0xa0, 0x8a, 0x3a, + 0xd5, 0x2d, 0x18, 0x2f, 0x58, 0xc7, 0x2b, 0x9c, + 0x60, 0xfb, 0xe4, 0xa9, 0xca, 0x46, 0xa3, 0xcb, + 0x89, 0xe3, 0x86, 0x38, 0x45, 0xe2, 0x2c, 0x9e }, + { 0x87, 0x72, 0x5b, 0xd4, 0x3a, 0x45, 0x60, 0x88, + 0x14, 0x18, 0x07, 0x73, 0xf0, 0xe7, 0xab, 0x95, + 0xa3, 0xc8, 0x59, 0xd8, 0x3a, 0x21, 0x30, 0xe8, + 0x84, 0x19, 0x0e, 0x44, 0xd1, 0x4c, 0x69, 0x96 } + }; + static const struct { + const void *keys; + uint8_t key_size; + uint8_t count; + } keys[] = { + { keys128, AES_KEY_STORE_SIZE_KEY_SIZE_128, + sizeof(keys128) / sizeof(keys128[0]) }, + { keys192, AES_KEY_STORE_SIZE_KEY_SIZE_192, + sizeof(keys192) / sizeof(keys192[0]) }, + { keys256, AES_KEY_STORE_SIZE_KEY_SIZE_256, + sizeof(keys256) / sizeof(keys256[0]) } + }; + static const struct { + bool encrypt; + uint8_t key_size_index; + uint8_t key_area; + uint8_t iv[CBC_IV_LEN]; + uint8_t mdata[MDATA_MAX_LEN]; + uint16_t mdata_len; + uint8_t expected[MDATA_MAX_LEN]; + } vectors[] = { + { + true, /* encrypt */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98, + 0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8 }, /* iv */ + { 0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab, + 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22 }, /* mdata */ + 16, /* mdata_len */ + { 0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0, + 0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2 } /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 1, /* key_area */ + { 0xc8, 0x0f, 0x09, 0x5d, 0x8b, 0xb1, 0xa0, 0x60, + 0x69, 0x9f, 0x7c, 0x19, 0x97, 0x4a, 0x1a, 0xa0 }, /* iv */ + { 0x9a, 0xc1, 0x99, 0x54, 0xce, 0x13, 0x19, 0xb3, + 0x54, 0xd3, 0x22, 0x04, 0x60, 0xf7, 0x1c, 0x1e, + 0x37, 0x3f, 0x1c, 0xd3, 0x36, 0x24, 0x08, 0x81, + 0x16, 0x0c, 0xfd, 0xe4, 0x6e, 0xbf, 0xed, 0x2e, + 0x79, 0x1e, 0x8d, 0x5a, 0x1a, 0x13, 0x6e, 0xbd, + 0x1d, 0xc4, 0x69, 0xde, 0xc0, 0x0c, 0x41, 0x87, + 0x72, 0x2b, 0x84, 0x1c, 0xda, 0xbc, 0xb2, 0x2c, + 0x1b, 0xe8, 0xa1, 0x46, 0x57, 0xda, 0x20, 0x0e }, /* mdata */ + 64, /* mdata_len */ + { 0x19, 0xb9, 0x60, 0x97, 0x72, 0xc6, 0x3f, 0x33, + 0x86, 0x08, 0xbf, 0x6e, 0xb5, 0x2c, 0xa1, 0x0b, + 0xe6, 0x50, 0x97, 0xf8, 0x9c, 0x1e, 0x09, 0x05, + 0xc4, 0x24, 0x01, 0xfd, 0x47, 0x79, 0x1a, 0xe2, + 0xc5, 0x44, 0x0b, 0x2d, 0x47, 0x31, 0x16, 0xca, + 0x78, 0xbd, 0x9f, 0xf2, 0xfb, 0x60, 0x15, 0xcf, + 0xd3, 0x16, 0x52, 0x4e, 0xae, 0x7d, 0xcb, 0x95, + 0xae, 0x73, 0x8e, 0xbe, 0xae, 0x84, 0xa4, 0x67 } /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 2, /* key_area */ + { 0xf7, 0x24, 0x55, 0x8d, 0xb3, 0x43, 0x3a, 0x52, + 0x3f, 0x4e, 0x51, 0xa5, 0xbe, 0xa7, 0x04, 0x97 }, /* iv */ + { 0x80, 0x7b, 0xc4, 0xea, 0x68, 0x4e, 0xed, 0xcf, + 0xdc, 0xca, 0x30, 0x18, 0x06, 0x80, 0xb0, 0xf1, + 0xae, 0x28, 0x14, 0xf3, 0x5f, 0x36, 0xd0, 0x53, + 0xc5, 0xae, 0xa6, 0x59, 0x5a, 0x38, 0x6c, 0x14, + 0x42, 0x77, 0x0f, 0x4d, 0x72, 0x97, 0xd8, 0xb9, + 0x18, 0x25, 0xee, 0x72, 0x37, 0x24, 0x1d, 0xa8, + 0x92, 0x5d, 0xd5, 0x94, 0xcc, 0xf6, 0x76, 0xae, + 0xcd, 0x46, 0xca, 0x20, 0x68, 0xe8, 0xd3, 0x7a, + 0x3a, 0x0e, 0xc8, 0xa7, 0xd5, 0x18, 0x5a, 0x20, + 0x1e, 0x66, 0x3b, 0x5f, 0xf3, 0x6a, 0xe1, 0x97, + 0x11, 0x01, 0x88, 0xa2, 0x35, 0x03, 0x76, 0x3b, + 0x82, 0x18, 0x82, 0x6d, 0x23, 0xce, 0xd7, 0x4b, + 0x31, 0xe9, 0xf6, 0xe2, 0xd7, 0xfb, 0xfa, 0x6c, + 0xb4, 0x34, 0x20, 0xc7, 0x80, 0x7a, 0x86, 0x25 }, /* mdata */ + 112, /* mdata_len */ + { 0x40, 0x6a, 0xf1, 0x42, 0x9a, 0x47, 0x8c, 0x3d, + 0x07, 0xe5, 0x55, 0xc5, 0x28, 0x7a, 0x60, 0x50, + 0x0d, 0x37, 0xfc, 0x39, 0xb6, 0x8e, 0x5b, 0xbb, + 0x9b, 0xaf, 0xd6, 0xdd, 0xb2, 0x23, 0x82, 0x85, + 0x61, 0xd6, 0x17, 0x1a, 0x30, 0x8d, 0x5b, 0x1a, + 0x45, 0x51, 0xe8, 0xa5, 0xe7, 0xd5, 0x72, 0x91, + 0x8d, 0x25, 0xc9, 0x68, 0xd3, 0x87, 0x18, 0x48, + 0xd2, 0xf1, 0x66, 0x35, 0xca, 0xa9, 0x84, 0x7f, + 0x38, 0x59, 0x0b, 0x1d, 0xf5, 0x8a, 0xb5, 0xef, + 0xb9, 0x85, 0xf2, 0xc6, 0x6c, 0xfa, 0xf8, 0x6f, + 0x61, 0xb3, 0xf9, 0xc0, 0xaf, 0xad, 0x6c, 0x96, + 0x3c, 0x49, 0xce, 0xe9, 0xb8, 0xbc, 0x81, 0xa2, + 0xdd, 0xb0, 0x6c, 0x96, 0x7f, 0x32, 0x55, 0x15, + 0xa4, 0x84, 0x9e, 0xec, 0x37, 0xce, 0x72, 0x1a } /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 3, /* key_area */ + { 0x1d, 0xbb, 0xeb, 0x2f, 0x19, 0xab, 0xb4, 0x48, + 0xaf, 0x84, 0x97, 0x96, 0x24, 0x4a, 0x19, 0xd7 }, /* iv */ + { 0x40, 0xd9, 0x30, 0xf9, 0xa0, 0x53, 0x34, 0xd9, + 0x81, 0x6f, 0xe2, 0x04, 0x99, 0x9c, 0x3f, 0x82, + 0xa0, 0x3f, 0x6a, 0x04, 0x57, 0xa8, 0xc4, 0x75, + 0xc9, 0x45, 0x53, 0xd1, 0xd1, 0x16, 0x69, 0x3a, + 0xdc, 0x61, 0x80, 0x49, 0xf0, 0xa7, 0x69, 0xa2, + 0xee, 0xd6, 0xa6, 0xcb, 0x14, 0xc0, 0x14, 0x3e, + 0xc5, 0xcc, 0xcd, 0xbc, 0x8d, 0xec, 0x4c, 0xe5, + 0x60, 0xcf, 0xd2, 0x06, 0x22, 0x57, 0x09, 0x32, + 0x6d, 0x4d, 0xe7, 0x94, 0x8e, 0x54, 0xd6, 0x03, + 0xd0, 0x1b, 0x12, 0xd7, 0xfe, 0xd7, 0x52, 0xfb, + 0x23, 0xf1, 0xaa, 0x44, 0x94, 0xfb, 0xb0, 0x01, + 0x30, 0xe9, 0xde, 0xd4, 0xe7, 0x7e, 0x37, 0xc0, + 0x79, 0x04, 0x2d, 0x82, 0x80, 0x40, 0xc3, 0x25, + 0xb1, 0xa5, 0xef, 0xd1, 0x5f, 0xc8, 0x42, 0xe4, + 0x40, 0x14, 0xca, 0x43, 0x74, 0xbf, 0x38, 0xf3, + 0xc3, 0xfc, 0x3e, 0xe3, 0x27, 0x73, 0x3b, 0x0c, + 0x8a, 0xee, 0x1a, 0xbc, 0xd0, 0x55, 0x77, 0x2f, + 0x18, 0xdc, 0x04, 0x60, 0x3f, 0x7b, 0x2c, 0x1e, + 0xa6, 0x9f, 0xf6, 0x62, 0x36, 0x1f, 0x2b, 0xe0, + 0xa1, 0x71, 0xbb, 0xdc, 0xea, 0x1e, 0x5d, 0x3f }, /* mdata */ + 160, /* mdata_len */ + { 0x6b, 0xe8, 0xa1, 0x28, 0x00, 0x45, 0x5a, 0x32, + 0x05, 0x38, 0x85, 0x3e, 0x0c, 0xba, 0x31, 0xbd, + 0x2d, 0x80, 0xea, 0x0c, 0x85, 0x16, 0x4a, 0x4c, + 0x5c, 0x26, 0x1a, 0xe4, 0x85, 0x41, 0x7d, 0x93, + 0xef, 0xfe, 0x2e, 0xbc, 0x0d, 0x0a, 0x0b, 0x51, + 0xd6, 0xea, 0x18, 0x63, 0x3d, 0x21, 0x0c, 0xf6, + 0x3c, 0x0c, 0x4d, 0xdb, 0xc2, 0x76, 0x07, 0xf2, + 0xe8, 0x1e, 0xd9, 0x11, 0x31, 0x91, 0xef, 0x86, + 0xd5, 0x6f, 0x3b, 0x99, 0xbe, 0x6c, 0x41, 0x5a, + 0x41, 0x50, 0x29, 0x9f, 0xb8, 0x46, 0xce, 0x71, + 0x60, 0xb4, 0x0b, 0x63, 0xba, 0xf1, 0x17, 0x9d, + 0x19, 0x27, 0x5a, 0x2e, 0x83, 0x69, 0x83, 0x76, + 0xd2, 0x8b, 0x92, 0x54, 0x8c, 0x68, 0xe0, 0x6e, + 0x6d, 0x99, 0x4e, 0x2c, 0x15, 0x01, 0xed, 0x29, + 0x70, 0x14, 0xe7, 0x02, 0xcd, 0xef, 0xee, 0x2f, + 0x65, 0x64, 0x47, 0x70, 0x60, 0x09, 0x61, 0x4d, + 0x80, 0x1d, 0xe1, 0xca, 0xaf, 0x73, 0xf8, 0xb7, + 0xfa, 0x56, 0xcf, 0x1b, 0xa9, 0x4b, 0x63, 0x19, + 0x33, 0xbb, 0xe5, 0x77, 0x62, 0x43, 0x80, 0x85, + 0x0f, 0x11, 0x74, 0x35, 0xa0, 0x35, 0x5b, 0x2b } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 4, /* key_area */ + { 0xbd, 0x41, 0x72, 0x93, 0x40, 0x78, 0xc2, 0x01, + 0x1c, 0xb1, 0xf3, 0x1c, 0xff, 0xaf, 0x48, 0x6e }, /* iv */ + { 0xf8, 0xeb, 0x31, 0xb3, 0x1e, 0x37, 0x4e, 0x96, + 0x00, 0x30, 0xcd, 0x1c, 0xad, 0xb0, 0xef, 0x0c }, /* mdata */ + 16, /* mdata_len */ + { 0x94, 0x0b, 0xc7, 0x6d, 0x61, 0xe2, 0xc4, 0x9d, + 0xdd, 0xd5, 0xdf, 0x7f, 0x37, 0xfc, 0xf1, 0x05 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 5, /* key_area */ + { 0x0b, 0x1e, 0x74, 0xf4, 0x5c, 0x17, 0xff, 0x30, + 0x4d, 0x99, 0xc0, 0x59, 0xce, 0x5c, 0xde, 0x09 }, /* iv */ + { 0xd3, 0xf8, 0x9b, 0x71, 0xe0, 0x33, 0x07, 0x0f, + 0x9d, 0x75, 0x16, 0xa6, 0xcb, 0x4e, 0xa5, 0xef, + 0x51, 0xd6, 0xfb, 0x63, 0xd4, 0xf0, 0xfe, 0xa0, + 0x89, 0xd0, 0xa6, 0x0e, 0x47, 0xbb, 0xb3, 0xc2, + 0xe1, 0x0e, 0x9b, 0xa3, 0xb2, 0x82, 0xc7, 0xcb, + 0x79, 0xae, 0xfe, 0x30, 0x68, 0xce, 0x22, 0x83, + 0x77, 0xc2, 0x1a, 0x58, 0xfe, 0x5a, 0x0f, 0x88, + 0x83, 0xd0, 0xdb, 0xd3, 0xd0, 0x96, 0xbe, 0xca }, /* mdata */ + 64, /* mdata_len */ + { 0xb9, 0x68, 0xae, 0xb1, 0x99, 0xad, 0x6b, 0x3c, + 0x8e, 0x01, 0xf2, 0x6c, 0x2e, 0xda, 0xd4, 0x44, + 0x53, 0x8c, 0x78, 0xbf, 0xa3, 0x6e, 0xd6, 0x8c, + 0xa7, 0x61, 0x23, 0xb8, 0xcd, 0xce, 0x61, 0x5a, + 0x01, 0xf6, 0x11, 0x2b, 0xb8, 0x0b, 0xfc, 0x3f, + 0x17, 0x49, 0x05, 0x78, 0xfb, 0x1f, 0x90, 0x9a, + 0x52, 0xe1, 0x62, 0x63, 0x7b, 0x06, 0x2d, 0xb0, + 0x4e, 0xfe, 0xe2, 0x91, 0xa1, 0xf1, 0xaf, 0x60 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 6, /* key_area */ + { 0x68, 0xb9, 0x14, 0x0f, 0x30, 0x04, 0x90, 0xc5, + 0xc9, 0x42, 0xf6, 0x6e, 0x77, 0x7e, 0xb8, 0x06 }, /* iv */ + { 0xc6, 0x5b, 0x94, 0xb1, 0xf2, 0x91, 0xfa, 0x9f, + 0x06, 0x00, 0xf2, 0x2c, 0x3c, 0x04, 0x32, 0xc8, + 0x95, 0xad, 0x5d, 0x17, 0x7b, 0xcc, 0xcc, 0x9e, + 0xa4, 0x4e, 0x8e, 0xc3, 0x39, 0xc9, 0xad, 0xf4, + 0x38, 0x55, 0xb3, 0x26, 0x17, 0x9d, 0x6d, 0x81, + 0xaa, 0x36, 0xef, 0x59, 0x46, 0x2f, 0xd8, 0x61, + 0x27, 0xe9, 0xd8, 0x1b, 0x0f, 0x28, 0x6f, 0x93, + 0x30, 0x6b, 0xf7, 0x4d, 0x4c, 0x79, 0xe4, 0x7c, + 0x1b, 0x3d, 0x4b, 0x74, 0xed, 0xd3, 0xa1, 0x62, + 0x90, 0xe3, 0xc6, 0x3b, 0x74, 0x2e, 0x41, 0xf2, + 0x0d, 0x66, 0xce, 0xee, 0x79, 0x43, 0x16, 0xbb, + 0x63, 0xd3, 0xbd, 0x00, 0x27, 0x12, 0xa1, 0xb1, + 0x36, 0xba, 0x61, 0x85, 0xbd, 0x5c, 0x1d, 0xab, + 0x81, 0xb0, 0x7d, 0xb9, 0x0d, 0x2a, 0xf5, 0xe5 }, /* mdata */ + 112, /* mdata_len */ + { 0xc5, 0x58, 0x5f, 0xf2, 0x15, 0xbb, 0xb7, 0x3b, + 0xa5, 0x39, 0x34, 0x40, 0x85, 0x2f, 0xb1, 0x99, + 0x43, 0x6d, 0xe0, 0xd1, 0x5e, 0x55, 0xc6, 0x31, + 0xf8, 0x77, 0x67, 0x0a, 0xa3, 0xed, 0xa9, 0xf6, + 0x72, 0xeb, 0x1f, 0x87, 0x6f, 0x09, 0x54, 0x4e, + 0x63, 0x55, 0x84, 0x36, 0xb8, 0x92, 0x80, 0x00, + 0xdb, 0x2f, 0x02, 0xa5, 0xad, 0x90, 0xf9, 0x5b, + 0x05, 0xac, 0x4c, 0xf4, 0x9e, 0x19, 0x8e, 0x61, + 0x7e, 0x76, 0x78, 0x48, 0x0f, 0xdf, 0x0e, 0xfa, + 0xcc, 0x6a, 0xae, 0x69, 0x12, 0x71, 0xe6, 0xcd, + 0xd3, 0x54, 0x1e, 0xbf, 0x71, 0x9a, 0x1c, 0xca, + 0xed, 0xb2, 0x4e, 0x2f, 0x80, 0xf9, 0x24, 0x55, + 0xdd, 0x59, 0x10, 0xcb, 0x50, 0x86, 0xb0, 0x96, + 0x0a, 0x39, 0x42, 0xec, 0x18, 0x2d, 0xcb, 0xd7 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 7, /* key_area */ + { 0xd4, 0xb4, 0xea, 0xb9, 0x2a, 0xa9, 0x63, 0x7e, + 0x87, 0xd3, 0x66, 0x38, 0x4e, 0xd6, 0x91, 0x5c }, /* iv */ + { 0x22, 0xcd, 0xc3, 0x30, 0x6f, 0xcd, 0x4d, 0x31, + 0xcc, 0xd3, 0x27, 0x20, 0xcb, 0xb6, 0x1b, 0xad, + 0x28, 0xd8, 0x55, 0x67, 0x06, 0x57, 0xc4, 0x8c, + 0x7b, 0x88, 0xc3, 0x1f, 0x4f, 0xa1, 0xf9, 0x3c, + 0x01, 0xb5, 0x7d, 0xa9, 0x0b, 0xe6, 0x3e, 0xad, + 0x67, 0xd6, 0xa3, 0x25, 0x52, 0x5e, 0x6e, 0xd4, + 0x50, 0x83, 0xe6, 0xfb, 0x70, 0xa5, 0x35, 0x29, + 0xd1, 0xfa, 0x0f, 0x55, 0x65, 0x3b, 0x94, 0x2a, + 0xf5, 0x9d, 0x78, 0xa2, 0x66, 0x03, 0x61, 0xd6, + 0x3a, 0x72, 0x90, 0x15, 0x5a, 0xc5, 0xc4, 0x33, + 0x12, 0xa2, 0x5b, 0x23, 0x5d, 0xac, 0xbb, 0xc8, + 0x63, 0xfa, 0xf0, 0x09, 0x40, 0xc9, 0x96, 0x24, + 0x07, 0x6d, 0xfa, 0x44, 0x06, 0x8e, 0x7c, 0x55, + 0x4c, 0x90, 0x38, 0x17, 0x69, 0x53, 0xe5, 0x71, + 0x75, 0x1d, 0xfc, 0x09, 0x54, 0xd4, 0x1d, 0x11, + 0x37, 0x71, 0xb0, 0x64, 0x66, 0xb1, 0xc8, 0xd1, + 0x3e, 0x0d, 0x4c, 0xb6, 0x75, 0xed, 0x58, 0xd1, + 0xa6, 0x19, 0xe1, 0x54, 0x09, 0x70, 0x98, 0x37, + 0x81, 0xdc, 0x11, 0xd2, 0xdd, 0x85, 0x25, 0xab, + 0x57, 0x45, 0x95, 0x8d, 0x61, 0x5d, 0xef, 0xda }, /* mdata */ + 160, /* mdata_len */ + { 0xe8, 0xb8, 0x91, 0x50, 0xd8, 0x43, 0x8b, 0xf5, + 0xb1, 0x74, 0x49, 0xd6, 0xed, 0x26, 0xbd, 0x72, + 0x12, 0x7e, 0x10, 0xe4, 0xaa, 0x57, 0xca, 0xd8, + 0x52, 0x83, 0xe8, 0x35, 0x9e, 0x08, 0x92, 0x08, + 0xe8, 0x49, 0x21, 0x64, 0x9f, 0x5b, 0x60, 0xea, + 0x21, 0xf7, 0x86, 0x7c, 0xbc, 0x96, 0x20, 0x56, + 0x0c, 0x4c, 0x62, 0x38, 0xdb, 0x02, 0x12, 0x16, + 0xdb, 0x45, 0x3c, 0x99, 0x43, 0xf1, 0xf1, 0xa6, + 0x05, 0x46, 0x17, 0x3d, 0xae, 0xf2, 0x55, 0x7c, + 0x3c, 0xdd, 0x85, 0x50, 0x31, 0xb3, 0x53, 0xd4, + 0xbf, 0x17, 0x6f, 0x28, 0x43, 0x9e, 0x48, 0x78, + 0x5c, 0x37, 0xd3, 0x8f, 0x27, 0x0a, 0xa4, 0xa6, + 0xfa, 0xad, 0x2b, 0xaa, 0xbc, 0xb0, 0xc0, 0xb2, + 0xd1, 0xdd, 0x53, 0x22, 0x93, 0x74, 0x98, 0xce, + 0x80, 0x3b, 0xa1, 0x14, 0x84, 0x40, 0xa5, 0x2e, + 0x22, 0x7d, 0xdb, 0xa4, 0x87, 0x2f, 0xe4, 0xd8, + 0x1d, 0x2d, 0x76, 0xa9, 0x39, 0xd2, 0x47, 0x55, + 0xad, 0xb8, 0xa7, 0xb8, 0x45, 0x2c, 0xee, 0xd2, + 0xd1, 0x79, 0xe1, 0xa5, 0x84, 0x8f, 0x31, 0x6f, + 0x5c, 0x01, 0x63, 0x00, 0xa3, 0x90, 0xbf, 0xa7 } /* expected */ + }, { + true, /* encrypt */ + 1, /* key_size_index */ + 0, /* key_area */ + { 0x53, 0x1c, 0xe7, 0x81, 0x76, 0x40, 0x16, 0x66, + 0xaa, 0x30, 0xdb, 0x94, 0xec, 0x4a, 0x30, 0xeb }, /* iv */ + { 0xc5, 0x1f, 0xc2, 0x76, 0x77, 0x4d, 0xad, 0x94, + 0xbc, 0xdc, 0x1d, 0x28, 0x91, 0xec, 0x86, 0x68 }, /* mdata */ + 16, /* mdata_len */ + { 0x70, 0xdd, 0x95, 0xa1, 0x4e, 0xe9, 0x75, 0xe2, + 0x39, 0xdf, 0x36, 0xff, 0x4a, 0xee, 0x1d, 0x5d } /* expected */ + }, { + true, /* encrypt */ + 1, /* key_size_index */ + 2, /* key_area */ + { 0x24, 0x40, 0x80, 0x38, 0x16, 0x1a, 0x2c, 0xca, + 0xe0, 0x7b, 0x02, 0x9b, 0xb6, 0x63, 0x55, 0xc1 }, /* iv */ + { 0xbe, 0x8a, 0xbf, 0x00, 0x90, 0x13, 0x63, 0x98, + 0x7a, 0x82, 0xcc, 0x77, 0xd0, 0xec, 0x91, 0x69, + 0x7b, 0xa3, 0x85, 0x7f, 0x9e, 0x4f, 0x84, 0xbd, + 0x79, 0x40, 0x6c, 0x13, 0x8d, 0x02, 0x69, 0x8f, + 0x00, 0x32, 0x76, 0xd0, 0x44, 0x91, 0x20, 0xbe, + 0xf4, 0x57, 0x8d, 0x78, 0xfe, 0xca, 0xbe, 0x8e, + 0x07, 0x0e, 0x11, 0x71, 0x0b, 0x3f, 0x0a, 0x27, + 0x44, 0xbd, 0x52, 0x43, 0x4e, 0xc7, 0x00, 0x15, + 0x88, 0x4c, 0x18, 0x1e, 0xbd, 0xfd, 0x51, 0xc6, + 0x04, 0xa7, 0x1c, 0x52, 0xe4, 0xc0, 0xe1, 0x10, + 0xbc, 0x40, 0x8c, 0xd4, 0x62, 0xb2, 0x48, 0xa8, + 0x0b, 0x8a, 0x8a, 0xc0, 0x6b, 0xb9, 0x52, 0xac, + 0x1d, 0x7f, 0xae, 0xd1, 0x44, 0x80, 0x7f, 0x1a, + 0x73, 0x1b, 0x7f, 0xeb, 0xca, 0xf7, 0x83, 0x57, + 0x62, 0xde, 0xfe, 0x92, 0xec, 0xcf, 0xc7, 0xa9, + 0x94, 0x4e, 0x1c, 0x70, 0x2c, 0xff, 0xe6, 0xbc, + 0x86, 0x73, 0x3e, 0xd3, 0x21, 0x42, 0x31, 0x21, + 0x08, 0x5a, 0xc0, 0x2d, 0xf8, 0x96, 0x2b, 0xcb, + 0xc1, 0x93, 0x70, 0x92, 0xee, 0xbf, 0x0e, 0x90, + 0xa8, 0xb2, 0x0e, 0x3d, 0xd8, 0xc2, 0x44, 0xae }, /* mdata */ + 160, /* mdata_len */ + { 0xc8, 0x2c, 0xf2, 0xc4, 0x76, 0xde, 0xa8, 0xcb, + 0x6a, 0x6e, 0x60, 0x7a, 0x40, 0xd2, 0xf0, 0x39, + 0x1b, 0xe8, 0x2e, 0xa9, 0xec, 0x84, 0xa5, 0x37, + 0xa6, 0x82, 0x0f, 0x9a, 0xfb, 0x99, 0x7b, 0x76, + 0x39, 0x7d, 0x00, 0x54, 0x24, 0xfa, 0xa6, 0xa7, + 0x4d, 0xc4, 0xe8, 0xc7, 0xaa, 0x4a, 0x89, 0x00, + 0x69, 0x0f, 0x89, 0x4b, 0x6d, 0x1d, 0xca, 0x80, + 0x67, 0x53, 0x93, 0xd2, 0x24, 0x3a, 0xda, 0xc7, + 0x62, 0xf1, 0x59, 0x30, 0x1e, 0x35, 0x7e, 0x98, + 0xb7, 0x24, 0x76, 0x23, 0x10, 0xcd, 0x5a, 0x7b, + 0xaf, 0xe1, 0xc2, 0xa0, 0x30, 0xdb, 0xa4, 0x6f, + 0xd9, 0x3a, 0x9f, 0xdb, 0x89, 0xcc, 0x13, 0x2c, + 0xa9, 0xc1, 0x7d, 0xc7, 0x20, 0x31, 0xec, 0x68, + 0x22, 0xee, 0x5a, 0x9d, 0x99, 0xdb, 0xca, 0x66, + 0xc7, 0x84, 0xc0, 0x1b, 0x08, 0x85, 0xcb, 0xb6, + 0x2e, 0x29, 0xd9, 0x78, 0x01, 0x92, 0x7e, 0xc4, + 0x15, 0xa5, 0xd2, 0x15, 0x15, 0x8d, 0x32, 0x5f, + 0x9e, 0xe6, 0x89, 0x43, 0x7a, 0xd1, 0xb7, 0x68, + 0x4a, 0xd3, 0x3c, 0x0d, 0x92, 0x73, 0x94, 0x51, + 0xac, 0x87, 0xf3, 0x9f, 0xf8, 0xc3, 0x1b, 0x84 } /* expected */ + }, { + false, /* encrypt */ + 1, /* key_size_index */ + 4, /* key_area */ + { 0x32, 0x40, 0x15, 0x87, 0x8c, 0xdc, 0x82, 0xbf, + 0xae, 0x59, 0xa2, 0xdc, 0x1f, 0xf3, 0x4e, 0xa6 }, /* iv */ + { 0x39, 0xa9, 0xb4, 0x2d, 0xe1, 0x9e, 0x51, 0x2a, + 0xb7, 0xf3, 0x04, 0x35, 0x64, 0xc3, 0x51, 0x5a }, /* mdata */ + 16, /* mdata_len */ + { 0xaa, 0x41, 0x17, 0x9d, 0x88, 0x0e, 0x6f, 0xe3, + 0xb1, 0x48, 0x18, 0xd6, 0xe4, 0xa6, 0x2e, 0xb5 } /* expected */ + }, { + false, /* encrypt */ + 1, /* key_size_index */ + 6, /* key_area */ + { 0xd6, 0xd8, 0x6e, 0x0c, 0x82, 0xdd, 0x87, 0x88, + 0xf4, 0x14, 0x7a, 0x26, 0xf9, 0xa7, 0x1c, 0x74 }, /* iv */ + { 0x69, 0x28, 0x29, 0x9c, 0x52, 0xb4, 0xf0, 0x47, + 0x92, 0x6f, 0x8a, 0x54, 0x15, 0x29, 0xda, 0x2d, + 0x6b, 0xba, 0xa3, 0x99, 0x14, 0x3c, 0xed, 0x8e, + 0xfb, 0x77, 0xab, 0x47, 0x40, 0x9d, 0x9a, 0x95, + 0x3a, 0x38, 0x6c, 0x7a, 0xbd, 0x60, 0x26, 0xf4, + 0x98, 0x31, 0xc7, 0x17, 0x62, 0x7c, 0x2a, 0x5e, + 0x77, 0xbd, 0x2d, 0x43, 0x3d, 0x4d, 0x13, 0x0d, + 0xac, 0xd9, 0x27, 0xea, 0x0d, 0x13, 0xa2, 0x3d, + 0x01, 0xa7, 0xcf, 0x39, 0xc6, 0x71, 0x6d, 0xaf, + 0xb6, 0xed, 0x55, 0x24, 0x10, 0xef, 0x5d, 0x27, + 0xfb, 0x94, 0x7b, 0xe2, 0xc8, 0x78, 0x2e, 0xee, + 0x78, 0x29, 0x19, 0x6c, 0x7e, 0xdc, 0xf1, 0x51, + 0xc6, 0x5f, 0x9a, 0x01, 0xf5, 0x4f, 0x8d, 0x20, + 0xf3, 0x8b, 0x7d, 0xa4, 0xa7, 0xe8, 0x3a, 0x2f, + 0x01, 0x27, 0xd5, 0x9d, 0x3e, 0x24, 0x05, 0xd8, + 0x67, 0x4f, 0xc9, 0xf4, 0x1b, 0x60, 0x4f, 0x78, + 0x8f, 0x47, 0x15, 0xf9, 0xd3, 0x62, 0x4e, 0xee, + 0x57, 0xf3, 0x87, 0xbf, 0xad, 0xd1, 0x8a, 0x1f, + 0x90, 0x5e, 0x83, 0x9c, 0x26, 0xb8, 0x61, 0x74, + 0x82, 0x34, 0x7f, 0xab, 0x6d, 0x08, 0x84, 0x5a }, /* mdata */ + 160, /* mdata_len */ + { 0x67, 0xd2, 0xdd, 0xa6, 0xda, 0x26, 0xe2, 0x13, + 0x07, 0x97, 0x34, 0x00, 0x60, 0x07, 0x25, 0x72, + 0x7a, 0xe8, 0x14, 0x15, 0x51, 0x17, 0x72, 0xf4, + 0xa0, 0x9a, 0xd9, 0x90, 0x3b, 0xcf, 0x90, 0xcc, + 0x2c, 0x0d, 0xac, 0x58, 0xba, 0x55, 0x9a, 0x01, + 0x09, 0xc5, 0x4a, 0x9d, 0x61, 0x17, 0xb1, 0x5b, + 0xb5, 0x74, 0xca, 0x47, 0x3e, 0x84, 0x80, 0x47, + 0xe9, 0xa5, 0x4e, 0xe4, 0xab, 0xde, 0x76, 0xaf, + 0xf9, 0x84, 0x9c, 0x44, 0x10, 0x9d, 0x16, 0x1f, + 0x46, 0x44, 0x2e, 0x16, 0x10, 0xd8, 0xb0, 0x15, + 0xcf, 0x36, 0xa0, 0x10, 0xed, 0x8e, 0xfa, 0x32, + 0x07, 0xfd, 0xfc, 0x8f, 0xcc, 0x54, 0x8f, 0x14, + 0x5c, 0x02, 0x7e, 0x44, 0xc5, 0xb0, 0xec, 0x35, + 0xc9, 0x88, 0x6f, 0x4b, 0x9d, 0x65, 0x13, 0xa5, + 0xbc, 0x10, 0xd0, 0xea, 0x6b, 0xbb, 0xc2, 0x6f, + 0x54, 0xb1, 0x83, 0xbc, 0xae, 0x27, 0xfb, 0x79, + 0x9d, 0x88, 0x72, 0xff, 0x74, 0x8f, 0xc4, 0x59, + 0xd5, 0x5c, 0xfa, 0x25, 0x5a, 0xae, 0x29, 0xd7, + 0x1b, 0x07, 0x6d, 0x9b, 0x44, 0xc1, 0x4d, 0x5c, + 0xeb, 0xa9, 0x33, 0x2a, 0x76, 0x3d, 0x9c, 0x94 } /* expected */ + }, { + true, /* encrypt */ + 2, /* key_size_index */ + 0, /* key_area */ + { 0x85, 0x1e, 0x87, 0x64, 0x77, 0x6e, 0x67, 0x96, + 0xaa, 0xb7, 0x22, 0xdb, 0xb6, 0x44, 0xac, 0xe8 }, /* iv */ + { 0x62, 0x82, 0xb8, 0xc0, 0x5c, 0x5c, 0x15, 0x30, + 0xb9, 0x7d, 0x48, 0x16, 0xca, 0x43, 0x47, 0x62 }, /* mdata */ + 16, /* mdata_len */ + { 0x6a, 0xcc, 0x04, 0x14, 0x2e, 0x10, 0x0a, 0x65, + 0xf5, 0x1b, 0x97, 0xad, 0xf5, 0x17, 0x2c, 0x41 } /* expected */ + }, { + true, /* encrypt */ + 2, /* key_size_index */ + 2, /* key_area */ + { 0xd6, 0xd5, 0x81, 0xb8, 0xcf, 0x04, 0xeb, 0xd3, + 0xb6, 0xea, 0xa1, 0xb5, 0x3f, 0x04, 0x7e, 0xe1 }, /* iv */ + { 0x0c, 0x63, 0xd4, 0x13, 0xd3, 0x86, 0x45, 0x70, + 0xe7, 0x0b, 0xb6, 0x61, 0x8b, 0xf8, 0xa4, 0xb9, + 0x58, 0x55, 0x86, 0x68, 0x8c, 0x32, 0xbb, 0xa0, + 0xa5, 0xec, 0xc1, 0x36, 0x2f, 0xad, 0xa7, 0x4a, + 0xda, 0x32, 0xc5, 0x2a, 0xcf, 0xd1, 0xaa, 0x74, + 0x44, 0xba, 0x56, 0x7b, 0x4e, 0x7d, 0xaa, 0xec, + 0xf7, 0xcc, 0x1c, 0xb2, 0x91, 0x82, 0xaf, 0x16, + 0x4a, 0xe5, 0x23, 0x2b, 0x00, 0x28, 0x68, 0x69, + 0x56, 0x35, 0x59, 0x98, 0x07, 0xa9, 0xa7, 0xf0, + 0x7a, 0x1f, 0x13, 0x7e, 0x97, 0xb1, 0xe1, 0xc9, + 0xda, 0xbc, 0x89, 0xb6, 0xa5, 0xe4, 0xaf, 0xa9, + 0xdb, 0x58, 0x55, 0xed, 0xaa, 0x57, 0x50, 0x56, + 0xa8, 0xf4, 0xf8, 0x24, 0x22, 0x16, 0x24, 0x2b, + 0xb0, 0xc2, 0x56, 0x31, 0x0d, 0x9d, 0x32, 0x98, + 0x26, 0xac, 0x35, 0x3d, 0x71, 0x5f, 0xa3, 0x9f, + 0x80, 0xce, 0xc1, 0x44, 0xd6, 0x42, 0x45, 0x58, + 0xf9, 0xf7, 0x0b, 0x98, 0xc9, 0x20, 0x09, 0x6e, + 0x0f, 0x2c, 0x85, 0x5d, 0x59, 0x48, 0x85, 0xa0, + 0x06, 0x25, 0x88, 0x0e, 0x9d, 0xfb, 0x73, 0x41, + 0x63, 0xce, 0xce, 0xf7, 0x2c, 0xf0, 0x30, 0xb8 }, /* mdata */ + 160, /* mdata_len */ + { 0xfc, 0x58, 0x73, 0xe5, 0x0d, 0xe8, 0xfa, 0xf4, + 0xc6, 0xb8, 0x4b, 0xa7, 0x07, 0xb0, 0x85, 0x4e, + 0x9d, 0xb9, 0xab, 0x2e, 0x9f, 0x7d, 0x70, 0x7f, + 0xbb, 0xa3, 0x38, 0xc6, 0x84, 0x3a, 0x18, 0xfc, + 0x6f, 0xac, 0xeb, 0xaf, 0x66, 0x3d, 0x26, 0x29, + 0x6f, 0xb3, 0x29, 0xb4, 0xd2, 0x6f, 0x18, 0x49, + 0x4c, 0x79, 0xe0, 0x9e, 0x77, 0x96, 0x47, 0xf9, + 0xba, 0xfa, 0x87, 0x48, 0x96, 0x30, 0xd7, 0x9f, + 0x43, 0x01, 0x61, 0x0c, 0x23, 0x00, 0xc1, 0x9d, + 0xbf, 0x31, 0x48, 0xb7, 0xca, 0xc8, 0xc4, 0xf4, + 0x94, 0x41, 0x02, 0x75, 0x4f, 0x33, 0x2e, 0x92, + 0xb6, 0xf7, 0xc5, 0xe7, 0x5b, 0xc6, 0x17, 0x9e, + 0xb8, 0x77, 0xa0, 0x78, 0xd4, 0x71, 0x90, 0x09, + 0x02, 0x17, 0x44, 0xc1, 0x4f, 0x13, 0xfd, 0x2a, + 0x55, 0xa2, 0xb9, 0xc4, 0x4d, 0x18, 0x00, 0x06, + 0x85, 0xa8, 0x45, 0xa4, 0xf6, 0x32, 0xc7, 0xc5, + 0x6a, 0x77, 0x30, 0x6e, 0xfa, 0x66, 0xa2, 0x4d, + 0x05, 0xd0, 0x88, 0xdc, 0xd7, 0xc1, 0x3f, 0xe2, + 0x4f, 0xc4, 0x47, 0x27, 0x59, 0x65, 0xdb, 0x9e, + 0x4d, 0x37, 0xfb, 0xc9, 0x30, 0x44, 0x48, 0xcd } /* expected */ + }, { + false, /* encrypt */ + 2, /* key_size_index */ + 4, /* key_area */ + { 0xdd, 0xbb, 0xb0, 0x17, 0x3f, 0x1e, 0x2d, 0xeb, + 0x23, 0x94, 0xa6, 0x2a, 0xa2, 0xa0, 0x24, 0x0e }, /* iv */ + { 0xd5, 0x1d, 0x19, 0xde, 0xd5, 0xca, 0x4a, 0xe1, + 0x4b, 0x2b, 0x20, 0xb0, 0x27, 0xff, 0xb0, 0x20 }, /* mdata */ + 16, /* mdata_len */ + { 0x07, 0x27, 0x0d, 0x0e, 0x63, 0xaa, 0x36, 0xda, + 0xed, 0x8c, 0x6a, 0xde, 0x13, 0xac, 0x1a, 0xf1 } /* expected */ + }, { + false, /* encrypt */ + 2, /* key_size_index */ + 6, /* key_area */ + { 0xe4, 0x96, 0x51, 0x98, 0x8e, 0xbb, 0xb7, 0x2e, + 0xb8, 0xbb, 0x80, 0xbb, 0x9a, 0xbb, 0xca, 0x34 }, /* iv */ + { 0x5b, 0x97, 0xa9, 0xd4, 0x23, 0xf4, 0xb9, 0x74, + 0x13, 0xf3, 0x88, 0xd9, 0xa3, 0x41, 0xe7, 0x27, + 0xbb, 0x33, 0x9f, 0x8e, 0x18, 0xa3, 0xfa, 0xc2, + 0xf2, 0xfb, 0x85, 0xab, 0xdc, 0x8f, 0x13, 0x5d, + 0xeb, 0x30, 0x05, 0x4a, 0x1a, 0xfd, 0xc9, 0xb6, + 0xed, 0x7d, 0xa1, 0x6c, 0x55, 0xeb, 0xa6, 0xb0, + 0xd4, 0xd1, 0x0c, 0x74, 0xe1, 0xd9, 0xa7, 0xcf, + 0x8e, 0xdf, 0xae, 0xaa, 0x68, 0x4a, 0xc0, 0xbd, + 0x9f, 0x9d, 0x24, 0xba, 0x67, 0x49, 0x55, 0xc7, + 0x9d, 0xc6, 0xbe, 0x32, 0xae, 0xe1, 0xc2, 0x60, + 0xb5, 0x58, 0xff, 0x07, 0xe3, 0xa4, 0xd4, 0x9d, + 0x24, 0x16, 0x20, 0x11, 0xff, 0x25, 0x4d, 0xb8, + 0xbe, 0x07, 0x8e, 0x8a, 0xd0, 0x7e, 0x64, 0x8e, + 0x6b, 0xf5, 0x67, 0x93, 0x76, 0xcb, 0x43, 0x21, + 0xa5, 0xef, 0x01, 0xaf, 0xe6, 0xad, 0x88, 0x16, + 0xfc, 0xc7, 0x63, 0x46, 0x69, 0xc8, 0xc4, 0x38, + 0x92, 0x95, 0xc9, 0x24, 0x1e, 0x45, 0xff, 0xf3, + 0x9f, 0x32, 0x25, 0xf7, 0x74, 0x50, 0x32, 0xda, + 0xee, 0xbe, 0x99, 0xd4, 0xb1, 0x9b, 0xcb, 0x21, + 0x5d, 0x1b, 0xfd, 0xb3, 0x6e, 0xda, 0x2c, 0x24 }, /* mdata */ + 160, /* mdata_len */ + { 0xbf, 0xe5, 0xc6, 0x35, 0x4b, 0x7a, 0x3f, 0xf3, + 0xe1, 0x92, 0xe0, 0x57, 0x75, 0xb9, 0xb7, 0x58, + 0x07, 0xde, 0x12, 0xe3, 0x8a, 0x62, 0x6b, 0x8b, + 0xf0, 0xe1, 0x2d, 0x5f, 0xff, 0x78, 0xe4, 0xf1, + 0x77, 0x5a, 0xa7, 0xd7, 0x92, 0xd8, 0x85, 0x16, + 0x2e, 0x66, 0xd8, 0x89, 0x30, 0xf9, 0xc3, 0xb2, + 0xcd, 0xf8, 0x65, 0x4f, 0x56, 0x97, 0x25, 0x04, + 0x80, 0x31, 0x90, 0x38, 0x62, 0x70, 0xf0, 0xaa, + 0x43, 0x64, 0x5d, 0xb1, 0x87, 0xaf, 0x41, 0xfc, + 0xea, 0x63, 0x9b, 0x1f, 0x80, 0x26, 0xcc, 0xdd, + 0x0c, 0x23, 0xe0, 0xde, 0x37, 0x09, 0x4a, 0x8b, + 0x94, 0x1e, 0xcb, 0x76, 0x02, 0x99, 0x8a, 0x4b, + 0x26, 0x04, 0xe6, 0x9f, 0xc0, 0x42, 0x19, 0x58, + 0x5d, 0x85, 0x46, 0x00, 0xe0, 0xad, 0x6f, 0x99, + 0xa5, 0x3b, 0x25, 0x04, 0x04, 0x3c, 0x08, 0xb1, + 0xc3, 0xe2, 0x14, 0xd1, 0x7c, 0xde, 0x05, 0x3c, + 0xbd, 0xf9, 0x1d, 0xaa, 0x99, 0x9e, 0xd5, 0xb4, + 0x7c, 0x37, 0x98, 0x3b, 0xa3, 0xee, 0x25, 0x4b, + 0xc5, 0xc7, 0x93, 0x83, 0x7d, 0xaa, 0xa8, 0xc8, + 0x5c, 0xfc, 0x12, 0xf7, 0xf5, 0x4f, 0x69, 0x9f } /* expected */ + } + }; + static uint8_t mdata[MDATA_MAX_LEN]; + static int i; + static uint8_t key_size_index = -1, ret; + static int8_t res; + static rtimer_clock_t time, time2, total_time; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + if(key_size_index != vectors[i].key_size_index) { + key_size_index = vectors[i].key_size_index; + printf("-----------------------------------------\n" + "Filling %d-bit key store...\n", 128 + (key_size_index << 6)); + time = RTIMER_NOW(); + ret = aes_load_keys(keys[key_size_index].keys, + keys[key_size_index].key_size, keys[key_size_index].count, 0); + time = RTIMER_NOW() - time; + printf("aes_load_keys(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + + printf("-----------------------------------------\n" + "Test vector #%d: %s\n" + "key_area=%d mdata_len=%d\n", + i, vectors[i].encrypt ? "encrypt" : "decrypt", + vectors[i].key_area, vectors[i].mdata_len); + + /* mdata has to be in SRAM. */ + rom_util_memcpy(mdata, vectors[i].mdata, vectors[i].mdata_len); + + time = RTIMER_NOW(); + ret = cbc_crypt_start(vectors[i].encrypt, vectors[i].key_area, + vectors[i].iv, mdata, mdata, vectors[i].mdata_len, + &cbc_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL((res = cbc_crypt_check_status()) != + CRYPTO_PENDING); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("cbc_crypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("cbc_crypt_check_status() wait: %s, %lu us\n", str_res[res], + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(res != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(mdata, vectors[i].expected, vectors[i].mdata_len)) { + puts("Output message does not match expected one"); + } else { + puts("Output message OK"); + } + + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 05ebd50a6..85ecc909c 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -30,7 +30,7 @@ In terms of hardware support, the following drivers have been implemented: * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC * PWM - * Cryptoprocessor (AES-ECB/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * SmartRF06 EB and BB peripherals diff --git a/platform/zoul/README.md b/platform/zoul/README.md index d5288795f..6c138d31e 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -51,7 +51,7 @@ In terms of hardware support, the following drivers have been implemented for th * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC - * Cryptoprocessor (AES-ECB/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * PWM From 47c24cab11889f8092d892f73c494e934611f593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 27 Dec 2015 17:56:44 +0100 Subject: [PATCH 19/94] cc2538: Add crypto driver and example for AES-CTR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/Makefile.cc2538 | 2 +- cpu/cc2538/dev/ctr.c | 77 ++++++ cpu/cc2538/dev/ctr.h | 89 +++++++ examples/cc2538dk/crypto/Makefile | 2 +- examples/cc2538dk/crypto/ctr-test.c | 352 ++++++++++++++++++++++++++++ platform/cc2538dk/README.md | 2 +- platform/zoul/README.md | 2 +- 7 files changed, 522 insertions(+), 4 deletions(-) create mode 100644 cpu/cc2538/dev/ctr.c create mode 100644 cpu/cc2538/dev/ctr.h create mode 100644 examples/cc2538dk/crypto/ctr-test.c diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index ae8f91729..cfa0b1360 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -53,7 +53,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c -CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ccm.c sha256.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c ccm.c sha256.c CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c diff --git a/cpu/cc2538/dev/ctr.c b/cpu/cc2538/dev/ctr.c new file mode 100644 index 000000000..0b0a88580 --- /dev/null +++ b/cpu/cc2538/dev/ctr.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-ctr + * @{ + * + * \file + * Implementation of the cc2538 AES-CTR driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/ctr.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce, + const void *ictr, uint8_t ctr_len, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, struct process *process) +{ + uint32_t ctrl; + uint32_t iv[AES_IV_LEN / sizeof(uint32_t)]; + uint8_t nonce_len; + + /* Program AES-CTR crypto operation */ + ctrl = (((ctr_len >> 2) - 1) << AES_AES_CTRL_CTR_WIDTH_S) | /* CTR width */ + AES_AES_CTRL_CTR | /* CTR */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + /* Prepare the crypto initialization vector */ + nonce_len = AES_IV_LEN - ctr_len; + /* Nonce */ + rom_util_memcpy(&((uint8_t *)iv)[0], nonce, nonce_len); + /* Initial counter */ + rom_util_memcpy(&((uint8_t *)iv)[nonce_len], ictr, ctr_len); + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata_in, mdata_out, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +int8_t +ctr_crypt_check_status(void) +{ + return aes_auth_crypt_check_status() ? aes_auth_crypt_get_result(NULL, NULL) : + CRYPTO_PENDING; +} + +/** @} */ diff --git a/cpu/cc2538/dev/ctr.h b/cpu/cc2538/dev/ctr.h new file mode 100644 index 000000000..491859d8f --- /dev/null +++ b/cpu/cc2538/dev/ctr.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-aes + * @{ + * + * \defgroup cc2538-ctr cc2538 AES-CTR + * + * Driver for the cc2538 AES-CTR mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CTR driver + */ +#ifndef CTR_H_ +#define CTR_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CTR functions + * @{ + */ + +/** \brief Starts a CTR crypto operation + * \param encrypt \c true to encrypt, or \c false to decrypt + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param nonce Pointer to nonce (\c AES_IV_LEN - \p ctr_len octets), or \c NULL + * \param ictr Pointer to initial counter + * \param ctr_len Length of counter in octets (4, 8, 12, or 16) + * \param mdata_in Pointer to input message in SRAM + * \param mdata_out Pointer to output message in SRAM (may be \p mdata_in) + * \param mdata_len Length of message in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CTR error code + */ +uint8_t ctr_crypt_start(uint8_t encrypt, uint8_t key_area, const void *nonce, + const void *ictr, uint8_t ctr_len, const void *mdata_in, + void *mdata_out, uint16_t mdata_len, + struct process *process); + +/** \brief Checks the status of the CTR crypto operation + * \return \c CRYPTO_PENDING if operation still pending, \c CRYPTO_SUCCESS if + * successful, or CRYPTO/AES/CTR error code + * \note This function must be called only after \c ctr_crypt_start(). + */ +int8_t ctr_crypt_check_status(void); + +/** @} */ + +#endif /* CTR_H_ */ + +/** + * @} + * @} + */ diff --git a/examples/cc2538dk/crypto/Makefile b/examples/cc2538dk/crypto/Makefile index b11a2165c..49625ad59 100644 --- a/examples/cc2538dk/crypto/Makefile +++ b/examples/cc2538dk/crypto/Makefile @@ -1,4 +1,4 @@ -CONTIKI_PROJECT = ecb-test cbc-test ccm-test sha256-test +CONTIKI_PROJECT = ecb-test cbc-test ctr-test ccm-test sha256-test all: $(CONTIKI_PROJECT) diff --git a/examples/cc2538dk/crypto/ctr-test.c b/examples/cc2538dk/crypto/ctr-test.c new file mode 100644 index 000000000..4a20c9095 --- /dev/null +++ b/examples/cc2538dk/crypto/ctr-test.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-examples + * @{ + * + * \defgroup cc2538-ctr-test cc2538dk AES-CTR Test Project + * + * AES-CTR access example for CC2538 on SmartRF06EB. + * + * This example shows how AES-CTR should be used. The example also verifies + * the AES-CTR functionality. + * + * @{ + * + * \file + * Example demonstrating AES-CTR on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/ctr.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define NONCE_MAX_LEN 0 +#define ICTR_MAX_LEN 16 +#define MDATA_MAX_LEN 64 +/*---------------------------------------------------------------------------*/ +PROCESS(ctr_test_process, "ctr test process"); +AUTOSTART_PROCESSES(&ctr_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ctr_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error", + "keystore read error", + "keystore write error", + "authentication failed" + }; + static const uint8_t keys128[][128 / 8] = { + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c } + }; + static const uint8_t keys192[][192 / 8] = { + { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b } + }; + static const uint8_t keys256[][256 / 8] = { + { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 } + }; + static const struct { + const void *keys; + uint8_t key_size; + uint8_t count; + } keys[] = { + { keys128, AES_KEY_STORE_SIZE_KEY_SIZE_128, + sizeof(keys128) / sizeof(keys128[0]) }, + { keys192, AES_KEY_STORE_SIZE_KEY_SIZE_192, + sizeof(keys192) / sizeof(keys192[0]) }, + { keys256, AES_KEY_STORE_SIZE_KEY_SIZE_256, + sizeof(keys256) / sizeof(keys256[0]) } + }; + static const struct { + bool encrypt; + uint8_t key_size_index; + uint8_t key_area; + uint8_t nonce[NONCE_MAX_LEN]; + uint8_t ictr[ICTR_MAX_LEN]; + uint8_t ctr_len; + uint8_t mdata[MDATA_MAX_LEN]; + uint16_t mdata_len; + uint8_t expected[MDATA_MAX_LEN]; + } vectors[] = { + { + true, /* encrypt */ + 0, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, /* mdata */ + 64, /* mdata_len */ + { 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, + 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, + 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, + 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, + 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, + 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, + 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, + 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, + 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce, + 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, + 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff, + 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, + 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab, + 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, + 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee }, /* mdata */ + 64, /* mdata_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 } /* expected */ + }, { + true, /* encrypt */ + 1, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, /* mdata */ + 64, /* mdata_len */ + { 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, + 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b, + 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, + 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94, + 0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6, 0x70, + 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7, + 0x4f, 0x78, 0xa7, 0xf6, 0xd2, 0x98, 0x09, 0x58, + 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50 } /* expected */ + }, { + false, /* encrypt */ + 1, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x1a, 0xbc, 0x93, 0x24, 0x17, 0x52, 0x1c, 0xa2, + 0x4f, 0x2b, 0x04, 0x59, 0xfe, 0x7e, 0x6e, 0x0b, + 0x09, 0x03, 0x39, 0xec, 0x0a, 0xa6, 0xfa, 0xef, + 0xd5, 0xcc, 0xc2, 0xc6, 0xf4, 0xce, 0x8e, 0x94, + 0x1e, 0x36, 0xb2, 0x6b, 0xd1, 0xeb, 0xc6, 0x70, + 0xd1, 0xbd, 0x1d, 0x66, 0x56, 0x20, 0xab, 0xf7, + 0x4f, 0x78, 0xa7, 0xf6, 0xd2, 0x98, 0x09, 0x58, + 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50 }, /* mdata */ + 64, /* mdata_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 } /* expected */ + }, { + true, /* encrypt */ + 2, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, /* mdata */ + 64, /* mdata_len */ + { 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, + 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6 } /* expected */ + }, { + false, /* encrypt */ + 2, /* key_size_index */ + 0, /* key_area */ + {}, /* nonce */ + { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }, /* ictr */ + 16, /* ctr_len */ + { 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5, + 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28, + 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a, + 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5, + 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c, + 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d, + 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6, + 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6 }, /* mdata */ + 64, /* mdata_len */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 } /* expected */ + } + }; + static uint8_t mdata[MDATA_MAX_LEN]; + static int i; + static uint8_t key_size_index = -1, ret; + static int8_t res; + static rtimer_clock_t time, time2, total_time; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + if(key_size_index != vectors[i].key_size_index) { + key_size_index = vectors[i].key_size_index; + printf("-----------------------------------------\n" + "Filling %d-bit key store...\n", 128 + (key_size_index << 6)); + time = RTIMER_NOW(); + ret = aes_load_keys(keys[key_size_index].keys, + keys[key_size_index].key_size, keys[key_size_index].count, 0); + time = RTIMER_NOW() - time; + printf("aes_load_keys(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + + printf("-----------------------------------------\n" + "Test vector #%d: %s\n" + "key_area=%d ctr_len=%d mdata_len=%d\n", + i, vectors[i].encrypt ? "encrypt" : "decrypt", + vectors[i].key_area, vectors[i].ctr_len, vectors[i].mdata_len); + + /* mdata has to be in SRAM. */ + rom_util_memcpy(mdata, vectors[i].mdata, vectors[i].mdata_len); + + time = RTIMER_NOW(); + ret = ctr_crypt_start(vectors[i].encrypt, vectors[i].key_area, + vectors[i].nonce, vectors[i].ictr, vectors[i].ctr_len, + mdata, mdata, vectors[i].mdata_len, + &ctr_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL((res = ctr_crypt_check_status()) != + CRYPTO_PENDING); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("ctr_crypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("ctr_crypt_check_status() wait: %s, %lu us\n", str_res[res], + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(res != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(mdata, vectors[i].expected, vectors[i].mdata_len)) { + puts("Output message does not match expected one"); + } else { + puts("Output message OK"); + } + + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 85ecc909c..131c8c3e4 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -30,7 +30,7 @@ In terms of hardware support, the following drivers have been implemented: * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC * PWM - * Cryptoprocessor (AES-ECB/CBC/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * SmartRF06 EB and BB peripherals diff --git a/platform/zoul/README.md b/platform/zoul/README.md index 6c138d31e..4628a833f 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -51,7 +51,7 @@ In terms of hardware support, the following drivers have been implemented for th * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC - * Cryptoprocessor (AES-ECB/CBC/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * PWM From e77e9861fe5826a94dd9f4914e704c8e79325c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Wed, 6 Jan 2016 21:51:40 +0100 Subject: [PATCH 20/94] cc2538: Add crypto driver and example for AES-CBC-MAC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/Makefile.cc2538 | 3 +- cpu/cc2538/dev/cbc-mac.c | 91 +++++ cpu/cc2538/dev/cbc-mac.h | 98 +++++ examples/cc2538dk/crypto/Makefile | 2 +- examples/cc2538dk/crypto/cbc-mac-test.c | 506 ++++++++++++++++++++++++ platform/cc2538dk/README.md | 2 +- platform/zoul/README.md | 2 +- 7 files changed, 700 insertions(+), 4 deletions(-) create mode 100644 cpu/cc2538/dev/cbc-mac.c create mode 100644 cpu/cc2538/dev/cbc-mac.h create mode 100644 examples/cc2538dk/crypto/cbc-mac-test.c diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index cfa0b1360..e7c53f4df 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -53,7 +53,8 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c -CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c ccm.c sha256.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c ccm.c +CONTIKI_CPU_SOURCEFILES += sha256.c CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c diff --git a/cpu/cc2538/dev/cbc-mac.c b/cpu/cc2538/dev/cbc-mac.c new file mode 100644 index 000000000..0635e4f53 --- /dev/null +++ b/cpu/cc2538/dev/cbc-mac.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * 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 cc2538-cbc-mac + * @{ + * + * \file + * Implementation of the cc2538 AES-CBC-MAC driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/cbc-mac.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_mac_auth_start(uint8_t key_area, const void *mdata, uint16_t mdata_len, + struct process *process) +{ + uint32_t ctrl; + uint32_t iv[AES_IV_LEN / sizeof(uint32_t)]; + + /* Program AES-CBC-MAC authentication operation */ + ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + AES_AES_CTRL_CBC_MAC | /* CBC-MAC */ + AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */ + + /* Prepare the crypto initialization vector + * Set initialization vector to 0 */ + rom_util_memset(iv, 0, AES_IV_LEN); + + return aes_auth_crypt_start(ctrl, key_area, iv, NULL, 0, + mdata, NULL, mdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +cbc_mac_auth_get_result(const void *mac_in, void *mac_out) +{ + uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)]; + uint8_t ret; + + ret = aes_auth_crypt_get_result(NULL, tag); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + + if(mac_in != NULL) { + /* Check MAC */ + if(rom_util_memcmp(tag, mac_in, CBC_MAC_MAC_LEN)) { + ret = AES_AUTHENTICATION_FAILED; + } + } + + if(mac_out != NULL) { + /* Copy tag to MAC */ + rom_util_memcpy(mac_out, tag, CBC_MAC_MAC_LEN); + } + + return ret; +} + +/** @} */ diff --git a/cpu/cc2538/dev/cbc-mac.h b/cpu/cc2538/dev/cbc-mac.h new file mode 100644 index 000000000..76b750bf5 --- /dev/null +++ b/cpu/cc2538/dev/cbc-mac.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * 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 cc2538-aes + * @{ + * + * \defgroup cc2538-cbc-mac cc2538 AES-CBC-MAC + * + * Driver for the cc2538 AES-CBC-MAC mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CBC-MAC driver + */ +#ifndef CBC_MAC_H_ +#define CBC_MAC_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC-MAC constants + * @{ + */ +#define CBC_MAC_MAC_LEN AES_TAG_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CBC-MAC functions + * @{ + */ + +/** \brief Starts a CBC-MAC authentication operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param mdata Pointer to message to authenticate in SRAM + * \param mdata_len Length of message to authenticate in octets + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code + * \warning CBC-MAC is not secure for variable-length messages. There are a few + * workarounds that can be implemented by the caller, like prepending the + * message length to the first block of the message before passing it. + */ +uint8_t cbc_mac_auth_start(uint8_t key_area, const void *mdata, + uint16_t mdata_len, struct process *process); + +/** \brief Checks the status of the CBC-MAC authentication operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define cbc_mac_auth_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the CBC-MAC authentication operation + * \param mac_in Pointer to 128-bit input MAC, or \c NULL + * \param mac_out Pointer to 128-bit output MAC, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CBC-MAC error code + * \note This function must be called only after \c cbc_mac_auth_start(). + */ +uint8_t cbc_mac_auth_get_result(const void *mac_in, void *mac_out); + +/** @} */ + +#endif /* CBC_MAC_H_ */ + +/** + * @} + * @} + */ diff --git a/examples/cc2538dk/crypto/Makefile b/examples/cc2538dk/crypto/Makefile index 49625ad59..c015301e9 100644 --- a/examples/cc2538dk/crypto/Makefile +++ b/examples/cc2538dk/crypto/Makefile @@ -1,4 +1,4 @@ -CONTIKI_PROJECT = ecb-test cbc-test ctr-test ccm-test sha256-test +CONTIKI_PROJECT = ecb-test cbc-test ctr-test cbc-mac-test ccm-test sha256-test all: $(CONTIKI_PROJECT) diff --git a/examples/cc2538dk/crypto/cbc-mac-test.c b/examples/cc2538dk/crypto/cbc-mac-test.c new file mode 100644 index 000000000..ff355fc1f --- /dev/null +++ b/examples/cc2538dk/crypto/cbc-mac-test.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2016, Benoît Thébaudeau + * 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 cc2538-examples + * @{ + * + * \defgroup cc2538-cbc-mac-test cc2538dk AES-CBC-MAC Test Project + * + * AES-CBC-MAC access example for CC2538 on SmartRF06EB. + * + * This example shows how AES-CBC-MAC should be used. The example also + * verifies the AES-CBC-MAC functionality. + * + * @{ + * + * \file + * Example demonstrating AES-CBC-MAC on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/cbc-mac.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define MDATA_MAX_LEN 160 +/*---------------------------------------------------------------------------*/ +PROCESS(cbc_mac_test_process, "cbc_mac test process"); +AUTOSTART_PROCESSES(&cbc_mac_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cbc_mac_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error", + "keystore read error", + "keystore write error", + "authentication failed" + }; + static const uint8_t keys128[][128 / 8] = { + { 0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0, + 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17 }, + { 0xb7, 0xf3, 0xc9, 0x57, 0x6e, 0x12, 0xdd, 0x0d, + 0xb6, 0x3e, 0x8f, 0x8f, 0xac, 0x2b, 0x9a, 0x39 }, + { 0x89, 0xa5, 0x53, 0x73, 0x04, 0x33, 0xf7, 0xe6, + 0xd6, 0x7d, 0x16, 0xd3, 0x73, 0xbd, 0x53, 0x60 }, + { 0x2c, 0x14, 0x41, 0x37, 0x51, 0xc3, 0x1e, 0x27, + 0x30, 0x57, 0x0b, 0xa3, 0x36, 0x1c, 0x78, 0x6b }, + { 0x6a, 0x70, 0x82, 0xcf, 0x8c, 0xda, 0x13, 0xef, + 0xf4, 0x8c, 0x81, 0x58, 0xdd, 0xa2, 0x06, 0xae }, + { 0x7b, 0x1a, 0xb9, 0x14, 0x4b, 0x02, 0x39, 0x31, + 0x5c, 0xd5, 0xee, 0xc6, 0xc7, 0x56, 0x63, 0xbd }, + { 0xba, 0xb0, 0xcc, 0xed, 0xdc, 0x0a, 0xbd, 0x63, + 0xe3, 0xf8, 0x2e, 0x9f, 0xbf, 0xf7, 0xb8, 0xaa }, + { 0x97, 0xa1, 0x02, 0x55, 0x29, 0xb9, 0x92, 0x5e, + 0x25, 0xbb, 0xe7, 0x87, 0x70, 0xca, 0x2f, 0x99 } + }; + static const uint8_t keys192[][192 / 8] = { + { 0xba, 0x75, 0xf4, 0xd1, 0xd9, 0xd7, 0xcf, 0x7f, + 0x55, 0x14, 0x45, 0xd5, 0x6c, 0xc1, 0xa8, 0xab, + 0x2a, 0x07, 0x8e, 0x15, 0xe0, 0x49, 0xdc, 0x2c }, + { 0x16, 0x2a, 0xd5, 0x0e, 0xe6, 0x4a, 0x07, 0x02, + 0xaa, 0x55, 0x1f, 0x57, 0x1d, 0xed, 0xc1, 0x6b, + 0x2c, 0x1b, 0x6a, 0x1e, 0x4d, 0x4b, 0x5e, 0xee }, + { 0x8e, 0x27, 0x40, 0xfb, 0xa1, 0x57, 0xae, 0xf2, + 0x42, 0x2e, 0x44, 0x23, 0x12, 0xd1, 0x5c, 0x14, + 0xd3, 0x12, 0x55, 0x36, 0x84, 0xfc, 0xdc, 0x15 }, + { 0x50, 0x9b, 0xaf, 0x46, 0xfb, 0x9d, 0xe3, 0x42, + 0x81, 0xda, 0xfc, 0xc3, 0xdb, 0x79, 0x59, 0x3b, + 0xff, 0xa8, 0x42, 0x69, 0x04, 0x30, 0x26, 0x88 } + }; + static const uint8_t keys256[][256 / 8] = { + { 0x6e, 0xd7, 0x6d, 0x2d, 0x97, 0xc6, 0x9f, 0xd1, + 0x33, 0x95, 0x89, 0x52, 0x39, 0x31, 0xf2, 0xa6, + 0xcf, 0xf5, 0x54, 0xb1, 0x5f, 0x73, 0x8f, 0x21, + 0xec, 0x72, 0xdd, 0x97, 0xa7, 0x33, 0x09, 0x07 }, + { 0x48, 0xbe, 0x59, 0x7e, 0x63, 0x2c, 0x16, 0x77, + 0x23, 0x24, 0xc8, 0xd3, 0xfa, 0x1d, 0x9c, 0x5a, + 0x9e, 0xcd, 0x01, 0x0f, 0x14, 0xec, 0x5d, 0x11, + 0x0d, 0x3b, 0xfe, 0xc3, 0x76, 0xc5, 0x53, 0x2b }, + { 0x43, 0xe9, 0x53, 0xb2, 0xae, 0xa0, 0x8a, 0x3a, + 0xd5, 0x2d, 0x18, 0x2f, 0x58, 0xc7, 0x2b, 0x9c, + 0x60, 0xfb, 0xe4, 0xa9, 0xca, 0x46, 0xa3, 0xcb, + 0x89, 0xe3, 0x86, 0x38, 0x45, 0xe2, 0x2c, 0x9e }, + { 0x87, 0x72, 0x5b, 0xd4, 0x3a, 0x45, 0x60, 0x88, + 0x14, 0x18, 0x07, 0x73, 0xf0, 0xe7, 0xab, 0x95, + 0xa3, 0xc8, 0x59, 0xd8, 0x3a, 0x21, 0x30, 0xe8, + 0x84, 0x19, 0x0e, 0x44, 0xd1, 0x4c, 0x69, 0x96 } + }; + static const struct { + const void *keys; + uint8_t key_size; + uint8_t count; + } keys[] = { + { keys128, AES_KEY_STORE_SIZE_KEY_SIZE_128, + sizeof(keys128) / sizeof(keys128[0]) }, + { keys192, AES_KEY_STORE_SIZE_KEY_SIZE_192, + sizeof(keys192) / sizeof(keys192[0]) }, + { keys256, AES_KEY_STORE_SIZE_KEY_SIZE_256, + sizeof(keys256) / sizeof(keys256[0]) } + }; + static const struct { + uint8_t key_size_index; + uint8_t key_area; + uint8_t mdata[MDATA_MAX_LEN]; + uint16_t mdata_len; + uint8_t mac[CBC_MAC_MAC_LEN]; + } vectors[] = { + { + 0, /* key_size_index */ + 0, /* key_area */ + { 0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab, + 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22 }, /* mdata */ + 16, /* mdata_len */ + { 0x97, 0x67, 0x0c, 0x83, 0x99, 0x24, 0xa4, 0xc6, + 0x15, 0xb0, 0xf6, 0x14, 0xae, 0x75, 0xa8, 0x69 } /* mac */ + }, { + 0, /* key_size_index */ + 1, /* key_area */ + { 0x9a, 0xc1, 0x99, 0x54, 0xce, 0x13, 0x19, 0xb3, + 0x54, 0xd3, 0x22, 0x04, 0x60, 0xf7, 0x1c, 0x1e, + 0x37, 0x3f, 0x1c, 0xd3, 0x36, 0x24, 0x08, 0x81, + 0x16, 0x0c, 0xfd, 0xe4, 0x6e, 0xbf, 0xed, 0x2e, + 0x79, 0x1e, 0x8d, 0x5a, 0x1a, 0x13, 0x6e, 0xbd, + 0x1d, 0xc4, 0x69, 0xde, 0xc0, 0x0c, 0x41, 0x87, + 0x72, 0x2b, 0x84, 0x1c, 0xda, 0xbc, 0xb2, 0x2c, + 0x1b, 0xe8, 0xa1, 0x46, 0x57, 0xda, 0x20, 0x0e }, /* mdata */ + 64, /* mdata_len */ + { 0x9d, 0x15, 0xb9, 0xfb, 0xff, 0xe2, 0x32, 0x97, + 0x56, 0x36, 0x36, 0x6d, 0x13, 0x65, 0x78, 0xb5 } /* mac */ + }, { + 0, /* key_size_index */ + 2, /* key_area */ + { 0x80, 0x7b, 0xc4, 0xea, 0x68, 0x4e, 0xed, 0xcf, + 0xdc, 0xca, 0x30, 0x18, 0x06, 0x80, 0xb0, 0xf1, + 0xae, 0x28, 0x14, 0xf3, 0x5f, 0x36, 0xd0, 0x53, + 0xc5, 0xae, 0xa6, 0x59, 0x5a, 0x38, 0x6c, 0x14, + 0x42, 0x77, 0x0f, 0x4d, 0x72, 0x97, 0xd8, 0xb9, + 0x18, 0x25, 0xee, 0x72, 0x37, 0x24, 0x1d, 0xa8, + 0x92, 0x5d, 0xd5, 0x94, 0xcc, 0xf6, 0x76, 0xae, + 0xcd, 0x46, 0xca, 0x20, 0x68, 0xe8, 0xd3, 0x7a, + 0x3a, 0x0e, 0xc8, 0xa7, 0xd5, 0x18, 0x5a, 0x20, + 0x1e, 0x66, 0x3b, 0x5f, 0xf3, 0x6a, 0xe1, 0x97, + 0x11, 0x01, 0x88, 0xa2, 0x35, 0x03, 0x76, 0x3b, + 0x82, 0x18, 0x82, 0x6d, 0x23, 0xce, 0xd7, 0x4b, + 0x31, 0xe9, 0xf6, 0xe2, 0xd7, 0xfb, 0xfa, 0x6c, + 0xb4, 0x34, 0x20, 0xc7, 0x80, 0x7a, 0x86, 0x25 }, /* mdata */ + 112, /* mdata_len */ + { 0x5f, 0x4f, 0x06, 0xe0, 0x62, 0x65, 0xf2, 0xeb, + 0x16, 0x1c, 0xda, 0x9f, 0x30, 0xe9, 0x79, 0x53 } /* mac */ + }, { + 0, /* key_size_index */ + 3, /* key_area */ + { 0x40, 0xd9, 0x30, 0xf9, 0xa0, 0x53, 0x34, 0xd9, + 0x81, 0x6f, 0xe2, 0x04, 0x99, 0x9c, 0x3f, 0x82, + 0xa0, 0x3f, 0x6a, 0x04, 0x57, 0xa8, 0xc4, 0x75, + 0xc9, 0x45, 0x53, 0xd1, 0xd1, 0x16, 0x69, 0x3a, + 0xdc, 0x61, 0x80, 0x49, 0xf0, 0xa7, 0x69, 0xa2, + 0xee, 0xd6, 0xa6, 0xcb, 0x14, 0xc0, 0x14, 0x3e, + 0xc5, 0xcc, 0xcd, 0xbc, 0x8d, 0xec, 0x4c, 0xe5, + 0x60, 0xcf, 0xd2, 0x06, 0x22, 0x57, 0x09, 0x32, + 0x6d, 0x4d, 0xe7, 0x94, 0x8e, 0x54, 0xd6, 0x03, + 0xd0, 0x1b, 0x12, 0xd7, 0xfe, 0xd7, 0x52, 0xfb, + 0x23, 0xf1, 0xaa, 0x44, 0x94, 0xfb, 0xb0, 0x01, + 0x30, 0xe9, 0xde, 0xd4, 0xe7, 0x7e, 0x37, 0xc0, + 0x79, 0x04, 0x2d, 0x82, 0x80, 0x40, 0xc3, 0x25, + 0xb1, 0xa5, 0xef, 0xd1, 0x5f, 0xc8, 0x42, 0xe4, + 0x40, 0x14, 0xca, 0x43, 0x74, 0xbf, 0x38, 0xf3, + 0xc3, 0xfc, 0x3e, 0xe3, 0x27, 0x73, 0x3b, 0x0c, + 0x8a, 0xee, 0x1a, 0xbc, 0xd0, 0x55, 0x77, 0x2f, + 0x18, 0xdc, 0x04, 0x60, 0x3f, 0x7b, 0x2c, 0x1e, + 0xa6, 0x9f, 0xf6, 0x62, 0x36, 0x1f, 0x2b, 0xe0, + 0xa1, 0x71, 0xbb, 0xdc, 0xea, 0x1e, 0x5d, 0x3f }, /* mdata */ + 160, /* mdata_len */ + { 0xda, 0x15, 0x2d, 0xf1, 0xf5, 0x6a, 0x44, 0x0e, + 0x1c, 0x7e, 0x27, 0x80, 0xed, 0x87, 0xd9, 0x3d } /* mac */ + }, { + 0, /* key_size_index */ + 4, /* key_area */ + { 0xf8, 0xeb, 0x31, 0xb3, 0x1e, 0x37, 0x4e, 0x96, + 0x00, 0x30, 0xcd, 0x1c, 0xad, 0xb0, 0xef, 0x0c }, /* mdata */ + 16, /* mdata_len */ + { 0x11, 0x0b, 0x18, 0xdb, 0xe0, 0x97, 0x56, 0x39, + 0xf7, 0x1d, 0x87, 0x7d, 0x6d, 0x07, 0x27, 0x55 } /* mac */ + }, { + 0, /* key_size_index */ + 5, /* key_area */ + { 0xd3, 0xf8, 0x9b, 0x71, 0xe0, 0x33, 0x07, 0x0f, + 0x9d, 0x75, 0x16, 0xa6, 0xcb, 0x4e, 0xa5, 0xef, + 0x51, 0xd6, 0xfb, 0x63, 0xd4, 0xf0, 0xfe, 0xa0, + 0x89, 0xd0, 0xa6, 0x0e, 0x47, 0xbb, 0xb3, 0xc2, + 0xe1, 0x0e, 0x9b, 0xa3, 0xb2, 0x82, 0xc7, 0xcb, + 0x79, 0xae, 0xfe, 0x30, 0x68, 0xce, 0x22, 0x83, + 0x77, 0xc2, 0x1a, 0x58, 0xfe, 0x5a, 0x0f, 0x88, + 0x83, 0xd0, 0xdb, 0xd3, 0xd0, 0x96, 0xbe, 0xca }, /* mdata */ + 64, /* mdata_len */ + { 0x6d, 0x91, 0x75, 0x52, 0x10, 0xcc, 0x69, 0x4a, + 0xde, 0x6c, 0xf6, 0xa0, 0xcd, 0x2d, 0x51, 0x8e } /* mac */ + }, { + 0, /* key_size_index */ + 6, /* key_area */ + { 0xc6, 0x5b, 0x94, 0xb1, 0xf2, 0x91, 0xfa, 0x9f, + 0x06, 0x00, 0xf2, 0x2c, 0x3c, 0x04, 0x32, 0xc8, + 0x95, 0xad, 0x5d, 0x17, 0x7b, 0xcc, 0xcc, 0x9e, + 0xa4, 0x4e, 0x8e, 0xc3, 0x39, 0xc9, 0xad, 0xf4, + 0x38, 0x55, 0xb3, 0x26, 0x17, 0x9d, 0x6d, 0x81, + 0xaa, 0x36, 0xef, 0x59, 0x46, 0x2f, 0xd8, 0x61, + 0x27, 0xe9, 0xd8, 0x1b, 0x0f, 0x28, 0x6f, 0x93, + 0x30, 0x6b, 0xf7, 0x4d, 0x4c, 0x79, 0xe4, 0x7c, + 0x1b, 0x3d, 0x4b, 0x74, 0xed, 0xd3, 0xa1, 0x62, + 0x90, 0xe3, 0xc6, 0x3b, 0x74, 0x2e, 0x41, 0xf2, + 0x0d, 0x66, 0xce, 0xee, 0x79, 0x43, 0x16, 0xbb, + 0x63, 0xd3, 0xbd, 0x00, 0x27, 0x12, 0xa1, 0xb1, + 0x36, 0xba, 0x61, 0x85, 0xbd, 0x5c, 0x1d, 0xab, + 0x81, 0xb0, 0x7d, 0xb9, 0x0d, 0x2a, 0xf5, 0xe5 }, /* mdata */ + 112, /* mdata_len */ + { 0x47, 0x12, 0x32, 0xdc, 0x47, 0xca, 0x7e, 0xe2, + 0xd8, 0xd6, 0x43, 0x6c, 0xe5, 0x75, 0x03, 0xb9 } /* mac */ + }, { + 0, /* key_size_index */ + 7, /* key_area */ + { 0x22, 0xcd, 0xc3, 0x30, 0x6f, 0xcd, 0x4d, 0x31, + 0xcc, 0xd3, 0x27, 0x20, 0xcb, 0xb6, 0x1b, 0xad, + 0x28, 0xd8, 0x55, 0x67, 0x06, 0x57, 0xc4, 0x8c, + 0x7b, 0x88, 0xc3, 0x1f, 0x4f, 0xa1, 0xf9, 0x3c, + 0x01, 0xb5, 0x7d, 0xa9, 0x0b, 0xe6, 0x3e, 0xad, + 0x67, 0xd6, 0xa3, 0x25, 0x52, 0x5e, 0x6e, 0xd4, + 0x50, 0x83, 0xe6, 0xfb, 0x70, 0xa5, 0x35, 0x29, + 0xd1, 0xfa, 0x0f, 0x55, 0x65, 0x3b, 0x94, 0x2a, + 0xf5, 0x9d, 0x78, 0xa2, 0x66, 0x03, 0x61, 0xd6, + 0x3a, 0x72, 0x90, 0x15, 0x5a, 0xc5, 0xc4, 0x33, + 0x12, 0xa2, 0x5b, 0x23, 0x5d, 0xac, 0xbb, 0xc8, + 0x63, 0xfa, 0xf0, 0x09, 0x40, 0xc9, 0x96, 0x24, + 0x07, 0x6d, 0xfa, 0x44, 0x06, 0x8e, 0x7c, 0x55, + 0x4c, 0x90, 0x38, 0x17, 0x69, 0x53, 0xe5, 0x71, + 0x75, 0x1d, 0xfc, 0x09, 0x54, 0xd4, 0x1d, 0x11, + 0x37, 0x71, 0xb0, 0x64, 0x66, 0xb1, 0xc8, 0xd1, + 0x3e, 0x0d, 0x4c, 0xb6, 0x75, 0xed, 0x58, 0xd1, + 0xa6, 0x19, 0xe1, 0x54, 0x09, 0x70, 0x98, 0x37, + 0x81, 0xdc, 0x11, 0xd2, 0xdd, 0x85, 0x25, 0xab, + 0x57, 0x45, 0x95, 0x8d, 0x61, 0x5d, 0xef, 0xda }, /* mdata */ + 160, /* mdata_len */ + { 0xe9, 0xae, 0x7e, 0x63, 0x54, 0x23, 0xc3, 0x66, + 0xd5, 0x23, 0xf9, 0x7c, 0x0e, 0xdb, 0x18, 0xb0 } /* mac */ + }, { + 1, /* key_size_index */ + 0, /* key_area */ + { 0xc5, 0x1f, 0xc2, 0x76, 0x77, 0x4d, 0xad, 0x94, + 0xbc, 0xdc, 0x1d, 0x28, 0x91, 0xec, 0x86, 0x68 }, /* mdata */ + 16, /* mdata_len */ + { 0x40, 0xd1, 0x7f, 0x9a, 0x6f, 0x5b, 0xc6, 0xaf, + 0x34, 0x1e, 0x6a, 0xc5, 0xe4, 0x9e, 0x71, 0xad } /* mac */ + }, { + 1, /* key_size_index */ + 2, /* key_area */ + { 0xbe, 0x8a, 0xbf, 0x00, 0x90, 0x13, 0x63, 0x98, + 0x7a, 0x82, 0xcc, 0x77, 0xd0, 0xec, 0x91, 0x69, + 0x7b, 0xa3, 0x85, 0x7f, 0x9e, 0x4f, 0x84, 0xbd, + 0x79, 0x40, 0x6c, 0x13, 0x8d, 0x02, 0x69, 0x8f, + 0x00, 0x32, 0x76, 0xd0, 0x44, 0x91, 0x20, 0xbe, + 0xf4, 0x57, 0x8d, 0x78, 0xfe, 0xca, 0xbe, 0x8e, + 0x07, 0x0e, 0x11, 0x71, 0x0b, 0x3f, 0x0a, 0x27, + 0x44, 0xbd, 0x52, 0x43, 0x4e, 0xc7, 0x00, 0x15, + 0x88, 0x4c, 0x18, 0x1e, 0xbd, 0xfd, 0x51, 0xc6, + 0x04, 0xa7, 0x1c, 0x52, 0xe4, 0xc0, 0xe1, 0x10, + 0xbc, 0x40, 0x8c, 0xd4, 0x62, 0xb2, 0x48, 0xa8, + 0x0b, 0x8a, 0x8a, 0xc0, 0x6b, 0xb9, 0x52, 0xac, + 0x1d, 0x7f, 0xae, 0xd1, 0x44, 0x80, 0x7f, 0x1a, + 0x73, 0x1b, 0x7f, 0xeb, 0xca, 0xf7, 0x83, 0x57, + 0x62, 0xde, 0xfe, 0x92, 0xec, 0xcf, 0xc7, 0xa9, + 0x94, 0x4e, 0x1c, 0x70, 0x2c, 0xff, 0xe6, 0xbc, + 0x86, 0x73, 0x3e, 0xd3, 0x21, 0x42, 0x31, 0x21, + 0x08, 0x5a, 0xc0, 0x2d, 0xf8, 0x96, 0x2b, 0xcb, + 0xc1, 0x93, 0x70, 0x92, 0xee, 0xbf, 0x0e, 0x90, + 0xa8, 0xb2, 0x0e, 0x3d, 0xd8, 0xc2, 0x44, 0xae }, /* mdata */ + 160, /* mdata_len */ + { 0xea, 0x57, 0x08, 0xb7, 0x8b, 0xf0, 0x51, 0xd6, + 0x94, 0xeb, 0x37, 0x01, 0xca, 0x6b, 0xd5, 0x7b } /* mac */ + }, { + 1, /* key_size_index */ + 4, /* key_area */ + { 0x39, 0xa9, 0xb4, 0x2d, 0xe1, 0x9e, 0x51, 0x2a, + 0xb7, 0xf3, 0x04, 0x35, 0x64, 0xc3, 0x51, 0x5a }, /* mdata */ + 16, /* mdata_len */ + { 0xa8, 0xd9, 0x3d, 0x9e, 0x1c, 0x14, 0xe4, 0x1e, + 0xa3, 0xf0, 0xaa, 0x50, 0xa4, 0xa3, 0x26, 0x09 } /* mac */ + }, { + 1, /* key_size_index */ + 6, /* key_area */ + { 0x69, 0x28, 0x29, 0x9c, 0x52, 0xb4, 0xf0, 0x47, + 0x92, 0x6f, 0x8a, 0x54, 0x15, 0x29, 0xda, 0x2d, + 0x6b, 0xba, 0xa3, 0x99, 0x14, 0x3c, 0xed, 0x8e, + 0xfb, 0x77, 0xab, 0x47, 0x40, 0x9d, 0x9a, 0x95, + 0x3a, 0x38, 0x6c, 0x7a, 0xbd, 0x60, 0x26, 0xf4, + 0x98, 0x31, 0xc7, 0x17, 0x62, 0x7c, 0x2a, 0x5e, + 0x77, 0xbd, 0x2d, 0x43, 0x3d, 0x4d, 0x13, 0x0d, + 0xac, 0xd9, 0x27, 0xea, 0x0d, 0x13, 0xa2, 0x3d, + 0x01, 0xa7, 0xcf, 0x39, 0xc6, 0x71, 0x6d, 0xaf, + 0xb6, 0xed, 0x55, 0x24, 0x10, 0xef, 0x5d, 0x27, + 0xfb, 0x94, 0x7b, 0xe2, 0xc8, 0x78, 0x2e, 0xee, + 0x78, 0x29, 0x19, 0x6c, 0x7e, 0xdc, 0xf1, 0x51, + 0xc6, 0x5f, 0x9a, 0x01, 0xf5, 0x4f, 0x8d, 0x20, + 0xf3, 0x8b, 0x7d, 0xa4, 0xa7, 0xe8, 0x3a, 0x2f, + 0x01, 0x27, 0xd5, 0x9d, 0x3e, 0x24, 0x05, 0xd8, + 0x67, 0x4f, 0xc9, 0xf4, 0x1b, 0x60, 0x4f, 0x78, + 0x8f, 0x47, 0x15, 0xf9, 0xd3, 0x62, 0x4e, 0xee, + 0x57, 0xf3, 0x87, 0xbf, 0xad, 0xd1, 0x8a, 0x1f, + 0x90, 0x5e, 0x83, 0x9c, 0x26, 0xb8, 0x61, 0x74, + 0x82, 0x34, 0x7f, 0xab, 0x6d, 0x08, 0x84, 0x5a }, /* mdata */ + 160, /* mdata_len */ + { 0x69, 0x27, 0xe7, 0xfb, 0x4c, 0xb9, 0x9d, 0x9c, + 0x54, 0xe2, 0x7f, 0x1c, 0x76, 0x20, 0xa0, 0x07 } /* mac */ + }, { + 2, /* key_size_index */ + 0, /* key_area */ + { 0x62, 0x82, 0xb8, 0xc0, 0x5c, 0x5c, 0x15, 0x30, + 0xb9, 0x7d, 0x48, 0x16, 0xca, 0x43, 0x47, 0x62 }, /* mdata */ + 16, /* mdata_len */ + { 0xa1, 0x07, 0x61, 0x82, 0xc1, 0xf4, 0x33, 0xc3, + 0xda, 0xfb, 0xe1, 0x1d, 0x3e, 0x71, 0xdd, 0x8a } /* mac */ + }, { + 2, /* key_size_index */ + 2, /* key_area */ + { 0x0c, 0x63, 0xd4, 0x13, 0xd3, 0x86, 0x45, 0x70, + 0xe7, 0x0b, 0xb6, 0x61, 0x8b, 0xf8, 0xa4, 0xb9, + 0x58, 0x55, 0x86, 0x68, 0x8c, 0x32, 0xbb, 0xa0, + 0xa5, 0xec, 0xc1, 0x36, 0x2f, 0xad, 0xa7, 0x4a, + 0xda, 0x32, 0xc5, 0x2a, 0xcf, 0xd1, 0xaa, 0x74, + 0x44, 0xba, 0x56, 0x7b, 0x4e, 0x7d, 0xaa, 0xec, + 0xf7, 0xcc, 0x1c, 0xb2, 0x91, 0x82, 0xaf, 0x16, + 0x4a, 0xe5, 0x23, 0x2b, 0x00, 0x28, 0x68, 0x69, + 0x56, 0x35, 0x59, 0x98, 0x07, 0xa9, 0xa7, 0xf0, + 0x7a, 0x1f, 0x13, 0x7e, 0x97, 0xb1, 0xe1, 0xc9, + 0xda, 0xbc, 0x89, 0xb6, 0xa5, 0xe4, 0xaf, 0xa9, + 0xdb, 0x58, 0x55, 0xed, 0xaa, 0x57, 0x50, 0x56, + 0xa8, 0xf4, 0xf8, 0x24, 0x22, 0x16, 0x24, 0x2b, + 0xb0, 0xc2, 0x56, 0x31, 0x0d, 0x9d, 0x32, 0x98, + 0x26, 0xac, 0x35, 0x3d, 0x71, 0x5f, 0xa3, 0x9f, + 0x80, 0xce, 0xc1, 0x44, 0xd6, 0x42, 0x45, 0x58, + 0xf9, 0xf7, 0x0b, 0x98, 0xc9, 0x20, 0x09, 0x6e, + 0x0f, 0x2c, 0x85, 0x5d, 0x59, 0x48, 0x85, 0xa0, + 0x06, 0x25, 0x88, 0x0e, 0x9d, 0xfb, 0x73, 0x41, + 0x63, 0xce, 0xce, 0xf7, 0x2c, 0xf0, 0x30, 0xb8 }, /* mdata */ + 160, /* mdata_len */ + { 0xf2, 0xb7, 0x45, 0x13, 0xd6, 0xcf, 0x2d, 0x80, + 0xe6, 0x72, 0xb8, 0x37, 0x45, 0xfa, 0xdc, 0x0f } /* mac */ + }, { + 2, /* key_size_index */ + 4, /* key_area */ + { 0xd5, 0x1d, 0x19, 0xde, 0xd5, 0xca, 0x4a, 0xe1, + 0x4b, 0x2b, 0x20, 0xb0, 0x27, 0xff, 0xb0, 0x20 }, /* mdata */ + 16, /* mdata_len */ + { 0xb0, 0x52, 0xa1, 0xdf, 0xe6, 0xa4, 0x8e, 0x63, + 0x43, 0x23, 0xdc, 0xaa, 0x85, 0xfa, 0xda, 0x3c } /* mac */ + }, { + 2, /* key_size_index */ + 6, /* key_area */ + { 0x5b, 0x97, 0xa9, 0xd4, 0x23, 0xf4, 0xb9, 0x74, + 0x13, 0xf3, 0x88, 0xd9, 0xa3, 0x41, 0xe7, 0x27, + 0xbb, 0x33, 0x9f, 0x8e, 0x18, 0xa3, 0xfa, 0xc2, + 0xf2, 0xfb, 0x85, 0xab, 0xdc, 0x8f, 0x13, 0x5d, + 0xeb, 0x30, 0x05, 0x4a, 0x1a, 0xfd, 0xc9, 0xb6, + 0xed, 0x7d, 0xa1, 0x6c, 0x55, 0xeb, 0xa6, 0xb0, + 0xd4, 0xd1, 0x0c, 0x74, 0xe1, 0xd9, 0xa7, 0xcf, + 0x8e, 0xdf, 0xae, 0xaa, 0x68, 0x4a, 0xc0, 0xbd, + 0x9f, 0x9d, 0x24, 0xba, 0x67, 0x49, 0x55, 0xc7, + 0x9d, 0xc6, 0xbe, 0x32, 0xae, 0xe1, 0xc2, 0x60, + 0xb5, 0x58, 0xff, 0x07, 0xe3, 0xa4, 0xd4, 0x9d, + 0x24, 0x16, 0x20, 0x11, 0xff, 0x25, 0x4d, 0xb8, + 0xbe, 0x07, 0x8e, 0x8a, 0xd0, 0x7e, 0x64, 0x8e, + 0x6b, 0xf5, 0x67, 0x93, 0x76, 0xcb, 0x43, 0x21, + 0xa5, 0xef, 0x01, 0xaf, 0xe6, 0xad, 0x88, 0x16, + 0xfc, 0xc7, 0x63, 0x46, 0x69, 0xc8, 0xc4, 0x38, + 0x92, 0x95, 0xc9, 0x24, 0x1e, 0x45, 0xff, 0xf3, + 0x9f, 0x32, 0x25, 0xf7, 0x74, 0x50, 0x32, 0xda, + 0xee, 0xbe, 0x99, 0xd4, 0xb1, 0x9b, 0xcb, 0x21, + 0x5d, 0x1b, 0xfd, 0xb3, 0x6e, 0xda, 0x2c, 0x24 }, /* mdata */ + 160, /* mdata_len */ + { 0xc9, 0xa0, 0x14, 0x60, 0xaa, 0x2f, 0x85, 0x25, + 0x88, 0x75, 0xa1, 0x76, 0xcc, 0x85, 0x46, 0xf9 } /* mac */ + } + }; + static uint8_t mdata[MDATA_MAX_LEN]; + static uint8_t mac[CBC_MAC_MAC_LEN]; + static int i; + static uint8_t key_size_index = -1, ret; + static rtimer_clock_t time, time2, total_time; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + if(key_size_index != vectors[i].key_size_index) { + key_size_index = vectors[i].key_size_index; + printf("-----------------------------------------\n" + "Filling %d-bit key store...\n", 128 + (key_size_index << 6)); + time = RTIMER_NOW(); + ret = aes_load_keys(keys[key_size_index].keys, + keys[key_size_index].key_size, keys[key_size_index].count, 0); + time = RTIMER_NOW() - time; + printf("aes_load_keys(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + + printf("-----------------------------------------\n" + "Test vector #%d:\n" + "key_area=%d mdata_len=%d\n", + i, vectors[i].key_area, vectors[i].mdata_len); + + /* mdata has to be in SRAM. */ + rom_util_memcpy(mdata, vectors[i].mdata, vectors[i].mdata_len); + + time = RTIMER_NOW(); + ret = cbc_mac_auth_start(vectors[i].key_area, mdata, vectors[i].mdata_len, + &cbc_mac_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL(cbc_mac_auth_check_status()); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("cbc_mac_auth_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("cbc_mac_auth_check_status() wait: %lu us\n", + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + + time = RTIMER_NOW(); + ret = cbc_mac_auth_get_result(vectors[i].mac, mac); + time = RTIMER_NOW() - time; + total_time += time; + printf("cbc_mac_auth_get_result(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(mac, vectors[i].mac, CBC_MAC_MAC_LEN)) { + puts("MAC does not match expected one"); + } else { + puts("MAC OK"); + } + + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 131c8c3e4..dbe69cbe7 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -30,7 +30,7 @@ In terms of hardware support, the following drivers have been implemented: * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC * PWM - * Cryptoprocessor (AES-ECB/CBC/CTR/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * SmartRF06 EB and BB peripherals diff --git a/platform/zoul/README.md b/platform/zoul/README.md index 4628a833f..05cef3463 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -51,7 +51,7 @@ In terms of hardware support, the following drivers have been implemented for th * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC - * Cryptoprocessor (AES-ECB/CBC/CTR/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * PWM From ccceb63e88fe8358ad541ed472d884226cd3a399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 2 Jan 2016 04:20:16 +0100 Subject: [PATCH 21/94] cc2538: Add crypto driver and example for AES-GCM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/Makefile.cc2538 | 4 +- cpu/cc2538/dev/gcm.c | 125 ++++++ cpu/cc2538/dev/gcm.h | 139 ++++++ examples/cc2538dk/crypto/Makefile | 3 +- examples/cc2538dk/crypto/gcm-test.c | 669 ++++++++++++++++++++++++++++ platform/cc2538dk/README.md | 2 +- platform/zoul/README.md | 2 +- 7 files changed, 939 insertions(+), 5 deletions(-) create mode 100644 cpu/cc2538/dev/gcm.c create mode 100644 cpu/cc2538/dev/gcm.h create mode 100644 examples/cc2538dk/crypto/gcm-test.c diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index e7c53f4df..a11dc2b87 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -53,8 +53,8 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c -CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c ccm.c -CONTIKI_CPU_SOURCEFILES += sha256.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ecb.c cbc.c ctr.c cbc-mac.c gcm.c +CONTIKI_CPU_SOURCEFILES += ccm.c sha256.c CONTIKI_CPU_SOURCEFILES += cc2538-aes-128.c cc2538-ccm-star.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += pka.c bignum-driver.c ecc-driver.c ecc-algorithm.c diff --git a/cpu/cc2538/dev/gcm.c b/cpu/cc2538/dev/gcm.c new file mode 100644 index 000000000..3108f00d0 --- /dev/null +++ b/cpu/cc2538/dev/gcm.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-gcm + * @{ + * + * \file + * Implementation of the cc2538 AES-GCM driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/gcm.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +static uint8_t +gcm_auth_crypt_start(uint8_t encrypt, uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *data_in, void *data_out, uint16_t data_len, + struct process *process) +{ + uint32_t ctrl; + uint32_t aes_iv[AES_IV_LEN / sizeof(uint32_t)]; + + /* Program AES-GCM authentication/crypto operation */ + ctrl = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + AES_AES_CTRL_GCM | /* GCM */ + AES_AES_CTRL_CTR_WIDTH_32 | /* CTR width 32 */ + AES_AES_CTRL_CTR | /* CTR */ + (encrypt ? AES_AES_CTRL_DIRECTION_ENCRYPT : 0); /* En/decryption */ + + /* Prepare the crypto initialization vector + * Initialization vector */ + rom_util_memcpy(aes_iv, iv, GCM_IV_LEN); + /* Initialize counter to 1 */ + aes_iv[GCM_IV_LEN / sizeof(aes_iv[0])] = 0x01000000; + + return aes_auth_crypt_start(ctrl, key_area, aes_iv, adata, adata_len, + data_in, data_out, data_len, process); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +gcm_auth_crypt_get_result(const void *tag_in, void *tag_out) +{ + uint32_t tag[AES_TAG_LEN / sizeof(uint32_t)]; + uint8_t ret; + + ret = aes_auth_crypt_get_result(NULL, tag); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + + if(tag_in != NULL) { + /* Check tag */ + if(rom_util_memcmp(tag, tag_in, GCM_TAG_LEN)) { + ret = AES_AUTHENTICATION_FAILED; + } + } + + if(tag_out != NULL) { + /* Copy tag */ + rom_util_memcpy(tag_out, tag, GCM_TAG_LEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_encrypt_start(uint8_t key_area, const void *iv, const void *adata, + uint16_t adata_len, const void *pdata, + uint16_t pdata_len, void *cdata, struct process *process) +{ + return gcm_auth_crypt_start(true, key_area, iv, adata, adata_len, + pdata, cdata, pdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_encrypt_get_result(void *tag) +{ + return gcm_auth_crypt_get_result(NULL, tag); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_decrypt_start(uint8_t key_area, const void *iv, const void *adata, + uint16_t adata_len, const void *cdata, + uint16_t cdata_len, void *pdata, struct process *process) +{ + return gcm_auth_crypt_start(false, key_area, iv, adata, adata_len, + cdata, pdata, cdata_len, process); +} +/*---------------------------------------------------------------------------*/ +uint8_t +gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out) +__attribute__ ((alias("gcm_auth_crypt_get_result"))); + +/** @} */ diff --git a/cpu/cc2538/dev/gcm.h b/cpu/cc2538/dev/gcm.h new file mode 100644 index 000000000..9633b6ff2 --- /dev/null +++ b/cpu/cc2538/dev/gcm.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-aes + * @{ + * + * \defgroup cc2538-gcm cc2538 AES-GCM + * + * Driver for the cc2538 AES-GCM mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-GCM driver + */ +#ifndef GCM_H_ +#define GCM_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-GCM constants + * @{ + */ +#define GCM_IV_LEN (96 / 8) +#define GCM_TAG_LEN AES_TAG_LEN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-GCM functions + * @{ + */ + +/** \brief Starts a GCM authentication and encryption operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 96-bit initialization vector + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param pdata Pointer to message to authenticate and encrypt in SRAM, or + * \c NULL + * \param pdata_len Length of message to authenticate and encrypt in octets, or + * \c 0 + * \param cdata Pointer to encrypted message in SRAM (may be \p pdata), or + * \c NULL + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + */ +uint8_t gcm_auth_encrypt_start(uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *pdata, uint16_t pdata_len, + void *cdata, struct process *process); + +/** \brief Checks the status of the GCM authentication and encryption operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define gcm_auth_encrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the GCM authentication and encryption operation + * \param tag Pointer to 128-bit authentication tag, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + * \note This function must be called only after \c gcm_auth_encrypt_start(). + */ +uint8_t gcm_auth_encrypt_get_result(void *tag); + +/** \brief Starts a GCM authentication checking and decryption operation + * \param key_area Area in Key RAM where the key is stored (0 to + * \c AES_KEY_AREAS - 1) + * \param iv Pointer to 96-bit initialization vector + * \param adata Pointer to additional authenticated data in SRAM, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param cdata Pointer to encrypted message in SRAM, or \c NULL + * \param cdata_len Length of encrypted message in octets, or \c 0 + * \param pdata Pointer to decrypted message in SRAM (may be \p cdata), or + * \c NULL + * \param process Process to be polled upon completion of the operation, or + * \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + */ +uint8_t gcm_auth_decrypt_start(uint8_t key_area, const void *iv, + const void *adata, uint16_t adata_len, + const void *cdata, uint16_t cdata_len, + void *pdata, struct process *process); + +/** \brief Checks the status of the GCM authentication checking and decryption + * operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +#define gcm_auth_decrypt_check_status aes_auth_crypt_check_status + +/** \brief Gets the result of the GCM authentication checking and decryption + * operation + * \param tag_in Pointer to 128-bit input authentication tag, or \c NULL + * \param tag_out Pointer to 128-bit output authentication tag, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/GCM error code + * \note This function must be called only after \c gcm_auth_decrypt_start(). + */ +uint8_t gcm_auth_decrypt_get_result(const void *tag_in, void *tag_out); + +/** @} */ + +#endif /* GCM_H_ */ + +/** + * @} + * @} + */ diff --git a/examples/cc2538dk/crypto/Makefile b/examples/cc2538dk/crypto/Makefile index c015301e9..968347fae 100644 --- a/examples/cc2538dk/crypto/Makefile +++ b/examples/cc2538dk/crypto/Makefile @@ -1,4 +1,5 @@ -CONTIKI_PROJECT = ecb-test cbc-test ctr-test cbc-mac-test ccm-test sha256-test +CONTIKI_PROJECT = ecb-test cbc-test ctr-test cbc-mac-test gcm-test ccm-test +CONTIKI_PROJECT += sha256-test all: $(CONTIKI_PROJECT) diff --git a/examples/cc2538dk/crypto/gcm-test.c b/examples/cc2538dk/crypto/gcm-test.c new file mode 100644 index 000000000..53c476fb1 --- /dev/null +++ b/examples/cc2538dk/crypto/gcm-test.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2015, Benoît Thébaudeau + * 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 cc2538-examples + * @{ + * + * \defgroup cc2538-gcm-test cc2538dk AES-GCM Test Project + * + * AES-GCM access example for CC2538 on SmartRF06EB. + * + * This example shows how AES-GCM should be used. The example also verifies + * the AES-GCM functionality. + * + * @{ + * + * \file + * Example demonstrating AES-GCM on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/gcm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define ADATA_MAX_LEN 90 +#define MDATA_MAX_LEN 51 +/*---------------------------------------------------------------------------*/ +PROCESS(gcm_test_process, "gcm test process"); +AUTOSTART_PROCESSES(&gcm_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(gcm_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error", + "keystore read error", + "keystore write error", + "authentication failed" + }; + static const uint8_t keys128[][128 / 8] = { + { 0x2f, 0xb4, 0x5e, 0x5b, 0x8f, 0x99, 0x3a, 0x2b, + 0xfe, 0xbc, 0x4b, 0x15, 0xb5, 0x33, 0xe0, 0xb4 }, + { 0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37, + 0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c }, + { 0xfe, 0x01, 0x21, 0xf4, 0x2e, 0x59, 0x9f, 0x88, + 0xff, 0x02, 0xa9, 0x85, 0x40, 0x3e, 0x19, 0xbb }, + { 0x99, 0x71, 0x07, 0x10, 0x59, 0xab, 0xc0, 0x09, + 0xe4, 0xf2, 0xbd, 0x69, 0x86, 0x9d, 0xb3, 0x38 }, + { 0x76, 0x2d, 0xa5, 0x8b, 0xb0, 0x00, 0xf5, 0xd4, + 0x99, 0x81, 0x8b, 0xc8, 0x59, 0x98, 0x9a, 0x30 }, + { 0x30, 0x0b, 0x8f, 0xfa, 0xb4, 0x36, 0x8c, 0xc9, + 0x0f, 0x6d, 0x40, 0x63, 0xe4, 0x27, 0x9f, 0x2a }, + { 0xef, 0x1d, 0xa9, 0xdd, 0x79, 0x42, 0x19, 0xeb, + 0xf8, 0xf7, 0x17, 0xd5, 0xa9, 0x8a, 0xb0, 0xaf }, + { 0x93, 0xae, 0x11, 0x40, 0x52, 0xb7, 0x98, 0x5d, + 0x40, 0x9a, 0x39, 0xa4, 0x0d, 0xf8, 0xc7, 0xee } + }; + static const uint8_t keys192[][192 / 8] = { + { 0x5d, 0xaa, 0x89, 0x10, 0xd9, 0xdc, 0x50, 0x68, + 0xf2, 0xf5, 0x5c, 0x16, 0x39, 0x86, 0xd0, 0x71, + 0x45, 0x23, 0x44, 0xa5, 0xea, 0xc5, 0xa8, 0x05 }, + { 0x1b, 0x8f, 0xef, 0x01, 0xcf, 0x6e, 0xfa, 0xbc, + 0x2c, 0x7c, 0xff, 0x16, 0xff, 0x67, 0xa3, 0x30, + 0x13, 0xf0, 0x62, 0x9a, 0x0a, 0xd9, 0x36, 0x95 }, + { 0x51, 0x9d, 0xdb, 0xcf, 0xb3, 0x41, 0x1c, 0x75, + 0x39, 0xdf, 0x0b, 0x61, 0xff, 0x2b, 0x3e, 0x3d, + 0x2b, 0x6a, 0xd8, 0xf0, 0x30, 0xcd, 0xdc, 0xc2 }, + { 0x9b, 0x37, 0xbf, 0x6b, 0x0a, 0xa8, 0xff, 0x75, + 0xf3, 0x04, 0xed, 0xa7, 0xa9, 0x51, 0x2d, 0xba, + 0x7c, 0x9f, 0x80, 0xd6, 0x1e, 0x29, 0x5e, 0x85 } + }; + static const uint8_t keys256[][256 / 8] = { + { 0xdc, 0x77, 0x6f, 0x01, 0x56, 0xc1, 0x5d, 0x03, + 0x26, 0x23, 0x85, 0x4b, 0x62, 0x5c, 0x61, 0x86, + 0x8e, 0x5d, 0xb8, 0x4b, 0x7b, 0x6f, 0x9f, 0xbd, + 0x36, 0x72, 0xf1, 0x2f, 0x00, 0x25, 0xe0, 0xf6 }, + { 0x14, 0x85, 0x79, 0xa3, 0xcb, 0xca, 0x86, 0xd5, + 0x52, 0x0d, 0x66, 0xc0, 0xec, 0x71, 0xca, 0x5f, + 0x7e, 0x41, 0xba, 0x78, 0xe5, 0x6d, 0xc6, 0xee, + 0xbd, 0x56, 0x6f, 0xed, 0x54, 0x7f, 0xe6, 0x91 }, + { 0x42, 0xf6, 0xc2, 0x51, 0x59, 0xb8, 0x65, 0x53, + 0x80, 0xf0, 0x52, 0xdd, 0x5d, 0xad, 0x18, 0x0e, + 0x76, 0x81, 0x3b, 0x60, 0xeb, 0x81, 0x36, 0x65, + 0xc5, 0x01, 0x5f, 0x26, 0xcf, 0x32, 0xe8, 0xf1 }, + { 0x5f, 0x72, 0x04, 0x62, 0x45, 0xd3, 0xf4, 0xa0, + 0x87, 0x7e, 0x50, 0xa8, 0x65, 0x54, 0xbf, 0xd5, + 0x7d, 0x1c, 0x5e, 0x07, 0x3d, 0x1e, 0xd3, 0xb5, + 0x45, 0x1f, 0x6d, 0x0f, 0xc2, 0xa8, 0x50, 0x7a } + }; + static const struct { + const void *keys; + uint8_t key_size; + uint8_t count; + } keys[] = { + { keys128, AES_KEY_STORE_SIZE_KEY_SIZE_128, + sizeof(keys128) / sizeof(keys128[0]) }, + { keys192, AES_KEY_STORE_SIZE_KEY_SIZE_192, + sizeof(keys192) / sizeof(keys192[0]) }, + { keys256, AES_KEY_STORE_SIZE_KEY_SIZE_256, + sizeof(keys256) / sizeof(keys256[0]) } + }; + static const struct { + bool encrypt; + uint8_t key_size_index; + uint8_t key_area; + uint8_t iv[GCM_IV_LEN]; + uint8_t adata[ADATA_MAX_LEN]; + uint16_t adata_len; + uint8_t mdata[MDATA_MAX_LEN]; + uint16_t mdata_len; + uint8_t tag[GCM_TAG_LEN]; + uint8_t expected[MDATA_MAX_LEN]; + } vectors[] = { + { + true, /* encrypt */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x5b, 0x05, 0x75, 0x5f, 0x98, 0x4d, 0x2b, 0x90, + 0xf9, 0x4b, 0x80, 0x27 }, /* iv */ + { 0xe8, 0x54, 0x91, 0xb2, 0x20, 0x2c, 0xaf, 0x1d, + 0x7d, 0xce, 0x03, 0xb9, 0x7e, 0x09, 0x33, 0x1c, + 0x32, 0x47, 0x39, 0x41 }, /* adata */ + 20, /* adata_len */ + {}, /* mdata */ + 0, /* mdata_len */ + { 0xc7, 0x5b, 0x78, 0x32, 0xb2, 0xa2, 0xd9, 0xbd, + 0x82, 0x74, 0x12, 0xb6, 0xef, 0x57, 0x69, 0xdb }, /* tag */ + {} /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 1, /* key_area */ + { 0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3, + 0x9e, 0x0f, 0x67, 0xe2 }, /* iv */ + { 0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84, + 0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f }, /* adata */ + 16, /* adata_len */ + { 0xc3, 0xb3, 0xc4, 0x1f, 0x11, 0x3a, 0x31, 0xb7, + 0x3d, 0x9a, 0x5c, 0xd4, 0x32, 0x10, 0x30, 0x69 }, /* mdata */ + 16, /* mdata_len */ + { 0x00, 0x32, 0xa1, 0xdc, 0x85, 0xf1, 0xc9, 0x78, + 0x69, 0x25, 0xa2, 0xe7, 0x1d, 0x82, 0x72, 0xdd }, /* tag */ + { 0x93, 0xfe, 0x7d, 0x9e, 0x9b, 0xfd, 0x10, 0x34, + 0x8a, 0x56, 0x06, 0xe5, 0xca, 0xfa, 0x73, 0x54 } /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 2, /* key_area */ + { 0x3b, 0xb9, 0xeb, 0x77, 0x24, 0xcb, 0xe1, 0x94, + 0x3d, 0x43, 0xde, 0x21 }, /* iv */ + { 0x26, 0x62, 0xd8, 0x95, 0x03, 0x5b, 0x65, 0x19, + 0xf3, 0x51, 0x0e, 0xae, 0x0f, 0xaa, 0x39, 0x00, + 0xad, 0x23, 0xcf, 0xdf }, /* adata */ + 20, /* adata_len */ + { 0xfd, 0x33, 0x1c, 0xa8, 0x64, 0x60, 0x91, 0xc2, + 0x9f, 0x21, 0xe5, 0xf0, 0xa1 }, /* mdata */ + 13, /* mdata_len */ + { 0xd2, 0x4c, 0x3e, 0x9c, 0x1c, 0x73, 0xc0, 0xaf, + 0x10, 0x97, 0xe2, 0x60, 0x61, 0xc8, 0x57, 0xde }, /* tag */ + { 0x59, 0xfe, 0x29, 0xb0, 0x7b, 0x0d, 0xe8, 0xd8, + 0x69, 0xef, 0xbb, 0xd9, 0xb4 } /* expected */ + }, { + true, /* encrypt */ + 0, /* key_size_index */ + 3, /* key_area */ + { 0x07, 0xa9, 0xa9, 0x5e, 0xa3, 0x82, 0x1e, 0x9c, + 0x13, 0xc6, 0x32, 0x51 }, /* iv */ + {}, /* adata */ + 0, /* adata_len */ + { 0xf5, 0x4b, 0xc3, 0x50, 0x1f, 0xed, 0x4f, 0x6f, + 0x6d, 0xfb, 0x5e, 0xa8, 0x01, 0x06, 0xdf, 0x0b, + 0xd8, 0x36, 0xe6, 0x82, 0x62, 0x25, 0xb7, 0x5c, + 0x02, 0x22, 0xf6, 0xe8, 0x59, 0xb3, 0x59, 0x83 }, /* mdata */ + 32, /* mdata_len */ + { 0x78, 0x70, 0xd9, 0x11, 0x7f, 0x54, 0x81, 0x1a, + 0x34, 0x69, 0x70, 0xf1, 0xde, 0x09, 0x0c, 0x41 }, /* tag */ + { 0x05, 0x56, 0xc1, 0x59, 0xf8, 0x4e, 0xf3, 0x6c, + 0xb1, 0x60, 0x2b, 0x45, 0x26, 0xb1, 0x20, 0x09, + 0xc7, 0x75, 0x61, 0x1b, 0xff, 0xb6, 0x4d, 0xc0, + 0xd9, 0xca, 0x92, 0x97, 0xcd, 0x2c, 0x6a, 0x01 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 4, /* key_area */ + { 0x58, 0x4c, 0x29, 0x1f, 0xf1, 0xaa, 0x38, 0x8a, + 0x51, 0x12, 0x52, 0x1e }, /* iv */ + { 0x91, 0xf9, 0x2e, 0x8b, 0xbd, 0xa7, 0xb5, 0xec, + 0x96, 0x7a, 0xde, 0x76, 0x6f, 0x4f, 0x26, 0xe9, + 0x18, 0x9e, 0xaa, 0xfa, 0xd4, 0x16, 0xf3, 0x7b, + 0x48, 0x91, 0xd3, 0xe3, 0x7d, 0x70, 0xcb, 0x9a, + 0x26, 0x7a, 0xa8, 0x43, 0xdd, 0x20, 0x28, 0x58, + 0xad, 0xe0, 0x20, 0x26, 0x12, 0x23, 0xdf, 0xce }, /* adata */ + 48, /* adata_len */ + {}, /* mdata */ + 0, /* mdata_len */ + { 0x9a, 0xc7, 0xeb, 0x2d, 0x76, 0x2f, 0xac, 0xae, + 0x06, 0x08, 0x6c, 0x95, 0x79, 0x59, 0x88, 0x0e }, /* tag */ + {} /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 5, /* key_area */ + { 0x8e, 0x69, 0xfa, 0x64, 0xe8, 0x71, 0xd0, 0xe9, + 0x8a, 0x18, 0x3a, 0x49 }, /* iv */ + { 0x51, 0x66, 0x30, 0x9e, 0x15, 0x34, 0x47, 0xb2, + 0x7c, 0x67, 0x05, 0x14, 0x53, 0xab, 0xf4, 0x41, + 0xde, 0x3f, 0x4a, 0x7f, 0x6b, 0x63, 0x3e, 0xc6, + 0x12, 0x2f, 0xf8, 0x2d, 0xc1, 0x32, 0xcf, 0xb4, + 0x22, 0xd3, 0x6c, 0x5e, 0xc6, 0xe7, 0xcc, 0x90, + 0xa9, 0xad, 0x55, 0xca, 0xa1, 0xcc, 0xdc, 0xb8, + 0x2d, 0xc5, 0x02, 0x2a, 0x20, 0x06, 0x2a, 0x9c, + 0x6e, 0x92, 0x38, 0xf3, 0x4d, 0x08, 0x5b, 0x1f, + 0x55, 0x4b, 0x5e, 0xac, 0x05, 0xef, 0xf2, 0x5b, + 0x5a, 0x5c, 0xb6, 0xe1, 0x8e, 0x78, 0x27, 0xd7, + 0x01, 0x75, 0xdc, 0x06, 0x62, 0xd7, 0x70, 0x33, + 0xd1, 0x18 }, /* adata */ + 90, /* adata_len */ + { 0x2d, 0x22, 0x92, 0xda, 0x61, 0xc2, 0x80, 0xaf, + 0xf8, 0x67, 0x67, 0xd2, 0x5b, 0x75, 0xe8, 0x14 }, /* mdata */ + 16, /* mdata_len */ + { 0x63, 0x3e, 0xe6, 0x57, 0xa8, 0x98, 0x1a, 0x76, + 0x82, 0xf8, 0x75, 0x05, 0x59, 0x4c, 0x95, 0xad }, /* tag */ + { 0x49, 0x53, 0xb5, 0x48, 0x59, 0x87, 0x06, 0x31, + 0xe8, 0x18, 0xda, 0x71, 0xfc, 0x69, 0xc9, 0x81 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 6, /* key_area */ + { 0x3f, 0x39, 0x83, 0xdc, 0x63, 0x98, 0x6e, 0x33, + 0xd1, 0xb6, 0xbf, 0xfc }, /* iv */ + { 0x5a, 0xbd, 0x0c, 0x1c, 0x52, 0xb6, 0x87, 0xe9, + 0xa1, 0x67, 0x3b, 0x69, 0x13, 0x78, 0x95, 0xe5, + 0x02, 0x5c, 0x2b, 0xd1, 0x8c, 0xbe, 0xac, 0xdb, + 0x94, 0x72, 0xe9, 0x18, 0xfe, 0x15, 0x87, 0xda, + 0x55, 0x8c, 0x49, 0x2c, 0xc7, 0x08, 0xd2, 0x70, + 0xfd, 0x10, 0x57, 0x2e, 0xea, 0x83, 0xd2, 0xde }, /* adata */ + 48, /* adata_len */ + { 0x95, 0xea, 0x05, 0x70, 0x14, 0x81, 0xe9, 0x15, + 0xc7, 0x24, 0x46, 0xc8, 0x76 }, /* mdata */ + 13, /* mdata_len */ + { 0x5c, 0x86, 0x69, 0x92, 0x66, 0x20, 0x05, 0xca, + 0x88, 0x86, 0x81, 0x0e, 0x27, 0x8c, 0x8a, 0xb4 }, /* tag */ + { 0x55, 0x11, 0x87, 0x29, 0x05, 0x43, 0x6c, 0x7d, + 0xe3, 0x8e, 0x95, 0x01, 0xe7 } /* expected */ + }, { + false, /* encrypt */ + 0, /* key_size_index */ + 7, /* key_area */ + { 0x8a, 0xd7, 0x33, 0xa4, 0xa9, 0xb8, 0x33, 0x06, + 0x90, 0x23, 0x8c, 0x42 }, /* iv */ + {}, /* adata */ + 0, /* adata_len */ + { 0xbb, 0xb5, 0xb6, 0x72, 0xa4, 0x79, 0xaf, 0xca, + 0x2b, 0x11, 0xad, 0xb0, 0xa4, 0xc7, 0x62, 0xb6, + 0x98, 0xdd, 0x56, 0x59, 0x08, 0xfe, 0xe1, 0xd1, + 0x01, 0xf6, 0xa0, 0x1d, 0x63, 0x33, 0x2c, 0x91, + 0xb8, 0x5d, 0x7f, 0x03, 0xac, 0x48, 0xa4, 0x77, + 0x89, 0x7d, 0x51, 0x2b, 0x45, 0x72, 0xf9, 0x04, + 0x2c, 0xb7, 0xea }, /* mdata */ + 51, /* mdata_len */ + { 0x4d, 0x78, 0xbd, 0xcb, 0x13, 0x66, 0xfc, 0xba, + 0x02, 0xfd, 0xcc, 0xee, 0x57, 0xe1, 0xff, 0x44 }, /* tag */ + { 0x3f, 0x3b, 0xb0, 0x64, 0x4e, 0xac, 0x87, 0x8b, + 0x97, 0xd9, 0x90, 0xd2, 0x57, 0xf5, 0xb3, 0x6e, + 0x17, 0x93, 0x49, 0x0d, 0xbc, 0x13, 0xfe, 0xa4, + 0xef, 0xe9, 0x82, 0x2c, 0xeb, 0xba, 0x74, 0x44, + 0xcc, 0xe4, 0xde, 0xe5, 0xa7, 0xf5, 0xdf, 0xdf, + 0x28, 0x5f, 0x96, 0x78, 0x57, 0x92, 0x81, 0x22, + 0x00, 0xc2, 0x79 } /* expected */ + }, { + true, /* encrypt */ + 1, /* key_size_index */ + 0, /* key_area */ + { 0x8f, 0x88, 0xd7, 0x0e, 0x25, 0x0d, 0xbf, 0x12, + 0x82, 0x41, 0x3f, 0xd7 }, /* iv */ + { 0x3b, 0x3b, 0xbb, 0x2c, 0xcd, 0x76, 0x23, 0x6f, + 0x07, 0x4e, 0xec, 0xc1, 0x9f, 0x34, 0x10, 0x57 }, /* adata */ + 16, /* adata_len */ + { 0x42, 0x35, 0xe4, 0x2f, 0x32, 0xcf, 0xf4, 0x4a, + 0x50, 0x7d, 0xd8, 0xa3, 0x66 }, /* mdata */ + 13, /* mdata_len */ + { 0x4c, 0xdd, 0xdb, 0x4a, 0x95, 0x46, 0xa8, 0xd7, + 0x3a, 0xfc, 0x9f, 0x5e, 0x46, 0xa9, 0x26, 0xf3 }, /* tag */ + { 0xe9, 0x2d, 0xf9, 0xd2, 0xfd, 0x43, 0x6e, 0xd2, + 0x54, 0xfa, 0x92, 0x78, 0x9c } /* expected */ + }, { + true, /* encrypt */ + 1, /* key_size_index */ + 2, /* key_area */ + { 0xe9, 0x5e, 0xbb, 0x1e, 0x8d, 0x31, 0xd1, 0xac, + 0x41, 0x4a, 0xd5, 0xf1 }, /* iv */ + { 0x9c, 0x1a, 0x35, 0x60, 0x40, 0xa1, 0x87, 0xb7, + 0xd8, 0x5c, 0x7b, 0xbd, 0xc2, 0x3d, 0x3e, 0x9c, + 0x63, 0x8f, 0x01, 0x4b, 0xd5, 0x62, 0x90, 0x88, + 0x75, 0x7b, 0x57, 0x05, 0xb4, 0xf2, 0x78, 0x33, + 0xb0, 0xa2, 0xb3, 0xfa, 0x4c, 0x9c, 0x43, 0xa7, + 0x7c, 0x69, 0xa3, 0xa2, 0x0a, 0xff, 0xd2, 0xac, + 0x4a, 0xa6, 0xfd, 0xf2, 0xe0, 0x7c, 0x0a, 0x8d, + 0xaf, 0x1a, 0x19, 0xc4, 0x9a, 0x6a, 0x69, 0xfb, + 0xf4, 0x25, 0x1b, 0x77, 0x98, 0x17, 0x31, 0x82, + 0xa5, 0x28, 0xe6, 0xeb, 0x94, 0x19, 0x28, 0xaf, + 0x99, 0x53, 0xbf, 0x59, 0x5b, 0xfb, 0x7b, 0xdf, + 0x5c, 0x3a }, /* adata */ + 90, /* adata_len */ + { 0xc0, 0xc9, 0x22, 0x56, 0x03, 0x2e, 0xd3, 0x11, + 0x3a, 0x79, 0x41, 0x0a, 0x8b, 0x0e, 0x25, 0x0e, + 0x9a, 0x97, 0xfb, 0x47, 0x29, 0x8d, 0x12, 0x29, + 0x32, 0xff, 0x94, 0xd8, 0xf9, 0x40, 0xbc, 0xf8 }, /* mdata */ + 32, /* mdata_len */ + { 0x6b, 0xce, 0x3a, 0xbe, 0xe7, 0xb7, 0xa6, 0x56, + 0x3a, 0xb7, 0x9f, 0x68, 0xa4, 0x19, 0x72, 0xf4 }, /* tag */ + { 0x2c, 0x04, 0x3e, 0xc6, 0x9c, 0x25, 0x5c, 0x7e, + 0xaf, 0x7b, 0xef, 0x47, 0x9b, 0x74, 0x67, 0x4f, + 0xf2, 0x0c, 0x18, 0x5b, 0xcc, 0x6f, 0x94, 0x24, + 0x22, 0xc7, 0xb5, 0xbe, 0x19, 0x99, 0x68, 0x37 } /* expected */ + }, { + false, /* encrypt */ + 1, /* key_size_index */ + 4, /* key_area */ + { 0x78, 0xec, 0x38, 0x73, 0xbd, 0x88, 0x46, 0xac, + 0x42, 0xff, 0x3a, 0x9b }, /* iv */ + { 0x7b, 0x4d, 0x41, 0x23, 0x02, 0xf3, 0x31, 0x96, + 0x53, 0xcc, 0xed, 0x7d, 0xc6, 0xd7, 0xd8, 0x45, + 0xcf, 0x10, 0x71, 0xd3, 0x80, 0x2c, 0xf0, 0x9b, + 0xcd, 0x2b, 0xf3, 0x07, 0x76, 0x09, 0xa1, 0xda, + 0xe1, 0xbf, 0x64, 0xe7, 0x88, 0x20, 0xf3, 0x68, + 0x86, 0x2b, 0x2c, 0x0d, 0xaa, 0x17, 0xff, 0x9b, + 0x33, 0xd1, 0xa7, 0xe4, 0xf6, 0x27, 0x50, 0x7c, + 0x5a, 0x91, 0x6a, 0x80, 0x0e, 0x6d, 0x34, 0x9f, + 0x72, 0xa4, 0x5f, 0x8f, 0x76, 0xb0, 0x1e, 0x63, + 0xdf, 0xcb, 0x44, 0xf0, 0x0a, 0x22, 0x57, 0x41, + 0xd1, 0x72, 0x37, 0x1e, 0xb9, 0x6f, 0x96, 0x49, + 0x87, 0xeb }, /* adata */ + 90, /* adata_len */ + { 0xf1, 0xfb, 0x8d, 0xf2, 0x8f, 0x5a, 0x86, 0x49, + 0xd9, 0x30, 0xb4, 0x77, 0xe6 }, /* mdata */ + 13, /* mdata_len */ + { 0xf7, 0x1b, 0x01, 0x98, 0xae, 0xe9, 0x70, 0xe0, + 0xcb, 0x9f, 0x83, 0x5b, 0x4e, 0xe9, 0xf4, 0x33 }, /* tag */ + { 0x16, 0xea, 0xad, 0xec, 0x26, 0x20, 0x4a, 0x64, + 0x4e, 0x2f, 0x24, 0xb1, 0xee } /* expected */ + }, { + false, /* encrypt */ + 1, /* key_size_index */ + 6, /* key_area */ + { 0x2e, 0x8e, 0xf3, 0x3d, 0x26, 0x5d, 0x48, 0x19, + 0xb6, 0x3c, 0xfd, 0xfc }, /* iv */ + { 0xf2, 0x16, 0xc7, 0xde, 0xf5, 0x5c, 0x8f, 0xf3, + 0x25, 0x93, 0x35, 0x40, 0x96, 0x35, 0x62, 0xef, + 0xe9, 0x6a, 0xe3, 0xf4, 0xb5, 0x4e, 0x6e, 0xc9, + 0x5b, 0x25, 0x19, 0x42, 0x64, 0x67, 0x11, 0xd1, + 0x7e, 0x4e, 0x39, 0xf2, 0x0f, 0xfb, 0x35, 0xd0, + 0x33, 0x4c, 0x9c, 0x03, 0x83, 0x0d, 0x00, 0xc3 }, /* adata */ + 48, /* adata_len */ + { 0x66, 0xd3, 0xe6, 0x06, 0x6c, 0x51, 0xf3, 0x74, + 0xc8, 0xde, 0xf9, 0x1d, 0xdd, 0xd7, 0x76, 0xeb, + 0xc3, 0xbd, 0x9c, 0x96, 0x19, 0xeb, 0xc6, 0x81, + 0x3c, 0x63, 0xd6, 0x9a, 0xac, 0x51, 0xb9, 0x77, + 0x5a, 0x47, 0x19, 0x6e, 0x48, 0x83, 0xce, 0x5e, + 0x32, 0x33, 0x2c, 0xe0, 0x09, 0xe0, 0x27, 0xec, + 0x62, 0x2a, 0xe3 }, /* mdata */ + 51, /* mdata_len */ + { 0xcc, 0xef, 0x02, 0x7c, 0x0a, 0xe1, 0x90, 0x87, + 0xe1, 0x8b, 0x13, 0xab, 0x5e, 0x1c, 0x89, 0xa6 }, /* tag */ + { 0x44, 0x8e, 0x59, 0xef, 0x95, 0x88, 0x67, 0xd6, + 0x99, 0xfa, 0xf7, 0x4a, 0xa0, 0x46, 0x28, 0x1d, + 0xb5, 0x1c, 0x44, 0xbd, 0x7a, 0xac, 0xb0, 0x52, + 0x21, 0xcf, 0x3c, 0x7f, 0x1e, 0xfd, 0x47, 0x04, + 0xf9, 0xb4, 0x79, 0x67, 0xb7, 0x05, 0x16, 0x8b, + 0x5e, 0xd2, 0x52, 0x38, 0x64, 0x48, 0x29, 0xb7, + 0x54, 0xdc, 0x75 } /* expected */ + }, { + true, /* encrypt */ + 2, /* key_size_index */ + 0, /* key_area */ + { 0x67, 0x13, 0x09, 0x51, 0xc4, 0xa5, 0x7f, 0x6a, + 0xe7, 0xf1, 0x32, 0x41 }, /* iv */ + { 0xfd, 0x09, 0x20, 0xfa, 0xeb, 0x7b, 0x21, 0x29, + 0x32, 0x28, 0x0a, 0x00, 0x9b, 0xac, 0x96, 0x91, + 0x45, 0xe5, 0xc3, 0x16, 0xcf, 0x39, 0x22, 0x62, + 0x2c, 0x37, 0x05, 0xc3, 0x45, 0x7c, 0x4e, 0x9f, + 0x12, 0x4b, 0x20, 0x76, 0x99, 0x43, 0x23, 0xfb, + 0xcf, 0xb5, 0x23, 0xf8, 0xed, 0x16, 0xd2, 0x41 }, /* adata */ + 48, /* adata_len */ + { 0x93, 0x78, 0xa7, 0x27, 0xa5, 0x11, 0x95, 0x95, + 0xad, 0x63, 0x1b, 0x12, 0xa5, 0xa6, 0xbc, 0x8a, + 0x91, 0x75, 0x6e, 0xf0, 0x9c, 0x8d, 0x6e, 0xaa, + 0x2b, 0x71, 0x8f, 0xe8, 0x68, 0x76, 0xda, 0x20 }, /* mdata */ + 32, /* mdata_len */ + { 0xb8, 0x76, 0x83, 0x1b, 0x4e, 0xcd, 0x72, 0x42, + 0x96, 0x3b, 0x04, 0x0a, 0xa4, 0x5c, 0x41, 0x14 }, /* tag */ + { 0x6d, 0x95, 0x8c, 0x20, 0x87, 0x0d, 0x40, 0x1a, + 0x3c, 0x1f, 0x7a, 0x0a, 0xc0, 0x92, 0xc9, 0x77, + 0x74, 0xd4, 0x51, 0xc0, 0x9f, 0x7a, 0xae, 0x99, + 0x2a, 0x88, 0x41, 0xff, 0x0a, 0xb9, 0xd6, 0x0d } /* expected */ + }, { + true, /* encrypt */ + 2, /* key_size_index */ + 2, /* key_area */ + { 0xb0, 0x8a, 0x5e, 0xa1, 0x92, 0x74, 0x99, 0xc6, + 0xec, 0xbf, 0xd4, 0xe0 }, /* iv */ + { 0xe4, 0xf9, 0x63, 0xf0, 0x15, 0xff, 0xbb, 0x99, + 0xee, 0x33, 0x49, 0xbb, 0xaf, 0x7e, 0x8e, 0x8e, + 0x6c, 0x2a, 0x71, 0xc2, 0x30, 0xa4, 0x8f, 0x9d, + 0x59, 0x86, 0x0a, 0x29, 0x09, 0x1d, 0x27, 0x47, + 0xe0, 0x1a, 0x5c, 0xa5, 0x72, 0x34, 0x7e, 0x24, + 0x7d, 0x25, 0xf5, 0x6b, 0xa7, 0xae, 0x8e, 0x05, + 0xcd, 0xe2, 0xbe, 0x3c, 0x97, 0x93, 0x12, 0x92, + 0xc0, 0x23, 0x70, 0x20, 0x8e, 0xcd, 0x09, 0x7e, + 0xf6, 0x92, 0x68, 0x7f, 0xec, 0xf2, 0xf4, 0x19, + 0xd3, 0x20, 0x01, 0x62, 0xa6, 0x48, 0x0a, 0x57, + 0xda, 0xd4, 0x08, 0xa0, 0xdf, 0xeb, 0x49, 0x2e, + 0x2c, 0x5d }, /* adata */ + 90, /* adata_len */ + { 0x9d, 0x0b, 0x15, 0xfd, 0xf1, 0xbd, 0x59, 0x5f, + 0x91, 0xf8, 0xb3, 0xab, 0xc0, 0xf7, 0xde, 0xc9, + 0x27, 0xdf, 0xd4, 0x79, 0x99, 0x35, 0xa1, 0x79, + 0x5d, 0x9c, 0xe0, 0x0c, 0x9b, 0x87, 0x94, 0x34, + 0x42, 0x0f, 0xe4, 0x2c, 0x27, 0x5a, 0x7c, 0xd7, + 0xb3, 0x9d, 0x63, 0x8f, 0xb8, 0x1c, 0xa5, 0x2b, + 0x49, 0xdc, 0x41 }, /* mdata */ + 51, /* mdata_len */ + { 0xad, 0xbe, 0xcd, 0xb0, 0xd5, 0xc2, 0x22, 0x4d, + 0x80, 0x4d, 0x28, 0x86, 0xff, 0x9a, 0x57, 0x60 }, /* tag */ + { 0x20, 0x97, 0xe3, 0x72, 0x95, 0x0a, 0x5e, 0x93, + 0x83, 0xc6, 0x75, 0xe8, 0x9e, 0xea, 0x1c, 0x31, + 0x4f, 0x99, 0x91, 0x59, 0xf5, 0x61, 0x13, 0x44, + 0xb2, 0x98, 0xcd, 0xa4, 0x5e, 0x62, 0x84, 0x37, + 0x16, 0xf2, 0x15, 0xf8, 0x2e, 0xe6, 0x63, 0x91, + 0x9c, 0x64, 0x00, 0x2a, 0x5c, 0x19, 0x8d, 0x78, + 0x78, 0xfd, 0x3f } /* expected */ + }, { + false, /* encrypt */ + 2, /* key_size_index */ + 4, /* key_area */ + { 0x72, 0x48, 0xa5, 0xed, 0x48, 0xf4, 0xf1, 0xb4, + 0xa9, 0xdb, 0x38, 0x26 }, /* iv */ + { 0x8e, 0x3c, 0x74, 0xf1, 0x27, 0xdb, 0xfe, 0x29, + 0xac, 0x4d, 0xe0, 0xa7, 0xc3, 0x24, 0x0e, 0xe8, + 0xaa, 0x8d, 0x38, 0xa8, 0x2f, 0x38, 0xad, 0x6b, + 0x48, 0x02, 0x36, 0xc8, 0xcd, 0x42, 0x32, 0x05, + 0x7a, 0x55, 0x02, 0xe9, 0x36, 0xbf, 0xe2, 0x22, + 0x25, 0x83, 0x0f, 0xa1, 0x95, 0xa8, 0xaf, 0xce }, /* adata */ + 48, /* adata_len */ + { 0x26, 0x32, 0x5c, 0x34, 0x63, 0x81, 0x3a, 0x7d, + 0x59, 0xd1, 0x84, 0xa3, 0x30, 0xef, 0x80, 0x95, + 0x96, 0x37, 0xfa, 0x6d, 0xb4, 0xf5, 0xdb, 0x30, + 0x62, 0xd3, 0xd2, 0xec, 0x7e, 0x32, 0xd8, 0x2a }, /* mdata */ + 32, /* mdata_len */ + { 0x4f, 0x39, 0xc6, 0x3d, 0x4f, 0x21, 0x5d, 0x5b, + 0x39, 0xa5, 0x88, 0x53, 0xd3, 0x84, 0x21, 0x75 }, /* tag */ + { 0x9a, 0x32, 0x9c, 0xb4, 0x5b, 0x00, 0x93, 0xe9, + 0xc0, 0x06, 0x15, 0x13, 0x7d, 0xd7, 0xdb, 0xd1, + 0xf8, 0xb5, 0x25, 0x99, 0x9a, 0xf3, 0xbf, 0xc2, + 0x22, 0x31, 0x5f, 0x41, 0x81, 0x77, 0x17, 0xa7 } /* expected */ + }, { + false, /* encrypt */ + 2, /* key_size_index */ + 6, /* key_area */ + { 0xea, 0x6f, 0x5b, 0x39, 0x1e, 0x44, 0xb7, 0x51, + 0xb2, 0x6b, 0xce, 0x6f }, /* iv */ + { 0x9b, 0x3a, 0x68, 0xc9, 0x41, 0xd4, 0x27, 0x44, + 0x67, 0x3f, 0xb6, 0x0f, 0xea, 0x49, 0x07, 0x5e, + 0xae, 0x77, 0x32, 0x2e, 0x7e, 0x70, 0xe3, 0x45, + 0x02, 0xc1, 0x15, 0xb6, 0x49, 0x5e, 0xbf, 0xc7, + 0x96, 0xd6, 0x29, 0x08, 0x07, 0x65, 0x3c, 0x6b, + 0x53, 0xcd, 0x84, 0x28, 0x1b, 0xd0, 0x31, 0x16, + 0x56, 0xd0, 0x01, 0x3f, 0x44, 0x61, 0x9d, 0x27, + 0x48, 0x17, 0x7e, 0x99, 0xe8, 0xf8, 0x34, 0x7c, + 0x98, 0x9a, 0x7b, 0x59, 0xf9, 0xd8, 0xdc, 0xf0, + 0x0f, 0x31, 0xdb, 0x06, 0x84, 0xa4, 0xa8, 0x3e, + 0x03, 0x7e, 0x87, 0x77, 0xba, 0xe5, 0x5f, 0x79, + 0x9b, 0x0d }, /* adata */ + 90, /* adata_len */ + { 0x0e, 0x6e, 0x0b, 0x21, 0x14, 0xc4, 0x07, 0x69, + 0xc1, 0x59, 0x58, 0xd9, 0x65, 0xa1, 0x4d, 0xcf, + 0x50, 0xb6, 0x80, 0xe0, 0x18, 0x5a, 0x44, 0x09, + 0xd7, 0x7d, 0x89, 0x4c, 0xa1, 0x5b, 0x1e, 0x69, + 0x8d, 0xd8, 0x3b, 0x35, 0x36, 0xb1, 0x8c, 0x05, + 0xd8, 0xcd, 0x08, 0x73, 0xd1, 0xed, 0xce, 0x81, + 0x50, 0xec, 0xb5 }, /* mdata */ + 51, /* mdata_len */ + { 0xfd, 0xaa, 0xff, 0x86, 0xce, 0xb9, 0x37, 0x50, + 0x2c, 0xd9, 0x01, 0x2d, 0x03, 0x58, 0x58, 0x00 }, /* tag */ + { 0xb0, 0xa8, 0x81, 0xb7, 0x51, 0xcc, 0x1e, 0xb0, + 0xc9, 0x12, 0xa4, 0xcf, 0x9b, 0xd9, 0x71, 0x98, + 0x37, 0x07, 0xdb, 0xd2, 0x41, 0x17, 0x25, 0x66, + 0x45, 0x03, 0x45, 0x5c, 0x55, 0xdb, 0x25, 0xcd, + 0xb1, 0x9b, 0xc6, 0x69, 0xc2, 0x65, 0x4a, 0x3a, + 0x80, 0x11, 0xde, 0x6b, 0xf7, 0xef, 0xf3, 0xf9, + 0xf0, 0x78, 0x34 } /* expected */ + } + }; + static uint8_t adata[ADATA_MAX_LEN]; + static uint8_t mdata[MDATA_MAX_LEN]; + static uint8_t tag[GCM_TAG_LEN]; + static int i; + static uint8_t key_size_index = -1, ret; + static rtimer_clock_t time, time2, total_time; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + if(key_size_index != vectors[i].key_size_index) { + key_size_index = vectors[i].key_size_index; + printf("-----------------------------------------\n" + "Filling %d-bit key store...\n", 128 + (key_size_index << 6)); + time = RTIMER_NOW(); + ret = aes_load_keys(keys[key_size_index].keys, + keys[key_size_index].key_size, keys[key_size_index].count, 0); + time = RTIMER_NOW() - time; + printf("aes_load_keys(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + + printf("-----------------------------------------\n" + "Test vector #%d: %s\n" + "key_area=%d adata_len=%d mdata_len=%d\n", + i, vectors[i].encrypt ? "encrypt" : "decrypt", + vectors[i].key_area, vectors[i].adata_len, vectors[i].mdata_len); + + /* adata and mdata have to be in SRAM. */ + rom_util_memcpy(adata, vectors[i].adata, vectors[i].adata_len); + rom_util_memcpy(mdata, vectors[i].mdata, vectors[i].mdata_len); + + time = RTIMER_NOW(); + if(vectors[i].encrypt) { + ret = gcm_auth_encrypt_start(vectors[i].key_area, vectors[i].iv, adata, + vectors[i].adata_len, mdata, + vectors[i].mdata_len, mdata, + &gcm_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL(gcm_auth_encrypt_check_status()); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("gcm_auth_encrypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("gcm_auth_encrypt_check_status() wait: %lu us\n", + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + + time = RTIMER_NOW(); + ret = gcm_auth_encrypt_get_result(tag); + time = RTIMER_NOW() - time; + total_time += time; + printf("gcm_auth_encrypt_get_result(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(mdata, vectors[i].expected, vectors[i].mdata_len)) { + puts("Encrypted message does not match expected one"); + } else { + puts("Encrypted message OK"); + } + + if(rom_util_memcmp(tag, vectors[i].tag, GCM_TAG_LEN)) { + puts("Tag does not match expected one"); + } else { + puts("Tag OK"); + } + } else { + ret = gcm_auth_decrypt_start(vectors[i].key_area, vectors[i].iv, adata, + vectors[i].adata_len, mdata, + vectors[i].mdata_len, mdata, + &gcm_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL(gcm_auth_decrypt_check_status()); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("gcm_auth_decrypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("gcm_auth_decrypt_check_status() wait: %lu us\n", + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + + time = RTIMER_NOW(); + ret = gcm_auth_decrypt_get_result(vectors[i].tag, tag); + time = RTIMER_NOW() - time; + total_time += time; + printf("gcm_auth_decrypt_get_result(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(mdata, vectors[i].expected, vectors[i].mdata_len)) { + puts("Decrypted message does not match expected one"); + } else { + puts("Decrypted message OK"); + } + } + + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index dbe69cbe7..809f46d6a 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -30,7 +30,7 @@ In terms of hardware support, the following drivers have been implemented: * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC * PWM - * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * SmartRF06 EB and BB peripherals diff --git a/platform/zoul/README.md b/platform/zoul/README.md index 05cef3463..d8eb07bfd 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -51,7 +51,7 @@ In terms of hardware support, the following drivers have been implemented for th * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC - * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/CCM-128/192/256, SHA-256) + * Cryptoprocessor (AES-ECB/CBC/CTR/CBC-MAC/GCM/CCM-128/192/256, SHA-256) * Public Key Accelerator (ECDH, ECDSA) * Flash-based port of Coffee * PWM From 94143f93fff3964f58c13002ce17f1524fcdde11 Mon Sep 17 00:00:00 2001 From: Theo van Daele Date: Thu, 7 Jan 2016 09:47:29 +0100 Subject: [PATCH 22/94] Changed NXP maintainers for JN516x platform --- platform/jn516x/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/jn516x/README.md b/platform/jn516x/README.md index b593895aa..1d45ca7a4 100644 --- a/platform/jn516x/README.md +++ b/platform/jn516x/README.md @@ -24,16 +24,13 @@ These system on chip (SoC) devices have the following main [features][jn516x-dat ## Maintainers and Contact Long-term maintainers: -* Theo Van Daele, NXP, theo.van.daele@nxp.com, github user: [TeVeDe](https://github.com/TeVeDe) +* Chris Gray, NXP, christopher.gray@nxp.com, github user: [NxpChrisGray](https://github.com/NxpChrisGray) * Simon Duquennoy, SICS, simonduq@sics.se, github user: [simonduq](https://github.com/simonduq) Other contributors: * Beshr Al Nahas, SICS (now Chalmers University), beshr@chalmers.se, github user: [beshrns](https://github.com/beshrns) * Atis Elsts, SICS, atis.elsts@sics.se, github user: [atiselsts](https://github.com/atiselsts) -Additional long-term contact: -* Hugh Maaskant, NXP, hugh.maaskant@nxp.com, github user: [hugh-maaskant](https://github.com/hugh-maaskant) - ## License All files are under BSD license, as described by the copyright statement in every source file. From 881e78cb600d3c0a4f73275e14b7cd35ee8b453d Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 4 Jan 2016 09:30:25 +0100 Subject: [PATCH 23/94] Rewamped TSL2563 light sensor --- examples/zolertia/zoul/test-tsl2563.c | 20 +- platform/zoul/dev/tsl2563.c | 289 +++++++++++++++++++++++--- platform/zoul/dev/tsl2563.h | 112 ++++++++-- platform/zoul/dev/zoul-sensors.h | 5 +- platform/zoul/remote/board.h | 7 +- 5 files changed, 376 insertions(+), 57 deletions(-) diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl2563.c index 11fa8933e..8e74dad08 100644 --- a/examples/zolertia/zoul/test-tsl2563.c +++ b/examples/zolertia/zoul/test-tsl2563.c @@ -50,13 +50,8 @@ #include "dev/i2c.h" #include "dev/tsl2563.h" /*---------------------------------------------------------------------------*/ -#if 1 -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -/*---------------------------------------------------------------------------*/ -#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 2) +/* Default sensor's integration cycle is 402ms */ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND/2) /*---------------------------------------------------------------------------*/ PROCESS(remote_tsl2563_process, "TSL2563 test process"); AUTOSTART_PROCESSES(&remote_tsl2563_process); @@ -66,14 +61,21 @@ static struct etimer et; PROCESS_THREAD(remote_tsl2563_process, ev, data) { PROCESS_BEGIN(); - int light; + static uint16_t light; + + /* Use Contiki's sensor macro to enable the sensor */ SENSORS_ACTIVATE(tsl2563); + /* 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); + while(1) { etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); light = tsl2563.value(TSL2563_VAL_READ); - PRINTF("Light = %u\n", light); + printf("Light = %u\n", (uint16_t) light); } PROCESS_END(); } diff --git a/platform/zoul/dev/tsl2563.c b/platform/zoul/dev/tsl2563.c index a5a2ef77c..0c8d23b9c 100644 --- a/platform/zoul/dev/tsl2563.c +++ b/platform/zoul/dev/tsl2563.c @@ -40,28 +40,69 @@ * Toni Lozano */ /*---------------------------------------------------------------------------*/ -#include #include "contiki.h" #include "dev/i2c.h" +#include "dev/gpio.h" +#include "dev/zoul-sensors.h" #include "lib/sensors.h" #include "tsl2563.h" /*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#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) +/*---------------------------------------------------------------------------*/ static uint8_t enabled; +static uint8_t gain; +static uint8_t timming; +/*---------------------------------------------------------------------------*/ +void (*tsl2563_int_callback)(uint8_t value); /*---------------------------------------------------------------------------*/ static uint16_t -calculateLux(uint8_t *buf) +calculate_lux(uint8_t *buf) { uint32_t ch0, ch1 = 0; - uint32_t aux = (1 << 14); + uint32_t chscale; uint32_t ratio, lratio, tmp = 0; uint16_t buffer[2]; + /* The calculations below assume the integration time is 402ms and the gain + * is 16x (nominal), if not then it is required to normalize the reading + * before converting to lux + */ + buffer[0] = (buf[1] << 8 | (buf[0])); buffer[1] = (buf[3] << 8 | (buf[2])); - ch0 = (buffer[0] * aux) >> 10; - ch1 = (buffer[1] * aux) >> 10; - ratio = (ch1 << 10); - ratio = ratio / ch0; + + switch(timming) { + case TSL2563_TIMMING_INTEG_402MS: + chscale = (1 << CH_SCALE); + break; + case TSL2563_TIMMING_INTEG_101MS: + chscale = CHSCALE_TINT1; + break; + case TSL2563_TIMMING_INTEG_13_7MS: + chscale = CHSCALE_TINT0; + break; + } + + if(!gain) { + chscale = chscale << 4; + } + + ch0 = (buffer[0] * chscale) >> CH_SCALE; + ch1 = (buffer[1] * chscale) >> CH_SCALE; + + if(ch0 > 0) { + ratio = (ch1 << CH_SCALE); + ratio = ratio / ch0; + } + lratio = (ratio + 1) >> 1; if((lratio >= 0) && (lratio <= K1T)) { @@ -86,14 +127,16 @@ calculateLux(uint8_t *buf) tmp = 0; } - tmp += (1 << 13); - return tmp >> 14; + tmp += (1 << (LUX_SCALE - 1)); + return tmp >> LUX_SCALE; } /*---------------------------------------------------------------------------*/ static int tsl2563_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) { + while(i2c_master_busy()); if(i2c_burst_receive(TSL2563_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { return TSL2563_SUCCESS; } @@ -102,49 +145,226 @@ tsl2563_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) } /*---------------------------------------------------------------------------*/ static int -light_ziglet_on(void) +tsl2563_write_reg(uint8_t *buf, uint8_t num) { - if(i2c_single_send(TSL2563_ADDR, (uint8_t)TSL2563_PWRN) == I2C_MASTER_ERR_NONE) { + if((buf == NULL) || (num <= 0)) { + PRINTF("TSL2563: invalid write values\n"); + return TSL2563_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(TSL2563_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { return TSL2563_SUCCESS; } return TSL2563_ERROR; } /*---------------------------------------------------------------------------*/ static int -light_ziglet_off(void) +tsl2563_on(void) { - if(i2c_single_send(TSL2563_ADDR, (uint8_t)TSL2563_PWROFF) == I2C_MASTER_ERR_NONE) { - return TSL2563_SUCCESS; - } - return TSL2563_ERROR; -} -/*---------------------------------------------------------------------------*/ -static int -light_ziglet_read(uint16_t *lux) -{ - uint8_t buf[4]; - if(light_ziglet_on() == TSL2563_SUCCESS) { - if(tsl2563_read_reg(TSL2563_READ, buf, 4) == TSL2563_SUCCESS) { - *lux = calculateLux(buf); - return light_ziglet_off(); + uint8_t buf[2]; + buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); + buf[1] = TSL2563_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; + } } } + + PRINTF("TSL2563: failed to power on\n"); return TSL2563_ERROR; } /*---------------------------------------------------------------------------*/ static int +tsl2563_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; + } + + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_off(void) +{ + uint8_t buf[2]; + buf[0] = (TSL2563_COMMAND + TSL2563_CONTROL); + buf[1] = TSL2563_CONTROL_POWER_OFF; + + if(tsl2563_write_reg(buf, 2) == I2C_MASTER_ERR_NONE) { + PRINTF("TSL2563: powered off\n"); + return TSL2563_SUCCESS; + } + + PRINTF("TSL2563: failed to power off\n"); + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_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) { + *lux = calculate_lux(buf); + return TSL2563_SUCCESS; + } + } + PRINTF("TSL2563: failed to read\n"); + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +PROCESS(tsl2563_int_process, "TSL2563 interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tsl2563_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + + /* FIXME: Read interrupt source and clear */ + tsl2563_int_callback(0); + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +static void +tsl2563_interrupt_handler(uint8_t port, uint8_t pin) +{ + /* FIXME: Check if the interrupt is ours */ + process_poll(&tsl2563_int_process); +} +/*---------------------------------------------------------------------------*/ +static int configure(int type, int value) { - if(type != SENSORS_ACTIVE) { + uint8_t buf[2]; + + 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; } - enabled = value; - if(value) { - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); - } else { - light_ziglet_off(); + + /* 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(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* 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) { + + /* 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); + return TSL2563_SUCCESS; + } + } + } + } + return TSL2563_ERROR; + + } else { + if(tsl2563_off() == TSL2563_SUCCESS) { + PRINTF("TSL2563: stopped\n"); + return TSL2563_SUCCESS; + } + return TSL2563_ERROR; + } } + + if(type == TSL2563_INT_DISABLE) { + /* FIXME: disable interrupt */ + GPIO_DISABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + return TSL2563_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; + } + + buf[0] = (TSL2563_COMMAND + TSL2563_TIMMING); + buf[1] = value; + + if(tsl2563_write_reg(buf, 2) == TSL2563_SUCCESS) { + if(value == TSL2563_G16X_402MS) { + gain = 1; + } + + switch(value) { + case TSL2563_G16X_402MS: + case TSL2563_G1X_402MS: + timming = TSL2563_TIMMING_INTEG_402MS; + break; + case TSL2563_G1X_101MS: + timming = TSL2563_TIMMING_INTEG_101MS; + break; + case TSL2563_G1X_13_7MS: + timming = TSL2563_TIMMING_INTEG_13_7MS; + break; + } + + PRINTF("TSL2563: new timming %u gain %u\n", timming, gain); + return TSL2563_SUCCESS; + } + PRINTF("TSL2563: failed to configure timming\n"); + return TSL2563_ERROR; + } + + /* Configure interrupt pins and initialize interrupts handlers */ + tsl2563_int_callback = NULL; + + /* 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); + + /* 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); + + /* Spin process until an interrupt is received */ + process_start(&tsl2563_int_process, NULL); + + if(type == TSL2563_INT_OVER) { + /* FIXME: add code */ + } else if(type == TSL2563_INT_BELOW) { + /* FIXME: add code */ + } + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); + ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(I2C_INT_VECTOR); + return TSL2563_SUCCESS; } /*---------------------------------------------------------------------------*/ @@ -164,9 +384,10 @@ value(int type) { uint16_t lux; if(type == TSL2563_VAL_READ) { - if(light_ziglet_read(&lux) != TSL2563_ERROR) { + if(tsl2563_read_sensor(&lux) != TSL2563_ERROR) { return lux; } + PRINTF("TSL2563: fail to read\n"); } return TSL2563_ERROR; } diff --git a/platform/zoul/dev/tsl2563.h b/platform/zoul/dev/tsl2563.h index 08c538050..8cff19bcb 100644 --- a/platform/zoul/dev/tsl2563.h +++ b/platform/zoul/dev/tsl2563.h @@ -49,24 +49,93 @@ * Toni Lozano */ /*---------------------------------------------------------------------------*/ -#ifndef LIGHT_SENSOR_H_ -#define LIGHT_SENSOR_H_ +#ifndef TSL2563_H_ +#define TSL2563_H_ #include #include "lib/sensors.h" +#include "dev/zoul-sensors.h" #include "i2c.h" /* -------------------------------------------------------------------------- */ /** - * \name TSL2563 digital Light sensor + * \name TSL2563 digital Light sensor address and registers * @{ */ /* -------------------------------------------------------------------------- */ -#define TSL2563_ADDR 0x39 /**< TSL2563 slave address */ +#define TSL2563_ADDR 0x39 /* -------------------------------------------------------------------------- */ -#define TSL2563_READ 0xAC /**< TSL2563 read register */ -#define TSL2563_PWRN 0x03 /**< TSL2563 enable register */ -#define TSL2563_PWROFF 0x00 /**< TSL2563 Power OFF */ +#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 /* -------------------------------------------------------------------------- */ -#define K1T 0X0040 /**< Calibration values (hardcoded) */ +/* Uses the word read/write operation protocol */ +#define TSL2563_COMMAND 0xA0 +/* -------------------------------------------------------------------------- */ +#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 + +#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 +#define TSL2563_EXPECTED_PARTNO 0x30 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 convertion and calibration values + * @{ + */ + +#define LUX_SCALE 14 /**< scale by 2^14 */ +#define RATIO_SCALE 9 /**< scale ratio */ +#define CH_SCALE 10 /**< scale channel values by 2^10 */ +#define CHSCALE_TINT0 0x7517 /**< 322/11 * 2^CH_SCALE */ +#define CHSCALE_TINT1 0x0fe7 /**< 322/81 * 2^CH_SCALE */ + +/* T/FN/CL package coefficients (hardcoded) */ +#define K1T 0X0040 #define B1T 0x01f2 #define M1T 0x01b2 #define K2T 0x0080 @@ -92,11 +161,30 @@ #define M8T 0x0000 /** @} */ /* -------------------------------------------------------------------------- */ -#define TSL2563_SUCCESS 0x00 -#define TSL2563_LIGHT 0x01 -#define TSL2563_ERROR -1 +/** + * \name Callback function to handle the TSL2563 alarm interrupt and macro + * @{ + */ +#define TSL2563_REGISTER_INT(ptr) tsl2563_int_callback = ptr; +extern void (*tsl2563_int_callback)(uint8_t value); +/** @} */ /* -------------------------------------------------------------------------- */ -#define TSL2563_VAL_READ 0x01 +/** + * \name TSL2563 return and command values + * @{ + */ +#define TSL2563_SUCCESS 0x00 +#define TSL2563_LIGHT 0x01 +#define TSL2563_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 TSL2563_VAL_READ 0x01 +/** @} */ /* -------------------------------------------------------------------------- */ #define TSL2563_SENSOR "TSL2563 Light Sensor" /* -------------------------------------------------------------------------- */ diff --git a/platform/zoul/dev/zoul-sensors.h b/platform/zoul/dev/zoul-sensors.h index 6a7bc1a86..476ec41da 100644 --- a/platform/zoul/dev/zoul-sensors.h +++ b/platform/zoul/dev/zoul-sensors.h @@ -55,9 +55,12 @@ * \name Zoul sensor constants * * These constants are used by various sensors on the Zoul. They can be used - * to configure ADC decimation rate (where applicable). + * to configure ADC decimation rate (where applicable), enable interrupts, etc. * @{ */ +#define HW_INT_OVER_THRS 0x01 +#define HW_INT_BELOW_THRS 0x02 +#define HW_INT_DISABLE 0x03 #define ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE 0x0100 #define ZOUL_SENSORS_ERROR CC2538_SENSORS_ERROR /** @} */ diff --git a/platform/zoul/remote/board.h b/platform/zoul/remote/board.h index a249ff1bf..563415f25 100644 --- a/platform/zoul/remote/board.h +++ b/platform/zoul/remote/board.h @@ -261,12 +261,18 @@ * These values configure which CC2538 pins to use for the I2C lines, exposed * over JP6 connector, also available as testpoints T2 (PC2) and T3 (PC3). * The I2C bus is shared with the on-board RTC. + * The I2C is exposed over the JP6 header, using a 5-pin connector with 2.54 mm + * spacing, providing also D+3.3V, GND and a generic pin that can be used as an + * interrupt pin * @{ */ #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 /** @} */ /*---------------------------------------------------------------------------*/ /** @@ -374,7 +380,6 @@ /** * \name On-board RTC * - * The Abracon AB0805 RTC is used by both the * The shutdown mode can be disabled by hardware by short-circuiting or placing * an 0Ohm resistor across W1 pad. As the RTC_INT1 pin is also shared with the * BUTTON_USER, so either disable or not use the user button, or upon receiving From a8a1ebf8b5e7a9c0e19f7d6f9e357f717a910ddb Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 7 Jan 2016 00:41:14 +0100 Subject: [PATCH 24/94] Added interruption feature to the TSL2563 driver --- examples/zolertia/zoul/project-conf.h | 1 + examples/zolertia/zoul/test-tsl2563.c | 35 +++++- platform/zoul/dev/tsl2563.c | 154 ++++++++++++++++++-------- platform/zoul/dev/tsl2563.h | 3 +- platform/zoul/firefly/board.h | 3 + 5 files changed, 146 insertions(+), 50 deletions(-) diff --git a/examples/zolertia/zoul/project-conf.h b/examples/zolertia/zoul/project-conf.h index 420d9a8e0..126ea1058 100644 --- a/examples/zolertia/zoul/project-conf.h +++ b/examples/zolertia/zoul/project-conf.h @@ -39,6 +39,7 @@ #define PROJECT_CONF_H_ #define BROADCAST_CHANNEL 129 +#define NETSTACK_CONF_RDC nullrdc_driver #endif /* PROJECT_CONF_H_ */ diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl2563.c index 8e74dad08..f32242f74 100644 --- a/examples/zolertia/zoul/test-tsl2563.c +++ b/examples/zolertia/zoul/test-tsl2563.c @@ -48,16 +48,24 @@ #include #include "contiki.h" #include "dev/i2c.h" +#include "dev/leds.h" #include "dev/tsl2563.h" /*---------------------------------------------------------------------------*/ /* Default sensor's integration cycle is 402ms */ -#define SENSOR_READ_INTERVAL (CLOCK_SECOND/2) +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) /*---------------------------------------------------------------------------*/ PROCESS(remote_tsl2563_process, "TSL2563 test process"); AUTOSTART_PROCESSES(&remote_tsl2563_process); /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ +void +light_interrupt_callback(uint8_t value) +{ + printf("* Light sensor interrupt!\n"); + leds_toggle(LEDS_PURPLE); +} +/*---------------------------------------------------------------------------*/ PROCESS_THREAD(remote_tsl2563_process, ev, data) { PROCESS_BEGIN(); @@ -66,16 +74,35 @@ PROCESS_THREAD(remote_tsl2563_process, ev, data) /* Use Contiki's sensor macro to enable the sensor */ SENSORS_ACTIVATE(tsl2563); - /* Default integration time is 402ms with 1x gain, use the below call to + /* 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); + /* tsl2563.configure(TSL2563_TIMMING_CFG, TSL2563_G16X_402MS); */ + + /* Register the interrupt handler */ + TSL2563_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 + * threshold for a given lux quantity is to enable the DEBUG flag and see + * the CH0 value for a given measurement. The other is to reverse the + * 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); + + /* 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); - printf("Light = %u\n", (uint16_t) light); + if(light != TSL2563_ERROR) { + printf("Light = %u\n", (uint16_t)light); + } else { + printf("Error, enable the DEBUG flag in the tsl2563 driver for info, "); + printf("or check if the sensor is properly connected\n"); + } } PROCESS_END(); } diff --git a/platform/zoul/dev/tsl2563.c b/platform/zoul/dev/tsl2563.c index 0c8d23b9c..874bf893c 100644 --- a/platform/zoul/dev/tsl2563.c +++ b/platform/zoul/dev/tsl2563.c @@ -47,7 +47,7 @@ #include "lib/sensors.h" #include "tsl2563.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -66,9 +66,9 @@ void (*tsl2563_int_callback)(uint8_t value); static uint16_t calculate_lux(uint8_t *buf) { - uint32_t ch0, ch1 = 0; - uint32_t chscale; - uint32_t ratio, lratio, tmp = 0; + uint32_t ch0, ch1, chscale = 0; + uint32_t ratio = 0; + uint32_t lratio, tmp = 0; uint16_t buffer[2]; /* The calculations below assume the integration time is 402ms and the gain @@ -80,15 +80,15 @@ calculate_lux(uint8_t *buf) buffer[1] = (buf[3] << 8 | (buf[2])); switch(timming) { - case TSL2563_TIMMING_INTEG_402MS: - chscale = (1 << CH_SCALE); - break; - case TSL2563_TIMMING_INTEG_101MS: - chscale = CHSCALE_TINT1; - break; - case TSL2563_TIMMING_INTEG_13_7MS: - chscale = CHSCALE_TINT0; - break; + case TSL2563_TIMMING_INTEG_402MS: + chscale = (1 << CH_SCALE); + break; + case TSL2563_TIMMING_INTEG_101MS: + chscale = CHSCALE_TINT1; + break; + case TSL2563_TIMMING_INTEG_13_7MS: + chscale = CHSCALE_TINT0; + break; } if(!gain) { @@ -183,7 +183,7 @@ static int tsl2563_id_register(uint8_t *buf) { if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_ID_REG), - buf, 1) == TSL2563_SUCCESS) { + buf, 1) == TSL2563_SUCCESS) { PRINTF("TSL2563: partnum/revnum 0x%02X\n", *buf); return TSL2563_SUCCESS; } @@ -208,6 +208,17 @@ tsl2563_off(void) } /*---------------------------------------------------------------------------*/ static int +tsl2563_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; + } + return TSL2563_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int tsl2563_read_sensor(uint16_t *lux) { uint8_t buf[4]; @@ -217,6 +228,9 @@ tsl2563_read_sensor(uint16_t *lux) &buf[0], 2) == TSL2563_SUCCESS) { if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_D1LOW), &buf[2], 2) == TSL2563_SUCCESS) { + + PRINTF("TSL2563: CH0 0x%02X%02X CH1 0x%02X%02X\n", buf[1], buf[0], + buf[3], buf[2]); *lux = calculate_lux(buf); return TSL2563_SUCCESS; } @@ -231,31 +245,32 @@ PROCESS_THREAD(tsl2563_int_process, ev, data) { PROCESS_EXITHANDLER(); PROCESS_BEGIN(); + while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - - /* FIXME: Read interrupt source and clear */ + tsl2563_clear_interrupt(); tsl2563_int_callback(0); } PROCESS_END(); } - /*---------------------------------------------------------------------------*/ static void tsl2563_interrupt_handler(uint8_t port, uint8_t pin) { - /* FIXME: Check if the interrupt is ours */ + /* 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); } /*---------------------------------------------------------------------------*/ static int configure(int type, int value) { - uint8_t buf[2]; + uint8_t buf[3]; if((type != TSL2563_ACTIVE) && (type != TSL2563_INT_OVER) && - (type != TSL2563_INT_BELOW) && (type != TSL2563_INT_DISABLE) && - (type != TSL2563_TIMMING_CFG)) { + (type != TSL2563_INT_BELOW) && (type != TSL2563_INT_DISABLE) && + (type != TSL2563_TIMMING_CFG)) { PRINTF("TSL2563: invalid start value\n"); return TSL2563_ERROR; } @@ -264,11 +279,14 @@ configure(int type, int value) * time (not nominal), with manual control disabled */ - if(type == TSL2563_ACTIVE) { + if(type == TSL2563_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; + /* Power on the sensor and check for the part number */ if(tsl2563_on() == TSL2563_SUCCESS) { if(tsl2563_id_register(&buf[0]) == TSL2563_SUCCESS) { @@ -276,17 +294,20 @@ configure(int type, int value) /* Read the timming/gain configuration */ if(tsl2563_read_reg((TSL2563_COMMAND + TSL2563_TIMMING), - &buf[0], 1) == TSL2563_SUCCESS) { + &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); - return TSL2563_SUCCESS; + + /* Clear any pending interrupt */ + if(tsl2563_clear_interrupt() == TSL2563_SUCCESS) { + return TSL2563_SUCCESS; + } } } } } return TSL2563_ERROR; - } else { if(tsl2563_off() == TSL2563_SUCCESS) { PRINTF("TSL2563: stopped\n"); @@ -297,15 +318,30 @@ configure(int type, int value) } if(type == TSL2563_INT_DISABLE) { - /* FIXME: disable interrupt */ + + /* 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); + + /* 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; + + if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to disable the interrupt\n"); + return TSL2563_ERROR; + } return TSL2563_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)) { + (value != TSL2563_G1X_101MS) && (value != TSL2563_G1X_13_7MS)) { PRINTF("TSL2563: invalid timming configuration values\n"); return TSL2563_ERROR; } @@ -319,16 +355,16 @@ configure(int type, int value) } switch(value) { - case TSL2563_G16X_402MS: - case TSL2563_G1X_402MS: - timming = TSL2563_TIMMING_INTEG_402MS; - break; - case TSL2563_G1X_101MS: - timming = TSL2563_TIMMING_INTEG_101MS; - break; - case TSL2563_G1X_13_7MS: - timming = TSL2563_TIMMING_INTEG_13_7MS; - break; + case TSL2563_G16X_402MS: + case TSL2563_G1X_402MS: + timming = TSL2563_TIMMING_INTEG_402MS; + break; + case TSL2563_G1X_101MS: + timming = TSL2563_TIMMING_INTEG_101MS; + break; + case TSL2563_G1X_13_7MS: + timming = TSL2563_TIMMING_INTEG_13_7MS; + break; } PRINTF("TSL2563: new timming %u gain %u\n", timming, gain); @@ -338,8 +374,36 @@ configure(int type, int value) return TSL2563_ERROR; } - /* Configure interrupt pins and initialize interrupts handlers */ - tsl2563_int_callback = NULL; + /* From here we handle the interrupt configuration, it requires the interrupt + * callback handler to have been previously set using the TSL2563_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(tsl2563_write_reg(buf, 3) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to set interrupt level\n"); + return TSL2563_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; + + if(tsl2563_write_reg(buf, 2) != TSL2563_SUCCESS) { + PRINTF("TSL2563: failed to enable interrupt\n"); + return TSL2563_ERROR; + } /* Configure the interrupts pins */ GPIO_SOFTWARE_CONTROL(TSL2563_INT_PORT_BASE, TSL2563_INT_PIN_MASK); @@ -354,17 +418,17 @@ configure(int type, int value) /* Spin process until an interrupt is received */ process_start(&tsl2563_int_process, NULL); - if(type == TSL2563_INT_OVER) { - /* FIXME: add code */ - } else if(type == TSL2563_INT_BELOW) { - /* FIXME: add code */ - } - /* Enable interrupts */ GPIO_ENABLE_INTERRUPT(TSL2563_INT_PORT_BASE, TSL2563_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 + * resistor instead if no external pull-up is present. + */ 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; } /*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/dev/tsl2563.h b/platform/zoul/dev/tsl2563.h index 8cff19bcb..f8619140e 100644 --- a/platform/zoul/dev/tsl2563.h +++ b/platform/zoul/dev/tsl2563.h @@ -79,6 +79,7 @@ /* -------------------------------------------------------------------------- */ /* 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 @@ -90,7 +91,7 @@ #define TSL2563_TIMMING_INTEG_13_7MS 0x00 #define TSL2563_TIMMING_INTEG_MASK 0x03 -#define TSL2563_G16X_402MS (TSL2563_TIMMING_INTEG_402MS + TSL2563_TIMMING_GAIN) +#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 diff --git a/platform/zoul/firefly/board.h b/platform/zoul/firefly/board.h index 9af39e2b1..07d5eaf10 100644 --- a/platform/zoul/firefly/board.h +++ b/platform/zoul/firefly/board.h @@ -250,6 +250,9 @@ #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 /** @} */ /*---------------------------------------------------------------------------*/ /** From f78a1323953a50347eabdd02973d78db0f414aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 9 Jan 2016 15:07:57 +0100 Subject: [PATCH 25/94] cc2538: pka: Fix include paths breakage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PKA drivers and examples were full of include paths missing the appropriate prefix, or using angle brackets instead of double quotes or the other way around. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/bignum-driver.c | 6 +++--- cpu/cc2538/dev/bignum-driver.h | 2 +- cpu/cc2538/dev/ecc-algorithm.c | 10 +++++----- cpu/cc2538/dev/ecc-algorithm.h | 4 ++-- cpu/cc2538/dev/ecc-curve.c | 4 ++-- cpu/cc2538/dev/ecc-driver.c | 2 +- cpu/cc2538/dev/ecc-driver.h | 2 +- examples/cc2538dk/pka/ecc-ecdh.c | 10 +++++----- examples/cc2538dk/pka/ecc-sign.c | 8 ++++---- examples/cc2538dk/pka/ecc-verify.c | 8 ++++---- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cpu/cc2538/dev/bignum-driver.c b/cpu/cc2538/dev/bignum-driver.c index 60ced2960..57c667e01 100644 --- a/cpu/cc2538/dev/bignum-driver.c +++ b/cpu/cc2538/dev/bignum-driver.c @@ -50,12 +50,12 @@ * bignum_divide_start bignum_divide_get_result (division) * bignum_cmp_start bignum_cmp_get_result (comparison) */ -#include "bignum-driver.h" +#include "dev/bignum-driver.h" -#include "stdio.h" +#include #include "reg.h" -#include "nvic.h" +#include "dev/nvic.h" #define ASSERT(IF) if(!(IF)) { return PKA_STATUS_INVALID_PARAM; } diff --git a/cpu/cc2538/dev/bignum-driver.h b/cpu/cc2538/dev/bignum-driver.h index 7cc646a84..dd83a3058 100644 --- a/cpu/cc2538/dev/bignum-driver.h +++ b/cpu/cc2538/dev/bignum-driver.h @@ -59,7 +59,7 @@ #define BIGNUM_DRIVER_H_ #include "contiki.h" -#include "pka.h" +#include "dev/pka.h" #include diff --git a/cpu/cc2538/dev/ecc-algorithm.c b/cpu/cc2538/dev/ecc-algorithm.c index 103e35bcb..7ecd99ad8 100644 --- a/cpu/cc2538/dev/ecc-algorithm.c +++ b/cpu/cc2538/dev/ecc-algorithm.c @@ -35,15 +35,15 @@ * \file * Implementation of the cc2538 ECC Algorithms */ -#include -#include +#include "contiki.h" +#include "sys/process.h" #include #include -#include "ecc-algorithm.h" -#include "ecc-driver.h" -#include "pka.h" +#include "dev/ecc-algorithm.h" +#include "dev/ecc-driver.h" +#include "dev/pka.h" #define CHECK_RESULT(...) \ state->result = __VA_ARGS__; \ diff --git a/cpu/cc2538/dev/ecc-algorithm.h b/cpu/cc2538/dev/ecc-algorithm.h index 31f07ec2e..059f011ee 100644 --- a/cpu/cc2538/dev/ecc-algorithm.h +++ b/cpu/cc2538/dev/ecc-algorithm.h @@ -49,8 +49,8 @@ #ifndef ECC_ALGORITHM_H_ #define ECC_ALGORITHM_H_ -#include "bignum-driver.h" -#include "ecc-driver.h" +#include "dev/bignum-driver.h" +#include "dev/ecc-driver.h" typedef struct { /* Containers for the State */ diff --git a/cpu/cc2538/dev/ecc-curve.c b/cpu/cc2538/dev/ecc-curve.c index bc3e9e8c6..d3291d1b6 100644 --- a/cpu/cc2538/dev/ecc-curve.c +++ b/cpu/cc2538/dev/ecc-curve.c @@ -32,8 +32,8 @@ * \addtogroup c2538-ecc-curves * @{ */ -#include -#include +#include "contiki.h" +#include "dev/ecc-driver.h" /* [NIST P-256, X9.62 prime256v1] */ static const uint32_t nist_p_256_p[8] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, diff --git a/cpu/cc2538/dev/ecc-driver.c b/cpu/cc2538/dev/ecc-driver.c index 89a345e14..d6bc5903c 100644 --- a/cpu/cc2538/dev/ecc-driver.c +++ b/cpu/cc2538/dev/ecc-driver.c @@ -39,7 +39,7 @@ * \file * Implementation of the cc2538 ECC driver */ -#include "ecc-driver.h" +#include "dev/ecc-driver.h" #include "reg.h" #include "dev/nvic.h" diff --git a/cpu/cc2538/dev/ecc-driver.h b/cpu/cc2538/dev/ecc-driver.h index 8afcc8332..3f71153a9 100644 --- a/cpu/cc2538/dev/ecc-driver.h +++ b/cpu/cc2538/dev/ecc-driver.h @@ -48,7 +48,7 @@ #define ECC_DRIVER_H_ #include "contiki.h" -#include "pka.h" +#include "dev/pka.h" #include /*---------------------------------------------------------------------------*/ diff --git a/examples/cc2538dk/pka/ecc-ecdh.c b/examples/cc2538dk/pka/ecc-ecdh.c index ec809fc29..623dbcc6c 100644 --- a/examples/cc2538dk/pka/ecc-ecdh.c +++ b/examples/cc2538dk/pka/ecc-ecdh.c @@ -45,11 +45,11 @@ * Example demonstrating ECDH on the cc2538dk platform */ #include "contiki.h" -#include "ecc-algorithm.h" -#include "ecc-curve.h" -#include "random.h" -#include "rtimer.h" -#include "pt.h" +#include "dev/ecc-algorithm.h" +#include "dev/ecc-curve.h" +#include "lib/random.h" +#include "sys/rtimer.h" +#include "sys/pt.h" #include #include diff --git a/examples/cc2538dk/pka/ecc-sign.c b/examples/cc2538dk/pka/ecc-sign.c index 5114073eb..f5dff50fb 100644 --- a/examples/cc2538dk/pka/ecc-sign.c +++ b/examples/cc2538dk/pka/ecc-sign.c @@ -45,10 +45,10 @@ * Example demonstrating ECDSA-Sign on the cc2538dk platform */ #include "contiki.h" -#include "ecc-algorithm.h" -#include "ecc-curve.h" -#include "rtimer.h" -#include "pt.h" +#include "dev/ecc-algorithm.h" +#include "dev/ecc-curve.h" +#include "sys/rtimer.h" +#include "sys/pt.h" #include #include diff --git a/examples/cc2538dk/pka/ecc-verify.c b/examples/cc2538dk/pka/ecc-verify.c index a970d2a02..84f20f24b 100644 --- a/examples/cc2538dk/pka/ecc-verify.c +++ b/examples/cc2538dk/pka/ecc-verify.c @@ -45,10 +45,10 @@ * Example demonstrating ECDSA-Verify on the cc2538dk platform */ #include "contiki.h" -#include "ecc-algorithm.h" -#include "ecc-curve.h" -#include "rtimer.h" -#include "pt.h" +#include "dev/ecc-algorithm.h" +#include "dev/ecc-curve.h" +#include "sys/rtimer.h" +#include "sys/pt.h" #include #include From ada5c6193e3c90464bbdaa2bb8849baaa37c7903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 9 Jan 2016 15:03:39 +0100 Subject: [PATCH 26/94] cc2538dk: pka: Fix missing Makefile.target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- examples/cc2538dk/pka/Makefile.target | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/cc2538dk/pka/Makefile.target diff --git a/examples/cc2538dk/pka/Makefile.target b/examples/cc2538dk/pka/Makefile.target new file mode 100644 index 000000000..777593c88 --- /dev/null +++ b/examples/cc2538dk/pka/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2538dk From 92d8f95cba6d739d7637459ae02fab297345f292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 9 Jan 2016 14:07:47 +0100 Subject: [PATCH 27/94] cc2538: Fix GCC 5 warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following warning issued by GCC ARM Embedded 5-2015-q4-major: ../../cpu/cc2538/dev/udma.c: In function 'udma_init': ../../cpu/cc2538/dev/udma.c:59:10: warning: passing argument 1 of 'memset' discards 'volatile' qualifier from pointer target type [-Wdiscarded-array-qualifiers] memset(&channel_config, 0, sizeof(channel_config)); ^ In file included from /arm-none-eabi/include/string.h:10:0, from ../../platform/cc2538dk/./contiki-conf.h:12, from ../../cpu/cc2538/dev/udma.c:38: /arm-none-eabi/include/string.h:25:7: note: expected 'void *' but argument is of type 'volatile struct channel_ctrl (*)[4]' _PTR _EXFUN(memset,(_PTR, int, size_t)); ^ Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/udma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/cc2538/dev/udma.c b/cpu/cc2538/dev/udma.c index c285d1b11..c9770869b 100644 --- a/cpu/cc2538/dev/udma.c +++ b/cpu/cc2538/dev/udma.c @@ -56,7 +56,7 @@ static volatile struct channel_ctrl channel_config[UDMA_CONF_MAX_CHANNEL + 1] void udma_init() { - memset(&channel_config, 0, sizeof(channel_config)); + memset((void *)&channel_config, 0, sizeof(channel_config)); REG(UDMA_CFG) = UDMA_CFG_MASTEN; From 3b73a9de3ed4048edddc9de8ecdce326a1d9e4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sat, 9 Jan 2016 15:09:02 +0100 Subject: [PATCH 28/94] cc2538dk: Fix missing Travis build rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau --- regression-tests/18-compile-arm-ports/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index a3b47cddd..16e24bd80 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -17,6 +17,8 @@ cc2538dk/cc2538dk \ cc2538dk/udp-ipv6-echo-server/cc2538dk \ cc2538dk/sniffer/cc2538dk \ cc2538dk/mqtt-demo/cc2538dk \ +cc2538dk/crypto/cc2538dk \ +cc2538dk/pka/cc2538dk \ ipv6/multicast/cc2538dk \ zolertia/zoul/zoul \ zolertia/zoul/cc1200-demo/zoul \ From 7abee394cb3a5880f0ac3cf04840d182fc76bc49 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 04:09:07 +0100 Subject: [PATCH 29/94] Initialized interrupt thresholds and added missing check --- examples/zolertia/zoul/test-tsl2563.c | 1 + platform/zoul/dev/tsl2563.c | 33 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl2563.c index f32242f74..b80a76eaf 100644 --- a/examples/zolertia/zoul/test-tsl2563.c +++ b/examples/zolertia/zoul/test-tsl2563.c @@ -102,6 +102,7 @@ PROCESS_THREAD(remote_tsl2563_process, ev, data) } else { printf("Error, enable the DEBUG flag in the tsl2563 driver for info, "); printf("or check if the sensor is properly connected\n"); + PROCESS_EXIT(); } } PROCESS_END(); diff --git a/platform/zoul/dev/tsl2563.c b/platform/zoul/dev/tsl2563.c index 874bf893c..e35698bec 100644 --- a/platform/zoul/dev/tsl2563.c +++ b/platform/zoul/dev/tsl2563.c @@ -299,8 +299,29 @@ configure(int type, int value) timming = buf[0] & TSL2563_TIMMING_INTEG_MASK; PRINTF("TSL2563: enabled, timming %u gain %u\n", timming, gain); + /* Restart the over interrupt threshold */ + buf[0] = (TSL2563_COMMAND + TSL2563_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; + } + + /* Restart the below interrupt threshold */ + buf[0] = (TSL2563_COMMAND + TSL2563_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; + } + /* Clear any pending interrupt */ if(tsl2563_clear_interrupt() == TSL2563_SUCCESS) { + enabled = 1; return TSL2563_SUCCESS; } } @@ -311,12 +332,18 @@ configure(int type, int value) } else { if(tsl2563_off() == TSL2563_SUCCESS) { PRINTF("TSL2563: stopped\n"); + enabled = 0; return TSL2563_SUCCESS; } return TSL2563_ERROR; } } + if(!enabled) { + PRINTF("TSL2563: sensor not started\n"); + return TSL2563_ERROR; + } + if(type == TSL2563_INT_DISABLE) { /* Ensure the GPIO doesn't generate more interrupts, this may affect others @@ -447,6 +474,12 @@ static int value(int type) { uint16_t lux; + + if(!enabled) { + PRINTF("TSL2563: sensor not started\n"); + return TSL2563_ERROR; + } + if(type == TSL2563_VAL_READ) { if(tsl2563_read_sensor(&lux) != TSL2563_ERROR) { return lux; From 7b953091e5d8cfb8f4de9a7ccc1675a7f7b0d91c Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 03:11:23 +0100 Subject: [PATCH 30/94] Added BMP085 barometric sensor for the Zoul platform --- examples/zolertia/zoul/Makefile | 3 +- examples/zolertia/zoul/test-bmp085.c | 94 +++++++ platform/zoul/dev/bmp085.c | 350 +++++++++++++++++++++++++++ platform/zoul/dev/bmp085.h | 136 +++++++++++ 4 files changed, 582 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/test-bmp085.c create mode 100644 platform/zoul/dev/bmp085.c create mode 100644 platform/zoul/dev/bmp085.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index beef98880..03dd8103a 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,6 +1,7 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c +CONTIKI_PROJECT += test-bmp085 +CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-bmp085.c b/examples/zolertia/zoul/test-bmp085.c new file mode 100644 index 000000000..4f19fd993 --- /dev/null +++ b/examples/zolertia/zoul/test-bmp085.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015, 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 zoul-examples + * @{ + * + * \defgroup zoul-bmp085-test BMP085 pressure and temperature sensor test + * + * Demonstrates the use of the BMP085 digital pressure and temperature sensor + * @{ + * + * \file + * Driver for the external BMP085 digital pressure and temperature sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include "dev/bmp085.h" +/*---------------------------------------------------------------------------*/ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_bmp085_process, "BMP085 test process"); +AUTOSTART_PROCESSES(&remote_bmp085_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_bmp085_process, ev, data) +{ + PROCESS_BEGIN(); + static uint16_t pressure; + static int16_t temperature; + + /* Use Contiki's sensor macro to enable the sensor */ + SENSORS_ACTIVATE(bmp085); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + pressure = bmp085.value(BMP085_READ_PRESSURE); + temperature = bmp085.value(BMP085_READ_TEMP); + + if((pressure != BMP085_ERROR) && (temperature != BMP085_ERROR)) { + printf("Pressure = %u.%u(hPa), ", pressure / 10, pressure % 10); + printf("Temperature = %d.%u(ºC)\n", temperature / 10, temperature % 10); + } else { + printf("Error, enable the DEBUG flag in the BMP085 driver for info, "); + printf("or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/bmp085.c b/platform/zoul/dev/bmp085.c new file mode 100644 index 000000000..6127715b5 --- /dev/null +++ b/platform/zoul/dev/bmp085.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2015, 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 zoul-bmp085-sensor + * @{ + * + * BMP085 driver implementation, calculations taken from Inga sensor driver + * + * \file + * Driver for the external BMP085 light sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/gpio.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "bmp085.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled = 0; +/*---------------------------------------------------------------------------*/ +typedef struct { + int16_t ac1; + int16_t ac2; + int16_t ac3; + uint16_t ac4; + uint16_t ac5; + uint16_t ac6; + int16_t b1; + int16_t b2; + int16_t mb; + int16_t mc; + int16_t md; +} bmp085_calibration_values; + +typedef struct { + uint8_t oversampling_mode; + bmp085_calibration_values calib; +} bmp085_config; + +static bmp085_config bmp085_values; +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("BMP085: invalid read values\n"); + return BMP085_ERROR; + } + + i2c_master_enable(); + if(i2c_single_send(BMP085_ADDR, reg) == I2C_MASTER_ERR_NONE) { + while(i2c_master_busy()); + if(i2c_burst_receive(BMP085_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMP085_SUCCESS; + } + } + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("BMP085: invalid write values\n"); + return BMP085_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(BMP085_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMP085_SUCCESS; + } + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_calib(void) +{ + uint8_t buf[BMP085_CALIB_TABLE_SIZE]; + + if(bmp085_read_reg(BMP085_AC1_CALIB, buf, + BMP085_CALIB_TABLE_SIZE) == BMP085_SUCCESS) { + + /* MSB first */ + bmp085_values.calib.ac1 = ((buf[0] << 8) + buf[1]); + bmp085_values.calib.ac2 = ((buf[2] << 8) + buf[3]); + bmp085_values.calib.ac3 = ((buf[4] << 8) + buf[5]); + bmp085_values.calib.ac4 = ((buf[6] << 8) + buf[7]); + bmp085_values.calib.ac5 = ((buf[8] << 8) + buf[9]); + bmp085_values.calib.ac6 = ((buf[10] << 8) + buf[11]); + bmp085_values.calib.b1 = ((buf[12] << 8) + buf[13]); + bmp085_values.calib.b2 = ((buf[14] << 8) + buf[15]); + bmp085_values.calib.mb = ((buf[16] << 8) + buf[17]); + bmp085_values.calib.mc = ((buf[18] << 8) + buf[19]); + bmp085_values.calib.md = ((buf[20] << 8) + buf[21]); + + return BMP085_SUCCESS; + } + + PRINTF("BMP085: failed to read calibration\n"); + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_uncompensated_pressure(int32_t *pressure) +{ + uint8_t buf[3]; + uint16_t delay; + int32_t upres; + + buf[0] = BMP085_CTRL_REG; + + switch(bmp085_values.oversampling_mode) { + case BMP085_MODE_ULTRA_LOW_POWER: + buf[1] = BMP085_CTRL_REG_PRESS_4_5MS; + delay = BMP085_DELAY_4_5MS; + break; + case BMP085_MODE_STANDARD: + buf[1] = BMP085_CTRL_REG_PRESS_7_5MS; + delay = BMP085_DELAY_7_5MS; + break; + case BMP085_MODE_HIGH_RES: + buf[1] = BMP085_CTRL_REG_PRESS_13_5MS; + delay = BMP085_DELAY_13_5MS; + break; + case BMP085_MODE_ULTRA_HIGH_RES: + buf[1] = BMP085_CTRL_REG_PRESS_25_5MS; + delay = BMP085_DELAY_25_5MS; + break; + default: + return BMP085_ERROR; + } + + if(bmp085_write_reg(buf, 2) == BMP085_SUCCESS) { + clock_delay_usec(delay); + if(bmp085_read_reg(BMP085_DATA_MSB, buf, 3) == BMP085_SUCCESS) { + upres = (buf[0] << 16) + (buf[1] << 8) + buf[2]; + *pressure = (upres >> (8 - bmp085_values.oversampling_mode)); + return BMP085_SUCCESS; + } + } + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_uncompensated_temperature(int32_t *temp) +{ + uint8_t buf[2]; + buf[0] = BMP085_CTRL_REG; + buf[1] = BMP085_CTRL_REG_TEMP; + + if(bmp085_write_reg(buf, 2) == BMP085_SUCCESS) { + clock_delay_usec(BMP085_DELAY_4_5MS); + if(bmp085_read_reg(BMP085_DATA_MSB, buf, 2) == BMP085_SUCCESS) { + *temp = (int32_t)((buf[0] << 8) + buf[1]); + return BMP085_SUCCESS; + } + } + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_temperature(int16_t *temp) +{ + int32_t ut = 0; + int32_t x1, x2, b5; + + if(bmp085_read_uncompensated_temperature(&ut) == BMP085_ERROR) { + return BMP085_ERROR; + } + + x1 = ((int32_t)ut - (int32_t)bmp085_values.calib.ac6) + * (int32_t)bmp085_values.calib.ac5 >> 15; + x2 = ((int32_t)bmp085_values.calib.mc << 11) / (x1 + bmp085_values.calib.md); + b5 = x1 + x2; + *temp = (int16_t)((b5 + 8) >> 4); + return BMP085_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_pressure(int32_t *pressure) +{ + int32_t ut = 0; + int32_t up = 0; + int32_t x1, x2, b5, b6, x3, b3, p; + uint32_t b4, b7; + + if(bmp085_read_uncompensated_pressure(&up) == BMP085_ERROR) { + return BMP085_ERROR; + } + + if(bmp085_read_uncompensated_temperature(&ut) == BMP085_ERROR) { + return BMP085_ERROR; + } + + b6 = b5 - 4000; + x1 = (bmp085_values.calib.b2 * (b6 * b6 >> 12)) >> 11; + x2 = bmp085_values.calib.ac2 * b6 >> 11; + x3 = x1 + x2; + b3 = ((((int32_t)bmp085_values.calib.ac1) * 4 + x3) + 2) >> 2; + + x1 = (bmp085_values.calib.ac3 * b6) >> 13; + x2 = (bmp085_values.calib.b1 * ((b6 * b6) >> 12)) >> 16; + x3 = ((x1 + x2) + 2) >> 2; + b4 = (bmp085_values.calib.ac4 * ((uint32_t)(x3 + 32768))) >> 15; + b7 = ((uint32_t)up - b3) * 50000; + + if(b7 < 0x80000000) { + p = (b7 << 1) / b4; + } else { + p = (b7 / b4) << 1; + } + + x1 = (p >> 8) * (p >> 8); + x1 = (x1 * 3038) >> 16; + x2 = (-7357 * p) >> 16; + *pressure = (p + ((x1 + x2 + 3791) >> 4)); + *pressure /= 10; + + return BMP085_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if((type != BMP085_ACTIVE) && (type != BMP085_OVERSAMPLING)) { + PRINTF("BMP085: invalid start value\n"); + return BMP085_ERROR; + } + + if(type == BMP085_ACTIVE) { + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Read the calibration values */ + if(bmp085_read_calib() != BMP085_ERROR) { + PRINTF("BMP085: sensor started\n"); + enabled = 1; + bmp085_values.oversampling_mode = BMP085_MODE_ULTRA_LOW_POWER; + return BMP085_SUCCESS; + } + + PRINTF("BMP085: failed to enable\n"); + return BMP085_ERROR; + } else { + enabled = 0; + return BMP085_SUCCESS; + } + } else if(type == BMP085_OVERSAMPLING) { + if((value < BMP085_MODE_ULTRA_LOW_POWER) || + (value > BMP085_MODE_ULTRA_HIGH_RES)) { + PRINTF("BMP085: invalid oversampling value\n"); + return BMP085_ERROR; + } + bmp085_values.oversampling_mode = value; + return BMP085_SUCCESS; + } + + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +bmp085_read_sensor(int32_t *value, uint8_t type) +{ + switch(type) { + case BMP085_READ_PRESSURE: + return bmp085_read_pressure(value); + case BMP085_READ_TEMP: + return bmp085_read_temperature((int16_t *)value); + } + + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int32_t value; + + if(!enabled) { + PRINTF("BMP085: sensor not started\n"); + return BMP085_ERROR; + } + + if((type != BMP085_READ_PRESSURE) && (type != BMP085_READ_TEMP)) { + PRINTF("BMP085: invalid read value\n"); + return BMP085_ERROR; + } + + if(bmp085_read_sensor(&value, type) == BMP085_SUCCESS) { + return (int)value; + } + + PRINTF("BMP085: fail to read\n"); + return BMP085_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(bmp085, BMP085_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/bmp085.h b/platform/zoul/dev/bmp085.h new file mode 100644 index 000000000..88a08e51d --- /dev/null +++ b/platform/zoul/dev/bmp085.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, 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. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-bmp085-sensor BMP085 Sensor + * + * Driver for the BMP085 sensor + * + * BMP085 digital pressure and temperature driver + * @{ + * + * \file + * Header file for the external BMP085 Sensor Driver + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#ifndef BMP085_H_ +#define BMP085_H_ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name BMP085 address and registers + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define BMP085_ADDR 0x77 +/* -------------------------------------------------------------------------- */ +/* Control register */ +#define BMP085_CTRL_REG 0xF4 +/* Read uncompensated temperature */ +#define BMP085_CTRL_REG_TEMP 0x2E +/* Read uncompensated pressure, no oversampling */ +#define BMP085_CTRL_REG_PRESS_4_5MS 0x34 +/* Read uncompensated pressure, oversampling 1*/ +#define BMP085_CTRL_REG_PRESS_7_5MS 0x74 +/* Read uncompensated pressure, oversampling 2 */ +#define BMP085_CTRL_REG_PRESS_13_5MS 0xB4 +/* Read uncompensated pressure, oversampling 3 */ +#define BMP085_CTRL_REG_PRESS_25_5MS 0xF4 +/* -------------------------------------------------------------------------- */ +#define BMP085_DATA_MSB 0xF6 +#define BMP085_DATA_LSB 0xF7 +/* 19-bit resolution */ +#define BMP085_DATA_XLSB 0xF8 +/* -------------------------------------------------------------------------- */ +/* Calibration registers, 16-bit wide */ +#define BMP085_AC1_CALIB 0xAA +#define BMP085_AC2_CALIB 0xAC +#define BMP085_AC3_CALIB 0xAE +#define BMP085_AC4_CALIB 0xB0 +#define BMP085_AC5_CALIB 0xB2 +#define BMP085_AC6_CALIB 0xB4 +#define BMP085_B1_CALIB 0xB6 +#define BMP085_B2_CALIB 0xB8 +#define BMP085_MB_CALIB 0xBA +#define BMP085_MC_CALIB 0xBC +#define BMP085_MD_CALIB 0xBE +#define BMP085_CALIB_TABLE_SIZE 22 /**< size in bytes */ +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name BMP085 operation modes + * @{ + */ +#define BMP085_MODE_ULTRA_LOW_POWER 0x00 +#define BMP085_MODE_STANDARD 0x01 +#define BMP085_MODE_HIGH_RES 0x02 +#define BMP085_MODE_ULTRA_HIGH_RES 0x03 +/* -------------------------------------------------------------------------- */ +#define BMP085_DELAY_4_5MS 4700 +#define BMP085_DELAY_7_5MS 7700 +#define BMP085_DELAY_13_5MS 13700 +#define BMP085_DELAY_25_5MS 25700 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name BMP085 return and command values + * @{ + */ +#define BMP085_SUCCESS 0x00 +#define BMP085_ERROR -1 + +#define BMP085_ACTIVE SENSORS_ACTIVE +#define BMP085_OVERSAMPLING 0x00 +#define BMP085_READ_PRESSURE 0x01 +#define BMP085_READ_TEMP 0x02 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define BMP085_SENSOR "BMP085 pressure and temperature sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor bmp085; +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + From 707353f71bb40e1dfc701132ac4a261a079cbc3e Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 15:01:58 +0000 Subject: [PATCH 31/94] Remove Sensinode platform, cpu, example and tools files This is part of a set of commits that will obsolete the Sensinode platform --- cpu/cc2430/8051def.h | 112 -- cpu/cc2430/Makefile.cc2430 | 116 --- cpu/cc2430/Makefile.customrules-cc2430 | 63 -- cpu/cc2430/bank-alloc.py | 228 ---- cpu/cc2430/cc2430_sfr.h | 709 ------------- cpu/cc2430/dev/bus.c | 58 -- cpu/cc2430/dev/bus.h | 53 - cpu/cc2430/dev/cc2430_rf.c | 750 -------------- cpu/cc2430/dev/cc2430_rf.h | 91 -- cpu/cc2430/dev/cc2430_rf_intr.c | 112 -- cpu/cc2430/dev/clock.c | 169 --- cpu/cc2430/dev/dma.c | 69 -- cpu/cc2430/dev/dma.h | 148 --- cpu/cc2430/dev/dma_intr.c | 73 -- cpu/cc2430/dev/hwconf.h | 148 --- cpu/cc2430/dev/lpm.h | 57 - cpu/cc2430/dev/random.c | 135 --- cpu/cc2430/dev/uart.h | 43 - cpu/cc2430/dev/uart0.c | 69 -- cpu/cc2430/dev/uart0.h | 31 - cpu/cc2430/dev/uart1.c | 74 -- cpu/cc2430/dev/uart1.h | 39 - cpu/cc2430/dev/uart_intr.c | 91 -- cpu/cc2430/dev/watchdog-cc2430.c | 129 --- cpu/cc2430/dev/watchdog-cc2430.h | 72 -- cpu/cc2430/mtarch.h | 49 - cpu/cc2430/rtimer-arch.c | 127 --- cpu/cc2430/rtimer-arch.h | 62 -- cpu/cc2430/segment.rules | 26 - cpu/cc2430/stack.c | 71 -- cpu/cc2430/stack.h | 68 -- examples/sensinode/Makefile | 17 - examples/sensinode/README.md | 60 -- examples/sensinode/blink-hello.c | 62 -- examples/sensinode/border-router/Makefile | 19 - examples/sensinode/border-router/README.md | 20 - .../sensinode/border-router/border-router.c | 150 --- .../sensinode/border-router/project-conf.h | 51 - .../sensinode/border-router/slip-bridge.c | 104 -- examples/sensinode/broadcast-rime.c | 119 --- .../sensinode/cc2431-location-engine/Makefile | 18 - .../cc2431-location-engine/blind-node.c | 280 ----- .../cc2431-location-engine/cc2431_loc_eng.h | 108 -- examples/sensinode/disco/Makefile | 18 - examples/sensinode/disco/disco-example.c | 53 - examples/sensinode/energy-scan/Makefile | 17 - examples/sensinode/energy-scan/energy-scan.c | 108 -- examples/sensinode/energy-scan/netstack.c | 49 - examples/sensinode/energy-scan/project-conf.h | 50 - examples/sensinode/energy-scan/stub-rdc.c | 100 -- examples/sensinode/event-post/Makefile | 17 - examples/sensinode/event-post/event-post.c | 98 -- examples/sensinode/event-post/event-post.h | 22 - examples/sensinode/sensors-ipv6/Makefile | 18 - .../sensinode/sensors-ipv6/project-conf.h | 52 - .../sensinode/sensors-ipv6/sensors-driver.c | 246 ----- .../sensinode/sensors-ipv6/sensors-ipv6.c | 154 --- examples/sensinode/sensors/Makefile | 17 - examples/sensinode/sensors/sensors-example.c | 376 ------- examples/sensinode/sensors/sensors-example.h | 53 - examples/sensinode/serial-flash/Makefile | 14 - examples/sensinode/serial-flash/flash.c | 268 ----- examples/sensinode/sniffer/Makefile | 16 - examples/sensinode/sniffer/README.md | 15 - examples/sensinode/sniffer/netstack.c | 49 - examples/sensinode/sniffer/project-conf.h | 52 - examples/sensinode/sniffer/sniffer.c | 54 - examples/sensinode/sniffer/stub-rdc.c | 100 -- examples/sensinode/timer-test.c | 139 --- examples/sensinode/udp-ipv6/Makefile | 20 - examples/sensinode/udp-ipv6/client.c | 213 ---- examples/sensinode/udp-ipv6/ping6.c | 139 --- examples/sensinode/udp-ipv6/project-conf.h | 52 - examples/sensinode/udp-ipv6/server.c | 207 ---- .../sensinode/Makefile.customrules-sensinode | 1 - platform/sensinode/Makefile.sensinode | 92 -- .../sensinode/apps/batmon/Makefile.batmon | 3 - platform/sensinode/apps/batmon/batmon.c | 230 ----- platform/sensinode/contiki-conf.h | 286 ----- platform/sensinode/contiki-sensinode-main.c | 382 ------- platform/sensinode/debug.c | 61 -- platform/sensinode/debug.h | 55 - platform/sensinode/dev/adc-sensor.c | 212 ---- platform/sensinode/dev/button-sensor.c | 205 ---- platform/sensinode/dev/button-sensor.h | 48 - platform/sensinode/dev/leds-arch.c | 90 -- platform/sensinode/dev/m25p16.c | 318 ------ platform/sensinode/dev/m25p16.h | 293 ------ platform/sensinode/dev/models.c | 95 -- platform/sensinode/dev/models.h | 60 -- platform/sensinode/dev/n740.c | 187 ---- platform/sensinode/dev/n740.h | 75 -- platform/sensinode/dev/sensinode-sensors.c | 81 -- platform/sensinode/dev/sensinode-sensors.h | 166 --- platform/sensinode/dev/slip-arch.c | 49 - platform/sensinode/disco.c | 350 ------- platform/sensinode/disco.h | 129 --- platform/sensinode/putchar.c | 39 - platform/sensinode/segment.rules | 13 - platform/sensinode/uip-debug.c | 82 -- platform/sensinode/viztool.c | 286 ----- tools/sensinode/nano_programmer/Makefile | 43 - tools/sensinode/nano_programmer/README.md | 38 - tools/sensinode/nano_programmer/cdi_program.c | 607 ----------- tools/sensinode/nano_programmer/ihex.c | 99 -- tools/sensinode/nano_programmer/ihex.h | 36 - tools/sensinode/nano_programmer/linux/port.c | 371 ------- .../sensinode/nano_programmer/nano_programmer | Bin 18776 -> 0 bytes tools/sensinode/nano_programmer/port.h | 94 -- tools/sensinode/nano_programmer/programmer.c | 440 -------- tools/sensinode/nano_programmer/programmer.h | 62 -- .../sensinode/nano_programmer/windows/port.c | 383 ------- tools/sensinode/nano_usb_programmer/Makefile | 32 - tools/sensinode/nano_usb_programmer/README.md | 60 -- .../sensinode/nano_usb_programmer/Rules.make | 14 - tools/sensinode/nano_usb_programmer/cdi.c | 506 --------- tools/sensinode/nano_usb_programmer/cdi.h | 44 - .../nano_usb_programmer/ftdi_linux/WinTypes.h | 116 --- .../nano_usb_programmer/ftdi_linux/ftd2xx.h | 975 ------------------ .../nano_usb_programmer/ftdi_win32/ftd2xx.h | 922 ----------------- tools/sensinode/nano_usb_programmer/ihex.c | 210 ---- tools/sensinode/nano_usb_programmer/ihex.h | 36 - tools/sensinode/nano_usb_programmer/main.c | 348 ------- tools/sensinode/nano_usb_programmer/prog.c | 372 ------- tools/sensinode/nano_usb_programmer/prog.h | 46 - 125 files changed, 17578 deletions(-) delete mode 100644 cpu/cc2430/8051def.h delete mode 100644 cpu/cc2430/Makefile.cc2430 delete mode 100644 cpu/cc2430/Makefile.customrules-cc2430 delete mode 100644 cpu/cc2430/bank-alloc.py delete mode 100644 cpu/cc2430/cc2430_sfr.h delete mode 100644 cpu/cc2430/dev/bus.c delete mode 100644 cpu/cc2430/dev/bus.h delete mode 100644 cpu/cc2430/dev/cc2430_rf.c delete mode 100644 cpu/cc2430/dev/cc2430_rf.h delete mode 100644 cpu/cc2430/dev/cc2430_rf_intr.c delete mode 100644 cpu/cc2430/dev/clock.c delete mode 100644 cpu/cc2430/dev/dma.c delete mode 100644 cpu/cc2430/dev/dma.h delete mode 100644 cpu/cc2430/dev/dma_intr.c delete mode 100644 cpu/cc2430/dev/hwconf.h delete mode 100644 cpu/cc2430/dev/lpm.h delete mode 100644 cpu/cc2430/dev/random.c delete mode 100644 cpu/cc2430/dev/uart.h delete mode 100644 cpu/cc2430/dev/uart0.c delete mode 100644 cpu/cc2430/dev/uart0.h delete mode 100644 cpu/cc2430/dev/uart1.c delete mode 100644 cpu/cc2430/dev/uart1.h delete mode 100644 cpu/cc2430/dev/uart_intr.c delete mode 100644 cpu/cc2430/dev/watchdog-cc2430.c delete mode 100644 cpu/cc2430/dev/watchdog-cc2430.h delete mode 100644 cpu/cc2430/mtarch.h delete mode 100644 cpu/cc2430/rtimer-arch.c delete mode 100644 cpu/cc2430/rtimer-arch.h delete mode 100644 cpu/cc2430/segment.rules delete mode 100644 cpu/cc2430/stack.c delete mode 100644 cpu/cc2430/stack.h delete mode 100644 examples/sensinode/Makefile delete mode 100644 examples/sensinode/README.md delete mode 100644 examples/sensinode/blink-hello.c delete mode 100644 examples/sensinode/border-router/Makefile delete mode 100644 examples/sensinode/border-router/README.md delete mode 100644 examples/sensinode/border-router/border-router.c delete mode 100644 examples/sensinode/border-router/project-conf.h delete mode 100644 examples/sensinode/border-router/slip-bridge.c delete mode 100644 examples/sensinode/broadcast-rime.c delete mode 100644 examples/sensinode/cc2431-location-engine/Makefile delete mode 100644 examples/sensinode/cc2431-location-engine/blind-node.c delete mode 100644 examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h delete mode 100644 examples/sensinode/disco/Makefile delete mode 100644 examples/sensinode/disco/disco-example.c delete mode 100644 examples/sensinode/energy-scan/Makefile delete mode 100644 examples/sensinode/energy-scan/energy-scan.c delete mode 100644 examples/sensinode/energy-scan/netstack.c delete mode 100644 examples/sensinode/energy-scan/project-conf.h delete mode 100644 examples/sensinode/energy-scan/stub-rdc.c delete mode 100644 examples/sensinode/event-post/Makefile delete mode 100644 examples/sensinode/event-post/event-post.c delete mode 100644 examples/sensinode/event-post/event-post.h delete mode 100644 examples/sensinode/sensors-ipv6/Makefile delete mode 100644 examples/sensinode/sensors-ipv6/project-conf.h delete mode 100644 examples/sensinode/sensors-ipv6/sensors-driver.c delete mode 100644 examples/sensinode/sensors-ipv6/sensors-ipv6.c delete mode 100644 examples/sensinode/sensors/Makefile delete mode 100644 examples/sensinode/sensors/sensors-example.c delete mode 100644 examples/sensinode/sensors/sensors-example.h delete mode 100644 examples/sensinode/serial-flash/Makefile delete mode 100644 examples/sensinode/serial-flash/flash.c delete mode 100644 examples/sensinode/sniffer/Makefile delete mode 100644 examples/sensinode/sniffer/README.md delete mode 100644 examples/sensinode/sniffer/netstack.c delete mode 100644 examples/sensinode/sniffer/project-conf.h delete mode 100644 examples/sensinode/sniffer/sniffer.c delete mode 100644 examples/sensinode/sniffer/stub-rdc.c delete mode 100644 examples/sensinode/timer-test.c delete mode 100644 examples/sensinode/udp-ipv6/Makefile delete mode 100644 examples/sensinode/udp-ipv6/client.c delete mode 100644 examples/sensinode/udp-ipv6/ping6.c delete mode 100644 examples/sensinode/udp-ipv6/project-conf.h delete mode 100644 examples/sensinode/udp-ipv6/server.c delete mode 100644 platform/sensinode/Makefile.customrules-sensinode delete mode 100644 platform/sensinode/Makefile.sensinode delete mode 100644 platform/sensinode/apps/batmon/Makefile.batmon delete mode 100644 platform/sensinode/apps/batmon/batmon.c delete mode 100644 platform/sensinode/contiki-conf.h delete mode 100644 platform/sensinode/contiki-sensinode-main.c delete mode 100644 platform/sensinode/debug.c delete mode 100644 platform/sensinode/debug.h delete mode 100644 platform/sensinode/dev/adc-sensor.c delete mode 100644 platform/sensinode/dev/button-sensor.c delete mode 100644 platform/sensinode/dev/button-sensor.h delete mode 100644 platform/sensinode/dev/leds-arch.c delete mode 100644 platform/sensinode/dev/m25p16.c delete mode 100644 platform/sensinode/dev/m25p16.h delete mode 100644 platform/sensinode/dev/models.c delete mode 100644 platform/sensinode/dev/models.h delete mode 100644 platform/sensinode/dev/n740.c delete mode 100644 platform/sensinode/dev/n740.h delete mode 100644 platform/sensinode/dev/sensinode-sensors.c delete mode 100644 platform/sensinode/dev/sensinode-sensors.h delete mode 100644 platform/sensinode/dev/slip-arch.c delete mode 100644 platform/sensinode/disco.c delete mode 100644 platform/sensinode/disco.h delete mode 100644 platform/sensinode/putchar.c delete mode 100644 platform/sensinode/segment.rules delete mode 100644 platform/sensinode/uip-debug.c delete mode 100644 platform/sensinode/viztool.c delete mode 100644 tools/sensinode/nano_programmer/Makefile delete mode 100755 tools/sensinode/nano_programmer/README.md delete mode 100644 tools/sensinode/nano_programmer/cdi_program.c delete mode 100644 tools/sensinode/nano_programmer/ihex.c delete mode 100644 tools/sensinode/nano_programmer/ihex.h delete mode 100644 tools/sensinode/nano_programmer/linux/port.c delete mode 100755 tools/sensinode/nano_programmer/nano_programmer delete mode 100644 tools/sensinode/nano_programmer/port.h delete mode 100644 tools/sensinode/nano_programmer/programmer.c delete mode 100644 tools/sensinode/nano_programmer/programmer.h delete mode 100644 tools/sensinode/nano_programmer/windows/port.c delete mode 100644 tools/sensinode/nano_usb_programmer/Makefile delete mode 100644 tools/sensinode/nano_usb_programmer/README.md delete mode 100644 tools/sensinode/nano_usb_programmer/Rules.make delete mode 100644 tools/sensinode/nano_usb_programmer/cdi.c delete mode 100644 tools/sensinode/nano_usb_programmer/cdi.h delete mode 100644 tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h delete mode 100644 tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h delete mode 100644 tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h delete mode 100644 tools/sensinode/nano_usb_programmer/ihex.c delete mode 100644 tools/sensinode/nano_usb_programmer/ihex.h delete mode 100644 tools/sensinode/nano_usb_programmer/main.c delete mode 100644 tools/sensinode/nano_usb_programmer/prog.c delete mode 100644 tools/sensinode/nano_usb_programmer/prog.h diff --git a/cpu/cc2430/8051def.h b/cpu/cc2430/8051def.h deleted file mode 100644 index f0acda7b9..000000000 --- a/cpu/cc2430/8051def.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * \file - * This file contains a set of configuration for using SDCC as a compiler. - * Modified from z80 port for cc2430 port. - * - * \author - * Takahide Matsutsuka (Original) - * George Oikonomou - - * (recent updates for the sensinode/cc2430 port) - */ - -#ifndef E051_DEF_H_ -#define E051_DEF_H_ - -#include - -/* This port no longer implements the legacy clock_delay. Hack its usages - * outta the way till it gets phased out completely - * NB: This also overwrites the prototype so delay_usec() is declared twice */ -#define clock_delay(t) clock_delay_usec(t) - -/* - * lint - style defines to help syntax parsers with sdcc-specific 8051 code - * They don't interfere with actual compilation - */ -#if !defined(__SDCC_mcs51) && !defined(SDCC_mcs51) -#define __data -#define __xdata -#define __code -#define __bit bool -#define __sfr volatile unsigned char -#define __sbit volatile bool -#define __critical -#define __at(x) -#define __using(x) -#define __interrupt(x) -#define __naked -#endif - -#define CC_CONF_FUNCTION_POINTER_ARGS 1 -#define CC_CONF_VA_ARGS 1 -#define CC_CONF_UNSIGNED_CHAR_BUGS 0 -#define CC_CONF_REGISTER_ARGS 0 -#define CC_CONF_FUNCTION_POINTER_KEYWORD __reentrant -#define CC_CONF_NON_BANKED_OPTIMIZATION 1 - -#if (defined(__SDCC_mcs51) || defined(SDCC_mcs51)) && CC_CONF_NON_BANKED_OPTIMIZATION -#define CC_NON_BANKED __nonbanked -#else -#define CC_NON_BANKED -#endif - -/* - * Max Stack Depth manipulation. It is possible to get up to 247 bytes - * allocated for the stack if: - * - You set this to 1 and - * - You have a patched toolchain and - * - You don't use __bit variables - * - You do not link libraries using BIT registers (e.g. printf_large) - * Enabling this will mean ISRs will NOT push bits (#pragma exclude bits) so - * make sure you know what you're doing - * - * More information on the wiki - */ -#define CC_CONF_OPTIMIZE_STACK_SIZE 0 - -#if CC_CONF_OPTIMIZE_STACK_SIZE -#define CC_AT_DATA -#else -#define CC_AT_DATA __data -#endif - -/* Generic types. */ -typedef unsigned short uip_stats_t; - -/* Time type. */ -typedef unsigned short clock_time_t; -#define MAX_TICKS (~((clock_time_t)0) / 2) -/* Defines tick counts for a second. */ -#define CLOCK_CONF_SECOND 128 - -/* Compiler configurations */ -#define CCIF -#define CLIF - -/* Single asm instruction without messing up syntax highlighting */ -#if defined(__SDCC_mcs51) || defined(SDCC_mcs51) -#define ASM(x) __asm \ - x \ - __endasm -#else -#define ASM(x) -#endif - -/* Critical section management */ -#define DISABLE_INTERRUPTS() do {EA = 0;} while(0) -#define ENABLE_INTERRUPTS() do {EA = 1;} while(0) - -/* Macro for a soft reset. */ -#define SOFT_RESET() do {((void (__code *) (void)) 0x0000) ();} while(0) - -/* We don't provide architecture-specific checksum calculations */ -#define UIP_ARCH_ADD32 0 -#define UIP_ARCH_CHKSUM 0 - -#define CC_CONF_ASSIGN_AGGREGATE(dest, src) \ - memcpy(dest, src, sizeof(*dest)) - -#define uip_ipaddr_copy(dest, src) \ - memcpy(dest, src, sizeof(*dest)) - -#endif /* E051_DEF_H_ */ diff --git a/cpu/cc2430/Makefile.cc2430 b/cpu/cc2430/Makefile.cc2430 deleted file mode 100644 index 1a1c12b1e..000000000 --- a/cpu/cc2430/Makefile.cc2430 +++ /dev/null @@ -1,116 +0,0 @@ -### Compiler definitions -CC = sdcc -LD = sdcc -AS = sdcc -AR = sdar -OBJCOPY = objcopy -STRIP = strip -PACKIHX = packihx -BANK_ALLOC = $(CONTIKI)/cpu/cc2430/bank-alloc.py -SEGMENT_RULES = $(OBJECTDIR)/segment.rules - -CFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --std-c99 -CFLAGS += --fomit-frame-pointer - -### Disable warning 110 (EVELYN the modified dog) and 126 (unreachable code) -CFLAGS += --disable-warning 110 --disable-warning 126 - -LDFLAGS += --model-$(MEMORY_MODEL) --stack-auto -DSDCC_CC2430 --out-fmt-ihx -LDFLAGS += --xram-loc 0xE000 --xram-size 0x1F00 -LDFLAGS += --code-loc $(START_ADDR) --code-size $(CODE_SIZE) - -ASFLAGS += -plosgff - -AROPTS = -rc - -### Our object files are .rel, so we can't use the default finalize dependency -### generation. Override here. -define FINALIZE_SDCC_DEPENDENCY -cp $(@:.rel=.d) $(@:.rel=.$$$$); \ -sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:.rel=.$$$$) >> $(@:.rel=.d); \ -rm -f $(@:.rel=.$$$$) -endef - -### Banking Guesswork: -### Examples outside examples/sensinode do not specify banking. -### We automatically turn it on if its unspecified and if we are building with -### CONTIKI_WITH_IPV6 -ifndef HAVE_BANKING - ifeq ($(CONTIKI_WITH_IPV6),1) - HAVE_BANKING=1 - else - HAVE_BANKING=0 - endif -endif - -### Does the project want us to offset the firmware? -### define start address and max code size accordingly, turn Disco on -ifeq ($(OFFSET_FIRMWARE),1) - START_ADDR = 0x01000 - HOME_START = 00001000 - ifeq ($(HAVE_BANKING),1) - CODE_SIZE = 0x1F000 - else - CODE_SIZE = 0x0F000 - endif -else - START_ADDR = 0x00000 - HOME_START = 00000000 - ifeq ($(HAVE_BANKING),1) - CODE_SIZE = 0x20000 - else - CODE_SIZE = 0x10000 - endif -endif - -### Are we building with BANKing supoprt? -ifeq ($(HAVE_BANKING),1) - ## Yes - MEMORY_MODEL=huge - LDFLAGS += -Wl-bBANK1=0x018000 - LD_POST_FLAGS += -Wl-bBANK2=0x028000 - LD_POST_FLAGS += -Wl-bBANK3=0x038000 - LDFLAGS += -Wl-r - CFLAGS += -DHAVE_SDCC_BANKING - #use this in $(call c_seg,$<) to get segment for a source file. - c_seg = --codeseg $(shell python $(BANK_ALLOC) $1 $(SEGMENT_RULES) $2) -else - ## No banking - MEMORY_MODEL=large - c_seg = -endif - -### CPU-dependent cleanup files -CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex -CLEAN += *.omf *.cdb *.banks -CLEAN += symbols.c symbols.h - -### CPU-dependent directories -CONTIKI_CPU_DIRS = . dev - -### CPU-dependent source files -CONTIKI_SOURCEFILES += bus.c clock.c uart0.c uart1.c cc2430_rf.c dma.c -CONTIKI_SOURCEFILES += uart_intr.c cc2430_rf_intr.c dma_intr.c -CONTIKI_SOURCEFILES += watchdog-cc2430.c rtimer-arch.c stack.c -CONTIKI_ASMFILES += - -CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel)) - -CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(CONTIKI_CASMFILES:.cS=.rel)) - -CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \ - $(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS)) - -CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, \ - $(CONTIKI_CPU_DIRS)) - -oname = $(patsubst %.c,%.rel,$(patsubst %.S,%.rel,$(1))) - -CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(call oname, $(CONTIKI_SOURCEFILES))) - -PROJECT_OBJECTFILES = $(addprefix $(OBJECTDIR)/, \ - $(call oname, $(PROJECT_SOURCEFILES))) - diff --git a/cpu/cc2430/Makefile.customrules-cc2430 b/cpu/cc2430/Makefile.customrules-cc2430 deleted file mode 100644 index 68ed21c60..000000000 --- a/cpu/cc2430/Makefile.customrules-cc2430 +++ /dev/null @@ -1,63 +0,0 @@ -### Compilation rules - -SEGMENT_RULE_FILES = $(foreach dir, . $(CONTIKI_PLATFORM_DIRS) \ - $(CONTIKI_CPU_DIRS_LIST), $(wildcard $(dir)/segment.rules) ) - -# NB: Assumes SEGMENT_RULES was not overridden and is in $(OBJECTDIR) -$(SEGMENT_RULES): $(SEGMENT_RULE_FILES) | $(OBJECTDIR) - cat $(SEGMENT_RULE_FILES) | \ - sed -e 's/#.*$$//' -e 's/^\s*//' -e '/^$$/d' > $@ - -CUSTOM_RULE_LINK=1 -CUSTOM_RULE_C_TO_OBJECTDIR_O=1 -CUSTOM_RULE_ALLOBJS_TO_TARGETLIB=1 - -$(OBJECTDIR)/%.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR) - $(TRACE_CC) - $(Q)$(CC) $(call c_seg,$<,$@) $(CFLAGS) -c $< -o $@ -Wp,-MMD,$(@:.rel=.d),-MQ,$@ - @$(FINALIZE_SDCC_DEPENDENCY) - -contiki-$(TARGET).lib: $(CONTIKI_OBJECTFILES) $(PROJECT_OBJECTFILES) \ - $(CONTIKI_ASMOBJECTFILES) $(CONTIKI_CASMOBJECTFILES) - rm -f $@ - for target in $^; do echo $$target >> $@; done - -.PRECIOUS: %.$(TARGET) %.hex - -# build app/example local object files. We need a separate rule so that we can -# pass -DAUTOSTART_ENABLE for those files only -$(OBJECTDIR)/%.app.rel: %.c $(SEGMENT_RULES) | $(OBJECTDIR) - $(TRACE_CC) - $(Q)$(CC) $(call c_seg,$<,$@) -DAUTOSTART_ENABLE $(CFLAGS) -c $< -o $@ - -# .ihx is the sdcc binary output file -%.ihx: $(OBJECTDIR)/%.app.rel $(CONTIKI_TARGET_MAIN) contiki-$(TARGET).lib -# Automatic bank relocation when building banked code -ifeq ($(HAVE_BANKING),1) - @echo "\nFirst Link" - @echo "===============" - $(TRACE_LD) - $(Q)$(LD) $(LDFLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib - @echo "\nBank Allocation" - @echo "===============" - python $(BANK_ALLOC) $(basename $(@F)) $(SEGMENT_RULES) $(OFFSET_FIRMWARE) - @echo "\nFinal Link" - @echo "===============" -endif - $(TRACE_LD) - $(Q)$(LD) $(LDFLAGS) $(LD_POST_FLAGS) -o $@ $(CONTIKI_TARGET_MAIN) $(OBJECTDIR)/$*.app.rel -llibsdcc.lib -lcontiki-$(TARGET).lib - -# Pack the hex file for programmers which dislike SDCC output hex format -%.hex: %.ihx - @echo "\nPack hex file" - @echo "===============" -ifeq ($(HAVE_BANKING),1) - srec_cat -disable_sequence_warnings $< -intel -crop 0x10000 0x1FFFF -offset -0x10000 -o bank1.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x20000 0x2FFFF -offset -0x18000 -o bank2.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x30000 0x3FFFF -offset -0x20000 -o bank3.hex -intel - srec_cat -disable_sequence_warnings $< -intel -crop 0x00000 0x0FFFF -o home.ihx -intel - srec_cat home.ihx -intel bank1.hex -intel bank2.hex -intel bank3.hex -intel -o $@ -intel - rm -f home.ihx bank1.hex bank2.hex bank3.hex -else - $(PACKIHX) $< > $@ -endif diff --git a/cpu/cc2430/bank-alloc.py b/cpu/cc2430/bank-alloc.py deleted file mode 100644 index 10e452577..000000000 --- a/cpu/cc2430/bank-alloc.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2010, Loughborough University - Computer Science -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the Institute nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# This file is part of the Contiki operating system. - -# \file -# Automatic allocation of modules to code segments for bankable builds -# with SDCC's huge memory model. -# -# \author -# George Oikonomou - -import sys -import re -import operator -import fileinput -import os - -# Open a module object file (.rel) and read it's code size -def retrieve_module_size(file_name): - size_pat = re.compile('^A\s+(?:HOME|BANK[0-9])\s+size\s+([1-9A-F][0-9A-F]*)') - for code_line in open(file_name): - matches = size_pat.search(code_line) - if matches is not None: - return int(matches.group(1), 16) - return 0 - -# Searches for a code segment rule for file_name in the segment_rules file -# If there is a rule, we respect it. Otherwise, we can move the file around -def get_source_seg(source_file, object_file, segment_rules): - for line in open(segment_rules): - tokens = line.split(None) - match = re.search(tokens[1], source_file) - if match is not None: - # Save it in basename.seg - base, ext = os.path.splitext(object_file) - of = open(base + '.seg', 'w') - of.write(tokens[0] + '\n') - of.close - return tokens[0] - return None - -# If segment.rules specified a rule for a source file, the respective object -# file's banking requirement will be stored in object_file.seg -def get_object_seg(object_file): - base, ext = os.path.splitext(object_file) - seg = base + '.seg' - bank = None - if os.path.isfile(seg) is True: - of = open(base + '.seg', 'r') - bank = of.readline().strip() - of.close() - return bank - -# Open project.mem and retreive the project's total code footprint -def get_total_size(project): - mem_file = project + '.mem' - pat = re.compile('FLASH\s+(0x[0-9a-f]+\s+){2}([0-9]+)') - for line in open(mem_file): - l = pat.search(line) - if l is not None: - return int(l.group(2)) - -# Open project.map and retrieve the list of modules linked in -# This will only consider contiki sources, not SDCC libraries -# NB: Sometimes object filenames get truncated: -# contiki-sensinode.lib [ obj_sensinode/watchdog-cc2430.re ] -# See how for this file the 'l' in 'rel' is missing. For that reason, we retrieve -# the filaname until the last '.' but without the extension and we append 'rel' -# As long as the filename doesn't get truncated, we're good -def populate(project, modules, segment_rules, bins): - bankable_total = 0 - user_total = 0 - - map_file = project + '.map' - file_pat = re.compile('obj_sensinode[^ ]+\.') - for line in open(map_file): - file_name = file_pat.search(line) - if file_name is not None: - mod = file_name.group(0) + 'rel' - code_size = retrieve_module_size(mod) - seg = get_object_seg(mod) - if seg is not None: - # This module has been assigned to a bank by the user - #print 'In', seg, file_name.group(0), 'size', code_size - bins[seg][0] += code_size - user_total += code_size - else: - # We are free to allocate this module - modules.append([mod, code_size, "NONE"]) - bankable_total += code_size - return bankable_total, user_total - -# Allocate bankable modules to banks according to a simple -# 'first fit, decreasing' bin packing heuristic. -def bin_pack(modules, bins, offset, log): - if offset==1: - bins['HOME'][1] -= 4096 - - # Sort by size, descending, in=place - modules.sort(key=operator.itemgetter(1), reverse=True) - - for module in modules: - # We want to iterate in a specific order and dict.keys() won't do that - for bin_id in ['BANK1', 'BANK2', 'BANK3', 'HOME']: - if bins[bin_id][0] + module[1] < bins[bin_id][1]: - bins[bin_id][0] += module[1] - module[2] = bin_id - log.writelines(' '.join([module[2].ljust(8), \ - str(module[1]).rjust(5), module[0], '\n'])) - break - else: - if bin_id == 'HOME': - print "Failed to allocate", module[0], "with size", module[1], \ - "to a code bank. This is fatal" - return 1 - return 0 - -# Hack the new bank directly in the .rel file -def relocate(module, bank): - code_pat = re.compile('(A\s+)(?:HOME|BANK[0-9])(\s+size\s+[1-9A-F][0-9A-F]*.+\n)') - - for line in fileinput.input(module, inplace=1): - m = code_pat.search(line) - if m is not None: - line = m.group(1) + bank + m.group(2) - sys.stdout.write(line) - return - -if len(sys.argv) < 3: - print 'Usage:' - print 'bank-alloc.py project path_to_segment_rules [offset]' - print 'bank-alloc.py source_file path_to_segment_rules object_file' - sys.exit(1) - -modules = list() -file_name = sys.argv[1] -segment_rules = sys.argv[2] - -# Magic: Guess whether we want to determine the code bank for a code file -# or whether we want to bin-pack -basename, ext = os.path.splitext(file_name) -if ext == '.c': - # Code Segment determination - if len(sys.argv) < 4: - print 'Usage:' - print 'bank-alloc.py project path_to_segment_rules [offset]' - print 'bank-alloc.py source_file path_to_segment_rules object_file' - sys.exit(1) - object_file = sys.argv[3] - seg = get_source_seg(file_name, object_file, segment_rules) - if seg is None: - print "BANK1" - else: - print seg - exit() - -# Bin-Packing -offset = 0 -if len(sys.argv) > 3 and sys.argv[3] is not None: - offset = int(sys.argv[3]) - -sizes = {'total': 0, 'bankable': 0, 'user': 0, 'libs': 0} - -# Name : [Allocated, capacity] -bins = { - 'HOME': [0, 32768], - 'BANK1': [0, 32768], - 'BANK2': [0, 32768], - 'BANK3': [0, 30720] -} - -sizes['total'] = get_total_size(basename) -sizes['bankable'], sizes['user'] = populate(basename, modules, segment_rules, bins) -sizes['libs'] = sizes['total'] - sizes['bankable'] - sizes['user'] - -print 'Total Size =', sizes['total'], 'bytes (' + \ - str(sizes['bankable']), 'bankable,', \ - str(sizes['user']), 'user-allocated,', \ - str(sizes['libs']), 'const+libs)' - -bins['HOME'][0] += sizes['libs'] - -print 'Preallocations: HOME=' + str(bins['HOME'][0]) + \ - ', BANK1=' + str(bins['BANK1'][0]) + ', BANK2=' + str(bins['BANK2'][0]) + \ - ', BANK3=' + str(bins['BANK3'][0]) - -# Open a log file -of = open(basename + '.banks', 'w') -pack = bin_pack(modules, bins, offset, of) -of.close() - -print "Bin-Packing results (target allocation):" -print "Segment - max - alloc" -for bin_id in ['HOME', 'BANK1', 'BANK2', 'BANK3']: - print bin_id.rjust(7), str(bins[bin_id][1]).rjust(6), str(bins[bin_id][0]).rjust(6) - -if pack > 0: - sys.exit(1) - -# If we reach here we seem to have a sane allocation. Start changing .rel files -for module in modules: - relocate(module[0], module[2]) diff --git a/cpu/cc2430/cc2430_sfr.h b/cpu/cc2430/cc2430_sfr.h deleted file mode 100644 index 53581cd29..000000000 --- a/cpu/cc2430/cc2430_sfr.h +++ /dev/null @@ -1,709 +0,0 @@ -/** - * - * \file cc2430_sfr.h - * \brief CC2430 registers header file for CC2430. - * - * Definitions for CC2430 SFR registers. - * - * - */ - -#ifndef REG_CC2430_H -#define REG_CC2430_H - -#include "8051def.h" - -/* BYTE Register */ - -__sfr __at (0x80) P0 ; -/* P0 */ -__sbit __at (0x87) P0_7 ; -__sbit __at (0x86) P0_6 ; -__sbit __at (0x85) P0_5 ; -__sbit __at (0x84) P0_4 ; -__sbit __at (0x83) P0_3 ; -__sbit __at (0x82) P0_2 ; -__sbit __at (0x81) P0_1 ; -__sbit __at (0x80) P0_0 ; - -__sfr __at (0x81) SP ; -__sfr __at (0x82) DPL0 ; -__sfr __at (0x83) DPH0 ; -/*DPL and DPH correspond DPL0 and DPH0 (82-83)*/ -__sfr __at (0x84) DPL1; -__sfr __at (0x85) DPH1; -__sfr __at (0x86) U0CSR; -#define U_MODE 0x80 -#define U_RE 0x40 -#define U_SLAVE 0x20 -#define U_FE 0x10 -#define U_ERR 0x08 -#define U_RXB 0x04 -#define U_TXB 0x02 -#define U_ACTIVE 0x01 - -__sfr __at (0x87) PCON ; -/* PCON (0x87) */ -#define IDLE 0x01 - -__sfr __at (0x88) TCON ; -/* TCON (0x88) */ -__sbit __at (0x8F) TCON_URX1IF; -/*__sbit __at (0x8E) RES;*/ -__sbit __at (0x8D) TCON_ADCIF; -/*__sbit __at (0x8C) RES;*/ -__sbit __at (0x8B) TCON_URX0IF; -__sbit __at (0x8A) TCON_IT1; -__sbit __at (0x89) TCON_RFERRIF; -__sbit __at (0x88) TCON_IT0; - - -__sfr __at (0x89) P0IFG; -__sfr __at (0x8A) P1IFG; -__sfr __at (0x8B) P2IFG; -__sfr __at (0x8C) PICTL; -/*PICTL bits*/ -#define PADSC 0x40 -#define P2IEN 0x20 -#define P0IENH 0x10 -#define P0IENL 0x08 -#define P2ICON 0x04 -#define P1ICON 0x02 -#define P0ICON 0x01 - -__sfr __at (0x8D) P1IEN; -__sfr __at (0x8F) P0INP; - -__sfr __at (0x90) P1 ; -/* P1 */ -__sbit __at (0x90) P1_0 ; -__sbit __at (0x91) P1_1 ; -__sbit __at (0x92) P1_2 ; -__sbit __at (0x93) P1_3 ; -__sbit __at (0x94) P1_4 ; -__sbit __at (0x95) P1_5 ; -__sbit __at (0x96) P1_6 ; -__sbit __at (0x97) P1_7 ; - -__sfr __at (0x91) RFIM; -__sfr __at (0x92) DPS; -__sfr __at (0x93) _XPAGE; /*MPAGE as paging register for sdcc*/ -__sfr __at (0x94) T2CMP; -__sfr __at (0x95) ST0; -__sfr __at (0x96) ST1; -__sfr __at (0x97) ST2; -__sfr __at (0x98) S0CON ; - -__sbit __at (0x99) S0CON_ENCIF_1; -__sbit __at (0x98) S0CON_ENCIF_0; - -__sfr __at (0x99) HSRC; -__sfr __at (0x9A) IEN2; -/*IEN2 bits*/ -#define WDTIE 0x20 -#define P1IE 0x10 -#define UTX1IE 0x08 -#define UTX0IE 0x04 -#define P2IE 0x02 -#define RFIE 0x01 -__sfr __at (0x9B) S1CON; -/*S1CON bits*/ -#define RFIF_1 0x02 -#define RFIF_0 0x01 -__sfr __at (0x9C) T2PEROF0; -__sfr __at (0x9D) T2PEROF1; -__sfr __at (0x9E) T2PEROF2; -/*T2PEROF2 bits*/ -#define CMPIM 0x80 -#define PERIM 0x40 -#define OFCMPIM 0x20 - -#define PEROF23 0x08 -#define PEROF22 0x04 -#define PEROF21 0x02 -#define PEROF20 0x01 - -__sfr __at (0x9F) FMAP; -__sfr __at (0x9F) PSBANK; - -__sfr __at (0xA0) P2 ; -/* P2 */ -__sbit __at (0xA0) P2_0 ; -__sbit __at (0xA1) P2_1 ; -__sbit __at (0xA2) P2_2 ; -__sbit __at (0xA3) P2_3 ; -__sbit __at (0xA4) P2_4 ; -/*__sbit __at (0xA5) P2_5 ; -__sbit __at (0xA6) P2_6 ; -__sbit __at (0xA7) P2_7 ;*/ - -__sfr __at (0xA1) T2OF0; -__sfr __at (0xA2) T2OF1; -__sfr __at (0xA3) T2OF2; -__sfr __at (0xA4) T2CAPLPL; -__sfr __at (0xA5) T2CAPHPH; -__sfr __at (0xA6) T2TLD; -__sfr __at (0xA7) T2THD; - -__sfr __at (0xA8) IE ; -__sfr __at (0xA8) IEN0; -/*IEN0 bits*/ -#define IEN0_EA_MASK 0x80 -#define STIE 0x20 -#define ENCIE 0x10 -#define URX1IE 0x08 -#define URX0IE 0x04 -#define ADCIE 0x02 -#define RFERRIE 0x01 -/* IEN0 (0xA8) */ -__sbit __at (0xAF) EA; -__sbit __at (0xAF) IEN0_EA; -/*__sbit __at (0xAE) RES;*/ -__sbit __at (0xAD) IEN0_STIE; -__sbit __at (0xAC) IEN0_ENCIE; -__sbit __at (0xAB) IEN0_URX1IE; -__sbit __at (0xAA) IEN0_URX0IE; -__sbit __at (0xA9) IEN0_ADCIE; -__sbit __at (0xA8) IEN0_RFERRIE; - -__sfr __at (0xA9) IP0; -/*IP0 bits*/ -#define IP0_5 0x20 -#define IP0_4 0x10 -#define IP0_3 0x08 -#define IP0_2 0x04 -#define IP0_1 0x02 -#define IP0_0 0x01 -__sfr __at (0xAB) FWT; -__sfr __at (0xAC) FADDRL; -__sfr __at (0xAD) FADDRH; - -__sfr __at (0xAE) FCTL; -#define F_BUSY 0x80 -#define F_SWBSY 0x40 -#define F_CONTRD 0x10 -#define F_WRITE 0x02 -#define F_ERASE 0x01 -__sfr __at (0xAF) FWDATA; - -/*No port 3 (0xB0)*/ -__sfr __at (0xB1) ENCDI; -__sfr __at (0xB2) ENCDO; -__sfr __at (0xB3) ENCCS; -#define CCS_MODE2 0x40 -#define CCS_MODE1 0x20 -#define CCS_MODE0 0x10 -#define CCS_RDY 0x08 -#define CCS_CMD1 0x04 -#define CCS_CMD0 0x02 -#define CCS_ST 0x01 -__sfr __at (0xB4) ADCCON1; -/*ADCCON1 bits*/ -#define ADEOC 0x80 -#define ADST 0x40 -#define ADSTS1 0x20 -#define ADSTS0 0x10 -#define ADRCTRL1 0x08 -#define ADRCTRL0 0x04 -__sfr __at (0xB5) ADCCON2; -/*ADCCON2 bits*/ -#define ADSREF1 0x80 -#define ADSREF0 0x40 -#define ADSDIV1 0x20 -#define ADSDIV0 0x10 -#define ADSCH3 0x08 -#define ADSCH2 0x04 -#define ADSCH1 0x02 -#define ADSCH0 0x01 -__sfr __at (0xB6) ADCCON3; -/*ADCCON3 bits*/ -#define ADEREF1 0x80 -#define ADEREF0 0x40 -#define ADEDIV1 0x20 -#define ADEDIV0 0x10 -#define ADECH3 0x08 -#define ADECH2 0x04 -#define ADECH1 0x02 -#define ADECH0 0x01 - -__sfr __at (0xB7) RCCTL; -#undef IP /*this is 0xb8 in base core*/ - -__sfr __at (0xB8) IEN1; -/*IEN1 bits*/ -#define P0IE 0x20 -#define T4IE 0x10 -#define T3IE 0x08 -#define T2IE 0x04 -#define T1IE 0x02 -#define DMAIE 0x01 -/* IEN1 (0xB8) */ -/*__sbit __at (0xBF) IEN1_RES;*/ -/*__sbit __at (0xBE) RES;*/ -__sbit __at (0xBD) IEN1_P0IE; -__sbit __at (0xBC) IEN1_T4IE; -__sbit __at (0xBB) IEN1_T3IE; -__sbit __at (0xBA) IEN1_T2IE; -__sbit __at (0xB9) IEN1_T1IE; -__sbit __at (0xB8) IEN1_DMAIE; - -__sfr __at (0xB9) IP1; -/*IP1 bits*/ -#define IP1_5 0x20 -#define IP1_4 0x10 -#define IP1_3 0x08 -#define IP1_2 0x04 -#define IP1_1 0x02 -#define IP1_0 0x01 - -__sfr __at (0xBA) ADCL; -__sfr __at (0xBB) ADCH; -__sfr __at (0xBC) RNDL; -__sfr __at (0xBD) RNDH; - -__sfr __at (0xBE) SLEEP; -#define OSC32K_CALDIS 0x80 -#define XOSC_STB 0x40 -#define HFRC_STB 0x20 -#define RST1 0x10 -#define RST0 0x08 -#define OSC_PD 0x04 -#define SLEEP_MODE1 0x02 -#define SLEEP_MODE0 0x01 - -__sfr __at (0xC0) IRCON; -/*IRCON bits*/ -#define STIF 0x80 -#define P0IF 0x20 -#define T4IF 0x10 -#define T3IF 0x08 -#define T2IF 0x04 -#define T1IF 0x02 -#define DMAIF 0x01 -/* IRCON */ -__sbit __at (0xC7) IRCON_STIF ; -/*__sbit __at (0x86) IRCON_6 ;*/ -__sbit __at (0xC5) IRCON_P0IF; -__sbit __at (0xC4) IRCON_T4IF; -__sbit __at (0xC3) IRCON_T3IF; -__sbit __at (0xC2) IRCON_T2IF; -__sbit __at (0xC1) IRCON_T1IF; -__sbit __at (0xC0) IRCON_DMAIF; - -__sfr __at (0xC1) U0BUF; - -__sfr __at (0xC2) U0BAUD; -__sfr __at (0xC3) T2CNF; -/*T2SEL bits*/ -#define CMPIF 0x80 -#define PERIF 0x40 -#define OFCMPIF 0x20 - -#define CMSEL 0x08 - -#define SYNC 0x02 -#define RUN 0x01 - -__sfr __at (0xC4) U0UCR; -#define U_FLUSH 0x80 -#define U_FLOW 0x40 -#define U_D9 0x20 -#define U_BIT9 0x10 -#define U_PARITY 0x08 -#define U_SPB 0x04 -#define U_STOP 0x02 -#define U_START 0x01 - -__sfr __at (0xC5) U0GCR; -#define U_CPOL 0x80 -#define U_CPHA 0x40 -#define U_ORDER 0x20 -#define U_BAUD_E4 0x10 -#define U_BAUD_E3 0x08 -#define U_BAUD_E2 0x04 -#define U_BAUD_E1 0x02 -#define U_BAUD_E0 0x01 - -__sfr __at (0xC6) CLKCON; -#define OSC32K 0x80 -#define OSC 0x40 -#define TICKSPD2 0x20 -#define TICKSPD1 0x10 -#define TICKSPD0 0x08 -#define CLKSPD 0x01 - -__sfr __at (0xC7) MEMCTR; -#define MUNIF 0x40 -__sfr __at (0xC8) T2CON; - -__sfr __at (0xC9) WDCTL; -#define WDT_CLR3 0x80 -#define WDT_CLR2 0x40 -#define WDT_CLR1 0x20 -#define WDT_CLR0 0x10 -#define WDT_EN 0x08 -#define WDT_MODE 0x04 -#define WDT_INT1 0x02 -#define WDT_INT0 0x01 - -__sfr __at (0xCA) T3CNT; - -__sfr __at (0xCB) T3CTL; -/*T3CTL bits*/ -#define T3DIV2 0x80 -#define T3DIV1 0x40 -#define T3DIV0 0x20 -#define T3START 0x10 -#define T3OVFIM 0x08 -#define T3CLR 0x04 -#define T3MODE1 0x02 -#define T3MODE0 0x01 - -__sfr __at (0xCC) T3CCTL0; -/*T3CCTL0 bits*/ -#define T3IM 0x40 -#define T3CMP2 0x20 -#define T3CMP1 0x10 -#define T3CMP0 0x08 -#define T3MODE 0x04 -#define T3CAP1 0x02 -#define T3CAP0 0x01 - -__sfr __at (0xCD) T3CC0; -__sfr __at (0xCE) T3CCTL1; -/*T3CCTL0 bits apply*/ -__sfr __at (0xCF) T3CC1; - -__sfr __at (0xD0) PSW ; -/* PSW */ -__sbit __at (0xD0) P ; -__sbit __at (0xD1) F1 ; -__sbit __at (0xD2) OV ; -__sbit __at (0xD3) RS0 ; -__sbit __at (0xD4) RS1 ; -__sbit __at (0xD5) F0 ; -__sbit __at (0xD6) AC ; -__sbit __at (0xD7) CY ; - -__sfr __at (0xD1) DMAIRQ; -/*DMAIRQ bits*/ -#define DMAIF4 0x10 -#define DMAIF3 0x08 -#define DMAIF2 0x04 -#define DMAIF1 0x02 -#define DMAIF0 0x01 - -__sfr __at (0xD2) DMA1CFGL; -__sfr __at (0xD3) DMA1CFGH; -__sfr __at (0xD4) DMA0CFGL; -__sfr __at (0xD5) DMA0CFGH; - -__sfr __at (0xD6) DMAARM; -/*DMAARM bits*/ -#define ABORT 0x80 -#define DMAARM4 0x10 -#define DMAARM3 0x08 -#define DMAARM2 0x04 -#define DMAARM1 0x02 -#define DMAARM0 0x01 - -__sfr __at (0xD7) DMAREQ; -/*DMAREQ bits*/ -#define DMAREQ4 0x10 -#define DMAREQ3 0x08 -#define DMAREQ2 0x04 -#define DMAREQ1 0x02 -#define DMAREQ0 0x01 - -__sfr __at (0xD8) TIMIF; -/*TIMIF bits*/ -#define OVFIM 0x40 -#define T4CH1IF 0x20 -#define T4CH0IF 0x10 -#define T4OVFIF 0x08 -#define T3CH1IF 0x04 -#define T3CH0IF 0x02 -#define T3OVFIF 0x01 - -__sfr __at (0xD9) RFD; -__sfr __at (0xDA) T1CC0L; -__sfr __at (0xDB) T1CC0H; -__sfr __at (0xDC) T1CC1L; -__sfr __at (0xDD) T1CC1H; -__sfr __at (0xDE) T1CC2L; -__sfr __at (0xDF) T1CC2H; - -__sfr __at (0xE0) ACC; -__sfr __at (0xE1) RFST; -__sfr __at (0xE2) T1CNTL; -__sfr __at (0xE3) T1CNTH; - -__sfr __at (0xE4) T1CTL; -/*T1CTL bits*/ -#define CH2IF 0x80 -#define CH1IF 0x40 -#define CH0IF 0x20 -#define OVFIF 0x10 -#define T1DIV1 0x08 -#define T1DIV0 0x04 -#define T1MODE1 0x02 -#define T1MODE0 0x01 - -__sfr __at (0xE5) T1CCTL0; -/*T1CCTL0 bits*/ -#define T1CPSEL 0x80 -#define T1IM 0x40 -#define T1CMP2 0x20 -#define T1CMP1 0x10 -#define T1CMP0 0x08 -#define T1MODE 0x04 -#define T1CAP1 0x02 -#define T1CAP0 0x01 - -__sfr __at (0xE6) T1CCTL1; -/*Bits defined in T1CCTL0 */ -__sfr __at (0xE7) T1CCTL2; -/*Bits defined in T1CCTL0 */ -__sfr __at (0xE8) IRCON2; -/*IRCON2 bits*/ -#define WDTIF 0x10 -#define P1IF 0x08 -#define UTX1IF 0x04 -#define UTX0IF 0x02 -#define P2IF 0x01 -/* IRCON 2 */ -/*__sbit __at (0xEF) IRCON2_P1_7 ; -__sbit __at (0xEE) IRCON2_P1_6 ; -__sbit __at (0xED) IRCON2_P1_5 ;*/ -__sbit __at (0xEC) IRCON2_WDTIF ; -__sbit __at (0xEB) IRCON2_P1IF ; -__sbit __at (0xEA) IRCON2_UTX1IF ; -__sbit __at (0xE9) IRCON2_UTX0IF ; -__sbit __at (0xE8) IRCON2_P2IF; - - -__sfr __at (0xE9) RFIF; -/*RFIF bits*/ -#define IRQ_RREG_ON 0x80 -#define IRQ_TXDONE 0x40 -#define IRQ_FIFOP 0x20 -#define IRQ_SFD 0x10 -#define IRQ_CCA 0x08 -#define IRQ_CSP_WT 0x04 -#define IRQ_CSP_STOP 0x02 -#define IRQ_CSP_INT 0x01 - -__sfr __at (0xEA) T4CNT; -__sfr __at (0xEB) T4CTL; -/*T4CTL bits*/ -#define T4DIV2 0x80 -#define T4DIV1 0x40 -#define T4DIV0 0x20 -#define T4START 0x10 -#define T4OVFIM 0x08 -#define T4CLR 0x04 -#define T4MODE1 0x02 -#define T4MODE0 0x01 - -__sfr __at (0xEC) T4CCTL0; -/*T4CCTL0 bits*/ -#define T4IM 0x40 -#define T4CMP2 0x20 -#define T4CMP1 0x10 -#define T4CMP0 0x08 -#define T4MODE 0x04 -#define T4CAP1 0x02 -#define T4CAP0 0x01 - -__sfr __at (0xED) T4CC0; -__sfr __at (0xEE) T4CCTL1; -/*T4CCTL0 bits apply*/ -__sfr __at (0xEF) T4CC1; - -__sfr __at (0xF0) B ; -__sfr __at (0xF1) PERCFG; -/*PERCFG bits*/ -#define T1CFG 0x40 -#define T3CFG 0x20 -#define T4CFG 0x10 -#define U1CFG 0x02 -#define U0CFG 0x01 - -__sfr __at (0xF2) ADCCFG; -/*ADCCFG bits*/ -#define ADC7EN 0x80 -#define ADC6EN 0x40 -#define ADC5EN 0x20 -#define ADC4EN 0x10 -#define ADC3EN 0x08 -#define ADC2EN 0x04 -#define ADC1EN 0x02 -#define ADC0EN 0x01 - -__sfr __at (0xF3) P0SEL; -__sfr __at (0xF4) P1SEL; -__sfr __at (0xF5) P2SEL; -/*P2SEL bits*/ -#define PRI3P1 0x40 -#define PRI2P1 0x20 -#define PRI1P1 0x10 -#define PRI0P1 0x08 -#define SELP2_4 0x04 -#define SELP2_3 0x02 -#define SELP2_0 0x01 - -__sfr __at (0xF6) P1INP; - -__sfr __at (0xF7) P2INP; -/*P2INP bits*/ -#define PDUP2 0x80 -#define PDUP1 0x40 -#define PDUP0 0x20 -#define MDP2_4 0x10 -#define MDP2_3 0x08 -#define MDP2_2 0x04 -#define MDP2_1 0x02 -#define MDP2_0 0x01 - -__sfr __at (0xF8) U1CSR; -__sfr __at (0xF9) U1BUF; -__sfr __at (0xFA) U1BAUD; -__sfr __at (0xFB) U1UCR; -__sfr __at (0xFC) U1GCR; -__sfr __at (0xFD) P0DIR; -__sfr __at (0xFE) P1DIR; - -__sfr __at (0xFF) P2DIR; -/*P2DIR bits*/ -#define PRI1P0 0x80 -#define PRI0P0 0x40 -#define DIRP2_4 0x10 -#define DIRP2_3 0x08 -#define DIRP2_2 0x04 -#define DIRP2_1 0x02 -#define DIRP2_0 0x01 - -/* IEN0 */ -/*__sbit __at (0xA8) EA ; -__sbit __at (0x99) TI ; -__sbit __at (0x9A) RB8 ; -__sbit __at (0x9B) TB8 ; -__sbit __at (0x9C) REN ; -__sbit __at (0x9D) SM2 ; -__sbit __at (0x9E) SM1 ; -__sbit __at (0x9F) SM0 ;*/ - - - -/* Interrupt numbers: address = (number * 8) + 3 */ -/*#undef IE0_VECTOR -#undef TF0_VECTOR -#undef IE1_VECTOR -#undef TF1_VECTOR -#undef SI0_VECTOR*/ - -/* CC2430 interrupt vectors */ -#define RFERR_VECTOR 0 -#define ADC_VECTOR 1 -#define URX0_VECTOR 2 -#define URX1_VECTOR 3 -#define ENC_VECTOR 4 -#define ST_VECTOR 5 -#define P2INT_VECTOR 6 -#define UTX0_VECTOR 7 -#define DMA_VECTOR 8 -#define T1_VECTOR 9 -#define T2_VECTOR 10 -#define T3_VECTOR 11 -#define T4_VECTOR 12 -#define P0INT_VECTOR 13 -#define UTX1_VECTOR 14 -#define P1INT_VECTOR 15 -#define RF_VECTOR 16 -#define WDT_VECTOR 17 - -/* RF control registers*/ -__xdata __at (0xDF02) unsigned char MDMCTRL0H; -__xdata __at (0xDF03) unsigned char MDMCTRL0L; -__xdata __at (0xDF04) unsigned char MDMCTRL1H; -__xdata __at (0xDF05) unsigned char MDMCTRL1L; -__xdata __at (0xDF06) unsigned char RSSIH; -__xdata __at (0xDF07) unsigned char RSSIL; -__xdata __at (0xDF08) unsigned char SYNCWORDH; -__xdata __at (0xDF09) unsigned char SYNCWORDL; -__xdata __at (0xDF0A) unsigned char TXCTRLH; -__xdata __at (0xDF0B) unsigned char TXCTRLL; -__xdata __at (0xDF0C) unsigned char RXCTRL0H; -__xdata __at (0xDF0D) unsigned char RXCTRL0L; -__xdata __at (0xDF0E) unsigned char RXCTRL1H; -__xdata __at (0xDF0F) unsigned char RXCTRL1L; -__xdata __at (0xDF10) unsigned char FSCTRLH; -__xdata __at (0xDF11) unsigned char FSCTRLL; -__xdata __at (0xDF12) unsigned char CSPX; -__xdata __at (0xDF13) unsigned char CSPY; -__xdata __at (0xDF14) unsigned char CSPZ; -__xdata __at (0xDF15) unsigned char CSPCTRL; -__xdata __at (0xDF16) unsigned char CSPT; -__xdata __at (0xDF17) unsigned char RFPWR; -#define ADI_RADIO_PD 0x10 -#define RREG_RADIO_PD 0x08 -#define RREG_DELAY_MASK 0x07 - -__xdata __at (0xDF20) unsigned char FSMTCH; -__xdata __at (0xDF21) unsigned char FSMTCL; -__xdata __at (0xDF22) unsigned char MANANDH; -__xdata __at (0xDF23) unsigned char MANANDL; -__xdata __at (0xDF24) unsigned char MANORH; -__xdata __at (0xDF25) unsigned char MANORL; -__xdata __at (0xDF26) unsigned char AGCCTRLH; -__xdata __at (0xDF27) unsigned char AGCCTRLL; - -__xdata __at (0xDF39) unsigned char FSMSTATE; -__xdata __at (0xDF3A) unsigned char ADCTSTH; -__xdata __at (0xDF3B) unsigned char ADCTSTL; -__xdata __at (0xDF3C) unsigned char DACTSTH; -__xdata __at (0xDF3D) unsigned char DACTSTL; - -__xdata __at (0xDF43) unsigned char IEEE_ADDR0; -__xdata __at (0xDF44) unsigned char IEEE_ADDR1; -__xdata __at (0xDF45) unsigned char IEEE_ADDR2; -__xdata __at (0xDF46) unsigned char IEEE_ADDR3; -__xdata __at (0xDF47) unsigned char IEEE_ADDR4; -__xdata __at (0xDF48) unsigned char IEEE_ADDR5; -__xdata __at (0xDF49) unsigned char IEEE_ADDR6; -__xdata __at (0xDF4A) unsigned char IEEE_ADDR7; -__xdata __at (0xDF4B) unsigned char PANIDH; -__xdata __at (0xDF4C) unsigned char PANIDL; -__xdata __at (0xDF4D) unsigned char SHORTADDRH; -__xdata __at (0xDF4E) unsigned char SHORTADDRL; -__xdata __at (0xDF4F) unsigned char IOCFG0; -__xdata __at (0xDF50) unsigned char IOCFG1; -__xdata __at (0xDF51) unsigned char IOCFG2; -__xdata __at (0xDF52) unsigned char IOCFG3; -__xdata __at (0xDF53) unsigned char RXFIFOCNT; -__xdata __at (0xDF54) unsigned char FSMTC1; -#define ABORTRX_ON_SRXON 0x20 -#define RX_INTERRUPTED 0x10 -#define AUTO_TX2RX_OFF 0x08 -#define RX2RX_TIME_OFF 0x04 -#define PENDING_OR 0x02 -#define ACCEPT_ACKPKT 0x01 - -__xdata __at (0xDF60) unsigned char CHVER; -__xdata __at (0xDF61) unsigned char CHIPID; -__xdata __at (0xDF62) unsigned char RFSTATUS; -#define TX_ACTIVE 0x10 -#define FIFO 0x08 -#define FIFOP 0x04 -#define SFD 0x02 -#define CCA 0x01 - -__xdata __at (0xDFC1) unsigned char U0BUF_SHADOW; - -__xdata __at (0xDFD9) unsigned char RFD_SHADOW; - -__xdata __at (0xDFF9) unsigned char U1BUF_SHADOW; - -__xdata __at (0xDFBA) unsigned int ADC_SHADOW; - -#endif /*REG_CC2430*/ diff --git a/cpu/cc2430/dev/bus.c b/cpu/cc2430/dev/bus.c deleted file mode 100644 index 0108cde58..000000000 --- a/cpu/cc2430/dev/bus.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Initialization functions for the 8051 bus - * \author - * Adam Dunkels - */ - -#include "cc2430_sfr.h" -#include "dev/bus.h" -#include "sys/clock.h" -#include "contiki-conf.h" - -/*---------------------------------------------------------------------------*/ -void -bus_init(void) -{ - CLKCON = (0x00 | OSC32K); /* 32k internal */ - while(CLKCON != (0x00 | OSC32K)); - - P1DIR |= 0x0E; - IEN0_EA = 1; - - /* Initialize the clock */ - clock_init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/bus.h b/cpu/cc2430/dev/bus.h deleted file mode 100644 index aa15cf0bd..000000000 --- a/cpu/cc2430/dev/bus.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * A brief description of what this file is. - * \author - * Adam Dunkels - */ - - -#ifndef BUS_H_ -#define BUS_H_ - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "contiki-conf.h" - -#define inline - -void bus_init(void); -void clock_ISR( void ) __interrupt (ST_VECTOR); - -#endif /* BUS_H_ */ diff --git a/cpu/cc2430/dev/cc2430_rf.c b/cpu/cc2430/dev/cc2430_rf.c deleted file mode 100644 index 7738cb34f..000000000 --- a/cpu/cc2430/dev/cc2430_rf.c +++ /dev/null @@ -1,750 +0,0 @@ -/** - * \file - * CC2430 RF driver - * \author - * Zach Shelby (Original) - * George Oikonomou - - * (port to the netstack API, hexdump output, RX FIFO overflow fixes - * code cleanup, ...) - * - * bankable code for cc2430 rf driver. this code can be placed in any bank. - * - */ - -#include - -#include "contiki.h" -#include "dev/radio.h" -#include "dev/cc2430_rf.h" -#include "cc2430_sfr.h" -#include "sys/clock.h" -#include "sys/rtimer.h" - -#include "net/packetbuf.h" -#include "net/rime/rimestats.h" -#include "net/netstack.h" - -#define CC2430_RF_TX_POWER_RECOMMENDED 0x5F -#ifdef CC2430_RF_CONF_TX_POWER -#define CC2430_RF_TX_POWER CC2430_RF_CONF_TX_POWER -#else -#define CC2430_RF_TX_POWER CC2430_RF_TX_POWER_RECOMMENDED -#endif - -#ifdef CC2430_RF_CONF_CHANNEL -#define CC2430_RF_CHANNEL CC2430_RF_CONF_CHANNEL -#else -#define CC2430_RF_CHANNEL 18 -#endif /* CC2430_RF_CONF_CHANNEL */ -#define CC2430_CHANNEL_MIN 11 -#define CC2430_CHANNEL_MAX 26 - -#ifdef CC2430_RF_CONF_AUTOACK -#define CC2430_RF_AUTOACK CC2430_RF_CONF_AUTOACK -#else -#define CC2430_RF_AUTOACK 1 -#endif - -#ifndef CC2430_CONF_CHECKSUM -#define CC2430_CONF_CHECKSUM 0 -#endif /* CC2420_CONF_CHECKSUM */ - -#if CC2430_CONF_CHECKSUM -#include "lib/crc16.h" -#define CHECKSUM_LEN 2 -#else -#define CHECKSUM_LEN 2 -#endif /* CC2430_CONF_CHECKSUM */ -#if DEBUG_LEDS -/* moved leds code to BANK1 to make space for cc2430_rf_process in HOME */ -/* can't call code in BANK1 from alternate banks unless it is marked with __banked */ -#include "dev/leds.h" -#define RF_RX_LED_ON() leds_on(LEDS_RED); -#define RF_RX_LED_OFF() leds_off(LEDS_RED); -#define RF_TX_LED_ON() leds_on(LEDS_GREEN); -#define RF_TX_LED_OFF() leds_off(LEDS_GREEN); -#else -#define RF_RX_LED_ON() -#define RF_RX_LED_OFF() -#define RF_TX_LED_ON() -#define RF_TX_LED_OFF() -#endif -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) do {} while (0) -#endif - -/* rf_flags bits */ -#define RX_ACTIVE 0x80 -#define TX_ACK 0x40 -#define TX_ON_AIR 0x20 -#define WAS_OFF 0x10 -#define INITIALISED 0x01 - -#define RX_NO_DMA -/* Bits of the last byte in the RX FIFO */ -#define CRC_BIT_MASK 0x80 -#define LQI_BIT_MASK 0x7F - -/* 192 ms, radio off -> on interval */ -#define ONOFF_TIME ((RTIMER_ARCH_SECOND / 3125) + 4) - -#if CC2430_RF_CONF_HEXDUMP -#include "uart1.h" -static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */ -#endif - -#ifdef HAVE_RF_ERROR -uint8_t rf_error = 0; -#endif - -/*---------------------------------------------------------------------------*/ -#if !NETSTACK_CONF_SHORTCUTS -PROCESS(cc2430_rf_process, "CC2430 RF driver"); -#endif -/*---------------------------------------------------------------------------*/ -static uint8_t CC_AT_DATA rf_flags; -static uint8_t rf_channel; - -static int on(void); /* prepare() needs our prototype */ -static int off(void); /* transmit() needs our prototype */ -static int channel_clear(void); /* transmit() needs our prototype */ -/*---------------------------------------------------------------------------*/ -/** - * Execute a single CSP command. - * - * \param command command to execute - * - */ -void -cc2430_rf_command(uint8_t command) -{ - if(command >= 0xE0) { /*immediate strobe*/ - uint8_t fifo_count; - switch (command) { /*hardware bug workaround*/ - case ISRFOFF: - case ISRXON: - case ISTXON: - fifo_count = RXFIFOCNT; - RFST = command; - clock_delay_usec(2); - if(fifo_count != RXFIFOCNT) { - RFST = ISFLUSHRX; - RFST = ISFLUSHRX; - } - break; - - default: - RFST = command; - } - } else if(command == SSTART) { - RFIF &= ~IRQ_CSP_STOP; /*clear IRQ flag*/ - RFST = SSTOP; /*make sure there is a stop in the end*/ - RFST = ISSTART; /*start execution*/ - while((RFIF & IRQ_CSP_STOP) == 0); - } else { - RFST = command; /*write command*/ - } -} -/*---------------------------------------------------------------------------*/ -static void -flush_rx() -{ - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISFLUSHRX); - -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RFIF &= ~IRQ_FIFOP; -} -/*---------------------------------------------------------------------------*/ -/** - * Select RF channel. - * - * \param channel channel number to select - * - * \return channel value or negative (invalid channel number) - */ - - /* channel freqdiv = (2048 + FSCTRL(9:0)) / 4 - freq = (2048 + FSCTRL(9:0)) MHz */ - -int8_t -cc2430_rf_channel_set(uint8_t channel) -{ - uint16_t freq; - - if((channel < 11) || (channel > 26)) { - return -1; - } - - cc2430_rf_command(ISSTOP); /*make sure CSP is not running*/ - cc2430_rf_command(ISRFOFF); - /* Channel values: 11-26 */ - freq = (uint16_t) channel - 11; - freq *= 5; /*channel spacing*/ - freq += 357; /*correct channel range*/ - freq |= 0x4000; /*LOCK_THR = 1*/ - FSCTRLH = (freq >> 8); - FSCTRLL = (uint8_t)freq; - - cc2430_rf_command(ISRXON); - - rf_channel = channel; - - return (int8_t) channel; -} -/*---------------------------------------------------------------------------*/ -uint8_t -cc2430_rf_channel_get() -{ - return rf_channel; -} -/*---------------------------------------------------------------------------*/ -/** - * Select RF transmit power. - * - * \param new_power new power level - * - * \return new level - */ -uint8_t -cc2430_rf_power_set(uint8_t new_power) -{ - /* Set transmitter power */ - TXCTRLL = new_power; - - return TXCTRLL; -} -/*---------------------------------------------------------------------------*/ -#if 0 /* unused */ -/** - * Enable RF transmitter. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ -int -cc2430_rf_tx_enable(void) -{ - DMAARM = 0x80 + (1 << 0); /*ABORT + channel bit*/ - - return 1; -} -#endif -/*---------------------------------------------------------------------------*/ -/** - * Set MAC addresses - * - * \param pan The PAN address to set - * \param addr The short address to set - * \param ieee_addr The 64-bit IEEE address to set - */ -void -cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr) -{ - uint8_t f; - __xdata unsigned char *ptr; - - PANIDH = pan >> 8; - PANIDL = pan & 0xff; - - SHORTADDRH = addr >> 8; - SHORTADDRL = addr & 0xff; - - if(ieee_addr != NULL) { - ptr = &IEEE_ADDR7; - /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ - for(f = 0; f < 8; f++) { - *ptr-- = ieee_addr[f]; - } - } -} -#if 0 /* currently unused */ -/*---------------------------------------------------------------------------*/ -/** - * Channel energy detect. - * - * Coordinator use this function detect best channel for PAN-network. - * \return RSSI-energy level dBm. - * \return 0 operation failed. - */ - -int8_t -cc2430_rf_analyze_rssi(void) -{ - int8_t retval = -128; - /*pause_us(128);*/ - - retval = (int8_t)RSSIL; - retval -= 45; - return retval; -} -#endif /* currently unused */ -/*---------------------------------------------------------------------------*/ -/** - * Send ACK. - * - *\param pending set up pending flag if pending > 0. - */ -void -cc2430_rf_send_ack(uint8_t pending) -{ - if(pending) { - cc2430_rf_command(ISACKPEND); - } else { - cc2430_rf_command(ISACK); - } -} -/*---------------------------------------------------------------------------*/ -/* Netstack API radio driver functions */ -/*---------------------------------------------------------------------------*/ -static int -init(void) -{ - if(rf_flags & INITIALISED) { - return 0; - } - - PRINTF("cc2430_rf_init called\n"); - - RFPWR &= ~RREG_RADIO_PD; /*make sure it's powered*/ - while((RFPWR & ADI_RADIO_PD) == 1); - while((RFIF & IRQ_RREG_ON) == 0); /*wait for power up*/ - SLEEP &= ~OSC_PD; /*Osc on*/ - while((SLEEP & XOSC_STB) == 0); /*wait for power up*/ - - rf_flags = 0; - - FSMTC1 = 1; /*don't abort reception, if enable called, accept ack, auto rx after tx*/ - - MDMCTRL0H = 0x0A; /* Generic client, standard hysteresis, decoder on 0x0a */ - MDMCTRL0L = 0xE2; /* automatic CRC, standard CCA and preamble 0xE2 */ -#if CC2430_RF_AUTOACK - MDMCTRL0L |= 0x10; -#endif - - MDMCTRL1H = 0x30; /* Defaults */ - MDMCTRL1L = 0x0; - - RXCTRL0H = 0x32; /* RX tuning optimized */ - RXCTRL0L = 0xf5; - - cc2430_rf_channel_set(CC2430_RF_CHANNEL); - cc2430_rf_command(ISFLUSHTX); - cc2430_rf_command(ISFLUSHRX); - - /* Temporary values, main() will sort this out later on */ - cc2430_rf_set_addr(0xffff, 0x0000, NULL); - - RFIM = IRQ_FIFOP; - RFIF &= ~(IRQ_FIFOP); - - S1CON &= ~(RFIF_0 | RFIF_1); -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif - - /* If contiki-conf.h turns on the RFERR interrupt, enable it here */ -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RF_TX_LED_OFF(); - RF_RX_LED_OFF(); - - rf_flags |= INITIALISED; - -#if !NETSTACK_CONF_SHORTCUTS - process_start(&cc2430_rf_process, NULL); -#endif - - cc2430_rf_power_set(CC2430_RF_TX_POWER); - - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -prepare(const void *payload, unsigned short payload_len) -{ - uint8_t i; - /* - * When we transmit in very quick bursts, make sure previous transmission - * is not still in progress before re-writing in the TX FIFO - */ - while(RFSTATUS & TX_ACTIVE); - - if(rf_flags & TX_ACK) { - return -1; - } - - if((rf_flags & RX_ACTIVE) == 0) { - on(); - } - - PRINTF("cc2430_rf: sending %u byte payload\n", payload_len); - - cc2430_rf_command(ISFLUSHTX); - PRINTF("cc2430_rf: data = "); - /* Send the phy length byte first */ - RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */ - PRINTF("(%d)", payload_len + CHECKSUM_LEN); - for(i = 0; i < payload_len; i++) { - RFD = ((unsigned char *)(payload))[i]; - PRINTF("%02X", ((unsigned char *)(payload))[i]); - } - PRINTF("\n"); - - /* Leave space for the FCS */ - RFD = 0; - RFD = 0; - - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -transmit(unsigned short transmit_len) -{ - uint8_t counter; - int ret = RADIO_TX_ERR; - - if(!(rf_flags & RX_ACTIVE)) { - on(); - rf_flags |= WAS_OFF; - } - - if(channel_clear() == CC2430_CCA_BUSY) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; - } - - /* - * prepare() double checked that TX_ACTIVE is low. If SFD is high we are - * receiving. Abort transmission and bail out with RADIO_TX_COLLISION - */ - if(RFSTATUS & SFD) { - RIMESTATS_ADD(contentiondrop); - return RADIO_TX_COLLISION; - } - - /* Start the transmission */ - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); - - cc2430_rf_command(ISTXON); - counter = 0; - while(!(RFSTATUS & TX_ACTIVE) && (counter++ < 3)) { - clock_delay_usec(6); - } - - if(!(RFSTATUS & TX_ACTIVE)) { - PRINTF("cc2430_rf: TX never active.\n"); - cc2430_rf_command(ISFLUSHTX); - ret = RADIO_TX_ERR; - } else { - /* Wait for the transmission to finish */ - while(RFSTATUS & TX_ACTIVE); - RF_RX_LED_OFF(); - RF_TX_LED_ON(); - ret = RADIO_TX_OK; - // rf_flags |= TX_ON_AIR; - } - ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - - if(rf_flags & WAS_OFF) { - off(); - } - - RIMESTATS_ADD(lltx); - /* OK, sent. We are now ready to send more */ - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -send(void *payload, unsigned short payload_len) -{ - prepare(payload, payload_len); - return transmit(payload_len); -} -/*---------------------------------------------------------------------------*/ -static int -read(void *buf, unsigned short bufsize) -{ - uint8_t i; - uint8_t len; - uint8_t crc_corr; - int8_t rssi; -#if CC2420_CONF_CHECKSUM - uint16_t checksum; -#endif /* CC2420_CONF_CHECKSUM */ - - /* Don't interrupt us while emptying the FIFO */ -#if !NETSTACK_CONF_SHORTCUTS - IEN2 &= ~RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 &= ~RFERRIE; -#endif - - /* RX interrupt polled the cc2430_rf_process, now read the RX FIFO */ - /* Check the length */ - len = RFD; - - /* Check for validity */ - if(len > CC2430_MAX_PACKET_LEN) { - /* Oops, we must be out of sync. */ - PRINTF("error: bad sync\n"); - - RIMESTATS_ADD(badsynch); - flush_rx(); - return 0; - } - - if(len <= CC2430_MIN_PACKET_LEN) { - PRINTF("error: too short\n"); - - RIMESTATS_ADD(tooshort); - flush_rx(); - return 0; - } - - if(len - CHECKSUM_LEN > bufsize) { - PRINTF("error: too long\n"); - - RIMESTATS_ADD(toolong); - flush_rx(); - return 0; - } - -#if CC2430_RF_CONF_HEXDUMP - /* If we reach here, chances are the FIFO is holding a valid frame */ - uart1_writeb(magic[0]); - uart1_writeb(magic[1]); - uart1_writeb(magic[2]); - uart1_writeb(magic[3]); - uart1_writeb(len); -#endif - - PRINTF("cc2430_rf: read = "); - PRINTF("(%d)", len); - len -= CHECKSUM_LEN; - for(i = 0; i < len; ++i) { - ((unsigned char *)(buf))[i] = RFD; -#if CC2430_RF_CONF_HEXDUMP - uart1_writeb(((unsigned char *)(buf))[i]); -#endif - PRINTF("%02X", ((unsigned char *)(buf))[i]); - } - PRINTF("\n"); - -#if CC2430_CONF_CHECKSUM - /* Deal with the checksum */ - checksum = RFD * 256; - checksum += RFD; -#endif /* CC2430_CONF_CHECKSUM */ - - /* Read the RSSI and CRC/Corr bytes */ - rssi = ((int8_t) RFD) - 45; - crc_corr = RFD; - -#if CC2430_RF_CONF_HEXDUMP - uart1_writeb(rssi); - uart1_writeb(crc_corr); -#endif - - /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */ - if(crc_corr & CRC_BIT_MASK) { - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); - packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK); - RIMESTATS_ADD(llrx); - } else { - RIMESTATS_ADD(badcrc); - flush_rx(); - return 0; - } - - /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */ - if((RFSTATUS & (FIFO | FIFOP)) == FIFOP) { - /* - * If we reach here means that there might be more intact packets in the - * FIFO despite the overflow. This can happen with bursts of small packets. - * - * Only flush if the FIFO is actually empty. If not, then next pass we will - * pick up one more packet or flush due to an error. - */ - if(!RXFIFOCNT) { - flush_rx(); - } - } - - RF_RX_LED_OFF(); - -#if !NETSTACK_CONF_SHORTCUTS - IEN2 |= RFIE; -#endif -#if CC2430_RFERR_INTERRUPT - IEN0 |= RFERRIE; -#endif - - RFIF &= ~IRQ_FIFOP; - - return (len); -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - if(!(RFSTATUS & CCA)) { - return CC2430_CCA_BUSY; - } - return CC2430_CCA_CLEAR; -} -/*---------------------------------------------------------------------------*/ -static int -receiving_packet(void) -{ - /* - * SFD high while transmitting and receiving. - * TX_ACTIVE high only when transmitting - * - * RFSTATUS & (TX_ACTIVE | SFD) == SFD <=> receiving - */ - return (RFSTATUS & (TX_ACTIVE | SFD) == SFD); -} -/*---------------------------------------------------------------------------*/ -static int -pending_packet(void) -{ - return (RFSTATUS & FIFOP); -} -/*---------------------------------------------------------------------------*/ -/** - * Enable RF receiver. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ -static int -on(void) -{ - rtimer_clock_t t0; - PRINTF("cc2430_rf_rx_enable called\n"); - if(!(rf_flags & RX_ACTIVE)) { - t0 = RTIMER_NOW(); - rf_flags |= RX_ACTIVE; - IOCFG0 = 0x7f; /* Set the FIFOP threshold 127 */ - RSSIH = 0xd2; /* -84dbm = 0xd2 default, 0xe0 -70 dbm */ - - RFPWR &= ~RREG_RADIO_PD; /* make sure it's powered */ - while((RFIF & IRQ_RREG_ON) == 0); /* wait for power up */ - - /* Make sure the RREG On Interrupt Flag is 0 next time we get called */ - RFIF &= ~IRQ_RREG_ON; - - cc2430_rf_command(ISRXON); - cc2430_rf_command(ISFLUSHRX); - while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME)); - - } - PRINTF("cc2430_rf_rx_enable done\n"); - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - return 1; -} -/*---------------------------------------------------------------------------*/ -/** - * Disable RF receiver. - * - * - * \return pdTRUE - * \return pdFALSE bus not free - */ - -static int -off(void) -{ - cc2430_rf_command(ISSTOP); /* make sure CSP is not running */ - cc2430_rf_command(ISRFOFF); - - RFPWR |= RREG_RADIO_PD; /* RF powerdown */ - - /* Clear the RREG On Interrupt Flag */ - RFIF &= ~IRQ_RREG_ON; - - rf_flags &= ~RX_ACTIVE; - rf_flags &= ~WAS_OFF; - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - return 1; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_value(radio_param_t param, radio_value_t *value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_value(radio_param_t param, radio_value_t value) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_object(radio_param_t param, void *dest, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_object(radio_param_t param, const void *src, size_t size) -{ - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -const struct radio_driver cc2430_rf_driver = { - init, - prepare, - transmit, - send, - read, - channel_clear, - receiving_packet, - pending_packet, - on, - off, - get_value, - set_value, - get_object, - set_object -}; -/*---------------------------------------------------------------------------*/ -#if !NETSTACK_CONF_SHORTCUTS -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(cc2430_rf_process, ev, data) -{ - int len; - PROCESS_BEGIN(); - while(1) { - PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - - packetbuf_clear(); - len = read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); - NETSTACK_RDC.input(); - } - } - - PROCESS_END(); -} -#endif -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/cc2430_rf.h b/cpu/cc2430/dev/cc2430_rf.h deleted file mode 100644 index 83527d4ba..000000000 --- a/cpu/cc2430/dev/cc2430_rf.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file - * CC2430 RF driver header file - * \author - * Zach Shelby - */ - -#ifndef CC2430_RF_H_ -#define CC2430_RF_H_ - -#include "contiki.h" -#include "dev/radio.h" -#include "cc2430_sfr.h" -#if HAVE_RF_DMA -#include "dev/dma.h" -#endif - -/* Constants */ -typedef enum rf_address_mode_t { - RF_DECODER_NONE = 0, - RF_DECODER_COORDINATOR, - RF_SOFTACK_MONITOR, - RF_MONITOR, - RF_SOFTACK_CLIENT, - RF_DECODER_ON -} rf_address_mode_t; - -/*CSP command set*/ -#define SSTOP 0xDF -/*this is not a real command but a way of having rf_command - wait until the script is done*/ -#define SSTART 0xDE - -#define SNOP 0xC0 -#define STXCALN 0xC1 -#define SRXON 0xC2 -#define STXON 0xC3 -#define STXONCCA 0xC4 -#define SRFOFF 0xC5 -#define SFLUSHRX 0xC6 -#define SFLUSHTX 0xC7 -#define SACK 0xC8 -#define SACKPEND 0xC9 - -#define ISTXCALN 0xE1 -#define ISRXON 0xE2 -#define ISTXON 0xE3 -#define ISTXONCCA 0xE4 -#define ISRFOFF 0xE5 -#define ISFLUSHRX 0xE6 -#define ISFLUSHTX 0xE7 -#define ISACK 0xE8 -#define ISACKPEND 0xE9 - -#define ISSTOP 0xFF -#define ISSTART 0xFE - -#define MAC_IFS (1200/128) - -#define CC2430_MAX_PACKET_LEN 127 -#define CC2430_MIN_PACKET_LEN 4 - -#define CC2430_CCA_CLEAR 1 -#define CC2430_CCA_BUSY 0 - -#ifdef CC2430_CONF_RFERR_INTERRUPT -#define CC2430_RFERR_INTERRUPT CC2430_CONF_RFERR_INTERRUPT -#else -#define CC2430_RFERR_INTERRUPT 0 -#endif - -extern const struct radio_driver cc2430_rf_driver; - -void cc2430_rf_command(uint8_t command); -int8_t cc2430_rf_channel_set(uint8_t channel); -uint8_t cc2430_rf_channel_get(); -uint8_t cc2430_rf_power_set(uint8_t new_power); -void cc2430_rf_set_addr(unsigned pan, unsigned addr, const uint8_t *ieee_addr); - -#if !NETSTACK_CONF_SHORTCUTS -extern void cc2430_rf_ISR(void) __interrupt(RF_VECTOR); -#endif -#if CC2430_RFERR_INTERRUPT -extern void cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR); -#endif - -#ifdef HAVE_RF_DMA -void rf_dma_callback_isr(void); -#endif - -#endif /* CC2430_RF_H_ */ diff --git a/cpu/cc2430/dev/cc2430_rf_intr.c b/cpu/cc2430/dev/cc2430_rf_intr.c deleted file mode 100644 index 85b9879c9..000000000 --- a/cpu/cc2430/dev/cc2430_rf_intr.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * \file - * CC2430 RF driver - * \author - * Zach Shelby (Original) - * George Oikonomou - - * (recent updates for the contiki cc2430 port) - * - * Non-bankable code for cc2430 rf driver. - * Interrupt routines must be placed into the HOME bank. - * - */ - -#include - -#include "contiki.h" -#include "dev/radio.h" -#include "dev/cc2430_rf.h" -#include "cc2430_sfr.h" -#ifdef RF_LED_ENABLE -#include "dev/leds.h" -#endif -#include "sys/clock.h" - -#include "net/packetbuf.h" -#include "net/rime/rimestats.h" -#include "net/netstack.h" -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) do {} while (0) -#endif - -#ifdef RF_LED_ENABLE -#define RF_RX_LED_ON() leds_on(LEDS_RED); -#define RF_RX_LED_OFF() leds_off(LEDS_RED); -#define RF_TX_LED_ON() leds_on(LEDS_GREEN); -#define RF_TX_LED_OFF() leds_off(LEDS_GREEN); -#else -#define RF_RX_LED_ON() -#define RF_RX_LED_OFF() -#define RF_TX_LED_ON() -#define RF_TX_LED_OFF() -#endif - -#ifdef HAVE_RF_ERROR -uint8_t rf_error = 0; -#endif - -PROCESS_NAME(cc2430_rf_process); - -#if !NETSTACK_CONF_SHORTCUTS -/*---------------------------------------------------------------------------*/ -/** - * RF interrupt service routine. - * - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_rf_ISR(void) __interrupt(RF_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* - * We only vector here if RFSTATUS.FIFOP goes high. - * Just double check the flag. - */ - if(RFIF & IRQ_FIFOP) { - RF_RX_LED_ON(); - /* Poll the RF process which calls cc2430_rf_read() */ - process_poll(&cc2430_rf_process); - } - S1CON &= ~(RFIF_0 | RFIF_1); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ -#if CC2430_RFERR_INTERRUPT -/** - * RF error interrupt service routine. - * Turned off by default, can be turned on in contiki-conf.h - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_rf_error_ISR(void) __interrupt(RFERR_VECTOR) -{ - EA = 0; - TCON_RFERRIF = 0; -#ifdef HAVE_RF_ERROR - rf_error = 254; -#endif - cc2430_rf_command(ISRFOFF); - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISFLUSHRX); - cc2430_rf_command(ISRXON); - RF_RX_LED_OFF(); - RF_TX_LED_OFF(); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/clock.c b/cpu/cc2430/dev/clock.c deleted file mode 100644 index 1fc781b1b..000000000 --- a/cpu/cc2430/dev/clock.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Implementation of the clock functions for the cc243x - * \author - * Zach Shelby (zach@sensinode.com) - original - * George Oikonomou - - */ -#include "sys/clock.h" -#include "sys/etimer.h" -#include "cc2430_sfr.h" -#include "sys/energest.h" - -/* Sleep timer runs on the 32k RC osc. */ -/* One clock tick is 7.8 ms */ -#define TICK_VAL (32768/128) /* 256 */ -/*---------------------------------------------------------------------------*/ -#if CLOCK_CONF_STACK_FRIENDLY -volatile uint8_t sleep_flag; -#endif -/*---------------------------------------------------------------------------*/ -/* Used in sleep timer interrupt for calculating the next interrupt time */ -static unsigned long timer_value; -static volatile CC_AT_DATA clock_time_t count = 0; /* Uptime in ticks */ -static volatile CC_AT_DATA clock_time_t seconds = 0; /* Uptime in secs */ -/*---------------------------------------------------------------------------*/ -/* - * Each iteration is ~1.0xy usec, so this function delays for roughly len usec - */ -void -clock_delay_usec(uint16_t len) -{ - DISABLE_INTERRUPTS(); - while(len--) { - ASM(nop); ASM(nop); - ASM(nop); ASM(nop); - } - ENABLE_INTERRUPTS(); -} -/*---------------------------------------------------------------------------*/ -/* - * Wait for a multiple of ~8 ms (a tick) - */ -void -clock_wait(clock_time_t i) -{ - clock_time_t start; - - start = clock_time(); - while(clock_time() - start < (clock_time_t)i); -} -/*---------------------------------------------------------------------------*/ -CCIF clock_time_t -clock_time(void) -{ - return count; -} -/*---------------------------------------------------------------------------*/ -CCIF unsigned long -clock_seconds(void) -{ - return seconds; -} -/*---------------------------------------------------------------------------*/ -void -clock_init(void) -{ - CLKCON = OSC32K | TICKSPD2 | TICKSPD1; /* tickspeed 500 kHz for timers[1-4] */ - - /* Initialize tick value */ - timer_value = ST0; /* ST low bits [7:0] */ - timer_value += ((unsigned long int)ST1) << 8; /* middle bits [15:8] */ - timer_value += ((unsigned long int)ST2) << 16; /* high bits [23:16] */ - timer_value += TICK_VAL; /* Init value 256 */ - ST2 = (unsigned char)(timer_value >> 16); - ST1 = (unsigned char)(timer_value >> 8); - ST0 = (unsigned char)timer_value; - - IEN0_STIE = 1; /* IEN0.STIE acknowledge Sleep Timer Interrupt */ -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -clock_ISR(void) __interrupt(ST_VECTOR) -{ - DISABLE_INTERRUPTS(); - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* - * If the Sleep timer throws an interrupt while we are powering down to - * PM1, we need to abort the power down. Clear SLEEP.MODE, this will signal - * main() to abort the PM1 transition - */ - SLEEP &= 0xFC; - - /* - * Read value of the ST0:ST1:ST2, add TICK_VAL and write it back. - * Next interrupt occurs after the current time + TICK_VAL - */ - timer_value = ST0; - timer_value += ((unsigned long int)ST1) << 8; - timer_value += ((unsigned long int)ST2) << 16; - timer_value += TICK_VAL; - ST2 = (unsigned char)(timer_value >> 16); - ST1 = (unsigned char)(timer_value >> 8); - ST0 = (unsigned char)timer_value; - - ++count; - - /* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure - that the modulo operation below becomes a logical and and not - an expensive divide. Algorithm from Wikipedia: - http://en.wikipedia.org/wiki/Power_of_two */ -#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0 -#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...). -#error Change CLOCK_CONF_SECOND in contiki-conf.h. -#endif - if(count % CLOCK_CONF_SECOND == 0) { - ++seconds; - } - -#if CLOCK_CONF_STACK_FRIENDLY - sleep_flag = 1; -#else - if(etimer_pending() - && (etimer_next_expiration_time() - count - 1) > MAX_TICKS) { - etimer_request_poll(); - } -#endif - - IRCON_STIF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - ENABLE_INTERRUPTS(); -} -#pragma restore -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/dma.c b/cpu/cc2430/dev/dma.c deleted file mode 100644 index 2c198acc3..000000000 --- a/cpu/cc2430/dev/dma.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * \file - * Driver for the cc2430 DMA controller. Can be assigned to any bank - * - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * Further Modifications: - * George Oikonomou - * - */ - -#include "contiki.h" -#include "dev/dma.h" -#include "cc2430_sfr.h" - -#if DMA_ON -struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */ -struct process *dma_callback[DMA_CHANNEL_COUNT]; -/*---------------------------------------------------------------------------*/ -void -dma_init(void) -{ - uint16_t tmp_ptr; - - memset(dma_conf, 0, 4 * sizeof(dma_config_t)); - - for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) { - dma_callback[tmp_ptr] = 0; - } - - /* The address of the descriptor for Channel 0 is configured separately */ - tmp_ptr = (uint16_t)&(dma_conf[0]); - DMA0CFGH = tmp_ptr >> 8; - DMA0CFGL = tmp_ptr; - - /* - * Descriptors for Channels 1-4 must be consecutive in RAM. - * We write the address of the 1st one to the register and the rest are - * derived by the SoC - */ -#if (DMA_CHANNEL_COUNT > 1) - tmp_ptr = (uint16_t)&(dma_conf[1]); - DMA1CFGH = tmp_ptr >> 8; - DMA1CFGL = tmp_ptr; -#endif - - IEN1_DMAIE = 1; /* Enable DMA interrupts */ -} -/*---------------------------------------------------------------------------*/ -/* - * Associate process p with DMA channel c. When a transfer on that channel - * completes, the ISR will poll this process. - */ -void -dma_associate_process(struct process *p, uint8_t c) -{ - if((!c) || (c >= DMA_CHANNEL_COUNT)) { - return; - } - - if(p) { - dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */ - IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */ - } - dma_callback[c] = p; -} -/*---------------------------------------------------------------------------*/ -#endif diff --git a/cpu/cc2430/dev/dma.h b/cpu/cc2430/dev/dma.h deleted file mode 100644 index 30060b40f..000000000 --- a/cpu/cc2430/dev/dma.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * \file - * Header file for the cc2430 DMA controller - * - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * Further Modifications: - * George Oikonomou - */ - -#ifndef __DMA_H -#define __DMA_H -#include "cc2430_sfr.h" - -/* DMA triggers */ -#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */ -#define DMA_T_PREV 1 /* completion of previous channel */ -#define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */ -#define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */ -#define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */ -#define DMA_T_T2_COMP 5 /* Timer 2, compare */ -#define DMA_T_T2_OVFL 6 /* Timer 2, overflow */ -#define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */ -#define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */ -#define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */ -#define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */ -#define DMA_T_ST 11 /* Sleep Timer compare */ -#define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */ -#define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */ -#define DMA_T_URX0 14 /* USART0 RX complete */ -#define DMA_T_UTX0 15 /* USART0 TX complete */ -#define DMA_T_URX1 16 /* USART1 RX complete */ -#define DMA_T_UTX1 17 /* USART1 TX complete */ -#define DMA_T_FLASH 18 /* Flash data write complete */ -#define DMA_T_RADIO 19 /* RF packet byte received/transmit */ -#define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */ -#define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */ -#define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */ -#define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */ -#define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */ -#define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */ -#define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */ -#define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */ -#define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */ -#define DMA_T_ENC_DW 29 /* AES processor requests download input data */ -#define DMA_T_ENC_UP 30 /* AES processor requests upload output data */ - -/* variable DMA length modes (VLEN) */ -#define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/ -/* - * Transfer the number of bytes/words specified by first byte/word + 1 - * (up to a maximum specified by LEN). - * Thus transfer count excludes length byte/word. - */ -#define DMA_VLEN_N1 (1 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word - * (up to a maximum specified by LEN). - * Thus transfer count includes length byte/word. - */ -#define DMA_VLEN_N (2 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word + 2 - * (up to a maximum specified by LEN). - */ -#define DMA_VLEN_N2 (3 << 5) - /* - * Transfer the number of bytes/words specified by first byte/word + 3 - * (up to a maximum specified by LEN). - */ -#define DMA_VLEN_N3 (4 << 5) -#define DMA_VLEN_RES1 (5 << 5) /* reserved */ -#define DMA_VLEN_RES2 (6 << 5) /* reserved */ -#define DMA_VLEN_LEN2 (7 << 5) /* Use LEN for transfer count */ - -/* Transfer Types (Byte 6 [6:5]) */ -#define DMA_SINGLE 0x00 /* Single */ -#define DMA_BLOCK 0x20 /* Block */ -#define DMA_RPT_SINGLE 0x40 /* Repeated single */ -#define DMA_RPT_BLOCK 0x60 /* Repeated block */ - -/* Source Increment Modes (Byte 7 [7:6])*/ -#define DMA_SRC_INC_NO 0x00 /* Source No increment */ -#define DMA_SRC_INC_1 0x40 /* Source Increment 1 */ -#define DMA_SRC_INC_2 0x80 /* Source Increment 2 */ -#define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */ -/* Source Increment Modes (Byte 7 [5:4])*/ -#define DMA_DST_INC_NO 0x00 /* DestinationNo increment */ -#define DMA_DST_INC_1 0x10 /* Destination Increment 1 */ -#define DMA_DST_INC_2 0x20 /* Destination Increment 2 */ -#define DMA_DST_DEC 0x30 /* Destination Decrement 1 */ - -/* Descriptor Byte 7, Bits[3:0] */ -#define DMA_IRQ_MASK_ENABLE 0x08 -#define DMA_MODE_7_BIT 0x04 -#define DMA_PRIO_HIGHEST 0x03 -#define DMA_PRIO_HIGH 0x02 -#define DMA_PRIO_GUARANTEED 0x01 -#define DMA_PRIO_LOW 0x00 - -/** DMA configuration structure */ -typedef struct dma_config { - uint8_t src_h; /* source address high byte*/ - uint8_t src_l; /* source address low byte*/ - uint8_t dst_h; /* dest. address high byte*/ - uint8_t dst_l; /* dest. address low byte*/ - uint8_t len_h; /* [7:5] VLEN, [4:0] length high byte, 5 lowest bits*/ - uint8_t len_l; /* length low byte*/ - uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */ - /* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */ - uint8_t inc_prio; -} dma_config_t; - -#ifdef DMA_CONF_ON -#define DMA_ON DMA_CONF_ON -#else -#define DMA_ON 0 -#endif - -/* Number of DMA Channels and their Descriptors */ -#if DMA_ON -#define DMA_CHANNEL_COUNT 2 -extern dma_config_t dma_conf[DMA_CHANNEL_COUNT]; -#endif - -/* DMA-Related Macros */ -#define DMA_ARM(c) (DMAARM |= (1 << c)) /* Arm DMA Channel C */ -#define DMA_TRIGGER(c) (DMAREQ |= (1 << c)) /* Trigger DMA Channel C */ -/* - * Check Channel C for Transfer Status - * 1: Complete, Pending Interrupt, 0: Incomplete - */ -#define DMA_STATUS(c) (DMAIRQ &(1 << c)) -/* Abort Ongoing DMA Transfers on Channel C */ -#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c)) -#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */ - -/* Functions Declarations */ -void dma_init(void); -void dma_associate_process(struct process *p, uint8_t c); - -/* Only link the ISR when DMA_ON is .... on */ -#if DMA_ON -void dma_ISR(void) __interrupt(DMA_VECTOR); -#endif - -#endif /*__DMA_H*/ diff --git a/cpu/cc2430/dev/dma_intr.c b/cpu/cc2430/dev/dma_intr.c deleted file mode 100644 index 01e96c8ac..000000000 --- a/cpu/cc2430/dev/dma_intr.c +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \file - * DMA driver ISRs - * \author - * Original: Martti Huttunen - * Port: Zach Shelby - * - * DMA interrupt routines, must be stored in HOME bank - */ - -#include - -#include "contiki.h" - -#include "dev/dma.h" -#include "cc2430_sfr.h" - -#if DMA_ON -extern struct process *dma_callback[DMA_CHANNEL_COUNT]; -#endif - -/*---------------------------------------------------------------------------*/ -#ifdef HAVE_RF_DMA -extern void rf_dma_callback_isr(void); -#endif -#ifdef SPI_DMA_RX -extern void spi_rx_dma_callback(void); -#endif -/*---------------------------------------------------------------------------*/ -/** - * DMA interrupt service routine. - * - * if callback defined a poll is made to that process - */ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -dma_ISR(void) __interrupt(DMA_VECTOR) -{ -#if DMA_ON - uint8_t i; -#endif - EA = 0; - IRCON_DMAIF = 0; -#ifdef HAVE_RF_DMA - if((DMAIRQ & 1) != 0) { - DMAIRQ &= ~1; - DMAARM = 0x81; - rf_dma_callback_isr(); - } -#endif -#ifdef SPI_DMA_RX - if((DMAIRQ & 0x08) != 0) { - DMAIRQ &= ~(1 << 3); - spi_rx_dma_callback(); - } -#endif -#if DMA_ON - for(i = 0; i < DMA_CHANNEL_COUNT; i++) { - if((DMAIRQ & (1 << i)) != 0) { - DMAIRQ &= ~(1 << i); - if(dma_callback[i] != 0) { - process_poll(dma_callback[i]); - } - } - } -#endif - EA = 1; -} -#pragma restore -/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc2430/dev/hwconf.h b/cpu/cc2430/dev/hwconf.h deleted file mode 100644 index 6d1fad135..000000000 --- a/cpu/cc2430/dev/hwconf.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef HWCONF_H_ -#define HWCONF_H_ - -#include "sys/cc.h" - -#include - -#define HWCONF_PIN(name, port, bit) \ -static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \ -static CC_INLINE void name##_SELECT_IO() {P##port##SEL &= ~(1 << bit);} \ -static CC_INLINE void name##_SELECT_PM() {P##port##SEL |= 1 << bit;} \ -static CC_INLINE void name##_SET() {P##port##_##bit = 1; } \ -static CC_INLINE void name##_CLEAR() {P##port##_##bit = 0; } \ -static CC_INLINE unsigned char name##_READ() {return P##port##_##bit; } \ -static CC_INLINE void name##_MAKE_OUTPUT() {P##port##DIR |= 1 << bit;} \ -static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit); } - -#define HWCONF_IRQ_XXX(name, port, bit) \ -static CC_INLINE void name##_ENABLE_IRQ() { \ - if ( port == 2 ) { PICTL |= P2IEN; p2ien |= 1<=4)) { PICTL |= P0IENH; p0ien |= 1<=4)) { \ - p0ien &= ~(1<=4 ) { PICTL |= P0IENH; p0ien |= 1<=4) { \ - p0ien &= ~(1< - */ -#ifndef LPM_H_ -#define LPM_H_ - -#include "contiki-conf.h" - -#define LPM_MODE_NONE 0 /* No LPM - Always on */ -#define LPM_MODE_IDLE 1 /* Set MCU Idle as part of the main loop */ -#define LPM_MODE_PM2 2 /* Drop to PM1 - causes radio packet losses for now */ - -#ifdef LPM_CONF_MODE -#define LPM_MODE LPM_CONF_MODE -#else -#define LPM_MODE LPM_MODE_IDLE -#endif /* LPM_CONF_MODE */ - -#endif /* LPM_H_ */ diff --git a/cpu/cc2430/dev/random.c b/cpu/cc2430/dev/random.c deleted file mode 100644 index 639f384e5..000000000 --- a/cpu/cc2430/dev/random.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Random number generator routines exploiting the cc2430 hardware - * capabilities. - * - * This file overrides core/lib/random.c. - * - * \author - * George Oikonomou - - */ -#include "cc2430_sfr.h" -#include "dev/cc2430_rf.h" -/*---------------------------------------------------------------------------*/ -/** - * \brief Generates a new random number using the cc2430 RNG. - * \return The random number. - */ -unsigned short -random_rand(void) -{ - /* Clock the RNG LSFR once */ - ADCCON1 |= ADRCTRL0; - - return (RNDL | (RNDH << 8)); -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Seed the cc2430 random number generator. - * \param seed Seed value for the RNG. - * - * If the SEED argument is 0, seed the RNG with IF_ADC as - * discussed in the cc2430 datasheet (rev. 2.1), section 13.11.2.2, - * page 134. Seeding with this method should not be done during - * normal radio operation. Thus, use this function before - * initialising the network. - * - * If the SEED is provided, seed with this value instead. This will - * result in the same sequence of random numbers each time the node - * reboots. So, don't use it unless you have a reason (e.g. tests) - */ -void -random_init(unsigned short seed) -{ - int i; - - /* Comment out this if() block to save a nice 16 bytes of code size */ - if(seed) { - /* If the caller provides a seed, write the high-byte first and then - * write the low byte */ - RNDL = seed >> 8; /* High byte first */ - RNDL = seed & 0xFF; - return; - } - - /* - * cc2430 Datasheet: - * "When a true random value is required, the LFSR should be seeded by - * writing RNDL with random values from the IF_ADC in the RF receive path." - * - * "To use this seeding method, the radio must first be powered on by - * enabling the voltage regulator" - */ - RFPWR &= ~RREG_RADIO_PD; /* Turn on the voltage regulator */ - while(!(RFIF & IRQ_RREG_ON)); /* Wait for power up*/ - - /* OK, it's powered. The respective interrupt flag has been set, clear it */ - RFIF &= ~IRQ_RREG_ON; - - /* - * "The radio should be placed in infinite TX state, to avoid possible sync - * detect in RX state." - * - * Judging by old chipcon cc2430 code examples as well as by the way cc2530 - * works, this is very likely to be "RX state" (i.e. a typo in the datasheet) - * - * With infinite TX, ADCTSTx always read as 0 so we'll use infinite RX - */ - MDMCTRL1L = 0x02; /* RX mode 10 - RX_INFINITE state */ - - /* "Enter RX State - Immediate" command strobe */ - cc2430_rf_command(ISRXON); - - /* Make sure the RNG is on */ - ADCCON1 &= ~(ADRCTRL1 | ADRCTRL0); - - /* Wait for IF_ADC I-branch and Q-branch values */ - while(!(ADCTSTH & ADCTSTL)); - - /* 32 times as per the chipcon example. This seems to increase randomness */ - for(i = 0; i < 32; i++) { - /* Seed the RNG by writing into RNDL twice with values from ADCTSTx */ - RNDL = ADCTSTH; - RNDL = ADCTSTL; - - /* Clock the RNG LSFR once */ - ADCCON1 |= ADRCTRL0; - } - - /* - * Exit RX state. Just shut down, network initialisation will take care of - * properly starting the radio for us. - */ - RFPWR |= RREG_RADIO_PD; -} diff --git a/cpu/cc2430/dev/uart.h b/cpu/cc2430/dev/uart.h deleted file mode 100644 index e230c3bcd..000000000 --- a/cpu/cc2430/dev/uart.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef UART_H -#define UART_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" - -/*---------------------------------------------------------------------------*/ -/* UART BAUD Rates */ -/* - * Macro to set speed of UART N by setting the UnBAUD SFR to M and the - * UnGCR SRF to E. See the cc2430 datasheet for possible values of M and E - */ -#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0) - -/* - * Sample Values for M and E in the macro above to achieve some common BAUD - * rates. For more values, see the cc2430 datasheet - */ -/* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */ -#define UART_2K_M 0 -#define UART_2K_E 16 -/* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */ -#define UART_1K_M 0 -#define UART_1K_E 15 -/* 921600 */ -#define UART_921_M 216 -#define UART_921_E 14 -/* 460800 Higher values lead to problems when the node needs to RX */ -#define UART_460_M 216 -#define UART_460_E 13 -/* 115200 */ -#define UART_115_M 216 -#define UART_115_E 11 -/* 38400 */ -#define UART_38_M 59 -#define UART_38_E 10 -/* 9600 */ -#define UART_9_M 59 -#define UART_9_E 8 - -#endif /* UART_H */ diff --git a/cpu/cc2430/dev/uart0.c b/cpu/cc2430/dev/uart0.c deleted file mode 100644 index 254dba765..000000000 --- a/cpu/cc2430/dev/uart0.c +++ /dev/null @@ -1,69 +0,0 @@ -/** - * \file - * - * uart0 write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - */ -#include -#include - -#include "cc2430_sfr.h" -#include "dev/uart0.h" - -#if UART_ZERO_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart0_init() -{ - UART_SET_SPEED(0, UART_115_M, UART_115_E); - -#ifdef UART0_ALTERNATIVE_2 - PERCFG |= U0CFG; /*alternative port 2 = P1.5-2*/ -#ifdef UART0_RTSCTS - P1SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P1SEL |= 0x30; /*peripheral select for TX and RX*/ - P1 &= ~0x08; /*RTS down*/ -#endif - P1DIR |= 0x28; /*RTS, TX out*/ - P1DIR &= ~0x14; /*CTS & RX in*/ -#else - PERCFG &= ~U0CFG; /*alternative port 1 = P0.5-2*/ -#ifdef UART0_RTSCTS - P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P0SEL |= 0x0C; /*peripheral select for TX and RX*/ - P0 &= ~0x20; /*RTS down*/ -#endif - P0DIR |= 0x28; /*RTS & TX out*/ - P0DIR &= ~0x14; /*CTS & RX in*/ -#endif - - -#ifdef UART0_RTSCTS - U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ -#else - U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ -#endif - - U0CSR = U_MODE | U_RE | U_TXB; /*UART mode, receiver enable, TX done*/ - - /*set priority group of group 3 to highest, so the UART won't miss bytes*/ - IP1 |= IP1_3; - IP0 |= IP0_3; -} -/*---------------------------------------------------------------------------*/ -/* Write one byte over the UART. */ -void -uart0_writeb(uint8_t byte) -{ - IRCON2_UTX0IF = 0; - U0BUF = byte; - while(!IRCON2_UTX0IF); /* Wait until byte has been transmitted. */ - IRCON2_UTX0IF = 0; -} -#endif diff --git a/cpu/cc2430/dev/uart0.h b/cpu/cc2430/dev/uart0.h deleted file mode 100644 index 8a1357639..000000000 --- a/cpu/cc2430/dev/uart0.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef UART_0_H -#define UART_0_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "uart.h" - -/*---------------------------------------------------------------------------*/ -/* UART0 Enable - Disable */ -#ifdef UART_ZERO_CONF_ENABLE -#define UART_ZERO_ENABLE UART_ZERO_CONF_ENABLE -#else -#define UART_ZERO_ENABLE 0 -#endif -/*---------------------------------------------------------------------------*/ -/* UART0 Function Declarations */ -#if UART_ZERO_ENABLE -void uart0_init(); -void uart0_writeb(uint8_t byte); - -void uart0_set_input(int (* input)(unsigned char c)); - -void uart0_rx_ISR(void) __interrupt(URX0_VECTOR); -void uart0_tx_ISR(void) __interrupt(UTX0_VECTOR); -/* Macro to turn on / off UART RX Interrupt */ -#define UART0_RX_INT(v) do { IEN0_URX0IE = v; } while(0) -#endif - -#endif /* UART_0_H */ diff --git a/cpu/cc2430/dev/uart1.c b/cpu/cc2430/dev/uart1.c deleted file mode 100644 index 7f388c5b6..000000000 --- a/cpu/cc2430/dev/uart1.c +++ /dev/null @@ -1,74 +0,0 @@ -/** - * \file - * - * uart1 write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - */ -#include -#include - -#include "cc2430_sfr.h" -#include "dev/uart1.h" - -#if UART_ONE_ENABLE -/*---------------------------------------------------------------------------*/ -/* UART1 initialization */ -void -uart1_init() -{ -#ifdef UART1_ALTERNATIVE_1 - PERCFG &= ~U1CFG; /*alternative port 1 = P0.5-2*/ -#ifdef UART1_RTSCTS - P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/ -#else - P0SEL |= 0x30; /*peripheral select for TX and RX*/ - P0 &= ~0x08; /*RTS down*/ -#endif - P0DIR |= 0x18; /*RTS, TX out*/ - P0DIR &= ~0x24; /*CTS, RX in*/ -#else - PERCFG |= U1CFG; /*alternative port 2 = P1.7-4*/ -#ifdef UART1_RTSCTS - P1SEL |= 0xF0; /*peripheral select for TX and RX*/ -#else - P1SEL |= 0xC0; /*peripheral select for TX and RX*/ - P1 &= ~0x20; /*RTS down*/ -#endif - P1DIR |= 0x60; /*RTS, TX out*/ - P1DIR &= ~0x90; /*CTS, RX in*/ -#endif - -#if UART_ONE_CONF_HIGH_SPEED - UART_SET_SPEED(1, UART_460_M, UART_460_E); -#else - UART_SET_SPEED(1, UART_115_M, UART_115_E); -#endif - -#ifdef UART1_RTSCTS - U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ -#else - U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ -#endif - - U1CSR = U_MODE | U_RE; /* UART mode, receiver enable */ - - /*set priority group of group 3 to highest, so the UART won't miss bytes*/ - IP1 |= IP1_3; - IP0 |= IP0_3; -} -/*---------------------------------------------------------------------------*/ -/* Write one byte over the UART. */ -void -uart1_writeb(uint8_t byte) -{ - IRCON2_UTX1IF = 0; - U1BUF = byte; - while(!IRCON2_UTX1IF); /* Wait until byte has been transmitted. */ - IRCON2_UTX1IF = 0; -} -/*---------------------------------------------------------------------------*/ -#endif diff --git a/cpu/cc2430/dev/uart1.h b/cpu/cc2430/dev/uart1.h deleted file mode 100644 index 1a4b7e9fa..000000000 --- a/cpu/cc2430/dev/uart1.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef UART_1_H -#define UART_1_H - -#include "contiki-conf.h" - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "uart.h" - -/*---------------------------------------------------------------------------*/ -/* UART1 Enable - Disable */ -#ifdef UART_ONE_CONF_ENABLE -#define UART_ONE_ENABLE UART_ONE_CONF_ENABLE -#else -#define UART_ONE_ENABLE 0 -#endif -/*---------------------------------------------------------------------------*/ -/* UART1 Function Declarations */ -#if UART_ONE_ENABLE -void uart1_init(); -void uart1_writeb(uint8_t byte); - -void uart1_set_input(int (*input)(unsigned char c)); -#if UART_ONE_CONF_WITH_INPUT -void uart1_rx_ISR(void) __interrupt(URX1_VECTOR); -void uart1_tx_ISR(void) __interrupt(UTX1_VECTOR); -/* Macro to turn on / off UART RX Interrupt */ -#define UART1_RX_INT(v) do { IEN0_URX1IE = v; } while(0) -#else -#define UART1_RX_INT(v) -#endif /* UART_ONE_CONF_WITH_INPUT */ -#else -#define uart1_init(...) -#define uart1_writeb(...) -#define uart1_set_input(...) -#define UART1_RX_INT(v) -#endif /* UART_ONE_ENABLE */ - -#endif /* UART_1_H */ diff --git a/cpu/cc2430/dev/uart_intr.c b/cpu/cc2430/dev/uart_intr.c deleted file mode 100644 index 17a5427aa..000000000 --- a/cpu/cc2430/dev/uart_intr.c +++ /dev/null @@ -1,91 +0,0 @@ -/** - * \file - * - * uart write routines - * - * \author - * - * Anthony "Asterisk" Ambuehl - * - * interrupt routines which must be in HOME bank. handles received data from UART. - * - */ -#include -#include - -#include "cc2430_sfr.h" - -#include "dev/leds.h" -#include "dev/uart0.h" -#include "dev/uart1.h" -#include "sys/energest.h" - -#if UART_ZERO_ENABLE -static int (* uart0_input_handler)(unsigned char c); -#endif -#if UART_ONE_ENABLE -static int (* uart1_input_handler)(unsigned char c); -#endif - -#if UART_ZERO_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart0_set_input(int (* input)(unsigned char c)) -{ - uart0_input_handler = input; -} - -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -uart0_rx_ISR(void) __interrupt(URX0_VECTOR) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - TCON_URX0IF = 0; - if(uart0_input_handler != NULL) { - uart0_input_handler(U0BUF); - } - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -void -uart0_tx_ISR(void) __interrupt(UTX0_VECTOR) -{ -} -#pragma restore -#endif /* UART_ZERO_ENABLE */ -#if UART_ONE_ENABLE -/*---------------------------------------------------------------------------*/ -void -uart1_set_input(int (* input)(unsigned char c)) -{ - uart1_input_handler = input; -} -/*---------------------------------------------------------------------------*/ -#if UART_ONE_CONF_WITH_INPUT -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -uart1_rx_ISR(void) __interrupt(URX1_VECTOR) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - TCON_URX1IF = 0; - if(uart1_input_handler != NULL) { - uart1_input_handler(U1BUF); - } - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -void -uart1_tx_ISR(void) __interrupt(UTX1_VECTOR) -{ -} -#pragma restore -/*---------------------------------------------------------------------------*/ -#endif /* UART_ONE_CONF_WITH_INPUT */ -#endif /* UART_ONE_ENABLE */ diff --git a/cpu/cc2430/dev/watchdog-cc2430.c b/cpu/cc2430/dev/watchdog-cc2430.c deleted file mode 100644 index f8c4646a5..000000000 --- a/cpu/cc2430/dev/watchdog-cc2430.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Hardware-dependent functions used for the cc2430 watchdog timer. - * - * This file contains an ISR and must reside in the HOME bank. - * - * \author - * George Oikonomou - - */ - -#include "sys/energest.h" -#include "cc2430_sfr.h" -#include "contiki-conf.h" -#include "dev/watchdog-cc2430.h" - -/*---------------------------------------------------------------------------*/ -/* The watchdog only throws interrupts in timer mode */ -#if WDT_TIMER_MODE -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc4230_watchdog_ISR(void) __interrupt(WDT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* Do something */ - IRCON2 &= ~WDTIF; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#pragma restore -#endif -/*---------------------------------------------------------------------------*/ -void -watchdog_init(void) -{ - WDCTL = WDT_TIMER_MODE | WDT_INTERVAL; - -#if WDT_TIMER_MODE - /* Enable the watchdog interrupts in timer mode */ - IEN2 |= WDTIE; -#endif - return; -} -/*---------------------------------------------------------------------------*/ -void -watchdog_start(void) -{ - WDCTL |= WDT_EN; -} -/*---------------------------------------------------------------------------*/ -void -watchdog_periodic(void) -{ -#if WDT_TIMER_MODE - /* In timer mode, all we need to do is write 1 to WDT:CLR[0] */ - WDCTL |= WDT_CLR0; -#else - /* Write the 'clear' sequence while maintaining mode and interval setting */ - WDCTL = (WDCTL & 0x0F) | WDT_CLR3 | WDT_CLR1; - WDCTL = (WDCTL & 0x0F) | WDT_CLR2 | WDT_CLR0; -#endif -} -/*---------------------------------------------------------------------------*/ -void -watchdog_stop(void) -{ -#if WDT_TIMER_MODE - /* In timer mode, the watchdog can actually be stopped */ - WDCTL &= ~WDT_EN; - IRCON2 &= ~WDTIF; -#else - /* In watchdog mode, stopping is impossible so we just reset the timer */ - watchdog_periodic(); -#endif -} -/*---------------------------------------------------------------------------*/ -void -watchdog_reboot(void) -{ -#if WDT_TIMER_MODE - /* Switch modes to watchdog, minimum interval, enable */ - WDCTL = WDT_EN | WDT_TIMEOUT_2_MSEC; -#else - /* Let's get this over with ASAP */ - WDCTL = WDT_TIMEOUT_2_MSEC; -#endif - /* Dis-acknowledge all interrupts while we wait for the dog to bark */ - DISABLE_INTERRUPTS(); - /* NOP till the dog barks... */ - while(1) { - __asm - nop - __endasm; - } -} diff --git a/cpu/cc2430/dev/watchdog-cc2430.h b/cpu/cc2430/dev/watchdog-cc2430.h deleted file mode 100644 index 8ea81fa2c..000000000 --- a/cpu/cc2430/dev/watchdog-cc2430.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Hardware-dependent header file for the cc2430 watchdog timer. - * - * The interrupt service routine's prototype must be included by the - * file containing main(). - * - * \author - * George Oikonomou - - */ - -#ifndef WATCHDOG_CC2430_H_ -#define WATCHDOG_CC2430_H_ - -#include "dev/watchdog.h" -#include "cc2430_sfr.h" -#include "contiki-conf.h" - -#define WDT_TIMEOUT_1_SEC 0x00 -#define WDT_TIMEOUT_250_MSEC WDT_INT0 -#define WDT_TIMEOUT_15_MSEC WDT_INT1 -#define WDT_TIMEOUT_2_MSEC WDT_INT1 | WDT_INT0 - -#if WDT_CONF_TIMER_MODE -#define WDT_TIMER_MODE WDT_MODE /* Timer */ -#else -#define WDT_TIMER_MODE 0x00 /* Watchdog */ -#endif - -#ifdef WDT_CONF_INTERVAL -#define WDT_INTERVAL WDT_CONF_INTERVAL -#else -#define WDT_INTERVAL WDT_TIMEOUT_1_SEC /* 2 secs */ -#endif - -/* The watchdog only throws interrupts in timer mode */ -#if WDT_TIMER_MODE -void cc4230_watchdog_ISR(void) __interrupt (WDT_VECTOR); -#endif - -#endif /* WATCHDOG_CC2430_H_ */ diff --git a/cpu/cc2430/mtarch.h b/cpu/cc2430/mtarch.h deleted file mode 100644 index 9542270a1..000000000 --- a/cpu/cc2430/mtarch.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * 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. 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. - * - */ - -/* - * \file - * Stub header file for cc2430 multi-threading. It doesn't do anything, it - * just exists so that mt.c can compile cleanly. - * - * This is based on the original mtarch.h for z80 by Takahide Matsutsuka - * - * \author - * George Oikonomou - - */ -#ifndef MTARCH_H_ -#define MTARCH_H_ - -struct mtarch_thread { - unsigned char *sp; -}; - -#endif /* MTARCH_H_ */ diff --git a/cpu/cc2430/rtimer-arch.c b/cpu/cc2430/rtimer-arch.c deleted file mode 100644 index 1abff5c08..000000000 --- a/cpu/cc2430/rtimer-arch.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Hardware-dependent functions used to support the - * contiki rtimer module. - * - * clock and etimer are using the sleep timer on the cc2430 - * - * clock_init() has set our tick speed prescaler already, so we - * are ticking with 500 kHz freq. - * - * rtimer_clock_t is unsigned short (16bit on the cc2430) - * It thus makes sense to use the 16bit clock (Timer 1) - * - * This file contains an ISR and must reside in the HOME bank - * - * \author - * George Oikonomou - - */ - -#include "sys/rtimer.h" /* Includes rtimer-arch.h for us */ -#include "cc2430_sfr.h" -#include "sys/energest.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/*---------------------------------------------------------------------------*/ -void -rtimer_arch_init(void) -{ - PRINTF("rtimer_arch_init() "); - /* - * - Free running mode - * - Prescale by 32: - * Tick Speed has been prescaled to 500 kHz already in clock_init() - * We further prescale by 32 resulting in 15625 Hz for this timer. - */ - T1CTL = (T1DIV1 | T1MODE0); /* 00001001 */ - PRINTF("T1CTL=0x%02x\n", T1CTL); - /* Acknowledge Timer 1 Interrupts */ - IEN1_T1IE = 1; - PRINTF("IEN1_T1IE=0x%02x\n", IEN1_T1IE); - - /* Timer 1, Channel 1. Compare Mode (0x04), Interrupt mask on (0x40) */ - T1CCTL1 = T1MODE + T1IM; - PRINTF("T1CCTL1=0x%02x\n", T1CCTL1); - - /* Interrupt Mask Flags: No interrupt on overflow */ - TIMIF &= ~OVFIM; - PRINTF("TIMIF=0x%02x\n", TIMIF); - - PRINTF("done\n"); -} -/*---------------------------------------------------------------------------*/ -void -rtimer_arch_schedule(rtimer_clock_t t) -{ - PRINTF("rtimer_arch_schedule(%u)\n", t); - - /* set the compare mode values so we can get an interrupt after t */ - T1CC1L = (unsigned char)t; - T1CC1H = (unsigned char)(t >> 8); - PRINTF("T1CC1=%u, t=%u\n", (T1CC1L + (T1CC1H << 8)), t); - - /* Turn on compare mode interrupt */ - PRINTF("T1CTL=0x%02x\n", T1CTL); - T1CCTL1 |= T1IM; -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -cc2430_timer_1_ISR(void) __interrupt(T1_VECTOR) -{ - IEN1_T1IE = 0; /* Ignore Timer 1 Interrupts */ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - /* No more interrupts from Channel 1 till next rtimer_arch_schedule() call. - * Setting the mask will instantly generate an interrupt so we clear the - * flag first. */ - T1CTL &= ~(CH1IF); - T1CCTL1 &= ~T1IM; - - rtimer_run_next(); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - IEN1_T1IE = 1; /* Acknowledge Timer 1 Interrupts */ -} -#pragma restore diff --git a/cpu/cc2430/rtimer-arch.h b/cpu/cc2430/rtimer-arch.h deleted file mode 100644 index f007cff91..000000000 --- a/cpu/cc2430/rtimer-arch.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Hardware-dependent function declarations used to - * support the contiki rtimer module. - * - * We use Timer 1 on the cc2431. - * - * \author - * Zach Shelby (Original) - * George Oikonomou - - * (rtimer-arch implementation for cc2430) - */ - -#ifndef RTIMER_ARCH_H_ -#define RTIMER_ARCH_H_ - -#include "contiki-conf.h" -#include "cc2430_sfr.h" - -/* - * 32 MHz clock, prescaled down to 500 kHz for all 4 timers in clock_init(). - * Further prescaled factor 32 for T1, thus T1 is 15625 Hz - */ -#define RTIMER_ARCH_SECOND (15625U) - -#define rtimer_arch_now() ((rtimer_clock_t)(T1CNTL + (T1CNTH << 8))) - -void cc2430_timer_1_ISR(void) __interrupt(T1_VECTOR); - -#endif /* RTIMER_ARCH_H_ */ diff --git a/cpu/cc2430/segment.rules b/cpu/cc2430/segment.rules deleted file mode 100644 index 3b4ffbdfa..000000000 --- a/cpu/cc2430/segment.rules +++ /dev/null @@ -1,26 +0,0 @@ -# segment.rules files assign source code modules to specific banks -# These files are only used when we build code with banking (HAVE_BANKING=1) -# The final segment.rules file is constructed from any segment.rules found in -# the search path, defined in Makefile.cc2430 -# When building bankable code, the bank-alloc.py script automatically allocates -# modules to banks. segment.rules files provide hints, instructing the script -# as to which files are safe to move around and which files to leave alone -# In other words, only specify a rule for a file if you need to -# comments starting with "#" are supported -# The file spec in rules is actually interpreted as a python regex so you can -# write a rule that will match multiple files -# -# general rules -- -# This file is only used when the Makefile defines HAVE_BANKING=1 -# SDCC's standard libraries will always go in CSEG - We don't touch them -# Interrupt code must be in HOME. Specify all files with an ISR here -# All files without an associated rule get allocated to a bank automatically - -# Files with ISRs must be in HOME -HOME intr.c # Match all files ending in intr.c (e.g. uart_intr.c) -HOME rtimer-arch.c -HOME watchdog-cc2430.c -HOME clock.c - -# Some cc2430 files which need special treatment -HOME bus.c # bus.c::flash_read() must be run from HOME (if compiled in) diff --git a/cpu/cc2430/stack.c b/cpu/cc2430/stack.c deleted file mode 100644 index 7043b2edf..000000000 --- a/cpu/cc2430/stack.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2011, George Oikonomou - - * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * 8051 stack debugging facilities - * - * \author - * George Oikonomou - - * Philippe Retornaz (EPFL) - */ -#include "contiki.h" - -#ifndef STACK_POISON -#define STACK_POISON 0xAA -#endif - -CC_AT_DATA uint8_t sp; - -void -stack_poison(void) -{ - __asm - mov r1, _SP -poison_loop: - inc r1 - mov @r1, #STACK_POISON - cjne r1, #0xFF, poison_loop - __endasm; -} - -uint8_t -stack_get_max(void) -{ - __data uint8_t *sp = (__data uint8_t *)0xff; - uint8_t free = 0; - - while(*sp-- == STACK_POISON) { - free++; - } - - return 0xff - free; -} diff --git a/cpu/cc2430/stack.h b/cpu/cc2430/stack.h deleted file mode 100644 index 6ee7442b6..000000000 --- a/cpu/cc2430/stack.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2011, George Oikonomou - - * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for 8051 stack debugging facilities - * - * \author - * George Oikonomou - - * Philippe Retornaz (EPFL) - */ -#ifndef STACK_H_ -#define STACK_H_ - -#if STACK_CONF_DEBUGGING -extern CC_AT_DATA uint8_t sp; - -#define stack_dump(f) do { \ - putstring(f); \ - sp = SP; \ - puthex(sp); \ - putchar('\n'); \ -} while(0) - -#define stack_max_sp_print(f) do { \ - putstring(f); \ - puthex(stack_get_max()); \ - putchar('\n'); \ -} while(0) - -void stack_poison(void); -uint8_t stack_get_max(void); -#else -#define stack_dump(...) -#define stack_max_sp_print(...) -#define stack_poison() -#define stack_get_max() -#endif - -#endif /* STACK_H_ */ diff --git a/examples/sensinode/Makefile b/examples/sensinode/Makefile deleted file mode 100644 index cd1472d33..000000000 --- a/examples/sensinode/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# These examples don't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT += timer-test blink-hello broadcast-rime - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../.. -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/README.md b/examples/sensinode/README.md deleted file mode 100644 index 5168ff692..000000000 --- a/examples/sensinode/README.md +++ /dev/null @@ -1,60 +0,0 @@ -Sensinode platform example and test applications -================================================ - -by Zach Shelby - -Some more examples by George Oikonomou - -Loughborough University - -cc2431-location-engine, udp-ipv6, broadcast-rime blink-hello, event-post, -timer-test - -This directory contains example and test applications for Sensinode CC2430 -based devices. By default it is set to use the sensinode platform: - -/platform/sensinode -/cpu/cc2430 - -To build an application: - - make [app_name] - make hello_world - -To build and upload an application using the Sensinode nano_programmer included -under /tools (default /dev/ttyUSB0): - - make [app_name].upload - make hello_world.upload - -To dump the serial port output (default /dev/ttyUSB0): - - make sensinode.serialdump - -To configure the hardware model, you can include a make option e.g. for the -N601 (N100 is assumed by default): - - make hello_world DEFINES=MODEL_N601 - -These make options are defined in /platform/sensinode/Makefile.sensinode - -Descriptions of applications: - -- udp-ipv6: UDP client-server example over uIPv6. Uses link-local and global - addresses. Button 1 on the client will send an echo request. - -- broadcast-rime: Just a broadcast rime example, slightly modified - -- sensors: Demonstrating button and ADC functionality - -- cc2431-location-engine: Example demonstrating the usage cc2431 location - engine (blind node) N.B. Not all sensinode devides have a cc2431 - -- event-post: Demonstrating the interaction between two processes with custom - events - -- blink-hello: Hello World with LED blinking. - -- timer-test: Same as clock_test above + testing the rtimer-arch code - -- border-router: 802.15.4 to SLIP bridge example. The node will forward packets - from the 15.4 network to its UART (and thus a connected PC over SLIP) diff --git a/examples/sensinode/blink-hello.c b/examples/sensinode/blink-hello.c deleted file mode 100644 index 80d2fb9ad..000000000 --- a/examples/sensinode/blink-hello.c +++ /dev/null @@ -1,62 +0,0 @@ -/* This is a very simple hello_world program. - * It aims to demonstrate the co-existence of two processes: - * One of them prints a hello world message and the other blinks the LEDs - * - * It is largely based on hello_world in $(CONTIKI)/examples/sensinode - * - * Author: George Oikonomou - */ - -#include "contiki.h" -#include "dev/leds.h" - -#include -/*---------------------------------------------------------------------------*/ -PROCESS(hello_world_process, "Hello world process"); -PROCESS(blink_process, "LED blink process"); - -AUTOSTART_PROCESSES(&hello_world_process, &blink_process); -/*---------------------------------------------------------------------------*/ -/* Implementation of the first process */ -PROCESS_THREAD(hello_world_process, ev, data) -{ - static struct etimer timer; - static int count; - - PROCESS_BEGIN(); - - etimer_set(&timer, CLOCK_CONF_SECOND * 4); - count = 0; - - while(1) { - - PROCESS_WAIT_EVENT(); - - if(ev == PROCESS_EVENT_TIMER) { - printf("Sensor says no... #%d\r\n", count); - count++; - - etimer_reset(&timer); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/* Implementation of the second process */ -PROCESS_THREAD(blink_process, ev, data) -{ - static struct etimer timer; - PROCESS_BEGIN(); - - while(1) { - etimer_set(&timer, CLOCK_CONF_SECOND); - - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); - - printf("Blink... (state %0.2X).\r\n", leds_get()); - leds_toggle(LEDS_GREEN); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/border-router/Makefile b/examples/sensinode/border-router/Makefile deleted file mode 100644 index 38ebe9e27..000000000 --- a/examples/sensinode/border-router/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N601,PROJECT_CONF_H - -# We need uIPv6, therefore we also need banking -HAVE_BANKING=1 - -PROJECT_SOURCEFILES += slip-bridge.c - -CONTIKI_PROJECT = border-router -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -CONTIKI_WITH_IPV6 = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/border-router/README.md b/examples/sensinode/border-router/README.md deleted file mode 100644 index 92900008d..000000000 --- a/examples/sensinode/border-router/README.md +++ /dev/null @@ -1,20 +0,0 @@ -border-router example for sensinode devices -=========================================== - -This example is meant to be used with tunslip6 in tools/ - -- Build the code and load it onto your node -- Connect your node to your PC over USB -- run: - - sudo ./tunslip6
/ - -This will setup tun0 on your PC over device /dev/ttyUSBx. The address argument -should contain the v6 address that you want to assign to tun0 The node will use -this address to obtain the network prefix - -For example: - - sudo ./tunslip6 aaaa::1/64 - -This will use aaaa:: / 64 as the prefix for the 15.4 network. diff --git a/examples/sensinode/border-router/border-router.c b/examples/sensinode/border-router/border-router.c deleted file mode 100644 index 9442c9e03..000000000 --- a/examples/sensinode/border-router/border-router.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include - -#define DEBUG DEBUG_PRINT -#include "net/ip/uip-debug.h" -#include "net/rpl/rpl.h" -#include "dev/watchdog.h" -#include "dev/slip.h" -#include "dev/leds.h" -#include "dev/cc2430_rf.h" -#include "debug.h" - -static uint8_t prefix_set; - -#if DEBUG -#define PUTSTRING(...) putstring(__VA_ARGS__) -#define PUTHEX(...) puthex(__VA_ARGS__) -#define PUTBIN(...) putbin(__VA_ARGS__) -#define PUTDEC(...) putdec(__VA_ARGS__) -#define PUTCHAR(...) putchar(__VA_ARGS__) -#else -#define PUTSTRING(...) -#define PUTHEX(...) -#define PUTBIN(...) -#define PUTDEC(...) -#define PUTCHAR(...) -#endif -/*---------------------------------------------------------------------------*/ -PROCESS(border_router_process, "Border Router process"); -AUTOSTART_PROCESSES(&border_router_process); -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) CC_NON_BANKED -{ - int i; - uint8_t state; - - PUTSTRING("Router's IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PUTSTRING(" "); - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PUTCHAR('\n'); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - } - } -} -/*---------------------------------------------------------------------------*/ -static void -request_prefix(void) CC_NON_BANKED -{ - /* mess up uip_buf with a dirty request... */ - uip_buf[0] = '?'; - uip_buf[1] = 'P'; - uip_len = 2; - slip_send(); - uip_clear_buf(); -} -/*---------------------------------------------------------------------------*/ -/* Set our prefix when we receive one over SLIP */ -void -set_prefix_64(uip_ipaddr_t *prefix_64) -{ - rpl_dag_t *dag; - uip_ipaddr_t ipaddr; - memcpy(&ipaddr, prefix_64, 16); - prefix_set = 1; - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); - - /* Become root of a new DODAG with ID our global v6 address */ - dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr); - if(dag != NULL) { - rpl_set_prefix(dag, &ipaddr, 64); - PUTSTRING("Created a new RPL dag with ID: "); - PRINT6ADDR(&dag->dag_id); - PUTCHAR('\n'); - } -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(border_router_process, ev, data) -{ - static struct etimer et; - - PROCESS_BEGIN(); - PUTSTRING("Border Router started\n"); - prefix_set = 0; - - leds_on(LEDS_RED); - - /* Request prefix until it has been received */ - while(!prefix_set) { - leds_on(LEDS_GREEN); - PUTSTRING("Prefix request.\n"); - etimer_set(&et, CLOCK_SECOND); - request_prefix(); - leds_off(LEDS_GREEN); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - } - - /* We have created a new DODAG when we reach here */ - PUTSTRING("On Channel "); - PUTDEC(cc2430_rf_channel_get()); - PUTCHAR('\n'); - - print_local_addresses(); - - leds_off(LEDS_RED); - - PROCESS_EXIT(); - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/border-router/project-conf.h b/examples/sensinode/border-router/project-conf.h deleted file mode 100644 index 17cbe3193..000000000 --- a/examples/sensinode/border-router/project-conf.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Project specific configuration defines for the border router / - * slip bridge example. - * - * We make sure that SLIP is turned on - * - * \author - * George Oikonomou - - */ - -#ifndef PROJECT_CONF_H_ -#define PROJECT_CONF_H_ - -#define VIZTOOL_MAX_PAYLOAD_LEN 120 -#define SLIP_ARCH_CONF_ENABLE 1 -#define LPM_CONF_MODE 0 -#define UIP_FALLBACK_INTERFACE slip_interface - -#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensinode/border-router/slip-bridge.c b/examples/sensinode/border-router/slip-bridge.c deleted file mode 100644 index b0ebd066d..000000000 --- a/examples/sensinode/border-router/slip-bridge.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * Slip fallback interface - * \author - * Niclas Finne - * Joakim Eriksson - * Joel Hoglund - * Nicolas Tsiftes - */ - -#include "net/ip/uip.h" -#include "net/ipv6/uip-ds6.h" -#include "net/rpl/rpl.h" -#include "dev/slip.h" -#include "dev/uart1.h" -#include - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -void set_prefix_64(uip_ipaddr_t *); - -static uip_ipaddr_t last_sender; -/*---------------------------------------------------------------------------*/ -static void -slip_input_callback(void) -{ - PRINTF("SIN: %u\n", uip_len); - if((char)uip_buf[0] == '!') { - PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_clear_buf(); - if((char)uip_buf[1] == 'P') { - uip_ipaddr_t prefix; - /* Here we set a prefix !!! */ - memset(&prefix, 0, 16); - memcpy(&prefix, &uip_buf[2], 8); - PRINTF("Setting prefix "); - PRINT6ADDR(&prefix); - PRINTF("\n"); - set_prefix_64(&prefix); - } - } - /* Save the last sender received over SLIP to avoid bouncing the - packet back if no route is found */ - uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ - process_start(&slip_process, NULL); - slip_set_input_callback(slip_input_callback); -} -/*---------------------------------------------------------------------------*/ -static int -output(void) -{ - if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { - /* Do not bounce packets back over SLIP if the packet was received - over SLIP */ - PRINTF("slip-bridge: Destination off-link but no route\n"); - } else { - PRINTF("SUT: %u\n", uip_len); - slip_send(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -const struct uip_fallback_interface slip_interface = { - init, output -}; -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/broadcast-rime.c b/examples/sensinode/broadcast-rime.c deleted file mode 100644 index f69c2a1bc..000000000 --- a/examples/sensinode/broadcast-rime.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2007, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Testing the broadcast layer in Rime - * \author - * Adam Dunkels - */ -#include "contiki.h" -#include "net/rime/rime.h" -#include "lib/random.h" -#include "net/rime/rimestats.h" -#include "dev/leds.h" -#include "dev/models.h" - -#define DEBUG 1 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -#define BROADCAST_CHANNEL 129 - -/*---------------------------------------------------------------------------*/ -PROCESS(example_broadcast_process, "BROADCAST example"); -AUTOSTART_PROCESSES(&example_broadcast_process); -/*---------------------------------------------------------------------------*/ -static void -broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) -{ - leds_toggle(LEDS_RED); - PRINTF("broadcast message received from %02x.%02x\n", from->u8[0], - from->u8[1]); - PRINTF("Size=0x%02x: '0x%04x'\n", packetbuf_datalen(), - *(uint16_t *)packetbuf_dataptr()); -} -/*---------------------------------------------------------------------------*/ -static void -print_rime_stats() -{ - PRINTF("\nNetwork Stats\n"); - PRINTF(" TX=%lu , RX=%lu\n", RIMESTATS_GET(tx), RIMESTATS_GET(rx)); - PRINTF("LL-TX=%lu , LL-RX=%lu\n", RIMESTATS_GET(lltx), RIMESTATS_GET(llrx)); - PRINTF(" Long=%lu , Short=%lu\n", RIMESTATS_GET(toolong), - RIMESTATS_GET(tooshort)); - PRINTF("T/Out=%lu , CCA-Err=%lu\n", RIMESTATS_GET(timedout), - RIMESTATS_GET(contentiondrop)); -} - -static const struct broadcast_callbacks bc_rx = { broadcast_recv }; -static struct broadcast_conn broadcast; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(example_broadcast_process, ev, data) -{ - static struct etimer et; - static uint16_t counter; - - PROCESS_EXITHANDLER(broadcast_close(&broadcast);) - - PROCESS_BEGIN(); - - PRINTF("Start\n"); - broadcast_open(&broadcast, BROADCAST_CHANNEL, &bc_rx); - PRINTF("Open Broadcast Connection, channel %u\n", BROADCAST_CHANNEL); - - while(1) { - - /* Delay 2-4 seconds */ - etimer_set(&et, CLOCK_SECOND * 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - leds_on(LEDS_GREEN); - packetbuf_copyfrom(&counter, sizeof(counter)); - PRINTF("Sending %u bytes: 0x%04x\n", packetbuf_datalen(), - *(uint16_t *)packetbuf_dataptr()); - if(broadcast_send(&broadcast) == 0) { - PRINTF("Error Sending\n"); - } - - print_rime_stats(); - PRINTF("===================================\n"); - counter++; - leds_off(LEDS_GREEN); - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/cc2431-location-engine/Makefile b/examples/sensinode/cc2431-location-engine/Makefile deleted file mode 100644 index 4a14b80a9..000000000 --- a/examples/sensinode/cc2431-location-engine/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = blind-node - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/cc2431-location-engine/blind-node.c b/examples/sensinode/cc2431-location-engine/blind-node.c deleted file mode 100644 index f4c4aeacd..000000000 --- a/examples/sensinode/cc2431-location-engine/blind-node.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example demonstrating the cc2431 location engine. - * - * This file contains code for the blind node. The blind node must be - * equipped with a cc2431 SoC (as opposed to reference nodes which - * don't need to have a Loc. Eng.) - * - * The blind node receives co-ordinates of reference nodes over - * broadcast rime. Once it has enough data (3+ reference nodes), it - * will calculate its own position. - * - * We calculate with all potential values for parameter 'n' to - * demonstrate how 'n' influences the result of the calculation. - * - * Optionally, send the result of the calculation to a collection node - * - * More information on the cc2431 Location Engine can be found in: - * - cc2431 Datasheet - * - Texas Instruments Application Note 42 - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "net/rime/rime.h" -#include "cc2431_loc_eng.h" -#include "cc2430_sfr.h" - -#include -#include - -#define MAX_REF_NODES 16 /* Do not change */ - -#define SAMPLE_RSSI 100 /* Used for testing */ -#define SAMPLE_ALPHA 101 - -static struct meas_params parameters; -static struct refcoords ref_coords[MAX_REF_NODES]; - -/* Store our current location here to be transmitted to a collector node */ -static uint8_t coords[2]; - -/*---------------------------------------------------------------------------*/ -PROCESS(blindnode_bcast_rec, "Blind Node"); -AUTOSTART_PROCESSES(&blindnode_bcast_rec); -/*---------------------------------------------------------------------------*/ -/* - * This handles the calculation cycle. Returns non-zero on error, 0 on success. - * - * When we move this outside the example, we will perhaps want to pass - * struct refcoords *, struct meas_params * - * instead of exposing our own data structures. If this happens, we will need - * to add checks to our code to detect non-sane values - */ -static uint8_t -calculate() -{ - static int j, x; - uint8_t valid_rssi = 0; - - /* Turn on the Engine */ - LOCENG = LOCENG_EN; - while(!(LOCENG & LOCENG_EN)); - - /* Reference Coordinate Load Stage */ - LOCENG |= LOCENG_REFLD; - while(!(LOCENG & LOCENG_REFLD)); - - for(j = 0; j < MAX_REF_NODES; j++) { - /* Write the Reference Node x,y into the engine */ - REFCOORD = ref_coords[j].x; - REFCOORD = ref_coords[j].y; - } - - /* Reference Coordinate Load Stage Done. Proceed with measured params */ - LOCENG &= ~LOCENG_REFLD; - LOCENG |= LOCENG_PARLD; - - /* Load Parameters */ - MEASPARM = parameters.alpha; - MEASPARM = parameters.n; - MEASPARM = parameters.x_min; - MEASPARM = parameters.x_delta; - MEASPARM = parameters.y_min; - MEASPARM = parameters.y_delta; - - /* Load Neighbor RSSIs */ - for(j = 0; j < MAX_REF_NODES; j++) { - if(parameters.rssi[j] != 0) { - /* Range-check for the RSSI here, can only be in [-95 dBm , -40 dBm] - * so we only accept 80 <= rssi <= 190*/ - if(parameters.rssi[j] >= 80 && parameters.rssi[j] <= 190) { - valid_rssi++; - } - } - /* Write the value, even if it's zero */ - MEASPARM = parameters.rssi[j]; - } - - /* Done with measured parameters too */ - LOCENG &= ~LOCENG_PARLD; - - /* Only Calculate if we have 3+ reference nodes (non-zero RSSIs) */ - if(valid_rssi >= 3) { - LOCENG |= LOCENG_RUN; - } else { - LOCENG = 0; - printf("some error\n"); - return 1; - } - - /* Block on the calculation, between 50us and 13ms */ - while(!(LOCENG & LOCENG_DONE)); - - /* - * LOCX contains an offset. Remove it to obtain our actual X value. - * cc2431 datasheet, section 2.1.3 - */ - x = (LOCX - parameters.x_min + 1) % (parameters.x_delta + 1) - + parameters.x_min; - coords[0] = x; - coords[1] = LOCY; /* No offset here */ - printf("n=%2u: X=%3u, Y=%3u\n", parameters.n, LOCX, LOCY); - - /* Turn it off */ - LOCENG = 0; - - return 0; -} - -/*---------------------------------------------------------------------------*/ -/* - * We receive X, Y from reference nodes. - * We store this in location J of the ref_coords array, where J is the LSB - * of the reference node's rime address. So we can only accept data from nodes - * with rime address ending in [0 , 15] - */ -static void -broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) -{ - packetbuf_attr_t rssi; /* Careful here, this is uint16_t */ - - if(from->u8[1] < MAX_REF_NODES) { - memset(&ref_coords[from->u8[1] - 1], 0, sizeof(struct refcoords)); - - /* Obtain incoming message's RSSI from contiki */ - rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI); - /* Convert RSSI to the loc. eng. format */ - parameters.rssi[from->u8[1] - 1] = (-2 * rssi); - /* Raw dump the packetbuf into the ref_coords struct */ - memcpy(&ref_coords[from->u8[1] - 1], packetbuf_dataptr(), - 2 * sizeof(uint8_t)); - } - - return; -} -/* - * Imaginary nodes to test functionality - * All nodes at 1 meter distance, rssi = -40 (80) - * Since the rssi at 1 meter = -40 (A), the blind node should think it's at - * 5,5 - */ -/*---------------------------------------------------------------------------*/ -static void -set_imaginary_ref_nodes() -{ - ref_coords[0].x = 1; - ref_coords[0].y = 5; - parameters.rssi[0] = SAMPLE_RSSI; - - ref_coords[1].x = 5; - ref_coords[1].y = 1; - parameters.rssi[1] = SAMPLE_RSSI; - - ref_coords[2].x = 5; - ref_coords[2].y = 9; - parameters.rssi[2] = SAMPLE_RSSI; - - ref_coords[3].x = 9; - ref_coords[3].y = 5; - parameters.rssi[3] = SAMPLE_RSSI; -} -/*---------------------------------------------------------------------------*/ -static const struct broadcast_callbacks broadcast_call = { broadcast_recv }; -static struct broadcast_conn broadcast; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(blindnode_bcast_rec, ev, data) -{ - static struct etimer et; - static uint8_t n; - int i; - - PROCESS_EXITHANDLER(broadcast_close(&broadcast)); - - PROCESS_BEGIN(); - - printf("Reading Chip ID: 0x%02x\n", CHIPID); - /* Read our chip ID. If we are not cc2431, bail out */ - if(CHIPID != CC2431_CHIP_ID) { - printf("Hardware does not have a location engine. Exiting.\n"); - PROCESS_EXIT(); - } - - /* OK, we are cc2431. Do stuff */ - n = 0; - - /* Initalise our structs and parameters */ - memset(ref_coords, 0, sizeof(struct refcoords) * MAX_REF_NODES); - memset(¶meters, 0, sizeof(struct meas_params)); - - /* - * Just hard-coding measurement parameters here. - * Ideally, this should be part of a calibration mechanism - */ - parameters.alpha = SAMPLE_ALPHA; - parameters.x_min = 0; - parameters.x_delta = 255; - parameters.y_min = 0; - parameters.y_delta = 255; - - set_imaginary_ref_nodes(); - - broadcast_open(&broadcast, 129, &broadcast_call); - - while(1) { - - etimer_set(&et, CLOCK_SECOND); - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - /* - * With the hard-coded parameters and locations, we will calculate - * for all possible values of n [0 , 31] - */ - parameters.n = n; - calculate(); - n++; - if(n == 32) { - n = 0; - } - - /* Send our calculated location to some monitoring node */ - packetbuf_copyfrom(&coords, 2 * sizeof(uint8_t)); - broadcast_send(&broadcast); - } - PROCESS_END(); -} diff --git a/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h b/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h deleted file mode 100644 index b5489797c..000000000 --- a/examples/sensinode/cc2431-location-engine/cc2431_loc_eng.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file used by the example demonstrating the cc2431 location - * engine. - * - * This file contains declarations of the location engine registers and - * the LOCENG register bits. It also contains some data structures used - * to store calculation parameters and reference node coordinates. - * - * This file only needs to be included bye the blind node code file. - * - * More information on the cc2431 Location Engine can be found in: - * - cc2431 Datasheet - * - K. Aamodt, "CC2431 Location Engine", Texas Instruments Application - * Note 42. - * - * \author - * George Oikonomou - - */ - -#include "8051def.h" -#include /* For syntax parsers */ - -/* Location Engine Registers on the cc2431 */ -__xdata __at (0xDF55) unsigned char REFCOORD; -__xdata __at (0xDF56) unsigned char MEASPARM; -__xdata __at (0xDF57) unsigned char LOCENG; -__xdata __at (0xDF58) unsigned char LOCX; -__xdata __at (0xDF59) unsigned char LOCY; - -/* LOCENG Register Bits */ -#define LOCENG_RUN 0x01 -#define LOCENG_REFLD 0x02 -#define LOCENG_PARLD 0x04 -#define LOCENG_DONE 0x08 -#define LOCENG_EN 0x10 - -/* cc2431 chips report 0x89 when the CHIPID register is read */ -#define CC2431_CHIP_ID 0x89 - -/* - * Struct for the Calculation Parameters. - * Values stored here feed the MEASPARM register. - * - * Values should be stored here in Location Engine format: - * RSSI: 0.5 Precision, without the minus sign. All 16 must be used. Use 0 - * to reduce the number of ref. nodes used in the calculation. - * Value range [-95 dBm , -40 dBm] - * A: 0.5 Precision. Value range [30.0 , 50.0] (Thus [60 , 100] decimal) - * n: Use the n Index value [0 , 31] - See cc2431 datasheet, Table 2. - * delta: Must be present. If we want the calculation to be unrestricted, - * use 0xFF - * - */ -struct meas_params { - uint8_t alpha; - uint8_t n; - uint8_t x_min; - uint8_t x_delta; - uint8_t y_min; - uint8_t y_delta; - uint8_t rssi[16]; -}; - -/* - * Store the reference node coordinates here. - * This will feed REFCOORD. - * - * Values should be stored here in Location Engine format: - * 2 LS bits for the fractional part, 0.25 precision - * 6 MS bits for the integral part. - * Value range [0 , 63.75] (thus [0 , 255]) - */ -struct refcoords { - uint8_t x; - uint8_t y; -}; diff --git a/examples/sensinode/disco/Makefile b/examples/sensinode/disco/Makefile deleted file mode 100644 index 9c1903d4b..000000000 --- a/examples/sensinode/disco/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -HAVE_BANKING=1 -OFFSET_FIRMWARE=1 - -CONTIKI_PROJECT = disco-example - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -CONTIKI_WITH_IPV6 = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/disco/disco-example.c b/examples/sensinode/disco/disco-example.c deleted file mode 100644 index 8f97a13fc..000000000 --- a/examples/sensinode/disco/disco-example.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Stub project source file. We just need to build contiki with - * OFFSET_FIRMWARE, Makefile does so. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" - -/*---------------------------------------------------------------------------*/ -PROCESS(stub_process, "Stub process"); -AUTOSTART_PROCESSES(&stub_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(stub_process, ev, data) -{ - PROCESS_BEGIN(); - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/energy-scan/Makefile b/examples/sensinode/energy-scan/Makefile deleted file mode 100644 index e91d74b96..000000000 --- a/examples/sensinode/energy-scan/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -PROJECT_SOURCEFILES += stub-rdc.c - -CONTIKI_PROJECT = energy-scan - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. - -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/energy-scan/energy-scan.c b/examples/sensinode/energy-scan/energy-scan.c deleted file mode 100644 index 7f90e593a..000000000 --- a/examples/sensinode/energy-scan/energy-scan.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Minimalistic channel energy detection. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "cc2430_sfr.h" - -#include "debug.h" -#include "dev/cc2430_rf.h" -#include - -static uint8_t channel; -static int8_t j; -static int8_t cmax; -static int8_t rssi; -static struct etimer et; -static rtimer_clock_t t0; - -#define RSSI_BASE -50 -#define RSSI_SAMPLES 30 -#define SAMPLE_INTERVAL (CLOCK_SECOND) -#define CHANNEL_MIN 11 -#define CHANNEL_MAX 26 -/* ToDo: Do this in infinite RX. Take more samples */ -/*---------------------------------------------------------------------------*/ -PROCESS(energy_scan, "Energy Scanner"); -AUTOSTART_PROCESSES(&energy_scan); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(energy_scan, ev, data) -{ - - PROCESS_BEGIN(); - - printf("Energy Scanner\n"); - printf("CCA Threshold: %d\n", (int8_t)RSSIH); - printf("Channel scan range: [%u , %u]\n", CHANNEL_MIN, CHANNEL_MAX); - printf("%u samples per channel, interval %u ticks\n", - RSSI_SAMPLES, SAMPLE_INTERVAL); - - channel = CHANNEL_MIN; - while(1) { - cmax = RSSI_BASE; - cc2430_rf_channel_set(channel); - clock_delay_usec(200); - - for(j = 0; j < RSSI_SAMPLES; j++) { - t0 = RTIMER_NOW(); - rssi = RSSIL; - if(rssi > cmax) { - cmax = rssi; - } - while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + 25)); - } - printf("%u [%3d]: ", channel, cmax); - for(j = RSSI_BASE; j <= cmax; j++) { - printf("#"); - } - printf("\n"); - if(channel == CHANNEL_MAX) { - printf("===============\n"); - channel = CHANNEL_MIN; - } else { - channel++; - } - - etimer_set(&et, SAMPLE_INTERVAL); - PROCESS_YIELD(); - - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/energy-scan/netstack.c b/examples/sensinode/energy-scan/netstack.c deleted file mode 100644 index d59acc3fe..000000000 --- a/examples/sensinode/energy-scan/netstack.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Stub file overriding core/net/netstack.c. What we want to achieve - * here is call netstack_init from main without initialising the RDC, - * MAC and Network layers. It will just turn on the radio instead. - * - * \author - * George Oikonomou - - */ - -#include "netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/energy-scan/project-conf.h b/examples/sensinode/energy-scan/project-conf.h deleted file mode 100644 index 91c1917e4..000000000 --- a/examples/sensinode/energy-scan/project-conf.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Project specific configuration defines for the sniffer example. - * - * We make sure that the radio driver outputs all packets in hexdump - * format. - * - * \author - * George Oikonomou - - */ - -#ifndef PROJECT_CONF_H_ -#define PROJECT_CONF_H_ - -#define NETSTACK_CONF_RDC stub_rdc_driver -#define ADC_SENSOR_CONF_ON 0 -#define LPM_CONF_MODE 0 - -#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensinode/energy-scan/stub-rdc.c b/examples/sensinode/energy-scan/stub-rdc.c deleted file mode 100644 index ed335fc70..000000000 --- a/examples/sensinode/energy-scan/stub-rdc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Definition of a fake RDC driver to be used with passive - * examples. The code will never send packets and it will never - * push incoming packets up the stack. We do this by defining this - * driver as our RDC. We then drop everything - * - * \author - * George Oikonomou - - */ - -#include "net/mac/mac.h" -#include "net/mac/rdc.h" -/*---------------------------------------------------------------------------*/ -static void -send(mac_callback_t sent, void *ptr) -{ - if(sent) { - sent(ptr, MAC_TX_OK, 1); - } -} -/*---------------------------------------------------------------------------*/ -static void -send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) -{ - if(sent) { - sent(ptr, MAC_TX_OK, 1); - } -} -/*---------------------------------------------------------------------------*/ -static void -input(void) -{ -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -off(int keep_radio_on) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static unsigned short -cca(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ -} -/*---------------------------------------------------------------------------*/ -const struct rdc_driver stub_rdc_driver = { - "stub-rdc", - init, - send, - send_list, - input, - on, - off, - cca, -}; -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/event-post/Makefile b/examples/sensinode/event-post/Makefile deleted file mode 100644 index 114de943f..000000000 --- a/examples/sensinode/event-post/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = event-post - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/event-post/event-post.c b/examples/sensinode/event-post/event-post.c deleted file mode 100644 index 7a091cfa7..000000000 --- a/examples/sensinode/event-post/event-post.c +++ /dev/null @@ -1,98 +0,0 @@ -/* This file demonstrates the interaction between two processes via events. - * - * - "Sensor process": Throws an event periodically. This can be for example a - * sensor value. - * - "Print process" : Waits for events from "Sensor" and prints a message when - * an event occurs (e.g. prints the sensor value) - * - * This example is derived from the contiki code examples for the WSN430 - * (SensTools - Inria: http://senstools.gforge.inria.fr/) - * - * Author: George Oikonomou - */ - -#include "contiki.h" -//#include "dev/leds.h" -#include -#include -#include "event-post.h" - -/* This is our event type */ -static process_event_t event_data_ready; -/*---------------------------------------------------------------------------*/ -/* Declare the two processes here */ -PROCESS(sensor_process, "Sensor process"); -PROCESS(print_process, "Print process"); - -AUTOSTART_PROCESSES(&sensor_process, &print_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sensor_process, ev, data) -{ - static struct etimer timer; - static struct event_struct es; - - PROCESS_BEGIN(); - - es.s_val = SHRT_MAX - 2; - es.i_val = INT_MAX - 2; - es.l_val = LONG_MAX - 2; - es.ll_val = LONG_MAX - 2; - es.u8_val = UCHAR_MAX - 2; - es.u16_val = USHRT_MAX - 2; - es.u32_val = ULONG_MAX - 2; - - event_data_ready = process_alloc_event(); - - printf("Contiki allocated event ID %d.\r\n", event_data_ready); - - etimer_set(&timer, CLOCK_CONF_SECOND * 2); - - while(1) { - printf("Sensor process: Wait for timer event...\r\n"); - - PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); - - printf("Sensor Process: Incrementing values...\r\n"); - es.s_val++; - es.i_val++; - es.l_val++; - es.ll_val++; - es.u8_val++; - es.u16_val++; - es.u32_val++; - - printf("Sensor Process: Generating 'Data Ready' event.\r\n"); - process_post(&print_process, event_data_ready, &es); - - etimer_reset(&timer); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -/* Implementation of "Print Process" */ -PROCESS_THREAD(print_process, ev, data) -{ - - struct event_struct *sd; - - PROCESS_BEGIN(); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(ev == event_data_ready); - - sd = data; - printf("Print Process - Data Ready:\r\n"); - printf(" s: %d\r\n", sd->s_val); - printf(" i: %d\r\n", sd->i_val); - printf(" l: %ld\r\n", sd->l_val); - printf(" ll: %lld\r\n", sd->ll_val); - printf(" u8: %u\r\n", sd->u8_val); - printf(" u16: %u\r\n", sd->u16_val); - printf(" u32: %lu\r\n", sd->u32_val); - - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/event-post/event-post.h b/examples/sensinode/event-post/event-post.h deleted file mode 100644 index 650d38b4a..000000000 --- a/examples/sensinode/event-post/event-post.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * event-post.h - * Header file for the event_post example - * - * Created on: 30 Mar 2010 - * Author: George Oikonomou - */ - -#ifndef EVENT_POST_H_ -#define EVENT_POST_H_ - -struct event_struct { - short s_val; - int i_val; - long l_val; - long long ll_val; - uint8_t u8_val; - uint16_t u16_val; - uint32_t u32_val; -}; - -#endif /* EVENT_POST_H_ */ diff --git a/examples/sensinode/sensors-ipv6/Makefile b/examples/sensinode/sensors-ipv6/Makefile deleted file mode 100644 index 4332e42c9..000000000 --- a/examples/sensinode/sensors-ipv6/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -# This example won't fit in flash without banking so we turn it on -HAVE_BANKING=1 - -CONTIKI_SOURCEFILES += sensors-driver.c - -CONTIKI_PROJECT = sensors-ipv6 -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_IPV6 = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sensors-ipv6/project-conf.h b/examples/sensinode/sensors-ipv6/project-conf.h deleted file mode 100644 index 053f48d85..000000000 --- a/examples/sensinode/sensors-ipv6/project-conf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Project specific configuration defines for the UDP client/server - * example. - * - * We make sure that buttons and ADC are on. We also demonstrate the - * new LPM functionality - * - * \author - * George Oikonomou - - */ - -#ifndef PROJECT_CONF_H_ -#define PROJECT_CONF_H_ - -#define BUTTON_SENSOR_CONF_ON 1 -#define ADC_SENSOR_CONF_ON 1 -#define LPM_CONF_MODE 0 -#define VIZTOOL_CONF_ON 0 - -#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensinode/sensors-ipv6/sensors-driver.c b/examples/sensinode/sensors-ipv6/sensors-driver.c deleted file mode 100644 index c3e90a13b..000000000 --- a/examples/sensinode/sensors-ipv6/sensors-driver.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file handles the sensor readings and float conversions - * for sensors-example. We keep this separate in order to place it - * to a higher BANK. - * - * Bankable - * - * \author - * George Oikonomou - - */ - -#include "contiki-conf.h" -#include "uip.h" /* for htons / htonl */ -#include "dev/leds.h" -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#endif - -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -#include -#include - -#define SENSOR_OK 0 -#define SENSOR_ADC_OFF -1 -#define SENSOR_UNKNOWN -2 - -/* Request Bits */ -#define REQUEST_BIT_P0_GET 0x0400 -#define REQUEST_BIT_L2_SET 0x0200 -#define REQUEST_BIT_L1_SET 0x0100 -#define REQUEST_BIT_LED_GET 0x0080 -#define REQUEST_BIT_ACC 0x0040 -#define REQUEST_BIT_BAT 0x0020 -#define REQUEST_BIT_VDD 0x0010 -#define REQUEST_BIT_TEMP 0x0008 -#define REQUEST_BIT_LIGHT 0x0004 -#define REQUEST_BIT_UPTIME 0x0002 -#define REQUEST_BIT_CHIPID 0x0001 - -/*---------------------------------------------------------------------------*/ -int8_t -read_sensor(char *rs) -{ - /* Sensor Values */ - static int rv; - static struct sensors_sensor *sensor; - - /* Those 3 variables are only used for debugging */ -#if DEBUG - static float sane = 0; - static int dec; - static float frac; -#endif - uint16_t r; - uint8_t len = 0; - - sensor = sensors_find(ADC_SENSOR); - if(!sensor) { - PRINTF("ADC not found\n"); - return (SENSOR_ADC_OFF); - } - - /* Fetch the request bytes */ - memcpy(&r, rs, 2); - r = uip_ntohs(r); - PRINTF("R=%u\n", r); - - if(r & REQUEST_BIT_CHIPID) { - uint8_t chipid = CHIPID; - memcpy(rs + len, &chipid, sizeof(chipid)); - len += sizeof(chipid); - PRINTF("ChipID=0x%02x\n", chipid); - } - if(r & REQUEST_BIT_UPTIME) { - /* Uptime */ - unsigned long l; - - l = uip_htonl(clock_seconds()); - memcpy(rs + len, &l, sizeof(l)); - len += sizeof(l); - PRINTF("Uptime=%lu secs\n", uip_ntohl(l)); - } - if(r & REQUEST_BIT_LIGHT) { - rv = sensor->value(ADC_SENSOR_TYPE_LIGHT); - if(rv != -1) { -#if DEBUG - sane = (float)(rv * 0.4071); - dec = sane; - frac = sane - dec; - PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & REQUEST_BIT_TEMP) { - rv = sensor->value(ADC_SENSOR_TYPE_TEMP); - if(rv != -1) { -#if DEBUG - sane = ((rv * 0.61065 - 773) / 2.45); - dec = sane; - frac = sane - dec; - PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & (REQUEST_BIT_VDD | REQUEST_BIT_BAT)) { - /* We want VDD for both cases */ - rv = sensor->value(ADC_SENSOR_TYPE_VDD); - if(rv != -1) { -#if DEBUG - sane = rv * 3.75 / 2047; - dec = sane; - frac = sane - dec; - PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); - /* Store rv temporarily in dec so we can use it for the battery */ - dec = rv; -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - /* And then carry on with battery if needed */ - if(r & REQUEST_BIT_BAT) { - rv = sensor->value(ADC_SENSOR_TYPE_BATTERY); - if(rv != -1) { -#if DEBUG - sane = (11.25 * rv * dec) / (0x7FE002); - dec = sane; - frac = sane - dec; - PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - } - if(r & REQUEST_BIT_ACC) { - rv = sensor->value(ADC_SENSOR_TYPE_ACC_X); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - - PRINTF(" AccX="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - PRINTF(" AccY="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z); - if(rv != -1) { -#if DEBUG - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - PRINTF(" AccZ="); - if(sane < 0 && dec == 0) { - PRINTF('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); -#endif - memcpy(rs + len, &rv, sizeof(rv)); - len += sizeof(rv); - } - } - if(r & REQUEST_BIT_L1_SET) { - leds_toggle(LEDS_GREEN); - } - if(r & REQUEST_BIT_L2_SET) { - leds_toggle(LEDS_RED); - } - if(r & REQUEST_BIT_LED_GET) { - uint8_t leds = leds_get(); - memcpy(rs + len, &leds, sizeof(leds)); - len += sizeof(leds); - PRINTF(" LED 2=%u\n", leds); - } - if(r & REQUEST_BIT_P0_GET) { - uint8_t p0 = P0_3; - memcpy(rs + len, &p0, sizeof(p0)); - len += sizeof(p0); - } - return len; -} diff --git a/examples/sensinode/sensors-ipv6/sensors-ipv6.c b/examples/sensinode/sensors-ipv6/sensors-ipv6.c deleted file mode 100644 index 1b563975b..000000000 --- a/examples/sensinode/sensors-ipv6/sensors-ipv6.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example to demonstrate-test the sensors functionality on - * sensinode/cc2430 devices. - * - * A UDP/IPv6 process waits for requests from a monitoring station - * and responds with sensor values. - * - * The message exchange is based on a custom protocol. - * Check sensors-driver.c for protocol details. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -#include "dev/watchdog.h" -#include "dev/leds.h" -#include "net/rpl/rpl.h" -#include - -#if CONTIKI_TARGET_SENSINODE -#include "debug.h" -#include "dev/sensinode-sensors.h" -#else -#define putstring(s) -#endif - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *server_conn; -static char buf[MAX_PAYLOAD_LEN]; -static uint16_t len; - -#define SERVER_PORT 60000 - -#define SENSOR_OK 0 -#define SENSOR_ADC_OFF 1 -#define SENSOR_UNKNOWN 2 - -int8_t read_sensor(char *rs); -/*---------------------------------------------------------------------------*/ -extern const struct sensors_sensor adc_sensor; -/*---------------------------------------------------------------------------*/ -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - memset(buf, 0, MAX_PAYLOAD_LEN); - - if(uip_newdata()) { - len = uip_datalen(); - memcpy(buf, uip_appdata, len); - PRINTF("%u bytes from [", len); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); - len = read_sensor(buf); - if(len) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, buf, len); - PRINTF("Sent %u bytes\n", len); - } - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - return; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static struct sensors_sensor *b1; - static struct sensors_sensor *b2; -#endif - - PROCESS_BEGIN(); - putstring("Starting UDP server\n"); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - putstring("Button X: Toggle LED X\n"); -#endif - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(SERVER_PORT)); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - b1 = sensors_find(BUTTON_1_SENSOR); - b2 = sensors_find(BUTTON_2_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - } else if(ev == sensors_event && data != NULL) { - if(data == b1) { - leds_toggle(LEDS_GREEN); - } else if(data == b2) { - leds_toggle(LEDS_RED); - } -#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */ - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sensors/Makefile b/examples/sensinode/sensors/Makefile deleted file mode 100644 index 8502ff884..000000000 --- a/examples/sensinode/sensors/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -# This example doesn't need code banking so we turn it off -#HAVE_BANKING=1 - -CONTIKI_PROJECT = sensors-example - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sensors/sensors-example.c b/examples/sensinode/sensors/sensors-example.c deleted file mode 100644 index 4df6a7ac3..000000000 --- a/examples/sensinode/sensors/sensors-example.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Example to demonstrate-test the sensors functionality on - * sensinode/cc2430 devices. - * - * B1 turns L2 on and off. - * B2 reboots the node via the watchdog. - * - * The node takes readings from the various sensors every x seconds and - * prints out the results. - * - * We use floats here to translate the AD conversion results to - * meaningful values. However, our printf does not have %f support so - * we use an ugly hack to print out the value by extracting the integral - * part and then the fractional part. Don't try this at home. - * - * Temperature: - * Math is correct, the sensor needs calibration per device. - * I currently use default values for the math which may result in - * very incorrect values in degrees C. - * See TI Design Note DN102 about the offset calibration. - * - * Supply Voltage (VDD) and Battery Sensor: - * For VDD, math is correct, conversion is correct. See DN101 for details if - * interested. - * Battery reports different values when we run it many times - * in succession. The cause is unknown. - * I am fairly confident that I have captured the connections on the - * device correctly. I am however accepting input/feedback - * - * Light Sensor (Vishay Semiconductors TEPT4400): - * I am uncertain about the math. This needs testing. All I know is - * that 600lux = 0.9V and that the relation is linear. See inline for - * more details - * - * Accelerometer (Freescale Semiconductor MMA7340L): - * Math is correct but the sensor needs calibration. I've not - * attempted one cause the reported values differ per device. - * Place the N740 with the logo facing down to get 1g on the Z axis. - * Place the antenna side facing down to get 1g on the Y axis - * Place the N740 on its longer side while looking at the antenna and - * the D connector. Antenna on the bottom, D connector on the top. - * This should give you 1g on the X axis. - * - * Make sure you enable/disable things in contiki-conf.h - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-conf.h" -#include "net/rime/rime.h" -#include "dev/leds.h" -#include "dev/watchdog.h" -#include "lib/random.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#else -#include "lib/sensors.h" -#endif - -#define DEBUG 1 -#if DEBUG -#include -#if CONTIKI_TARGET_SENSINODE -#include "debug.h" -#endif /* CONTIKI_TARGET_SENSINODE */ -#define PRINTF(...) printf(__VA_ARGS__) -#else /* DEBUG */ -/* We overwrite (read as annihilate) all output functions here */ -#define PRINTF(...) -#define putstring(...) -#define putchar(...) -#endif /* DEBUG */ - - -#define SEND_BATTERY_INFO 0 -#if SEND_BATTERY_INFO -#include "sensors-example.h" -static void -bc_rx(struct broadcast_conn *c, const linkaddr_t *from) -{ - return; -} - -static const struct broadcast_callbacks bc_cb = { bc_rx }; -static struct broadcast_conn bc_con; -#endif - -#if BUTTON_SENSOR_ON -extern const struct sensors_sensor button_1_sensor, button_2_sensor; -#endif - -/*---------------------------------------------------------------------------*/ -PROCESS(sensors_test_process, "Sensor Test Process"); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) -PROCESS(buttons_test_process, "Button Test Process"); -AUTOSTART_PROCESSES(&sensors_test_process, &buttons_test_process); -#else -AUTOSTART_PROCESSES(&sensors_test_process); -#endif -/*---------------------------------------------------------------------------*/ -#if BUTTON_SENSOR_ON -PROCESS_THREAD(buttons_test_process, ev, data) -{ - struct sensors_sensor *sensor; - - PROCESS_BEGIN(); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event); - - /* If we woke up after a sensor event, inform what happened */ - sensor = (struct sensors_sensor *)data; - if(sensor == &button_1_sensor) { - leds_toggle(LEDS_GREEN); - } else if(sensor == &button_2_sensor) { - watchdog_reboot(); - } - } - - PROCESS_END(); -} -#endif -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sensors_test_process, ev, data) -{ - static struct etimer et; -#if SEND_BATTERY_INFO - /* Node Time */ - static struct sensor_data sd; -#endif - - /* Sensor Values */ - static int rv; - static struct sensors_sensor *sensor; - static float sane = 0; - static int dec; - static float frac; - -#if SEND_BATTERY_INFO - PROCESS_EXITHANDLER(broadcast_close(&bc_con);) -#endif - - PROCESS_BEGIN(); - - putstring("========================\n"); - putstring("Starting Sensor Example.\n"); - putstring("========================\n"); - -#if SEND_BATTERY_INFO - broadcast_open(&bc_con, BATTERY_RIME_CHANNEL, &bc_cb); -#endif - - /* Set an etimer. We take sensor readings when it expires and reset it. */ - etimer_set(&et, CLOCK_SECOND * 2); - - while(1) { - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - /* - * Request some ADC conversions - * Return value -1 means sensor not available or turned off in conf - */ - sensor = sensors_find(ADC_SENSOR); - if(sensor) { - putstring("------------------\n"); - leds_on(LEDS_RED); - /* - * Temperature: - * Using 1.25V ref. voltage (1250mV). - * Typical Voltage at 0°C : 743 mV - * Typical Co-efficient : 2.45 mV/°C - * Offset at 25°C : 30 (this varies and needs calibration) - * - * Thus, at 12bit resolution: - * - * ADC x 1250 / 2047 - (743 + 30) 0.61065 x ADC - 773 - * T = ------------------------------ ~= ------------------- °C - * 2.45 2.45 - */ - rv = sensor->value(ADC_SENSOR_TYPE_TEMP); - if(rv != -1) { - sane = ((rv * 0.61065 - 773) / 2.45); - dec = sane; - frac = sane - dec; - PRINTF(" Temp=%d.%02u C (%d)\n", dec, (unsigned int)(frac * 100), - rv); - } - /* - * Accelerometer: Freescale Semiconductor MMA7340L - * Using 1.25V ref. voltage. - * Sensitivity: 0.44 mV/g in ±3g mode. - * 0.1175 mV/g in ±11g mode. - * Typical 0g Vout = 1.65V (both modes, Vdd=3.3V, T=25°C) - * ADC Input Voltage is 1/3 Accelerometer Output Voltage - * - * +3g -> 2.97V Acc Out -> 0.9900V ADC Input -> 1621 - * +1g -> 2.09V Acc Out -> 0.6967V ADC Input -> 1141 - * 0g -> 1.65V Acc Out -> 0.5500V ADC Input -> 901 - * -1g -> 1.21V Acc Out -> 0.4033V ADC Input -> 660 - * -3g -> 0.33V Acc Out -> 0.1100V ADC Input -> 180 - * - * Thus, at 12bit resolution, ±3g mode: - * ADC x 1.25 x 3 - * Vout = -------------- V - * 2047 - * - * Vout - 0g Vout - 1.65 - * Acc = ----------- = ----------- g - * Sensitivity 0.44 - * - * Similar calc. for ±11g with 0.1175V increments - * - * This is only valid if you set ACC_SENSOR_CONF_GSEL 0 in contiki-conf.h - */ - rv = sensor->value(ADC_SENSOR_TYPE_ACC_X); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - - /* - * This will fail for numbers like -0.xyz (since there is no such thing - * as -0. We manually add a minus sign in the printout if sane is neg - * and dec is 0. - * This is the wrong way to do it... - */ - putstring(" AccX="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Y); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - putstring(" AccY="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - rv = sensor->value(ADC_SENSOR_TYPE_ACC_Z); - if(rv != -1) { - sane = ((rv * 3.75 / 2047) - 1.65) / 0.44; - dec = sane; - frac = sane - dec; - frac = (frac < 0) ? -frac : frac; - putstring(" AccZ="); - if(sane < 0 && dec == 0) { - putchar('-'); - } - PRINTF("%d.%02ug (%d)\n", dec, (unsigned int)(frac * 100), rv); - } - /* - * Light: Vishay Semiconductors TEPT4400 - * Using 1.25V ref. voltage. - * For 600 Lux illuminance, the sensor outputs 1mA current (0.9V ADC In) - * 600 lux = 1mA output => 1473 ADC value at 12 bit resolution) - * - * Thus, at 12bit resolution: - * 600 x 1.25 x ADC - * Lux = ---------------- ~= ADC * 0.4071 - * 2047 x 0.9 - */ - rv = sensor->value(ADC_SENSOR_TYPE_LIGHT); - if(rv != -1) { - sane = (float)(rv * 0.4071); - dec = sane; - frac = sane - dec; - PRINTF(" Light=%d.%02ulux (%d)\n", dec, (unsigned int)(frac * 100), - rv); - } - /* - * Power Supply Voltage. - * Using 1.25V ref. voltage. - * AD Conversion on VDD/3 - * - * Thus, at 12bit resolution: - * - * ADC x 1.25 x 3 - * Supply = -------------- V - * 2047 - */ - rv = sensor->value(ADC_SENSOR_TYPE_VDD); -#if SEND_BATTERY_INFO - sd.vdd = rv; -#endif - if(rv != -1) { - sane = rv * 3.75 / 2047; - dec = sane; - frac = sane - dec; - PRINTF("Supply=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); - /* Store rv temporarily in dec so we can use it for the battery */ - dec = rv; - } - /* - * Battery Voltage - Only 2/3 of the actual voltage reach the ADC input - * Using 1.25V ref. voltage would result in 2047 AD conversions all the - * time since ADC-in would be gt 1.25. We thus use AVDD_SOC as ref. - * - * Thus, at 12bit resolution (assuming VDD is 3.3V): - * - * ADC x 3.3 x 3 ADC x 4.95 - * Battery = ------------- = ---------- V - * 2047 x 2 2047 - * - * Replacing the 3.3V with an ADC reading of the actual VDD would yield - * better accuracy. See monitor-node.c for an example. - * - * 3 x ADC x VDD x 3.75 ADC x VDD x 11.25 - * Battery = -------------------- = ----------------- V - * 2 x 2047 x 2047 0x7FE002 - * - */ - rv = sensor->value(ADC_SENSOR_TYPE_BATTERY); - if(rv != -1) { - /* Instead of hard-coding 3.3 here, use the latest VDD (stored in dec) - * (slightly inaccurate still, but better than crude 3.3) */ - sane = (11.25 * rv * dec) / (0x7FE002); - dec = sane; - frac = sane - dec; - PRINTF(" Batt.=%d.%02uV (%d)\n", dec, (unsigned int)(frac * 100), rv); -#if SEND_BATTERY_INFO - sd.bat = rv; - packetbuf_copyfrom(&sd, sizeof(sd)); - broadcast_send(&bc_con); -#endif - } - leds_off(LEDS_RED); - } - etimer_reset(&et); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sensors/sensors-example.h b/examples/sensinode/sensors/sensors-example.h deleted file mode 100644 index 432d25073..000000000 --- a/examples/sensinode/sensors/sensors-example.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the sensors example. Must be included by the - * sensing node as well as the monitor node. - * - * \author - * George Oikonomou - - */ - -#ifndef SENSORSTEST_H_ -#define SENSORSTEST_H_ - -#define BATTERY_RIME_CHANNEL 222 - -/* This is what our PDU looks like */ -struct sensor_data { - int vdd; - int bat; -}; - - -#endif /* SENSORSTEST_H_ */ diff --git a/examples/sensinode/serial-flash/Makefile b/examples/sensinode/serial-flash/Makefile deleted file mode 100644 index 9e80a9c6d..000000000 --- a/examples/sensinode/serial-flash/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740 - -CONTIKI_PROJECT = flash - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/serial-flash/flash.c b/examples/sensinode/serial-flash/flash.c deleted file mode 100644 index 4ac6048c9..000000000 --- a/examples/sensinode/serial-flash/flash.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * - * Example demonstrating the flash memory functionality on - * sensinode N740s - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "dev/leds.h" -#include "cc2430_sfr.h" -#include "8051def.h" -#include "dev/m25p16.h" -#include "dev/n740.h" - -#define DEBUG 1 -#if DEBUG -#include -#include "debug.h" -#define PRINTF(...) printf(__VA_ARGS__) -#define PUTBIN(b) putbin(b) -#else -#define PRINTF(...) -#define PUTBIN(b) -#endif - -static struct m25p16_rdid id; - -#define USE_SECTOR 0x10 -#define MAX_READ_CHUNK 10 -static uint8_t r_addr[3]; /* Read address: {USE_SECTOR, 0, 0} */ -static uint8_t d_buf[MAX_READ_CHUNK]; -static uint8_t rv; -static uint8_t counter; -/*---------------------------------------------------------------------------*/ -PROCESS(serial_flash_process, "Serial Flash example"); -AUTOSTART_PROCESSES(&serial_flash_process); -/*---------------------------------------------------------------------------*/ -static void -rdsr() -{ - rv = 0; - - n740_analog_deactivate(); - rv = m25p16_rdsr(); - n740_analog_activate(); - - PRINTF("RDSR: "); - putbin(rv); - PRINTF("\n"); -} -/*---------------------------------------------------------------------------*/ -static void -rdid() -{ - uint8_t i; - memset(&id, 0, sizeof(struct m25p16_rdid)); - - n740_analog_deactivate(); - m25p16_rdid(&id); - n740_analog_activate(); - - PRINTF("RDID: 0x%02x\n", id.man_id); - PRINTF("Type: 0x%02x\n", id.mem_type); - PRINTF("Size: 0x%02x\n", id.mem_size); - PRINTF("ULen: 0x%02x\n", id.uid_len); - PRINTF(" UID:"); - for(i = 0; i < id.uid_len; i++) { - PRINTF(" %02x", id.uid[i]); - } - PRINTF("\n"); -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(serial_flash_process, ev, data) -{ - static struct etimer et; - uint8_t i; - - PROCESS_BEGIN(); - - PRINTF("Start\n"); - - memset(r_addr, 0, 3); - r_addr[0] = USE_SECTOR; - counter = 1; - - while(1) { - - /* Delay */ - etimer_set(&et, CLOCK_SECOND * 2); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - - leds_on(LEDS_GREEN); - - if(counter == 0) { - n740_analog_deactivate(); - rv = m25p16_rdsr(); - n740_analog_activate(); - /* If counter==0, we started Bulk Erasing earlier. Check if we still are */ - if(rv & M25P16_SR_WIP) { - PRINTF("Yield [%02x]\n", rv); - } else { - counter = 1; - } - } - if(counter) { - /* - * Take us out of Deep Power Down - On first power-on, the device will - * go to stand by mode (which is not DP). However, we drop to DP at the - * end of every loop. RES must be 0x14. This is the old style signature - * and is only still there for backward compatibility. - */ - n740_analog_deactivate(); - rv = m25p16_res_res(); - n740_analog_activate(); - - PRINTF(" RES: 0x%02x\n", rv); - - n740_analog_deactivate(); - rv = M25P16_WIP(); - n740_analog_activate(); - - PRINTF("========\n"); - memset(d_buf, 0, MAX_READ_CHUNK); - - - /* - * Read Device ID: Return values must be: - * man_id: 0x20 (Numonyx) - * mem_type: 0x20 - * mem_size: 0x15 (2 ^ 0x15 bytes = 2MB) - * uid_len: number of bytes in UID - * uid: Either all zeroes or a customized factory data content - * */ - rdid(); - - /* Check the value of our Status Register (SR) */ - rdsr(); - - /* Enable Write: Set Bit 1 in the SR to 1 (bit WEL) */ - PRINTF("WREN\n"); - n740_analog_deactivate(); - m25p16_wren(); - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 1 */ - rdsr(); - - /* Disable the WEL bit */ - PRINTF("WRDI\n"); - n740_analog_deactivate(); - m25p16_wrdi(); - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 0 */ - rdsr(); - - /* Write something to the SR. We don't need to explicitly set WEL, wrsr() - * will do it for us. When the cycle ends, WEL will go low */ - PRINTF("WRSR\n"); - n740_analog_deactivate(); - - /* For instance, let's protect sector 31 (that's the highest one) */ - m25p16_wrsr(M25P16_SR_BP0); - - /* - * While this is running, WEL should remain high and WIP (bit 0) should - * also be high. When this ends, WIP and WEL will go low. - * - * While the write is in ongoing, we can still read the SR to check the - * cycle's progress - */ - while(M25P16_WIP()); - - n740_analog_activate(); - - /* Confirm: SR & 0x02 must be 0 */ - rdsr(); - - /* Read MAX_READ_CHUNK bytes from Page 0x000000 */ - memset(d_buf, 0, MAX_READ_CHUNK); - n740_analog_deactivate(); - m25p16_read(r_addr, d_buf, MAX_READ_CHUNK); - n740_analog_activate(); - - PRINTF("READ:"); - for(i = 0; i < MAX_READ_CHUNK; i++) { - PRINTF(" %02x", d_buf[i]); - } - PRINTF("\n"); - - /* Write MAX_READ_CHUNK bytes to the same Page */ - PRINTF("WRITE\n"); - for(i = 0; i < MAX_READ_CHUNK; i++) { - d_buf[i] = i; - } - n740_analog_deactivate(); - - /* We don't need to wren() explicitly, pp() will do that for us */ - m25p16_pp(r_addr, d_buf, MAX_READ_CHUNK); - - /* Wait for the cycle */ - while(M25P16_WIP()); - - /* Trash our data buffer */ - memset(d_buf, 0, MAX_READ_CHUNK); - - PRINTF("ERASE\n"); - n740_analog_deactivate(); - - /* Bulk erase every 4 loops, sector erase otherwise */ - - /* Bulk Erase: This takes a few seconds so we can't really block on it. - * It'd be a bad thing to do and the watchdog would bark anyway. - * Bulk Erase will only be accepted if all SR_BP[2:0] == 0 */ - if((counter % 4) == 0) { - m25p16_wrsr(0); - while(M25P16_WIP()); - m25p16_be(); - counter = 0; - } else { - m25p16_se(USE_SECTOR); - while(M25P16_WIP()); - /* Drop to Deep Power Down */ - m25p16_dp(); - counter++; - } - n740_analog_activate(); - } - leds_off(LEDS_GREEN); - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sniffer/Makefile b/examples/sensinode/sniffer/Makefile deleted file mode 100644 index 5170c55b1..000000000 --- a/examples/sensinode/sniffer/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N601,PROJECT_CONF_H - -PROJECT_SOURCEFILES += stub-rdc.c - -CONTIKI_PROJECT = sniffer - -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/sniffer/README.md b/examples/sensinode/sniffer/README.md deleted file mode 100644 index dd3926f0a..000000000 --- a/examples/sensinode/sniffer/README.md +++ /dev/null @@ -1,15 +0,0 @@ -A very simple sniffer for sensinode devices. -============================================ - -The cc2430 RF driver supports outputting all captured packets in hexdump -format. We turn this on, and turn everything else off. We use a stub RDC driver -to make sure no incoming packet ever goes up the stack and no packet is ever -sent out. - -We only initialise the radio driver instead of the entire stack by over-riding -the default netstack.c with the one in this directory. - -You can then pipe the sniffer's output to the n601-cap util, which will convert -the hexdumps to pcap format, which can in turn be piped to wireshark. This is -handy if we want live capture of the lowpan traffic from wireshark. See the -README in n601-cap for more details diff --git a/examples/sensinode/sniffer/netstack.c b/examples/sensinode/sniffer/netstack.c deleted file mode 100644 index d59acc3fe..000000000 --- a/examples/sensinode/sniffer/netstack.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Stub file overriding core/net/netstack.c. What we want to achieve - * here is call netstack_init from main without initialising the RDC, - * MAC and Network layers. It will just turn on the radio instead. - * - * \author - * George Oikonomou - - */ - -#include "netstack.h" -/*---------------------------------------------------------------------------*/ -void -netstack_init(void) -{ - NETSTACK_RADIO.init(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sniffer/project-conf.h b/examples/sensinode/sniffer/project-conf.h deleted file mode 100644 index 3ed5ec99e..000000000 --- a/examples/sensinode/sniffer/project-conf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Project specific configuration defines for the sniffer example. - * - * We make sure that the radio driver outputs all packets in hexdump - * format. - * - * \author - * George Oikonomou - - */ - -#ifndef PROJECT_CONF_H_ -#define PROJECT_CONF_H_ - -#define CC2430_RF_CONF_HEXDUMP 1 -#define CC2430_RF_CONF_AUTOACK 0 -#define NETSTACK_CONF_RDC stub_rdc_driver -#define ADC_SENSOR_CONF_ON 0 -#define LPM_CONF_MODE 0 - -#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensinode/sniffer/sniffer.c b/examples/sensinode/sniffer/sniffer.c deleted file mode 100644 index 74d24588e..000000000 --- a/examples/sensinode/sniffer/sniffer.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "cc2430_sfr.h" - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -/*---------------------------------------------------------------------------*/ -PROCESS(sniffer_process, "Sniffer process"); -AUTOSTART_PROCESSES(&sniffer_process); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(sniffer_process, ev, data) -{ - - PROCESS_BEGIN(); - - PRINTF("Sniffer started\n"); - - /* Turn off cc2430 Address Recognition - We need to accept all frames */ - MDMCTRL0H &= ~0x08; - - PROCESS_EXIT(); - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/sniffer/stub-rdc.c b/examples/sensinode/sniffer/stub-rdc.c deleted file mode 100644 index a4db0710d..000000000 --- a/examples/sensinode/sniffer/stub-rdc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Definition of a fake RDC driver to be used with passive - * examples. The sniffer will never send packets and it will never - * push incoming packets up the stack. We do this by defining this - * driver as our RDC. We then drop everything - * - * \author - * George Oikonomou - - */ - -#include "net/mac/mac.h" -#include "net/mac/rdc.h" -/*---------------------------------------------------------------------------*/ -static void -send(mac_callback_t sent, void *ptr) -{ - if(sent) { - sent(ptr, MAC_TX_OK, 1); - } -} -/*---------------------------------------------------------------------------*/ -static void -send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *list) -{ - if(sent) { - sent(ptr, MAC_TX_OK, 1); - } -} -/*---------------------------------------------------------------------------*/ -static void -input(void) -{ -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -off(int keep_radio_on) -{ - return keep_radio_on; -} -/*---------------------------------------------------------------------------*/ -static unsigned short -cca(void) -{ - return 0; -} -/*---------------------------------------------------------------------------*/ -static void -init(void) -{ -} -/*---------------------------------------------------------------------------*/ -const struct rdc_driver stub_rdc_driver = { - "stub-rdc", - init, - send, - send_list, - input, - on, - off, - cca, -}; -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/timer-test.c b/examples/sensinode/timer-test.c deleted file mode 100644 index df954bccc..000000000 --- a/examples/sensinode/timer-test.c +++ /dev/null @@ -1,139 +0,0 @@ -/** - * \file - * Tests related to clocks and timers - * This is based on clock_test.c from the original sensinode port - * - * \author - * Zach Shelby (Original) - * George Oikonomou - (rtimer code) - * - */ - -#include "contiki.h" -#include "sys/clock.h" -#include "sys/rtimer.h" -#include "dev/leds.h" - -#include -/*---------------------------------------------------------------------------*/ -#define TEST_CLOCK_DELAY_USEC 1 -#define TEST_RTIMER 1 -#define TEST_ETIMER 1 -#define TEST_CLOCK_SECONDS 1 -/*---------------------------------------------------------------------------*/ -static struct etimer et; - -#if TEST_CLOCK_DELAY_USEC -static rtimer_clock_t start_count, end_count, diff; -#endif - -#if TEST_CLOCK_SECONDS -static unsigned long sec; -#endif - -#if TEST_ETIMER -static clock_time_t count; -#endif - -#if TEST_RTIMER -static struct rtimer rt; -rtimer_clock_t rt_now, rt_for; -static clock_time_t ct; -#endif - -static uint8_t i; -/*---------------------------------------------------------------------------*/ -PROCESS(clock_test_process, "Clock test process"); -AUTOSTART_PROCESSES(&clock_test_process); -/*---------------------------------------------------------------------------*/ -#if TEST_RTIMER -void -rt_callback(struct rtimer *t, void *ptr) -{ - rt_now = RTIMER_NOW(); - ct = clock_time(); - printf("Task called at %u (clock = %u)\n", rt_now, ct); -} -#endif -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(clock_test_process, ev, data) -{ - - PROCESS_BEGIN(); - - etimer_set(&et, 2 * CLOCK_SECOND); - - PROCESS_YIELD(); - -#if TEST_CLOCK_DELAY_USEC - printf("clock_delay_usec test, (10,000 x i) usec:\n"); - i = 1; - while(i < 7) { - start_count = RTIMER_NOW(); - clock_delay_usec(10000 * i); - end_count = RTIMER_NOW(); - diff = end_count - start_count; - printf("Requested: %u usec, Real: %u rtimer ticks = ~%u us\n", - 10000 * i, diff, diff * 64); - i++; - } -#endif - -#if TEST_RTIMER - printf("Rtimer Test, 1 sec (%u rtimer ticks):\n", RTIMER_SECOND); - i = 0; - while(i < 5) { - etimer_set(&et, 2 * CLOCK_SECOND); - printf("=======================\n"); - ct = clock_time(); - rt_now = RTIMER_NOW(); - rt_for = rt_now + RTIMER_SECOND; - printf("Now=%u (clock = %u) - For=%u\n", rt_now, ct, rt_for); - if(rtimer_set(&rt, rt_for, 1, (rtimer_callback_t) rt_callback, NULL) != - RTIMER_OK) { - printf("Error setting\n"); - } - - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - i++; - } -#endif - -#if TEST_ETIMER - printf("Clock tick and etimer test, 1 sec (%u clock ticks):\n", - CLOCK_SECOND); - i = 0; - while(i < 10) { - etimer_set(&et, CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - - count = clock_time(); - printf("%u ticks\n", count); - - leds_toggle(LEDS_RED); - i++; - } -#endif - -#if TEST_CLOCK_SECONDS - printf("Clock seconds test (5s):\n"); - i = 0; - while(i < 10) { - etimer_set(&et, 5 * CLOCK_SECOND); - PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - etimer_reset(&et); - - sec = clock_seconds(); - printf("%lu seconds\n", sec); - - leds_toggle(LEDS_GREEN); - i++; - } -#endif - - printf("Done!\n"); - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/udp-ipv6/Makefile b/examples/sensinode/udp-ipv6/Makefile deleted file mode 100644 index ae0bfad0f..000000000 --- a/examples/sensinode/udp-ipv6/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -ifndef TARGET -TARGET=sensinode -endif - -# Make absolutely certain that you specify your device here -DEFINES+=MODEL_N740,PROJECT_CONF_H - -# This example won't fit in flash without banking so we turn it on -HAVE_BANKING=1 - -CONTIKI_SOURCEFILES += ping6.c - -CONTIKI_PROJECT = client server -all: $(CONTIKI_PROJECT) - -CONTIKI = ../../.. -CONTIKI_WITH_IPV6 = 1 -# needed for rimestats -CONTIKI_WITH_RIME = 1 -include $(CONTIKI)/Makefile.include diff --git a/examples/sensinode/udp-ipv6/client.c b/examples/sensinode/udp-ipv6/client.c deleted file mode 100644 index 8308d13a8..000000000 --- a/examples/sensinode/udp-ipv6/client.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include -#include "dev/leds.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#else -#define putstring(s) -#define puthex(s) -#define putchar(s) -#endif - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define SEND_INTERVAL 2 * CLOCK_SECOND -#define MAX_PAYLOAD_LEN 40 - -static char buf[MAX_PAYLOAD_LEN]; - -/* Our destinations and udp conns. One link-local and one global */ -#define LOCAL_CONN_PORT 3001 -static struct uip_udp_conn *l_conn; -#if UIP_CONF_ROUTER -#define GLOBAL_CONN_PORT 3002 -static struct uip_udp_conn *g_conn; -#endif - -/*---------------------------------------------------------------------------*/ -PROCESS(udp_client_process, "UDP client process"); -#if BUTTON_SENSOR_ON -PROCESS_NAME(ping6_process); -AUTOSTART_PROCESSES(&udp_client_process, &ping6_process); -#else -AUTOSTART_PROCESSES(&udp_client_process); -#endif -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - leds_on(LEDS_GREEN); - if(uip_newdata()) { - putstring("0x"); - puthex(uip_datalen()); - putstring(" bytes response=0x"); - puthex((*(uint16_t *) uip_appdata) >> 8); - puthex((*(uint16_t *) uip_appdata) & 0xFF); - putchar('\n'); - } - leds_off(LEDS_GREEN); - return; -} -/*---------------------------------------------------------------------------*/ -static void -timeout_handler(void) -{ - static int seq_id; - struct uip_udp_conn *this_conn; - - leds_on(LEDS_RED); - memset(buf, 0, MAX_PAYLOAD_LEN); - seq_id++; - -#if UIP_CONF_ROUTER - /* evens / odds */ - if(seq_id & 0x01) { - this_conn = l_conn; - } else { - this_conn = g_conn; - } -#else - this_conn = l_conn; -#endif - - PRINTF("Client to: "); - PRINT6ADDR(&this_conn->ripaddr); - - memcpy(buf, &seq_id, sizeof(seq_id)); - - PRINTF(" Remote Port %u,", UIP_HTONS(this_conn->rport)); - PRINTF(" (msg=0x%04x), %u bytes\n", *(uint16_t *) buf, sizeof(seq_id)); - -#if SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION - uip_udp_packet_send(this_conn, buf, UIP_APPDATA_SIZE); -#else /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */ - uip_udp_packet_send(this_conn, buf, sizeof(seq_id)); -#endif /* SEND_TOO_LARGE_PACKET_TO_TEST_FRAGMENTATION */ - leds_off(LEDS_RED); -} -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Client IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - PRINTF(" state: %u.\n", uip_ds6_if.addr_list[i].state); - } - } - return; -} -/*---------------------------------------------------------------------------*/ -#if UIP_CONF_ROUTER -static void -set_global_address(void) -{ - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); -} -#endif /* UIP_CONF_ROUTER */ -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_client_process, ev, data) -{ - static struct etimer et; - uip_ipaddr_t ipaddr; - - PROCESS_BEGIN(); - PRINTF("UDP client process started\n"); - -#if UIP_CONF_ROUTER - set_global_address(); -#endif - - print_local_addresses(); - - uip_ip6addr(&ipaddr, 0xfe80, 0, 0, 0, 0x0215, 0x2000, 0x0002, 0x0302); - /* new connection with remote host */ - l_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); - if(!l_conn) { - PRINTF("udp_new l_conn error.\n"); - } - udp_bind(l_conn, UIP_HTONS(LOCAL_CONN_PORT)); - - PRINTF("Link-Local connection with "); - PRINT6ADDR(&l_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - UIP_HTONS(l_conn->lport), UIP_HTONS(l_conn->rport)); - -#if UIP_CONF_ROUTER - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0x0215, 0x2000, 0x0002, - 0x0302); - g_conn = udp_new(&ipaddr, UIP_HTONS(3000), NULL); - if(!g_conn) { - PRINTF("udp_new g_conn error.\n"); - } - udp_bind(g_conn, UIP_HTONS(GLOBAL_CONN_PORT)); - - PRINTF("Global connection with "); - PRINT6ADDR(&g_conn->ripaddr); - PRINTF(" local/remote port %u/%u\n", - UIP_HTONS(g_conn->lport), UIP_HTONS(g_conn->rport)); -#endif - - etimer_set(&et, SEND_INTERVAL); - - while(1) { - PROCESS_YIELD(); - if(etimer_expired(&et)) { - timeout_handler(); - etimer_restart(&et); - } else if(ev == tcpip_event) { - tcpip_handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/udp-ipv6/ping6.c b/examples/sensinode/udp-ipv6/ping6.c deleted file mode 100644 index 1acccd371..000000000 --- a/examples/sensinode/udp-ipv6/ping6.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#include -#include - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#endif - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define PING6_NB 5 -#define PING6_DATALEN 16 - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -static struct etimer ping6_periodic_timer; -static uint8_t count = 0; -static uip_ipaddr_t dest_addr; - -PROCESS(ping6_process, "PING6 process"); -/*---------------------------------------------------------------------------*/ -static void -ping6handler() -{ - if(count < PING6_NB) { - UIP_IP_BUF->vtc = 0x60; - UIP_IP_BUF->tcflow = 1; - UIP_IP_BUF->flow = 0; - UIP_IP_BUF->proto = UIP_PROTO_ICMP6; - UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit; - uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &dest_addr); - uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); - - UIP_ICMP_BUF->type = ICMP6_ECHO_REQUEST; - UIP_ICMP_BUF->icode = 0; - /* set identifier and sequence number to 0 */ - memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN, 0, 4); - /* put one byte of data */ - memset((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN, - count, PING6_DATALEN); - - - uip_len = UIP_ICMPH_LEN + UIP_ICMP6_ECHO_REQUEST_LEN + UIP_IPH_LEN + PING6_DATALEN; - UIP_IP_BUF->len[0] = (uint8_t)((uip_len - 40) >> 8); - UIP_IP_BUF->len[1] = (uint8_t)((uip_len - 40) & 0x00FF); - - UIP_ICMP_BUF->icmpchksum = 0; - UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); - - - PRINTF("Echo Request to "); - PRINT6ADDR(&UIP_IP_BUF->destipaddr); - PRINTF(" from "); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("\n"); - UIP_STAT(++uip_stat.icmp.sent); - - tcpip_ipv6_output(); - - count++; - etimer_set(&ping6_periodic_timer, 3 * CLOCK_SECOND); - } else { - count = 0; - } -} - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(ping6_process, ev, data) -{ - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static struct sensors_sensor *btn; -#endif - - PROCESS_BEGIN(); - PRINTF("ping6 running.\n"); - PRINTF("Button 1: 5 pings 16 byte payload.\n"); - - uip_ip6addr(&dest_addr, 0x2001, 0x470, 0x55, 0, 0x0215, 0x2000, 0x0002, - 0x0302); - count = 0; - - /* Check if we have buttons */ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - btn = sensors_find(BUTTON_1_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - if(ev == sensors_event) { - if(data == btn && count == 0) { - ping6handler(); - } - } -#endif - if(etimer_expired(&ping6_periodic_timer)) { - ping6handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/examples/sensinode/udp-ipv6/project-conf.h b/examples/sensinode/udp-ipv6/project-conf.h deleted file mode 100644 index bb755aee9..000000000 --- a/examples/sensinode/udp-ipv6/project-conf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Project specific configuration defines for the UDP client/server - * example. - * - * We just turn on buttons - * - * \author - * George Oikonomou - - */ - -#ifndef PROJECT_CONF_H_ -#define PROJECT_CONF_H_ - -#define BUTTON_SENSOR_CONF_ON 1 -#define RIMESTATS_CONF_ENABLED 1 -#define VIZTOOL_CONF_ON 0 -#define UIP_CONF_ND6_SEND_NA 1 - -#endif /* PROJECT_CONF_H_ */ diff --git a/examples/sensinode/udp-ipv6/server.c b/examples/sensinode/udp-ipv6/server.c deleted file mode 100644 index fcdc0fec8..000000000 --- a/examples/sensinode/udp-ipv6/server.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -#include "dev/watchdog.h" -#include "dev/leds.h" -#include "net/rpl/rpl.h" - -#if CONTIKI_TARGET_SENSINODE -#include "dev/sensinode-sensors.h" -#include "debug.h" -#else -#define putstring(s) -#endif - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#define MAX_PAYLOAD_LEN 120 - -static struct uip_udp_conn *server_conn; -static char buf[MAX_PAYLOAD_LEN]; -static uint16_t len; - -#define SERVER_REPLY 1 - -/* Should we act as RPL root? */ -#define SERVER_RPL_ROOT 0 - -#if SERVER_RPL_ROOT -static uip_ipaddr_t ipaddr; -#endif -/*---------------------------------------------------------------------------*/ -extern const struct sensors_sensor adc_sensor; -/*---------------------------------------------------------------------------*/ -PROCESS(udp_server_process, "UDP server process"); -AUTOSTART_PROCESSES(&udp_server_process); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) -{ - memset(buf, 0, MAX_PAYLOAD_LEN); - if(uip_newdata()) { - leds_on(LEDS_RED); - len = uip_datalen(); - memcpy(buf, uip_appdata, len); - PRINTF("%u bytes from [", len); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u", UIP_HTONS(UIP_UDP_BUF->srcport)); - PRINTF(" V=%u", *buf); - PRINTF(" I=%u", *(buf + 1)); - PRINTF(" T=%u", *(buf + 2)); - PRINTF(" Val=%u\n", *(uint16_t *)(buf + 3)); -#if SERVER_REPLY - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - server_conn->rport = UIP_UDP_BUF->srcport; - - uip_udp_packet_send(server_conn, buf, len); - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; -#endif - } - leds_off(LEDS_RED); - PRINTF("sent\n"); - return; -} -/*---------------------------------------------------------------------------*/ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON && (DEBUG==DEBUG_PRINT)) -static void -print_stats() -{ - PRINTF("tl=%lu, ts=%lu, bs=%lu, bc=%lu\n", - RIMESTATS_GET(toolong), RIMESTATS_GET(tooshort), - RIMESTATS_GET(badsynch), RIMESTATS_GET(badcrc)); - PRINTF("llrx=%lu, lltx=%lu, rx=%lu, tx=%lu\n", RIMESTATS_GET(llrx), - RIMESTATS_GET(lltx), RIMESTATS_GET(rx), RIMESTATS_GET(tx)); -} -#else -#define print_stats() -#endif -/*---------------------------------------------------------------------------*/ -static void -print_local_addresses(void) -{ - int i; - uint8_t state; - - PRINTF("Server IPv6 addresses:\n"); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - state = uip_ds6_if.addr_list[i].state; - if(uip_ds6_if.addr_list[i].isused && (state == ADDR_TENTATIVE || state - == ADDR_PREFERRED)) { - PRINTF(" "); - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - if(state == ADDR_TENTATIVE) { - uip_ds6_if.addr_list[i].state = ADDR_PREFERRED; - } - } - } -} -/*---------------------------------------------------------------------------*/ -#if SERVER_RPL_ROOT -void -create_dag() -{ - rpl_dag_t *dag; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); - - print_local_addresses(); - - dag = rpl_set_root(RPL_DEFAULT_INSTANCE, - &uip_ds6_get_global(ADDR_PREFERRED)->ipaddr); - if(dag != NULL) { - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - rpl_set_prefix(dag, &ipaddr, 64); - PRINTF("Created a new RPL dag with ID: "); - PRINT6ADDR(&dag->dag_id); - PRINTF("\n"); - } -} -#endif /* SERVER_RPL_ROOT */ -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(udp_server_process, ev, data) -{ -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - static const struct sensors_sensor *b1; - static const struct sensors_sensor *b2; -#endif - - PROCESS_BEGIN(); - putstring("Starting UDP server\n"); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - putstring("Button 1: Print RIME stats\n"); - putstring("Button 2: Reboot\n"); -#endif - -#if SERVER_RPL_ROOT - create_dag(); -#endif - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(3000)); - - PRINTF("Listen port: 3000, TTL=%u\n", server_conn->ttl); - -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - b1 = sensors_find(BUTTON_1_SENSOR); - b2 = sensors_find(BUTTON_2_SENSOR); -#endif - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); -#if (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) - } else if(ev == sensors_event && data != NULL) { - if(data == b1) { - print_stats(); - } else if(data == b2) { - watchdog_reboot(); - } -#endif /* (CONTIKI_TARGET_SENSINODE && BUTTON_SENSOR_ON) */ - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/Makefile.customrules-sensinode b/platform/sensinode/Makefile.customrules-sensinode deleted file mode 100644 index 13ec8cf5e..000000000 --- a/platform/sensinode/Makefile.customrules-sensinode +++ /dev/null @@ -1 +0,0 @@ -include $(CONTIKI)/cpu/cc2430/Makefile.customrules-cc2430 diff --git a/platform/sensinode/Makefile.sensinode b/platform/sensinode/Makefile.sensinode deleted file mode 100644 index 80937391c..000000000 --- a/platform/sensinode/Makefile.sensinode +++ /dev/null @@ -1,92 +0,0 @@ -# Sensinode CC2430 platform makefile -# Supported products: N100, N600, N601, N710, N711 -# Support for N740 is experimental. - -# We support defines for product models using the following format -# e.g. MODEL_N601. Run make TARGET=sensinode DEFINES=MODEL_N601 to -# automatically configure the correct LED, button, UART etc. settings -# for that product model. If undefined, MODEL_N100 is chosen by default. -# Model settings are defined in /dev/models.h - -# make sensinode.upload - Will use nano_programmer to upload file using D2xx Devboard -# make sensinode.serialdump - Will use the Contiki serialdump tool on the default UART -# make foo.model - Will copy foo.ihx to foo-XYZ.ihx (e.g. foo-n740.ihx) -PATH:=$(CONTIKI)/platform/$(TARGET)/tools/bin:$(PATH) -export PATH - -ifndef CONTIKI - $(error CONTIKI not defined! You must specify where CONTIKI resides!) -endif - -# Determine our model and (later on) add it as part of the .ihx filename -# Handy when building for various models so we can easily tell which ihx -# is for what model. -# Defaults to N100 (which is what the contiki code does as well) -MODEL_SUFFIX=n100 -ifdef DEFINES - MODEL_SUFFIX=$(patsubst MODEL_N%,n%, \ - $(filter MODEL_%,$(subst $(COMMA), ,$(DEFINES)))) -endif - -# Define the default UART for tools and tool commands -DEFUART = /dev/ttyUSB0 -PROG = $(CONTIKI)/tools/sensinode/nano_programmer/nano_programmer -d $(DEFUART) -SERIALDUMP = $(CONTIKI)/tools/sky/serialdump-linux -b115200 $(DEFUART) - -CONTIKI_TARGET_DIRS = . dev -CONTIKI_TARGET_MAIN = $(addprefix $(OBJECTDIR)/,contiki-sensinode-main.rel) - -CONTIKI_TARGET_SOURCEFILES = contiki-sensinode-main.c -CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c serial-line.c sensors.c -CONTIKI_TARGET_SOURCEFILES += sensinode-sensors.c button-sensor.c adc-sensor.c -CONTIKI_TARGET_SOURCEFILES += n740.c models.c m25p16.c slip-arch.c slip.c -CONTIKI_TARGET_SOURCEFILES += putchar.c debug.c - -CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) - -CLEAN += *.sensinode - -ifeq ($(CONTIKI_WITH_IPV6),1) - ifeq ($(OFFSET_FIRMWARE),1) - CFLAGS += -DDISCO_ENABLED=1 - CONTIKI_TARGET_SOURCEFILES += disco.c - endif - CONTIKI_TARGET_SOURCEFILES += viztool.c -endif - -FORCE: - -# .sensinode target so we can behave similar to other targets -# Lastly, it will create a %-$(MODEL).ihx file -%.$(TARGET): %.hex FORCE - cp $< $(<:.hex=.$(TARGET)) - if [ -f $(<:.hex=.ihx) ] ; then \ - cp $(<:.hex=.ihx) $(<:.hex=-$(MODEL_SUFFIX).ihx); fi - @echo "\nReport" - @echo "===============" - @echo 'Code footprint:' - @echo 'Area Addr Size' \ - ' Decimal' - @echo '---------------------------------- -------- --------' \ - ' --------' - @echo -n 'HOME,CSEG,CONST,XINIT,GS* $(HOME_START) ' - @egrep ',CODE\)' $(<:.hex=.map) | egrep -v '(^BANK[1-9][^=])' | uniq | \ - awk '{ SUM += $$5 } END { printf "%08X = %8d", SUM, SUM }' - @echo '. bytes (REL,CON,CODE)' - @egrep '(^BANK[1-9][^=])' $(<:.hex=.map) | uniq | sort - @egrep -A 5 'Other memory' $(<:.hex=.mem) - -%.upload: %.hex - $(PROG) -P $< - -sensinode.serialdump: - $(SERIALDUMP) - -### Define the CPU directory -CONTIKI_CPU=$(CONTIKI)/cpu/cc2430 -include $(CONTIKI)/cpu/cc2430/Makefile.cc2430 - -contiki-$(TARGET).a:# $(addprefix $(OBJECTDIR)/,symbols.rel) - -MODULES += core/net core/net/mac \ - core/net/llsec diff --git a/platform/sensinode/apps/batmon/Makefile.batmon b/platform/sensinode/apps/batmon/Makefile.batmon deleted file mode 100644 index 1ad4809da..000000000 --- a/platform/sensinode/apps/batmon/Makefile.batmon +++ /dev/null @@ -1,3 +0,0 @@ -batmon_src = batmon.c - -CFLAGS += -DBATMON_CONF_ON=1 \ No newline at end of file diff --git a/platform/sensinode/apps/batmon/batmon.c b/platform/sensinode/apps/batmon/batmon.c deleted file mode 100644 index 184404199..000000000 --- a/platform/sensinode/apps/batmon/batmon.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Sources for the BATtery MONitor app. It dumps a log entry to the - * external flash periodically as well as upon external trigger. - * - * It started off as a VDD and battery logger but now it also stores - * energest values and other goodies. - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" - -#define DEBUG 0 -#if DEBUG -#include -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -#include "sys/etimer.h" -#include "sys/energest.h" -#include "dev/sensinode-sensors.h" -#include "dev/n740.h" -#include "dev/m25p16.h" - -#define BATMON_LOG_PERIOD 60 /* in seconds */ -/*---------------------------------------------------------------------------*/ -static const uint8_t magic[3] = { 0x0B, 0xEE, 0xF0 }; -/*---------------------------------------------------------------------------*/ -struct record { - uint8_t magic[3]; - uint8_t trigger; - unsigned long c; /* uptime */ - int v; /* VDD (reference) */ - int b; /* Voltage ADC */ -#if ENERGEST_CONF_ON - unsigned long mcu; - unsigned long lpm; - unsigned long irq; - unsigned long tx; - unsigned long rx; - unsigned long f_write; - unsigned long f_read; -#endif -}; - -#define RECORD_SIZE 64 -#define LAST_WRITE (0xFFFF - RECORD_SIZE) - -#define LOG_TRIGGER_PERIODIC 0xFF -/*---------------------------------------------------------------------------*/ -struct flash_address { - uint8_t s; /* sector */ - uint8_t p; /* page */ - uint8_t a; /* address */ -}; -static struct flash_address f; - -static struct record r; -static struct sensors_sensor *s; -static struct etimer et; -#define FLASH_START_ADDR 0x1E0000 -#define FLASH_END_ADDR 0x1FFFFF -/*---------------------------------------------------------------------------*/ -PROCESS(batmon_process, "Logger Process"); -/*---------------------------------------------------------------------------*/ -static int -find_gap() CC_NON_BANKED -{ - uint8_t seq[3]; - uint32_t address = FLASH_START_ADDR; - memset(&f, 0, sizeof(f)); - - for(address = FLASH_START_ADDR; address <= FLASH_END_ADDR; address += - RECORD_SIZE) { - n740_analog_deactivate(); - f.s = ((address & 0xFF0000) >> 16); - f.p = ((address & 0xFF00) >> 8); - f.a = address & 0xFF; - m25p16_read_fast((uint8_t *)&f, seq, sizeof(magic)); - n740_analog_activate(); - if(memcmp(seq, magic, sizeof(magic)) != 0) { - PRINTF("BatMon: Resume write @ 0x%02x%02x%02x\n", f.s, f.p, f.a); - return 1; - } - } - - /* If we reach here, we ran out of flash */ - return -1; -} -/*---------------------------------------------------------------------------*/ -static void -abort() CC_NON_BANKED -{ - PRINTF("BatMon: Abort\n"); - etimer_stop(&et); - process_exit(&batmon_process); -} -/*---------------------------------------------------------------------------*/ -void -batmon_log(uint8_t trigger) -{ - uint32_t next; - - /* Only continue if the process (us) is running */ - if(!process_is_running(&batmon_process)) { - return; - } - - next = f.a; - next |= (((uint32_t) f.p) << 8); - next |= (((uint32_t) f.s) << 16); - - memcpy(r.magic, magic, sizeof(magic)); - r.trigger = trigger; - r.c = clock_seconds(); - - /* Read VDD and use as ADC reference */ - r.v = s->value(ADC_SENSOR_TYPE_VDD); - - /* And then carry on with battery */ - r.b = s->value(ADC_SENSOR_TYPE_BATTERY); - -#if ENERGEST_CONF_ON - /* ENERGEST values */ - r.mcu = energest_type_time(ENERGEST_TYPE_CPU); - r.lpm = energest_type_time(ENERGEST_TYPE_LPM); - r.irq = energest_type_time(ENERGEST_TYPE_IRQ); - r.tx = energest_type_time(ENERGEST_TYPE_TRANSMIT); - r.rx = energest_type_time(ENERGEST_TYPE_LISTEN); - r.f_write = energest_type_time(ENERGEST_TYPE_FLASH_WRITE); - r.f_read = energest_type_time(ENERGEST_TYPE_FLASH_READ); -#endif - - n740_analog_deactivate(); - /* Make sure we're on */ - if(M25P16_WIP()) { - m25p16_res(); - } - m25p16_pp((uint8_t *)&f, (uint8_t *)&r, sizeof(r)); - n740_analog_activate(); - - PRINTF("BatMon: @%lu [%u] ", r.c, r.trigger); - PRINTF("BatMon: 0x%02x%02x%02x\n", f.s, f.p, f.a); - - next += RECORD_SIZE; - - if(next >= FLASH_END_ADDR) { - abort(); - return; - } - - f.s = ((next & 0xFF0000) >> 16); - f.p = ((next & 0xFF00) >> 8); - f.a = next & 0xFF; - - if(trigger == LOG_TRIGGER_PERIODIC) { - etimer_reset(&et); - } -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(batmon_process, ev, data) -{ - - PROCESS_BEGIN(); - - PRINTF("BatMon\n", sizeof(r)); - - s = sensors_find(ADC_SENSOR); - if(!s) { - PRINTF("BatMon: ADC not found\n"); - PROCESS_EXIT(); - } - - n740_analog_deactivate(); - m25p16_res(); - n740_analog_activate(); - - /* Find last written location */ - if(find_gap() == -1) { - PRINTF("BatMon: Flash storage full\n"); - PROCESS_EXIT(); - } - - etimer_set(&et, BATMON_LOG_PERIOD * CLOCK_SECOND); - - while(1) { - PROCESS_YIELD(); - if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) { - batmon_log(LOG_TRIGGER_PERIODIC); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/contiki-conf.h b/platform/sensinode/contiki-conf.h deleted file mode 100644 index d09fdbcbd..000000000 --- a/platform/sensinode/contiki-conf.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef CONTIKI_CONF_H_ -#define CONTIKI_CONF_H_ - -#include "8051def.h" -#include "sys/cc.h" -#include - -/* Include Project Specific conf */ -#ifdef PROJECT_CONF_H -#include "project-conf.h" -#endif /* PROJECT_CONF_H */ - -/* - * Define this as 1 to poll the etimer process from within main instead of from - * the clock ISR. This reduces the ISR's stack usage and may prevent crashes. - */ -#ifndef CLOCK_CONF_STACK_FRIENDLY -#define CLOCK_CONF_STACK_FRIENDLY 1 -#endif - -/* Memory filesystem RAM size. */ -#define CFS_RAM_CONF_SIZE 512 - -/* Logging.. */ -#define LOG_CONF_ENABLED 0 - -#ifndef STACK_CONF_DEBUGGING -#define STACK_CONF_DEBUGGING 0 -#endif - -/* Energest Module */ -#ifndef ENERGEST_CONF_ON -#define ENERGEST_CONF_ON 0 -#endif - -/* Verbose Startup? Turning this off reduces our footprint a fair bit */ -#define STARTUP_CONF_VERBOSE 0 - -/* More CODE space savings by turning off process names */ -#define PROCESS_CONF_NO_PROCESS_NAMES 1 - -/* - * UARTs: 1=>Enabled, 0=>Disabled. Default: Both Disabled (see uart.h) - * Disabling UARTs reduces our CODE footprint - * Disabling UART1 also disables all debugging output. - * Should be used when nodes are meant to run on batteries - * - * On N740, by enabling UART1, you are also enabling an ugly hack which aims - * to detect the USB connection during execution. It will then turn on/off - * UART1 RX interrupts accordingly. This seems to work but you have been warned - * If you start seeing random crashes when on battery, this is where to look. - */ -#ifndef UART_ONE_CONF_ENABLE -#define UART_ONE_CONF_ENABLE 1 -#endif -#ifndef UART_ONE_CONF_WITH_INPUT -#define UART_ONE_CONF_WITH_INPUT 0 -#endif -#define UART_ZERO_CONF_ENABLE 0 - -#ifndef UART_ONE_CONF_HIGH_SPEED -#define UART_ONE_CONF_HIGH_SPEED 0 -#endif - -#define SLIP_RADIO_CONF_NO_PUTCHAR 1 - -#if defined (UIP_FALLBACK_INTERFACE) || defined (CMD_CONF_OUTPUT) -#define SLIP_ARCH_CONF_ENABLE 1 -#endif - -/* Are we a SLIP bridge? */ -#if SLIP_ARCH_CONF_ENABLE -/* Make sure UART1 is enabled, with interrupts */ -#undef UART_ONE_CONF_ENABLE -#undef UART_ONE_CONF_WITH_INPUT -#define UART_ONE_CONF_ENABLE 1 -#define UART_ONE_CONF_WITH_INPUT 1 -#endif - -/* Output all captured frames over the UART in hexdump format */ -#ifndef CC2430_RF_CONF_HEXDUMP -#define CC2430_RF_CONF_HEXDUMP 0 -#endif - -#if CC2430_RF_CONF_HEXDUMP -/* We need UART1 output */ -#undef UART_ONE_CONF_ENABLE -#define UART_ONE_CONF_ENABLE 1 -#endif - -/* Code Shortcuts */ -/* - * When set, the RF driver is no longer a contiki process and the RX ISR is - * disabled. Instead of polling the radio process when data arrives, we - * periodically check for data by directly invoking the driver from main() - * - * When set, this directive also configures the following bypasses: - * - process_post_synch() in tcpip_input() (we call packet_input()) - * - process_post_synch() in tcpip_uipcall (we call the relevant pthread) - * - mac_call_sent_callback() is replaced with sent() in various places - * - * These are good things to do, they reduce stack usage and prevent crashes - */ -#define NETSTACK_CONF_SHORTCUTS 1 - -/* - * Sensors - * It is harmless to #define XYZ 1 - * even if the sensor is not present on our device - */ -#ifndef BUTTON_SENSOR_CONF_ON -#define BUTTON_SENSOR_CONF_ON 1 /* Buttons */ -#endif -/* ADC - Turning this off will disable everything below */ -#ifndef ADC_SENSOR_CONF_ON -#define ADC_SENSOR_CONF_ON 1 -#endif -#define TEMP_SENSOR_CONF_ON 1 /* Temperature */ -#define BATTERY_SENSOR_CONF_ON 1 /* Battery */ -#define VDD_SENSOR_CONF_ON 1 /* Supply Voltage */ -#define ACC_SENSOR_CONF_ON 1 /* Accelerometer */ -#define ACC_SENSOR_CONF_GSEL 0 /* Acc. g-Select => 1: +/-11g, 0: +/-3g */ -#define LIGHT_SENSOR_CONF_ON 1 /* Light */ - -/* Watchdog */ -#define WDT_CONF_INTERVAL 0 -#define WDT_CONF_TIMER_MODE 0 /* 0 or undefined for watchdog mode */ - -/* Low Power Modes - We only support PM0/Idle and PM1 */ -#ifndef LPM_CONF_MODE -#define LPM_CONF_MODE 1 /* 0: no LPM, 1: MCU IDLE, 2: Drop to PM1 */ -#endif - -/* DMA Configuration */ -#ifndef DMA_CONF_ON -#define DMA_CONF_ON 0 -#endif - -/* N740 Serial Flash */ -#ifndef M25P16_CONF_ON -#define M25P16_CONF_ON 1 -#endif - -/* XXX argh, ugly hack to make stuff compile! */ -#define snprintf(BUF, SIZE, ...) sprintf(BUF, __VA_ARGS__) - -/* Sensinode-Specific Tools and APPs */ -/* Viztool on by default for IPv6 builds */ -#if NETSTACK_CONF_WITH_IPV6 -#ifndef VIZTOOL_CONF_ON -#define VIZTOOL_CONF_ON 1 -#endif /* VIZTOOL_CONF_ON */ -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -/* BatMon off by default unless we build with APPS += batmon */ -#ifndef BATMON_CONF_ON -#define BATMON_CONF_ON 0 -#endif - -/* Network Stack */ -#ifndef NETSTACK_CONF_NETWORK -#if NETSTACK_CONF_WITH_IPV6 -#define NETSTACK_CONF_NETWORK sicslowpan_driver -#else -#define NETSTACK_CONF_NETWORK rime_driver -#endif /* NETSTACK_CONF_WITH_IPV6 */ -#endif /* NETSTACK_CONF_NETWORK */ - -#ifndef NETSTACK_CONF_MAC -#define NETSTACK_CONF_MAC csma_driver -#endif - -#ifndef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC nullrdc_driver -#define NULLRDC_802154_AUTOACK 1 -#define NULLRDC_802154_AUTOACK_HW 1 -#endif - -#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 -#endif - -#ifndef NETSTACK_CONF_FRAMER -#define NETSTACK_CONF_FRAMER framer_802154 -#endif - -#define NETSTACK_CONF_RADIO cc2430_rf_driver - -/* RF Config */ -#define IEEE802154_CONF_PANID 0x4C55 /* LU */ - -#ifndef CC2430_RF_CONF_CHANNEL -#define CC2430_RF_CONF_CHANNEL 25 -#endif /* CC2430_RF_CONF_CHANNEL */ - -#ifndef CC2430_RF_CONF_TX_POWER -#define CC2430_RF_CONF_TX_POWER 0x5F /* Datasheet recommended value */ -#endif - -#ifndef CC2430_RF_CONF_AUTOACK -#define CC2430_RF_CONF_AUTOACK 1 -#endif /* CC2430_CONF_AUTOACK */ - -#if NETSTACK_CONF_WITH_IPV6 -/* Addresses, Sizes and Interfaces */ -/* 8-byte addresses here, 2 otherwise */ -#define LINKADDR_CONF_SIZE 8 -#define UIP_CONF_LL_802154 1 -#define UIP_CONF_LLH_LEN 0 -#define UIP_CONF_NETIF_MAX_ADDRESSES 3 - -/* TCP, UDP, ICMP */ -#define UIP_CONF_TCP 0 -#define UIP_CONF_UDP 1 -#define UIP_CONF_UDP_CHECKSUMS 1 - -/* ND and Routing */ -#ifndef UIP_CONF_ROUTER -#define UIP_CONF_ROUTER 1 -#endif - -#define UIP_CONF_ND6_SEND_RA 0 -#define UIP_CONF_IP_FORWARD 0 -#define RPL_CONF_STATS 0 - -#ifndef RPL_CONF_OF -#define RPL_CONF_OF rpl_mrhof -#endif - -#define UIP_CONF_ND6_REACHABLE_TIME 600000 -#define UIP_CONF_ND6_RETRANS_TIMER 10000 - -#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS -#define NBR_TABLE_CONF_MAX_NEIGHBORS 4 /* Handle n Neighbors */ -#endif -#ifndef UIP_CONF_MAX_ROUTES -#define UIP_CONF_MAX_ROUTES 4 /* Handle n Routes */ -#endif - -/* uIP */ -#ifndef UIP_CONF_BUFFER_SIZE -#define UIP_CONF_BUFFER_SIZE 240 -#endif -#define UIP_CONF_IPV6_QUEUE_PKT 0 -#define UIP_CONF_IPV6_CHECKS 1 -#define UIP_CONF_IPV6_REASSEMBLY 0 - -/* 6lowpan */ -#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 -#ifndef SICSLOWPAN_CONF_FRAG -#define SICSLOWPAN_CONF_FRAG 0 /* About 2KB of CODE if 1 */ -#endif -#define SICSLOWPAN_CONF_MAXAGE 8 - -/* Define our IPv6 prefixes/contexts here */ -#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 -#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ - addr_contexts[0].prefix[0] = 0x20; \ - addr_contexts[0].prefix[1] = 0x01; \ - addr_contexts[0].prefix[2] = 0x06; \ - addr_contexts[0].prefix[3] = 0x30; \ - addr_contexts[0].prefix[4] = 0x03; \ - addr_contexts[0].prefix[5] = 0x01; \ - addr_contexts[0].prefix[6] = 0x64; \ - addr_contexts[0].prefix[7] = 0x53; \ -} - -#define MAC_CONF_CHANNEL_CHECK_RATE 8 -#ifndef QUEUEBUF_CONF_NUM -#define QUEUEBUF_CONF_NUM 6 -#endif - -#else /* NETSTACK_CONF_WITH_IPV6 */ -/* Network setup for non-IPv6 (rime). */ -#define UIP_CONF_IP_FORWARD 1 -#define UIP_CONF_BUFFER_SIZE 108 -#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 -#define QUEUEBUF_CONF_NUM 8 -#endif /* NETSTACK_CONF_WITH_IPV6 */ - -/* Prevent SDCC compile error when UIP_CONF_ROUTER == 0 */ -#if !UIP_CONF_ROUTER -#define UIP_CONF_DS6_AADDR_NBU 1 -#endif - -#endif /* CONTIKI_CONF_H_ */ diff --git a/platform/sensinode/contiki-sensinode-main.c b/platform/sensinode/contiki-sensinode-main.c deleted file mode 100644 index 541b28d26..000000000 --- a/platform/sensinode/contiki-sensinode-main.c +++ /dev/null @@ -1,382 +0,0 @@ -#include "contiki.h" -#include "sys/clock.h" -#include "sys/autostart.h" - -#include "dev/serial-line.h" -#include "dev/slip.h" -#include "dev/bus.h" -#include "dev/leds.h" -#include "dev/uart1.h" -#include "dev/dma.h" -#include "dev/models.h" -#include "dev/cc2430_rf.h" -#include "dev/watchdog.h" -#include "dev/lpm.h" -#include "net/rime/rime.h" -#include "net/netstack.h" -#include "net/mac/frame802154.h" -#include "debug.h" -#include "stack.h" -#include "dev/watchdog-cc2430.h" -#include "dev/sensinode-sensors.h" -#include "disco.h" -#include "contiki-lib.h" -#include "contiki-net.h" - -unsigned short node_id = 0; /* Manually sets MAC address when > 0 */ - -#if VIZTOOL_CONF_ON -PROCESS_NAME(viztool_process); -#endif - -#if BATMON_CONF_ON -PROCESS_NAME(batmon_process); -#endif - -#if NETSTACK_CONF_SHORTCUTS -static CC_AT_DATA uint16_t len; -#endif - -#ifdef STARTUP_CONF_VERBOSE -#define STARTUP_VERBOSE STARTUP_CONF_VERBOSE -#else -#define STARTUP_VERBOSE 0 -#endif - -#if STARTUP_VERBOSE -#define PUTSTRING(...) putstring(__VA_ARGS__) -#define PUTHEX(...) puthex(__VA_ARGS__) -#define PUTBIN(...) putbin(__VA_ARGS__) -#define PUTCHAR(...) putchar(__VA_ARGS__) -#else -#define PUTSTRING(...) do {} while(0) -#define PUTHEX(...) do {} while(0) -#define PUTBIN(...) do {} while(0) -#define PUTCHAR(...) do {} while(0) -#endif - -#if CLOCK_CONF_STACK_FRIENDLY -extern volatile uint8_t sleep_flag; -#endif - -extern linkaddr_t linkaddr_node_addr; -#if ENERGEST_CONF_ON -static unsigned long irq_energest = 0; -#define ENERGEST_IRQ_SAVE(a) do { \ - a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0) -#define ENERGEST_IRQ_RESTORE(a) do { \ - energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0) -#else -#define ENERGEST_IRQ_SAVE(a) do {} while(0) -#define ENERGEST_IRQ_RESTORE(a) do {} while(0) -#endif -/*---------------------------------------------------------------------------*/ -static void -fade(int l) CC_NON_BANKED -{ - volatile int i, a; - int k, j; - for(k = 0; k < 400; ++k) { - j = k > 200 ? 400 - k : k; - - leds_on(l); - for(i = 0; i < j; ++i) { - a = i; - } - leds_off(l); - for(i = 0; i < 200 - j; ++i) { - a = i; - } - } -} -/*---------------------------------------------------------------------------*/ -static void -set_rime_addr(void) CC_NON_BANKED -{ - uint8_t *addr_long = NULL; - uint16_t addr_short = 0; - char i; - __code unsigned char *macp; - - PUTSTRING("Rime is 0x"); - PUTHEX(sizeof(linkaddr_t)); - PUTSTRING(" bytes long\n"); - - if(node_id == 0) { - PUTSTRING("Reading MAC from flash\n"); - /* - * The MAC is always stored in 0x1FFF8 of our flash. This maps to address - * 0xFFF8 of our CODE segment, when BANK3 is selected. - * Switch to BANK3, read 8 bytes starting at 0xFFF8 and restore last BANK - * Since we are called from main(), this MUST be BANK1 or something is very - * wrong. This code can be used even without banking - */ - - /* Don't interrupt us to make sure no BANK switching happens while working */ - DISABLE_INTERRUPTS(); - - /* Switch to BANK3, map CODE: 0x8000 - 0xFFFF to FLASH: 0x18000 - 0x1FFFF */ - FMAP = 3; - - /* Set our pointer to the correct address and fetch 8 bytes of MAC */ - macp = (__code unsigned char *)0xFFF8; - - for(i = (LINKADDR_SIZE - 1); i >= 0; --i) { - linkaddr_node_addr.u8[i] = *macp; - macp++; - } - - /* Remap 0x8000 - 0xFFFF to BANK1 */ - FMAP = 1; - ENABLE_INTERRUPTS(); - - } else { - PUTSTRING("Setting manual address from node_id\n"); - linkaddr_node_addr.u8[LINKADDR_SIZE - 1] = node_id >> 8; - linkaddr_node_addr.u8[LINKADDR_SIZE - 2] = node_id & 0xff; - } - - /* Now the address is stored MSB first */ -#if STARTUP_VERBOSE - PUTSTRING("Rime configured with address "); - for(i = 0; i < LINKADDR_SIZE - 1; i++) { - PUTHEX(linkaddr_node_addr.u8[i]); - PUTCHAR(':'); - } - PUTHEX(linkaddr_node_addr.u8[i]); - PUTCHAR('\n'); -#endif - - /* Set the cc2430 RF addresses */ -#if (LINKADDR_SIZE==8) - addr_short = (linkaddr_node_addr.u8[6] * 256) + linkaddr_node_addr.u8[7]; - addr_long = (uint8_t *) &linkaddr_node_addr; -#else - addr_short = (linkaddr_node_addr.u8[0] * 256) + linkaddr_node_addr.u8[1]; -#endif - cc2430_rf_set_addr(IEEE802154_PANID, addr_short, addr_long); -} -/*---------------------------------------------------------------------------*/ -int -main(void) -{ - - /* Hardware initialization */ - bus_init(); - rtimer_init(); - - stack_poison(); - - /* model-specific h/w init. */ - model_init(); - - /* Init LEDs here */ - leds_init(); - fade(LEDS_GREEN); - - /* initialize process manager. */ - process_init(); - - /* Init UART1 */ - uart1_init(); - -#if DMA_ON - dma_init(); -#endif - -#if SLIP_ARCH_CONF_ENABLE - /* On cc2430, the argument is not used */ - slip_arch_init(0); -#else - uart1_set_input(serial_line_input_byte); - serial_line_init(); -#endif - - PUTSTRING("##########################################\n"); - putstring(CONTIKI_VERSION_STRING "\n"); - putstring(SENSINODE_MODEL " (CC24"); - puthex(((CHIPID >> 3) | 0x20)); - putstring("-" FLASH_SIZE ")\n"); - -#if STARTUP_VERBOSE -#ifdef HAVE_SDCC_BANKING - PUTSTRING(" With Banking.\n"); -#endif /* HAVE_SDCC_BANKING */ -#ifdef SDCC_MODEL_LARGE - PUTSTRING(" --model-large\n"); -#endif /* SDCC_MODEL_LARGE */ -#ifdef SDCC_MODEL_HUGE - PUTSTRING(" --model-huge\n"); -#endif /* SDCC_MODEL_HUGE */ -#ifdef SDCC_STACK_AUTO - PUTSTRING(" --stack-auto\n"); -#endif /* SDCC_STACK_AUTO */ - - PUTCHAR('\n'); - - PUTSTRING(" Net: "); - PUTSTRING(NETSTACK_NETWORK.name); - PUTCHAR('\n'); - PUTSTRING(" MAC: "); - PUTSTRING(NETSTACK_MAC.name); - PUTCHAR('\n'); - PUTSTRING(" RDC: "); - PUTSTRING(NETSTACK_RDC.name); - PUTCHAR('\n'); - - PUTSTRING("##########################################\n"); -#endif - - watchdog_init(); - - /* Initialise the cc2430 RNG engine. */ - random_init(0); - - /* start services */ - process_start(&etimer_process, NULL); - ctimer_init(); - - /* initialize the netstack */ - netstack_init(); - set_rime_addr(); - -#if BUTTON_SENSOR_ON || ADC_SENSOR_ON - process_start(&sensors_process, NULL); - sensinode_sensors_activate(); -#endif - -#if NETSTACK_CONF_WITH_IPV6 - memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); - queuebuf_init(); - process_start(&tcpip_process, NULL); - -#if DISCO_ENABLED - process_start(&disco_process, NULL); -#endif /* DISCO_ENABLED */ - -#if VIZTOOL_CONF_ON - process_start(&viztool_process, NULL); -#endif - -#if (!UIP_CONF_IPV6_RPL) - { - uip_ipaddr_t ipaddr; - - uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); - uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); - } -#endif /* UIP_CONF_IPV6_RPL */ -#endif /* NETSTACK_CONF_WITH_IPV6 */ - - /* - * Acknowledge the UART1 RX interrupt - * now that we're sure we are ready to process it - */ - model_uart_intr_en(); - - energest_init(); - ENERGEST_ON(ENERGEST_TYPE_CPU); - - fade(LEDS_RED); - -#if BATMON_CONF_ON - process_start(&batmon_process, NULL); -#endif - - autostart_start(autostart_processes); - - watchdog_start(); - - while(1) { - uint8_t r; - do { - /* Reset watchdog and handle polls and events */ - watchdog_periodic(); - -#if CLOCK_CONF_STACK_FRIENDLY - if(sleep_flag) { - if(etimer_pending() && - (etimer_next_expiration_time() - clock_time() - 1) > MAX_TICKS) { - etimer_request_poll(); - } - sleep_flag = 0; - } -#endif - r = process_run(); - } while(r > 0); -#if NETSTACK_CONF_SHORTCUTS - len = NETSTACK_RADIO.pending_packet(); - if(len) { - packetbuf_clear(); - len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); - if(len > 0) { - packetbuf_set_datalen(len); - NETSTACK_RDC.input(); - } - } -#endif - -#if LPM_MODE -#if (LPM_MODE==LPM_MODE_PM2) - SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ - while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */ - CLKCON |= OSC; /* Switch to the RCOSC */ - while(!(CLKCON & OSC)); /* Wait till it's happened */ - SLEEP |= OSC_PD; /* Turn the other one off */ -#endif /* LPM_MODE==LPM_MODE_PM2 */ - - /* - * Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM - * Sleep Timer will wake us up in no more than 7.8ms (max idle interval) - */ - SLEEP = (SLEEP & 0xFC) | (LPM_MODE - 1); - -#if (LPM_MODE==LPM_MODE_PM2) - /* - * Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or - * no interrupt occurred and we can safely power down - */ - __asm - nop - nop - nop - __endasm; - - if(SLEEP & SLEEP_MODE0) { -#endif /* LPM_MODE==LPM_MODE_PM2 */ - - ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM); - - /* We are only interested in IRQ energest while idle or in LPM */ - ENERGEST_IRQ_RESTORE(irq_energest); - - /* Go IDLE or Enter PM1 */ - PCON |= IDLE; - - /* First instruction upon exiting PM1 must be a NOP */ - __asm - nop - __endasm; - - /* Remember energest IRQ for next pass */ - ENERGEST_IRQ_SAVE(irq_energest); - - ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU); - -#if (LPM_MODE==LPM_MODE_PM2) - SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */ - while(!(SLEEP & XOSC_STB)); /* Wait for XOSC to be stable */ - CLKCON &= ~OSC; /* Switch to the XOSC */ - /* - * On occasion the XOSC is reported stable when in reality it's not. - * We need to wait for a safeguard of 64us or more before selecting it - */ - clock_delay_usec(65); - while(CLKCON & OSC); /* Wait till it's happened */ - } -#endif /* LPM_MODE==LPM_MODE_PM2 */ -#endif /* LPM_MODE */ - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/debug.c b/platform/sensinode/debug.c deleted file mode 100644 index f2fcb9498..000000000 --- a/platform/sensinode/debug.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * \file - * - * Definition of some debugging functions for the sensinode port. - * - * This file is bankable. - * - * putstring() and puthex() are from msp430/watchdog.c - * - * \author - * George Oikonomou - - */ - -#include "cc2430_sfr.h" -#include "8051def.h" -#include "debug.h" - -static const char hexconv[] = "0123456789abcdef"; -static const char binconv[] = "01"; - -/*---------------------------------------------------------------------------*/ -void -putstring(char *s) -{ - while(*s) { - putchar(*s++); - } -} -/*---------------------------------------------------------------------------*/ -void -puthex(uint8_t c) -{ - putchar(hexconv[c >> 4]); - putchar(hexconv[c & 0x0f]); -} -/*---------------------------------------------------------------------------*/ -void -putbin(uint8_t c) -{ - unsigned char i = 0x80; - while(i) { - putchar(binconv[(c & i) != 0]); - i >>= 1; - } -} -/*---------------------------------------------------------------------------*/ -void -putdec(uint8_t c) -{ - uint8_t div; - uint8_t hassent = 0; - for(div = 100; div > 0; div /= 10) { - uint8_t disp = c / div; - c %= div; - if((disp != 0) || (hassent) || (div == 1)) { - hassent = 1; - putchar('0' + disp); - } - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/debug.h b/platform/sensinode/debug.h deleted file mode 100644 index 94eaa4f51..000000000 --- a/platform/sensinode/debug.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -/** - * \file - * Header file for debugging functions used by the sensinode port. - * - * putstring() and puthex() are from msp430/watchdog.c - * - * \author - * George Oikonomou - - */ - -#ifndef DEBUG_H_ -#define DEBUG_H_ - -#include "8051def.h" -#include "dev/uart1.h" - -void putchar(char c); -void putstring(char *s); -void puthex(uint8_t c); -void putbin(uint8_t c); -void putdec(uint8_t c); - -#endif /* DEBUG_H_ */ diff --git a/platform/sensinode/dev/adc-sensor.c b/platform/sensinode/dev/adc-sensor.c deleted file mode 100644 index c039adafa..000000000 --- a/platform/sensinode/dev/adc-sensor.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * ADC sensor module for sensinode devices. - * - * This file respects configuration in contiki-conf.h. It also turns - * off features which are not present in the model that we are - * building for. - * - * \author - * George Oikonomou - - */ -#include "dev/sensinode-sensors.h" - -#if ADC_SENSOR_ON -SENSORS_SENSOR(adc_sensor, ADC_SENSOR, value, configure, status); - -static uint8_t ready; - -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - uint16_t reading; - /* - * For single-shot AD conversions, we may only write to ADCCON3[3:0] once - * (This write triggers the conversion). We thus use the variable 'command' - * to store intermediate steps (reference, decimation rate, input channel) - */ - uint8_t command; - - ADCCFG = 0; /* Enables/Disables Input Channel */ - - /* 1.25V ref, max decimation rate */ - command = ADEDIV1 | ADEDIV0; - - /* Clear the Interrupt Flag */ - TCON_ADCIF = 0; - - /* Depending on the desired reading, append the input bits to 'command' and - * enable the corresponding input channel in ADCCFG if necessary */ - switch(type) { -#if TEMP_SENSOR_ON - case ADC_SENSOR_TYPE_TEMP: - command |= ADECH3 | ADECH2 | ADECH1; - break; -#endif -#if ACC_SENSOR_ON - case ADC_SENSOR_TYPE_ACC_X: - ADCCFG = ADC5EN; - command |= ADECH2 | ADECH0; - break; - case ADC_SENSOR_TYPE_ACC_Y: - ADCCFG = ADC6EN; - command |= ADECH2 | ADECH1; - break; - case ADC_SENSOR_TYPE_ACC_Z: - ADCCFG = ADC7EN; - command |= ADECH2 | ADECH1 | ADECH0; - break; -#endif -#if VDD_SENSOR_ON - case ADC_SENSOR_TYPE_VDD: - command |= ADECH3 | ADECH2 | ADECH1 | ADECH0; - break; -#endif -#if LIGHT_SENSOR_ON - case ADC_SENSOR_TYPE_LIGHT: - ADCCFG = ADC0EN; - break; -#endif -#if BATTERY_SENSOR_ON - case ADC_SENSOR_TYPE_BATTERY: - ADCCFG = ADC1EN; - command |= ADECH0 | ADEREF1; /* AVDD_SOC reference */ - break; -#endif - default: - /* If the sensor is not present or disabled in conf, return -1 */ - return -1; - } - - /* Writing in bits 3:0 of ADCCON3 will trigger a single conversion */ - ADCCON3 = command; - - /* - * When the conversion is complete, the ADC interrupt flag is set. We don't - * use an ISR here, we just wait on the flag and clear it afterwards. - */ - while(!TCON_ADCIF); - - /* Clear the Interrupt Flag */ - TCON_ADCIF = 0; - - reading = 0; - reading = ADCL; - reading |= (((uint8_t) ADCH) << 8); - /* 12-bit decimation rate: 4 LS bits are noise */ - reading >>= 4; - - return reading; -} -/*---------------------------------------------------------------------------*/ -static int -status(int type) -{ - return ready; -} -/*---------------------------------------------------------------------------*/ -/* - * On N740 we can control Ill and Acc individually: - * ADC_VAL_OTHERS 0x01 - * ADC_VAL_LIGHT_ON 0x04 - * ADC_VAL_ACC_ON 0x08 - * ADC_VAL_ACC_GSEL 0x10 - * - * Return Value is always light | acc | acc_gsel - * - * SENSORS_ACTIVE: - * - 1: Activate everything, use default setting for ACC G-select - * - 0: Turn everything off - * - xyz: Mask with the defines above and act accordingly. - * - * SENSORS_READY: - * - Return Status (0: all off or a value based on the defines above) - */ -static int -configure(int type, int value) -{ -#ifdef MODEL_N740 - /* - * Read current state of the ser-par, ignoring current sensor settings - * Those will be set all over depending on VALUE - */ - uint8_t ser_par_val = n740_ser_par_get() & 0xF2; -#endif /* MODEL_N740 */ - - /* 'Others' are either compiled in or not. Can't be turned on/off */ - ready = ADC_VAL_ALL; - - switch(type) { - case SENSORS_HW_INIT: - case SENSORS_ACTIVE: -#ifdef MODEL_N740 - if(value == ADC_VAL_ALL) { - value = ADC_VAL_ACC_ON | ADC_VAL_LIGHT_ON; -#if ACC_SENSOR_GSEL - value |= ADC_VAL_ACC_GSEL; -#endif /* ACC_SENSOR_GSEL */ - } -#endif /* MODEL_N740 */ - - /* OK, Now value definitely specifies our bits, start masking - * We will refuse to turn things on if they are specified OFF in conf. */ -#ifdef MODEL_N740 -#if ACC_SENSOR_ON - if(value & ADC_VAL_ACC_ON) { - P0SEL |= 0x80 | 0x40 | 0x20; - ser_par_val |= N740_SER_PAR_ACC; - ready |= ADC_VAL_ACC_ON; -#if ACC_SENSOR_GSEL - if(value & ADC_VAL_ACC_GSEL) { - ser_par_val |= N740_SER_PAR_ACC_GSEL; - ready |= ADC_VAL_ACC_GSEL; - } -#endif /*ACC_SENSOR_GSEL */ - } -#endif /* ACC_SENSOR_ON */ - -#if LIGHT_SENSOR_ON - if(value & ADC_VAL_LIGHT_ON) { - ser_par_val |= N740_SER_PAR_LIGHT; - ready |= ADC_VAL_LIGHT_ON; - } -#endif /* LIGHT_SENSOR_ON */ - n740_ser_par_set(ser_par_val); -#endif /* MODEL_N740 */ - } - return ready; -} - -#endif /* ADC_SENSOR_ON */ diff --git a/platform/sensinode/dev/button-sensor.c b/platform/sensinode/dev/button-sensor.c deleted file mode 100644 index 7b9c82ab4..000000000 --- a/platform/sensinode/dev/button-sensor.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/* - * Portions of this file build on button-sensor.c in platforms sky and esb - * This file contains ISRs: Keep it in the HOME bank. - */ - -#include "dev/models.h" -#include "lib/sensors.h" -#include "dev/hwconf.h" -#include "dev/sensinode-sensors.h" - -#if BUTTON_SENSOR_ON -static uint8_t p0ien; -static uint8_t p2ien; -static CC_AT_DATA struct timer debouncetimer[2]; - -#ifdef MODEL_N740 -HWCONF_PIN(BUTTON_1, 1, 0) -HWCONF_PORT_1_IRQ(BUTTON_1, 0) -HWCONF_PIN(BUTTON_2, 0, 4) -HWCONF_PORT_0_IRQ(BUTTON_2, 4) -#endif /* MODEL_N740 */ - -#ifdef MODEL_N711 -HWCONF_PIN(BUTTON_1, 0, 6) -HWCONF_PORT_0_IRQ(BUTTON_1, 6) -HWCONF_PIN(BUTTON_2, 0, 7) -HWCONF_PORT_0_IRQ(BUTTON_2, 7) -#endif /* MODEL_N711 */ - -/*---------------------------------------------------------------------------*/ -static int -value_b1(int type) -{ - return BUTTON_1_READ() || !timer_expired(&debouncetimer[0]); -} -/*---------------------------------------------------------------------------*/ -static int -status_b1(int type) -{ - switch(type) { - case SENSORS_ACTIVE: - case SENSORS_READY: - return BUTTON_1_IRQ_ENABLED(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -configure_b1(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - /* Generates INT when pressed */ - BUTTON_1_IRQ_EDGE_SELECTD(); - BUTTON_1_SELECT(); - BUTTON_1_MAKE_INPUT(); - return 1; - case SENSORS_ACTIVE: - if(value) { - if(!BUTTON_1_IRQ_ENABLED()) { - timer_set(&debouncetimer[0], 0); - BUTTON_1_IRQ_FLAG_OFF(); - BUTTON_1_ENABLE_IRQ(); - } - } else { - BUTTON_1_DISABLE_IRQ(); - } - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -value_b2(int type) -{ - return BUTTON_2_READ() || !timer_expired(&debouncetimer[1]); -} -/*---------------------------------------------------------------------------*/ -static int -status_b2(int type) -{ - switch(type) { - case SENSORS_ACTIVE: - case SENSORS_READY: - return BUTTON_2_IRQ_ENABLED(); - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -configure_b2(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - /* Generates INT when released */ - /* BUTTON_2_IRQ_EDGE_SELECTD(); */ - BUTTON_2_SELECT(); - BUTTON_2_MAKE_INPUT(); - return 1; - case SENSORS_ACTIVE: - if(value) { - if(!BUTTON_2_IRQ_ENABLED()) { - timer_set(&debouncetimer[1], 0); - BUTTON_2_IRQ_FLAG_OFF(); - BUTTON_2_ENABLE_IRQ(); - } - } else { - BUTTON_2_DISABLE_IRQ(); - } - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -#pragma save -#if CC_CONF_OPTIMIZE_STACK_SIZE -#pragma exclude bits -#endif -void -port_0_ISR(void) __interrupt (P0INT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* This ISR is for the entire port. Check if the interrupt was caused by our - * button's pin. */ - /* Check B1 for N711 */ -#ifdef MODEL_N711 - if(BUTTON_1_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[0])) { - timer_set(&debouncetimer[0], CLOCK_SECOND / 4); - sensors_changed(&button_1_sensor); - } - } -#endif /* MODEL_N711 */ - if(BUTTON_2_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[1])) { - timer_set(&debouncetimer[1], CLOCK_SECOND / 4); - sensors_changed(&button_2_sensor); - } - } - P0IFG = 0; - IRCON_P0IF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -/*---------------------------------------------------------------------------*/ -/* We only need this ISR for N740 */ -#ifdef MODEL_N740 -void -port_1_ISR(void) __interrupt (P1INT_VECTOR) -{ - EA = 0; - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - /* This ISR is for the entire port. Check if the interrupt was caused by our - * button's pin. This can only be B1 for N740 */ - if(BUTTON_1_CHECK_IRQ()) { - if(timer_expired(&debouncetimer[0])) { - timer_set(&debouncetimer[0], CLOCK_SECOND / 4); - sensors_changed(&button_1_sensor); - } - } - P1IFG = 0; - IRCON2_P1IF = 0; - ENERGEST_OFF(ENERGEST_TYPE_IRQ); - EA = 1; -} -#endif /* MODEL_N740 */ -#pragma restore - -SENSORS_SENSOR(button_1_sensor, BUTTON_1_SENSOR, value_b1, configure_b1, status_b1); -SENSORS_SENSOR(button_2_sensor, BUTTON_2_SENSOR, value_b2, configure_b2, status_b2); -#endif /* BUTTON_SENSOR_ON */ diff --git a/platform/sensinode/dev/button-sensor.h b/platform/sensinode/dev/button-sensor.h deleted file mode 100644 index 97a185223..000000000 --- a/platform/sensinode/dev/button-sensor.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Override core/dev/button-sensor.h - * - * We simply include "dev/sensinode-sensors.h". We do this so that apps - * and examples including button-sensor.h will compile for sensinodes - * - * \author - * George Oikonomou - - */ - -#ifndef BUTTON_SENSOR_H_ -#define BUTTON_SENSOR_H_ - -#include "dev/sensinode-sensors.h" - -#endif /* BUTTON_SENSOR_H_ */ diff --git a/platform/sensinode/dev/leds-arch.c b/platform/sensinode/dev/leds-arch.c deleted file mode 100644 index 5d4154d2f..000000000 --- a/platform/sensinode/dev/leds-arch.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "contiki-conf.h" -#include "dev/models.h" -#include "dev/leds.h" - -#include "cc2430_sfr.h" - -/* - * Sensinode v1.0 HW products have 2 red LEDs, LED1 is mapped to the Contiki - * LEDS_GREEN and LED2 is mapped to LEDS_RED. - */ - -/*---------------------------------------------------------------------------*/ -void -leds_arch_init(void) -{ -#ifdef MODEL_N740 - /* - * We don't need explicit led initialisation for N740s. They are controlled - * by the ser/par chip which is initalised already - */ - return; -#else - P0DIR |= 0x30; -#endif -} -/*---------------------------------------------------------------------------*/ -unsigned char -leds_arch_get(void) -{ - unsigned char l = 0; - -#ifdef MODEL_N740 - /* Read the current ser-par chip status */ - uint8_t ser_par; - ser_par = n740_ser_par_get(); - /* Check bits 7 & 8, ignore the rest */ - if(ser_par & N740_SER_PAR_LED_GREEN) { - l |= LEDS_GREEN; - } - if(ser_par & N740_SER_PAR_LED_RED) { - l |= LEDS_RED; - } -#else - if(LED1_PIN) { - l |= LEDS_GREEN; - } - if(LED2_PIN) { - l |= LEDS_RED; - } -#endif - return l; -} -/*---------------------------------------------------------------------------*/ -void -leds_arch_set(unsigned char leds) -{ -#ifdef MODEL_N740 - /* Read the current ser-par chip status - we want to change bits 7 & 8 but - * the remaining bit values should be retained */ - uint8_t ser_par; - ser_par = n740_ser_par_get(); - if(leds & LEDS_GREEN) { - ser_par |= N740_SER_PAR_LED_GREEN; /* Set bit 7 */ - } else { - ser_par &= ~N740_SER_PAR_LED_GREEN; /* Unset bit 7 */ - } - - if(leds & LEDS_RED) { - ser_par |= N740_SER_PAR_LED_RED; /* Set bit 8 */ - } else { - ser_par &= ~N740_SER_PAR_LED_RED; /* Unset bit 8 */ - } - - /* Write the new status back to the chip */ - n740_ser_par_set(ser_par); -#else - if(leds & LEDS_GREEN) { - LED1_PIN = 1; - } else { - LED1_PIN = 0; - } - - if(leds & LEDS_RED) { - LED2_PIN = 1; - } else { - LED2_PIN = 0; - } -#endif -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/m25p16.c b/platform/sensinode/dev/m25p16.c deleted file mode 100644 index f1cbdebfd..000000000 --- a/platform/sensinode/dev/m25p16.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file provides functions to control the M25P16 on sensinode N740s. - * This is a Numonyx Forte Serial Flash Memory (16Mbit) - * The S signal (Chip Select) is controlled via 0x02 on the 74HC595D - * The other instructions and timing are performed with bit bang - * - * We can enable, disable, read/write data, erase pages, hold, enter/exit - * deep sleep etc. - * - * Clock (C) => P1_5, - * Ser. I (D) => P1_6, - * Ser. O (Q) => P1_7, - * Hold => Pull Up, - * Write Prot => Pull Up, - * Chip Sel => 74HC595D (0x02) - * - * This file can be placed in any bank. - * - * \author - * George Oikonomou - - */ - -#include "dev/n740.h" -#include "dev/m25p16.h" -#include "sys/clock.h" -#include "sys/energest.h" -#include "cc2430_sfr.h" - -#define CLOCK_RISING() {M25P16_PIN_CLOCK = 1; M25P16_PIN_CLOCK = 0;} -#define CLOCK_FALLING() {M25P16_PIN_CLOCK = 0; M25P16_PIN_CLOCK = 1;} -/*---------------------------------------------------------------------------*/ -/* Bit-Bang write a byte to the chip */ -static void -bit_bang_write(uint8_t byte) CC_NON_BANKED -{ - uint8_t i; - uint8_t bit; - - /* bit-by-bit */ - for(i = 0x80; i > 0; i >>= 1) { - /* Is the bit set? */ - bit = 0; - if(i & byte) { - /* If it was set, we want to send 1 */ - bit = 1; - } - /* Send the bit */ - M25P16_PIN_SER_I = bit; - /* Clock - Rising */ - CLOCK_RISING(); - } -} -/*---------------------------------------------------------------------------*/ -/* Bit-Bang read a byte from the chip */ -static uint8_t -bit_bang_read() CC_NON_BANKED -{ - int8_t i; - uint8_t bits = 0; - - /* bit-by-bit */ - for(i = 7; i >= 0; i--) { - /* Clock - Falling */ - CLOCK_FALLING(); - - /* Read the bit */ - bits |= (M25P16_PIN_SER_O << i); - } - return bits; -} -/*---------------------------------------------------------------------------*/ -static void -select() CC_NON_BANKED -{ - /* Read current ser/par value */ - uint8_t ser_par = n740_ser_par_get(); - - M25P16_PIN_CLOCK = 0; - - ser_par &= ~N740_SER_PAR_CHIP_SEL; /* Select Flash */ - - /* Write the new status back to the ser/par */ - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -static void -deselect() CC_NON_BANKED -{ - /* Read current ser/par value */ - uint8_t ser_par = n740_ser_par_get(); - - ser_par |= N740_SER_PAR_CHIP_SEL; /* De-Select Flash */ - - /* Write the new status back to the ser/par */ - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wren() -{ - select(); - bit_bang_write(M25P16_I_WREN); - deselect(); - - while(!M25P16_WEL()); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wrdi() -{ - select(); - bit_bang_write(M25P16_I_WRDI); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_rdid(struct m25p16_rdid *rdid) -{ - uint8_t i; - - select(); - bit_bang_write(M25P16_I_RDID); - - rdid->man_id = bit_bang_read(); - rdid->mem_type = bit_bang_read(); /* Device ID MSB */ - rdid->mem_size = bit_bang_read(); /* Device ID LSB */ - rdid->uid_len = bit_bang_read(); - for(i = 0; i < rdid->uid_len; i++) { - rdid->uid[i] = bit_bang_read(); - } - deselect(); -} -/*---------------------------------------------------------------------------*/ -uint8_t -m25p16_rdsr() -{ - uint8_t rv; - - select(); - bit_bang_write(M25P16_I_RDSR); - rv = bit_bang_read(); - deselect(); - - return rv; -} -/*---------------------------------------------------------------------------*/ -void -m25p16_wrsr(uint8_t val) -{ - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_WRSR); - bit_bang_write(val); - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_read(uint8_t * addr, uint8_t * buff, uint8_t buff_len) -{ - uint8_t i; - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); - -#if M25P16_READ_FAST - bit_bang_write(M25P16_I_FAST_READ); -#else - bit_bang_write(M25P16_I_READ); -#endif - - /* Write the address, MSB in addr[0], bits [7:5] of the MSB: 'don't care' */ - for(i = 0; i < 3; i++) { - bit_bang_write(addr[i]); - } - - /* For FAST_READ, send the dummy byte */ -#if M25P16_READ_FAST - bit_bang_write(M25P16_DUMMY_BYTE); -#endif - - for(i = 0; i < buff_len; i++) { - buff[i] = ~bit_bang_read(); - } - ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_pp(uint8_t * addr, uint8_t * buff, uint8_t buff_len) -{ - uint8_t i; - - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_PP); - - /* Write the address, MSB in addr[0] */ - for(i = 0; i < 3; i++) { - bit_bang_write(addr[i]); - } - - /* Write the bytes */ - for(i = 0; i < buff_len; i++) { - bit_bang_write(~buff[i]); - } - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_se(uint8_t s) -{ - m25p16_wren(); /* Write Enable */ - - select(); - ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - bit_bang_write(M25P16_I_SE); - bit_bang_write(s); - bit_bang_write(0x00); - bit_bang_write(0x00); - deselect(); - ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_be() -{ - m25p16_wren(); /* Write Enable */ - - select(); - bit_bang_write(M25P16_I_BE); - deselect(); -} -/*---------------------------------------------------------------------------*/ -void -m25p16_dp() -{ - select(); - bit_bang_write(M25P16_I_DP); - deselect(); -} -/*---------------------------------------------------------------------------*/ -/* - * Release Deep Power Down. We do NOT read the Electronic Signature - */ -void -m25p16_res() -{ - select(); - bit_bang_write(M25P16_I_RES); - deselect(); - /* a few usec between RES and standby */ - while(M25P16_WIP()); -} -/*---------------------------------------------------------------------------*/ -/** - * Release Deep Power Down. Read and return the Electronic Signature - * must return 0x14 - * - * \return The old style Electronic Signature. This must be 0x14 - */ -uint8_t -m25p16_res_res() -{ - uint8_t rv; - - select(); - bit_bang_write(M25P16_I_RES); - bit_bang_write(M25P16_DUMMY_BYTE); - bit_bang_write(M25P16_DUMMY_BYTE); - bit_bang_write(M25P16_DUMMY_BYTE); - - rv = bit_bang_read(); - - deselect(); - - /* a few usec between RES and standby */ - while(M25P16_WIP()); - return rv; -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/m25p16.h b/platform/sensinode/dev/m25p16.h deleted file mode 100644 index 580564953..000000000 --- a/platform/sensinode/dev/m25p16.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the control of the M25P16 on sensinode N740s. - * - * \author - * George Oikonomou - - */ - -#ifndef M25P16_H_ -#define M25P16_H_ - -/* Instruction Set */ -#define M25P16_I_WREN 0x06 /* Write Enable */ -#define M25P16_I_WRDI 0x04 /* Write Disable */ -#define M25P16_I_RDID 0x9F /* Read Identification */ -#define M25P16_I_RDSR 0x05 /* Read Status Register */ -#define M25P16_I_WRSR 0x01 /* Write Status Register */ -#define M25P16_I_READ 0x03 /* Read Data Bytes */ -#define M25P16_I_FAST_READ 0x0B /* Read Data Bytes at Higher Speed */ -#define M25P16_I_PP 0x02 /* Page Program */ -#define M25P16_I_SE 0xD8 /* Sector Erase */ -#define M25P16_I_BE 0xC7 /* Bulk Erase */ -#define M25P16_I_DP 0xB9 /* Deep Power-down */ -#define M25P16_I_RES 0xAB /* Release from Deep Power-down */ - -/* Dummy Byte - Used in FAST_READ and RES */ -#define M25P16_DUMMY_BYTE 0x00 - -/* Pins */ -#define M25P16_PIN_CLOCK P1_5 -#define M25P16_PIN_SER_I P1_6 -#define M25P16_PIN_SER_O P1_7 - -/* Status Register Bits */ -#define M25P16_SR_SRWD 0x80 /* Status Register Write Disable */ -#define M25P16_SR_BP2 0x10 /* Block Protect 2 */ -#define M25P16_SR_BP1 0x08 /* Block Protect 1 */ -#define M25P16_SR_BP0 0x04 /* Block Protect 0 */ -#define M25P16_SR_BP 0x1C /* All Block Protect Bits */ -#define M25P16_SR_WEL 0x02 /* Write Enable Latch */ -#define M25P16_SR_WIP 0x01 /* Write in Progress */ - -/* Do we use READ or FAST_READ to read? Fast by default */ -#ifdef M25P16_CONF_READ_FAST -#define M25P16_READ_FAST M25P16_CONF_READ_FAST -#else -#define M25P16_READ_FAST 1 -#endif -/*---------------------------------------------------------------------------*/ -/** \brief Device Identifier - * - * Holds the value of the device identifier, returned by the RDID instruction. - * - * After a correct RDID, this structure should hold the following values: - * man_id = 0x20, mem_type = 0x20, mem_size = 0x15, uid_len = 0x10. - * - * UID holds optional Customized Factory Data (CFD) content. The CFD bytes are - * read-only and can be programmed with customers data upon their request. - * If the customers do not make requests, the devices are shipped with all the - * CFD bytes programmed to 0x00. - */ -struct m25p16_rdid { - uint8_t man_id; /** Manufacturer ID */ - uint8_t mem_type; /** Memory Type */ - uint8_t mem_size; /** Memory Size */ - uint8_t uid_len; /** Unique ID length */ - uint8_t uid[16]; /** Unique ID */ -}; -/*---------------------------------------------------------------------------*/ -/** - * \brief Retrieve Block Protect Bits from the status register - * - * This macro returns the software block protect status on the device - * by reading the value of the BP bits ([5:3]) in the Status Register - */ -#define M25P16_BP() (m25p16_rdsr() & M25P16_SR_BP) -/** - * \brief Check for Write in Progress - * \retval 1 Write in progress - * \retval 0 Write not in progress - * - * This macro checks if the device is currently in the middle of a write cycle - * by reading the value of the WIP bit (bit 0) in the Status Register - */ -#define M25P16_WIP() (m25p16_rdsr() & M25P16_SR_WIP) -/** - * \brief Check for Write-Enable - * \retval 1 Write enabled - * \retval 0 Write disabled - * - * This macro checks if the device is ready to accept a write instruction - * by reading the value of the WEL bit (bit 1) in the Status Register - */ -#define M25P16_WEL() (m25p16_rdsr() & M25P16_SR_WEL) -/*---------------------------------------------------------------------------*/ -/** - * \brief Write Enable (WREN) instruction. - * - * Completing a WRDI, PP, SE, BE and WRSR - * resets the write enable latch bit, so this instruction should be used every - * time before trying to write. - */ -void m25p16_wren(); - -/** - * \brief Write Disable (WRDI) instruction - */ -void m25p16_wrdi(); - -/** - * \brief Read Identifier (RDID)instruction - * - * \param rdid Pointer to a struct which will hold the information returned - * by the RDID instruction - */ -void m25p16_rdid(struct m25p16_rdid *rdid); - -/** - * \brief Read Status Register (RDSR) instruction - * - * \return Value of the status register - * - * Reads and returns the value of the status register on the Flash Chip - */ -uint8_t m25p16_rdsr(); - -/** - * \brief Write Status Register (WRSR) instruction - * \param val Value to be written to the status register - * - * This instruction does not afect bits 6, 5, 1 and 0 of the SR. - */ -void m25p16_wrsr(uint8_t val); - -/** - * \brief Read Data Bytes (READ) instruction - * \param addr 3 byte array holding the read start address. MSB stored in - * addr[0] and LSB in addr[2] - * \param buff Pointer to a buffer to hold the read bytes. - * \param buff_len Number of bytes to read. buff must be long enough to hold - * buff_len bytes - * - * The bytes will be inverted after being read, so that a value of 0xFF (empty) - * in the flash will read as 0x00 - */ -void m25p16_read(uint8_t * addr, uint8_t * buff, uint8_t buff_len); - -/** - * \brief Program Page (PP) instruction - * \param addr 3 byte array holding the write start address. MSB stored in - * addr[0] and LSB in addr[2] - * \param buff Pointer to a buffer with the data to be written - * \param buff_len Number of bytes to write, Maximum 256 bytes. - * - * Write BUFF_LEN bytes stored in BUFF to flash, starting from location - * ADDR. BUFF_LEN may not exceed 256. ADDR should point to a 3 byte array, - * with the address MSB stored in position 0 and LSB in position 2 - * - * If the start address + buff_len exceed page boundaries, the write will - * wrap to the start of the same page (the page at addr[2:1]). - * - * The bytes will be inverted before being written, so that a value of 0xFF - * will be written as 0x00 (and subsequently correctly read as 0xFF by READ) - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. This can take up to 5 msecs (typical - * duration for a 256 byte write is 640 usec) - */ -void m25p16_pp(uint8_t * addr, uint8_t * buff, uint8_t buff_len); - -/** - * \brief Sector Erase (SE) instruction - * \param s The number of the sector to be erased - * - * Delete the entire sector number s, by setting it's contents to all 0xFF - * (which will read as 0x00 by READ). The flash is broken down into 32 sectors, - * 64 KBytes each. - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. This can take up to 3 secs (typical - * duration 600 msec) - */ -void m25p16_se(uint8_t s); /* Sector Erase */ - - -/** - * \brief Bulk Erase (SE) instruction - * - * Delete the entire memory, by setting it's contents to all 0xFF - * (which will read as 0x00 by READ). - * - * This function will set the WEL bit on the SR before attempting to write, - * so the calling function doesn't need to worry about this. - * - * This call is asynchronous. It will return before the write cycle has - * completed. Thus, user software must check the WIP bit Write In Progress) - * before sending further instructions. - * - * This instructions takes a very long time to complete and must be used with - * care. It can take up to 40 secs (yes, secs). A typical duration is 13 secs - */ -void m25p16_be(); - -/** - * \brief Deep Power Down (DP) instruction - * - * Puts the device into its lowers power consumption mode (This is not the same - * as the stand-by mode caused by de-selecting the device). While the device - * is in DP, it will accept no instruction except a RES (Release from DP). - * - * This call is asynchronous and will return as soon as the instruction - * sequence has been written but before the device has actually entered DP - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -void m25p16_dp(); /* Deep Power down */ - -/** - * \brief Release from Deep Power Down (RES) instruction - * - * Take the device out of the Deep Power Down mode and bring it to standby. - * Does not read the electronic signature. - * - * This call is synchronous. When it returns the device will be in standby - * mode. - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -void m25p16_res(); - -/** - * \brief Release from Deep Power Down (RES) and Read Electronic - * Signature instruction - * - * \return The value of the electronic signature. This is provided for backward - * compatibility and must always be 0x14 - * - * Take the device out of the Deep Power Down mode and bring it to standby. - * Does not read the electronic signature. - * - * This call is synchronous. When it returns the device will be in standby - * mode. - * - * Dropping to DP takes 3usec and Resuming from DP takes at least 1.8usec, so - * this sequence should not be used when the sleep interval is estimated to be - * short (read as: don't DP then RES then DP repeatedly) - */ -uint8_t m25p16_res_res(); - -#endif /* M25P16_H_ */ diff --git a/platform/sensinode/dev/models.c b/platform/sensinode/dev/models.c deleted file mode 100644 index 15b21fffa..000000000 --- a/platform/sensinode/dev/models.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Model-specific functions for Sensinode devices. - * - * Bankable - * - * \author - * George Oikonomou - - */ - -#include "dev/models.h" -#include "dev/uart1.h" -#include "dev/m25p16.h" -/*---------------------------------------------------------------------------*/ -void -model_init() -{ -#ifdef MODEL_N740 - /* - * We want to prevent the dongle from controlling the state of the - * analog switch on the N740s. - * - * Set P0_3 as out and start with P0_3=0 (USB and Light selected) - */ - P0DIR |= 0x08; /* P0_3 out */ - P0_3 = 0; - - /* Init the serial-parallel chip for N740s. This will also 'init' LEDs */ - n740_ser_par_init(); - - /* Put the Serial Flash in Deep Power mode */ - n740_analog_deactivate(); - -#if M25P16_CONF_ON - m25p16_dp(); -#endif /* SERIAL_FLASH_CONF_ON */ - - n740_ser_par_set(0); -#endif -} -/*---------------------------------------------------------------------------*/ -void -model_uart_intr_en() -{ -#ifdef MODEL_N740 - /* - * Dirty, ugly hack for the N740 USART1 RX issue: - * When the USB is for whatever reason disabled (either disconnected or the - * analog switch has switched to the D-connector), RX starts flowing down - * pin 1.7 (and the line stays low), resulting in non-stop UART1_RX - * interrupts. So, we only acknowledge the interrupt when the line is - * high and the dongle is connected (thus we are on USB). - * - * For all other models, just turn the interrupt on - * - * Interrupts will only turn on if UART_ONE_CONF_WITH_INPUT is defined 1 - */ - if(P1_7 == 1 && P0_3 == 0) { - UART1_RX_INT(1); - } -#else - UART1_RX_INT(1); -#endif -} diff --git a/platform/sensinode/dev/models.h b/platform/sensinode/dev/models.h deleted file mode 100644 index 6cf4916f4..000000000 --- a/platform/sensinode/dev/models.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MODELS_H_ -#define MODELS_H_ - -/* Define model text */ -#ifdef MODEL_N100 -#define SENSINODE_MODEL "N100 Module" -#endif -#ifdef MODEL_N600 -#define SENSINODE_MODEL "N600 NanoRouter USB" -#endif -#ifdef MODEL_N601 -#define SENSINODE_MODEL "N601 NanoRouter USB" -#endif -#ifdef MODEL_N710 -#define SENSINODE_MODEL "N710 NanoSensor" -#endif -#ifdef MODEL_N711 -#define SENSINODE_MODEL "N711 NanoSensor" -#endif -#ifdef MODEL_N740 -#define SENSINODE_MODEL "N740 NanoSensor" -#endif - -#ifndef SENSINODE_MODEL -#define SENSINODE_MODEL "N100 Module" -#endif - -#ifndef FLASH_SIZE -#define FLASH_SIZE "F128" -#endif - -/* - * N740 has a serial-parallel chip onboard - * Defines and functions to control it - */ -#ifdef MODEL_N740 -#include "dev/n740.h" - -#else -/* All other models use these LED pins */ -#define LED1_PIN P0_4 -#define LED2_PIN P0_5 -#endif - -#ifdef MODEL_N711 -#define BUTTON1_PIN P0_6 -#define BUTTON2_PIN P0_7 -#endif - -/* Sensor pins */ - -#ifdef MODEL_N711 -#define LIGHT_PIN P0_0 -#define TEMP_PIN P0_1 -#endif - -/* Model-Specific startup functions */ -void model_init(); -void model_uart_intr_en(); -#endif /* MODELS_H_ */ diff --git a/platform/sensinode/dev/n740.c b/platform/sensinode/dev/n740.c deleted file mode 100644 index de1e20fd1..000000000 --- a/platform/sensinode/dev/n740.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This file provides functions to control various chips on the - * Sensinode N740s: - * - * - The 74HC595D is an 8-bit serial in-parallel out shift register. - * LEDs are connected to this chip. It also serves other functions such as - * enabling/disabling the Accelerometer (see n740.h). - * - The 74HC4053D is a triple, 2-channel analog mux/de-mux. - * It switches I/O between the USB and the D-Connector. - * It also controls P0_0 input source (Light Sensor / External I/O) - * - * Mux/De-mux: Connected to P0_3 (set to output in models.c - * Changing the state of the mux/demux can have catastrophic (tm) results - * on our software. If we are not careful, we risk entering a state where - * UART1 RX interrupts are being generated non-stop. Only change its state - * via the function in this file. - * - * Shift Register: - * For the shift register we can: - * - write a new instruction - * - remember and retrieve the last instruction sent - * - * The chip is connected to CPU pins as follows: - * - P0_2: Serial Data Input - * - P1_3: Shift Register Clock Input - * - P1_1: Storage Register Clock - * - * This file can be placed in any bank. - * - * \author - * George Oikonomou - - */ - -#include "dev/n740.h" -#include "dev/uart1.h" -#include "8051def.h" - -/* - * This variable stores the most recent instruction sent to the ser-par chip. - * We declare it as static and return its value through n740_ser_par_get(). - */ -static CC_AT_DATA uint8_t ser_par_status; - -/*---------------------------------------------------------------------------*/ -/* Init the serial-parallel chip: - * - Set I/O direction for all 3 pins (P0_2, P1_1 and P1_3) to output - */ -void -n740_ser_par_init() -{ - /* bus_init and uart1_init also touch the I/O direction for those pins */ - P1DIR |= 0x0A; - P0DIR |= 0x04; -} -/*---------------------------------------------------------------------------*/ -/* - * Send a command to the N740 serial-parallel chip. Each command is a single - * byte, each bit controls a different feature on the sensor. - */ -void -n740_ser_par_set(uint8_t data) -{ - uint8_t i; - uint8_t mask = 1; - uint8_t temp = 0; - - DISABLE_INTERRUPTS(); - /* bit-by-bit */ - for(i = 0; i < 8; i++) { - temp = (data & mask); - /* Is the bit set? */ - if(i && temp) { - /* If it was set, we want to send 1 */ - temp >>= i; - } - /* Send the bit */ - P0_2 = temp; - /* Shift */ - P1_3 = 1; - P1_3 = 0; - mask <<= 1; - } - /* Move to Par-Out */ - P1_1 = 1; - P1_1 = 0; - ENABLE_INTERRUPTS(); - - /* Right, we're done. Save the new status in ser_par_status */ - ser_par_status = data; -} -/*---------------------------------------------------------------------------*/ -/* This function returns the last value sent to the ser-par chip on the N740. - * - * The caveat here is that we must always use n740_set_ser_par() to send - * commands to the ser-par chip, never write directly. - * - * If any other function sends a command directly, ser_par_status and the - * actual status will end up out of sync. - */ -uint8_t -n740_ser_par_get() -{ - return ser_par_status; -} -/*---------------------------------------------------------------------------*/ -void -n740_analog_switch(uint8_t state) -{ - /* Turn off the UART RX interrupt before switching */ - DISABLE_INTERRUPTS(); - UART1_RX_INT(0); - - /* Switch */ - P0_3 = state; - - /* If P0_3 now points to the USB and nothing is flowing down P1_7, - * enable the interrupt again */ - if(P1_7 == 1 && P0_3 == N740_ANALOG_SWITCH_USB) { - UART1_RX_INT(1); - } - ENABLE_INTERRUPTS(); -} -/*---------------------------------------------------------------------------*/ -/* - * Activate the the 74HC4053D analog switch U5 on the N740 and at the same - * time set relevant pins to Peripheral I/O mode. This stops communications - * with the serial flash and enables UART1 I/O - */ -void -n740_analog_activate() -{ - uint8_t ser_par = n740_ser_par_get(); - ser_par &= ~N740_SER_PAR_U5_ENABLE; /* Turn on */ - - N740_PINS_PER_IO(); - - n740_ser_par_set(ser_par); -} -/*---------------------------------------------------------------------------*/ -/* - * De-Activate the the 74HC4053D analog switch U5 on the N740 and at the same - * time set relevant pins to GP I/O mode. This effectively prepares us to - * start talking with the serial flash chip - */ -void -n740_analog_deactivate() -{ - uint8_t ser_par = n740_ser_par_get(); - ser_par |= N740_SER_PAR_U5_ENABLE; /* Turn off */ - - n740_ser_par_set(ser_par); - - N740_PINS_GPIO(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/dev/n740.h b/platform/sensinode/dev/n740.h deleted file mode 100644 index 1bb74380e..000000000 --- a/platform/sensinode/dev/n740.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header File for the module which controls the Sensinode N740 - * 8-bit serial-in/serial or parallel-out shift register. - * - * This is where the Accelerometer, Leds, Light and Battery Sensors - * are connected. - * - * \author - * George Oikonomou - - */ - -#ifndef N740SERPAR_H_ -#define N740SERPAR_H_ - -#include "8051def.h" - -#define N740_SER_PAR_ACC_GSEL 0x01 /* Acceleration Sensor g-Select */ -#define N740_SER_PAR_CHIP_SEL 0x02 /* Flash Chip Select */ -#define N740_SER_PAR_LIGHT 0x04 /* Light Sensor */ -#define N740_SER_PAR_ACC 0x08 /* Acceleration Sensor */ -#define N740_SER_PAR_RF_IN_GAIN 0x10 /* Receiver Amplifier, best not set */ -#define N740_SER_PAR_U5_ENABLE 0x20 /* U5 analog switch enable */ -#define N740_SER_PAR_LED_GREEN 0x40 /* Led 1 */ -#define N740_SER_PAR_LED_RED 0x80 /* Led 2 */ - -#define N740_ANALOG_SWITCH_USB 0 -#define N740_ANALOG_SWITCH_SERIAL 1 - -#define N740_PINS 0xE0 -#define N740_PINS_GPIO() {P1SEL &= ~N740_PINS;} -#define N740_PINS_PER_IO() {P1SEL |= N740_PINS;} - -/* Serial/Parallel Shift Register (74HC595D) Functions */ -void n740_ser_par_init(void); -void n740_ser_par_set(uint8_t data); -uint8_t n740_ser_par_get(void); - -/* Analog Switch (U5 - 74HC4053D) Functions */ -void n740_analog_switch(uint8_t state); -void n740_analog_activate(); -void n740_analog_deactivate(); - -#endif /* N740SERPAR_H_ */ diff --git a/platform/sensinode/dev/sensinode-sensors.c b/platform/sensinode/dev/sensinode-sensors.c deleted file mode 100644 index c6dbbbfd5..000000000 --- a/platform/sensinode/dev/sensinode-sensors.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * This module centrally controls all sensors on sensinode devices - * - * It respects configuration in contiki-conf.h - * - * \author - * George Oikonomou - - */ - -#include "dev/sensinode-sensors.h" -#include "sys/energest.h" - -const struct sensors_sensor *sensors[] = { -#if ADC_SENSOR_ON - &adc_sensor, -#endif -#if BUTTON_SENSOR_ON - &button_1_sensor, - &button_2_sensor, -#endif - 0 -}; - -unsigned char sensors_flags[(sizeof(sensors) / sizeof(struct sensors_sensor *))]; - -/*---------------------------------------------------------------------------*/ -void -sensinode_sensors_activate() -{ - struct sensors_sensor *sensor; - sensor = sensors_first(); - while(sensor) { - sensor->configure(SENSORS_ACTIVE, 1); - sensor = sensors_next(sensor); - } - ENERGEST_ON(ENERGEST_TYPE_SENSORS); -} -/*---------------------------------------------------------------------------*/ -void -sensinode_sensors_deactivate() -{ - struct sensors_sensor *sensor; - sensor = sensors_first(); - while(sensor) { - sensor->configure(SENSORS_ACTIVE, 0); - sensor = sensors_next(sensor); - } - ENERGEST_OFF(ENERGEST_TYPE_SENSORS); -} diff --git a/platform/sensinode/dev/sensinode-sensors.h b/platform/sensinode/dev/sensinode-sensors.h deleted file mode 100644 index 503499ec8..000000000 --- a/platform/sensinode/dev/sensinode-sensors.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Defines for the sensors on the various Sensinode models. - * - * Sensors will be off by default, unless turned on explicitly - * in contiki-conf.h - * - * If you enable sensors generating interrupts, make sure you include - * this file in the file containing main(). - * - * \author - * George Oikonomou - - */ - -#ifndef SENSINODE_SENSORS_H_ -#define SENSINODE_SENSORS_H_ - -#include "cc2430_sfr.h" -#include "contiki-conf.h" -#include "dev/models.h" -#include "lib/sensors.h" - -void sensinode_sensors_activate(); -void sensinode_sensors_deactivate(); - -/* ADC Sensor Types */ -#define ADC_SENSOR "ADC" - -#define ADC_SENSOR_TYPE_TEMP 0 -#define ADC_SENSOR_TYPE_ACC_X 1 -#define ADC_SENSOR_TYPE_ACC_Y 2 -#define ADC_SENSOR_TYPE_ACC_Z 3 -#define ADC_SENSOR_TYPE_VDD 4 -#define ADC_SENSOR_TYPE_LIGHT 5 -#define ADC_SENSOR_TYPE_BATTERY 6 - -/* Defines to help us control Acc and Ill individually */ -#define ADC_VAL_NONE 0x00 -#define ADC_VAL_ALL 0x01 -#define ADC_VAL_LIGHT_ON 0x04 -#define ADC_VAL_ACC_ON 0x08 -#define ADC_VAL_ACC_GSEL 0x10 - -#ifdef ADC_SENSOR_CONF_ON -#define ADC_SENSOR_ON ADC_SENSOR_CONF_ON -#endif /* ADC_SENSOR_CONF_ON */ - -#if ADC_SENSOR_ON -extern const struct sensors_sensor adc_sensor; -#endif /* ADC_SENSOR_ON */ - -/* - * Accelerometer. Available on N740 only. - * This is a Freescale Semiconductor MMA7340L (3 axis, 3/11g) - * X: P0_5 - * Y: P0_6 - * Z: P0_7 - */ -#ifdef MODEL_N740 -#ifdef ACC_SENSOR_CONF_ON -#define ACC_SENSOR_ON ACC_SENSOR_CONF_ON -#endif /* ACC_SENSOR_CONF_ON */ - -/* Accelerometer g-Select - Define for +/-11g, +/-3g Otherwise */ -#if ACC_SENSOR_ON -#ifdef ACC_SENSOR_CONF_GSEL -#define ACC_SENSOR_GSEL ACC_SENSOR_CONF_GSEL -#endif /* ACC_SENSOR_CONF_GSEL */ -#endif /* ACC_SENSOR_ON */ -#endif /* MODEL_N740 */ - -/* - * Buttons - * N740: P1_0, P0_4 - * N711: P0_6, P0_7 - * N710: Unknown. This will mainly influence which ISRs to declare here - */ -#if defined(MODEL_N740) || defined(MODEL_N711) -#ifdef BUTTON_SENSOR_CONF_ON -#define BUTTON_SENSOR_ON BUTTON_SENSOR_CONF_ON -#endif /* BUTTON_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -#define BUTTON_1_SENSOR "Button 1" -#define BUTTON_2_SENSOR "Button 2" -#define BUTTON_SENSOR BUTTON_1_SENSOR - -#if BUTTON_SENSOR_ON -extern const struct sensors_sensor button_1_sensor; -extern const struct sensors_sensor button_2_sensor; -#define button_sensor button_1_sensor - -/* Port 0 ISR needed for both models */ -void port_0_ISR(void) __interrupt (P0INT_VECTOR); - -/* Only declare the Port 1 ISR for N740 */ -#ifdef MODEL_N740 -void port_1_ISR(void) __interrupt (P1INT_VECTOR); -#endif /* MODEL_N740 */ -#endif /* BUTTON_SENSOR_ON */ - -/* - * Light - N710, N711, N740 - * N740: P0_0 - * N711: P0_0 - * N710: P?_? - */ -#if defined(MODEL_N740) || defined(MODEL_N711) || defined(MODEL_N710) -#ifdef LIGHT_SENSOR_CONF_ON -#define LIGHT_SENSOR_ON LIGHT_SENSOR_CONF_ON -#endif /* LIGHT_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -/* - * Battery - N711, N740, (N710 likely) - * N740: P0_1 - * Unknown for other models - */ -#if defined(MODEL_N740) || defined(MODEL_N711) || defined(MODEL_N710) -#ifdef BATTERY_SENSOR_CONF_ON -#define BATTERY_SENSOR_ON BATTERY_SENSOR_CONF_ON -#endif /* BATTERY_SENSOR_CONF_ON */ -#endif /* defined(MODEL_FOO) */ - -/* Temperature - Available on all cc2430 devices */ -#ifdef TEMP_SENSOR_CONF_ON -#define TEMP_SENSOR_ON TEMP_SENSOR_CONF_ON -#endif /* TEMP_SENSOR_CONF_ON */ - -/* Supply Voltage - Available on all cc2430 devices*/ -#ifdef VDD_SENSOR_CONF_ON -#define VDD_SENSOR_ON VDD_SENSOR_CONF_ON -#endif /* VDD_SENSOR_CONF_ON */ - -#endif /* SENSINODE_SENSORS_H_ */ diff --git a/platform/sensinode/dev/slip-arch.c b/platform/sensinode/dev/slip-arch.c deleted file mode 100644 index 422847cf9..000000000 --- a/platform/sensinode/dev/slip-arch.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science - * 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. - * - */ - -/* - * Sensinode/cc2430 SLIP routines (over UART1). - */ - -#include "dev/slip.h" -#include "dev/uart1.h" -/*---------------------------------------------------------------------------*/ -void -slip_arch_writeb(unsigned char c) -{ - uart1_writeb(c); -} -/*---------------------------------------------------------------------------*/ -void -slip_arch_init(unsigned long ubr) -{ - uart1_set_input(slip_input_byte); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/disco.c b/platform/sensinode/disco.c deleted file mode 100644 index 63d95c6b9..000000000 --- a/platform/sensinode/disco.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Disco server sources - * (embedded part of the DISCOBALL project) - * - * It objective is to receive a code file over UDP, store it in - * external flash and disseminate it to other nodes of the - * 6LoWPAN network. - * - * For this to work, the image must be co-hosted with the BooTTY! - * bootloader, which will move the image from external to internal - * flash. - * - * To link this application in your contiki image, all you need to - * do is to add this line: - * OFFSET_FIRMWARE=1 - * to your project's makefile - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-net.h" -#include "sys/clock.h" -#include "sys/ctimer.h" -#include "dev/watchdog.h" - -#include "dev/n740.h" -#include "dev/m25p16.h" - -#include "disco.h" -/*---------------------------------------------------------------------------*/ -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" -/*---------------------------------------------------------------------------*/ -#if BATMON_CONF_ENABLED -void batmon_log(uint8_t trigger); - -#define LOG_TRIGGER_OAP_DISCO_START 0x01 -#define LOG_TRIGGER_OAP_DISCO_DONE 0x02 -#define LOG_TRIGGER_OAP_DISCO_ABORT 0x03 -#else -#define batmon_log(t) do { } while(0); -#endif -/*---------------------------------------------------------------------------*/ -static struct uip_udp_conn *server_conn; -static struct disco_request_pdu *req; -static struct disco_response_pdu resp; -static struct disco_seed seed; -static uint8_t state; -static uint8_t sector; -static uint16_t interval; -static struct ctimer disco_timer; - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -extern uint16_t uip_len; -extern void *uip_appdata; - -__xdata __at(BOOTTY_CMD_LOCATION) static uint8_t bd; -/*---------------------------------------------------------------------------*/ -static void timer_handler(void *p); -/*---------------------------------------------------------------------------*/ -static void -abort() CC_NON_BANKED -{ - PRINTF("Disco: Abort @ %lu\n", clock_seconds()); - n740_analog_deactivate(); - m25p16_dp(); - n740_analog_activate(); - state = DISCO_STATE_LISTENING; - memset(&seed, 0, sizeof(seed)); - ctimer_stop(&disco_timer); - batmon_log(LOG_TRIGGER_OAP_DISCO_ABORT); -} -/*---------------------------------------------------------------------------*/ -static void -restart_timer(uint16_t t) CC_NON_BANKED -{ - interval = t; - ctimer_stop(&disco_timer); - ctimer_set(&disco_timer, interval, timer_handler, &state); -} -/*---------------------------------------------------------------------------*/ -static void -timer_handler(void *p) -{ - uint8_t *s = p; - uint8_t wip; - - PRINTF("Disco: @ %lu, s: %u\n", clock_seconds(), *s); - - if(*s == DISCO_STATE_PREPARING) { - n740_analog_deactivate(); - wip = M25P16_WIP(); - n740_analog_activate(); - - if(wip) { - restart_timer(DISCO_TIMEOUT_PREPARE); - } else { - PRINTF("Disco: Erased %u\n", sector); - if((sector & 1) == 0) { - sector++; - PRINTF("Disco: Next %u\n", sector); - n740_analog_deactivate(); - m25p16_se(sector); - n740_analog_activate(); - restart_timer(DISCO_TIMEOUT_PREPARE); - } else { - PRINTF("Disco: Ready\n"); - *s = DISCO_STATE_READY; - resp.status = DISCO_CMD_INIT; - restart_timer(DISCO_TIMEOUT_ABORT); - server_conn->rport = seed.port; - uip_ipaddr_copy(&server_conn->ripaddr, &seed.addr); - uip_udp_packet_send(server_conn, &resp, DISCO_RESP_LEN_INIT); - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - } - } else if(*s == DISCO_STATE_READY) { - abort(); - } else if(*s == DISCO_STATE_REBOOTING) { - watchdog_reboot(); - } -} -/*---------------------------------------------------------------------------*/ -static uint8_t -is_protected(uint8_t a) CC_NON_BANKED -{ - uint8_t bp = M25P16_BP() >> 2; - - if(bp > 5) { - return SECTOR_PROTECTED; - } - - bp -= 1; - - if(a >= (32 - (1 << bp))) { - return SECTOR_PROTECTED; - } - return SECTOR_UNPROTECTED; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_init() CC_NON_BANKED -{ - PRINTF("Disco: Init 0x%02x\n", req->addr[0]); - if(uip_datalen() != DISCO_LEN_INIT) { - PRINTF("Disco: Bad len (%u)\n", uip_datalen()); - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - n740_analog_deactivate(); - m25p16_res(); - sector = 2 * req->addr[0]; - if(is_protected(sector) == SECTOR_PROTECTED - || is_protected(sector + 1) == SECTOR_PROTECTED) { - resp.status = DISCO_ERR_PROTECTED; - n740_analog_activate(); - return DISCO_RESP_LEN_ERR; - } - m25p16_se(sector); - n740_analog_activate(); - state = DISCO_STATE_PREPARING; - restart_timer(DISCO_TIMEOUT_PREPARE); - - /* Store the sender's address/port so we can reply when ready */ - seed.port = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&seed.addr, &UIP_IP_BUF->srcipaddr); - PRINTF("Disco: OK\n"); - - batmon_log(LOG_TRIGGER_OAP_DISCO_START); - - return DISCO_RESPONSE_NONE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_write() CC_NON_BANKED -{ - PRINTF("Disco: Write 0x%02x%02x%02x\n", req->addr[0], req->addr[1], - req->addr[2]); - if(uip_datalen() != DISCO_LEN_WRITE) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - restart_timer(DISCO_TIMEOUT_ABORT); - n740_analog_deactivate(); - m25p16_pp(req->addr, req->data, DISCO_FLEN_DATA); - watchdog_periodic(); - while(M25P16_WIP()); - n740_analog_activate(); - resp.status = DISCO_CMD_WRITE; - memcpy(resp.addr, req->addr, DISCO_FLEN_ADDR); - return DISCO_RESP_LEN_WRITE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_switch() CC_NON_BANKED -{ - PRINTF("Disco: Switch 0x%02x\n", req->addr[0]); - if(uip_datalen() != DISCO_LEN_SWITCH) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - if(req->addr[0] > 15) { - resp.status = DISCO_ERR_BAD_OFFSET; - return DISCO_RESP_LEN_ERR; - } - - bd = BOOTTY_CMD_COPY_IMAGE; - bd |= req->addr[0]; - - resp.status = DISCO_CMD_SWITCH; - resp.addr[0] = req->addr[0]; - - restart_timer(DISCO_TIMEOUT_REBOOT); - state = DISCO_STATE_REBOOTING; - - return DISCO_RESP_LEN_SWITCH; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -cmd_done() CC_NON_BANKED -{ - PRINTF("Disco: Done\n"); - if(uip_datalen() != DISCO_LEN_DONE) { - resp.status = DISCO_ERR_BAD_LEN; - return DISCO_RESP_LEN_ERR; - } - resp.status = DISCO_CMD_DONE; - - batmon_log(LOG_TRIGGER_OAP_DISCO_DONE); - - return DISCO_RESP_LEN_DONE; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -event_handler(process_event_t ev) CC_NON_BANKED -{ - uint8_t rv = DISCO_RESPONSE_NONE; - - if(ev != tcpip_event) { - return rv; - } - - /* Always accept CMD_DONE */ - if(req->cmd == DISCO_CMD_DONE) { - return cmd_done(); - } - - /* Always accept switch too */ - if(req->cmd == DISCO_CMD_SWITCH) { - return cmd_switch(); - } - - switch(state) { - case DISCO_STATE_LISTENING: - req = uip_appdata; - if(req->cmd == DISCO_CMD_INIT) { - rv = cmd_init(); - } - break; - case DISCO_STATE_PREPARING: - PRINTF("Disco: Not Ready\n"); - resp.status = DISCO_ERR_NOT_READY; - rv = DISCO_RESP_LEN_ERR; - break; - case DISCO_STATE_READY: - req = uip_appdata; - if(req->cmd == DISCO_CMD_WRITE) { - rv = cmd_write(); - } else if(req->cmd == DISCO_CMD_INIT) { - resp.status = DISCO_ERR_INIT_DONE; - rv = DISCO_RESP_LEN_ERR; - } else if(req->cmd == DISCO_CMD_SWITCH) { - rv = cmd_switch(); - } - break; - } - return rv; -} -/*---------------------------------------------------------------------------*/ -PROCESS(disco_process, "Disco Server Process"); -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(disco_process, ev, data) -{ - uint8_t len; - - PROCESS_BEGIN(); - - PRINTF("Disco Server\n"); - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(DISCO_UDP_PORT)); - - state = DISCO_STATE_LISTENING; - - while(1) { - PROCESS_YIELD(); - len = event_handler(ev); - - if(len > 0) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, &resp, len); - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/disco.h b/platform/sensinode/disco.h deleted file mode 100644 index 81549ab8d..000000000 --- a/platform/sensinode/disco.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Header file for the Disco server - * (embedded part of the DISCOBALL project) - * - * \author - * George Oikonomou - - */ - -#ifndef DISCO_H_ -#define DISCO_H_ - -#include "contiki.h" -#include "contiki-net.h" -/*---------------------------------------------------------------------------*/ -#define DISCO_UDP_PORT 60002 -#define DISCO_DESCRIPTORS_LOC /* In external Flash */ - -#define DATA_CHUNK_LEN 64 - -/* Intervals - Timeouts */ -#define DISCO_TIMEOUT_PREPARE (CLOCK_SECOND / 2) -#define DISCO_TIMEOUT_ABORT (CLOCK_SECOND * 10) -#define DISCO_TIMEOUT_REBOOT CLOCK_SECOND - -/* Disco State Machine */ -#define DISCO_STATE_LISTENING 0x00 /* Waiting for a transaction to start */ -#define DISCO_STATE_PREPARING 0x01 /* Erasing Sectors */ -#define DISCO_STATE_READY 0x02 -#define DISCO_STATE_REBOOTING 0x03 /* Reboot to BooTTY and copy new image */ - -/* Instructions */ -#define DISCO_CMD_INIT 0x00 /* Prepare flash area for writes */ -#define DISCO_CMD_SWITCH 0x01 /* Copy image from ext. to int. flash */ -#define DISCO_CMD_WRITE 0x02 /* Write Image to Ext Flash */ -#define DISCO_CMD_DONE 0x03 /* All Done */ - -/* Error Codes */ -#define DISCO_ERR_GENERIC 0xFF /* Generic Error */ -#define DISCO_ERR_BAD_LEN 0xFE /* Incorrect Length */ -#define DISCO_ERR_NOT_READY 0xFD /* Not Initialised */ -#define DISCO_ERR_BAD_OFFSET 0xFC /* Bad Offset */ -#define DISCO_ERR_PROTECTED 0xFB /* Target sector is protected */ -#define DISCO_ERR_INIT_DONE 0xFA /* Already Initialized */ - -/* Message Sizes */ -#define DISCO_FLEN_CMD 1 -#define DISCO_FLEN_IMG 1 -#define DISCO_FLEN_ADDR 3 -#define DISCO_FLEN_DATA 64 - -/* Request Lengths */ -#define DISCO_LEN_INIT (DISCO_FLEN_CMD + DISCO_FLEN_IMG) -#define DISCO_LEN_DONE DISCO_FLEN_CMD -#define DISCO_LEN_WRITE (DISCO_FLEN_CMD + DISCO_FLEN_ADDR + DISCO_FLEN_DATA) -#define DISCO_LEN_SWITCH (DISCO_FLEN_CMD + DISCO_FLEN_IMG) - -/* Response Lengths */ -#define DISCO_RESPONSE_NONE 0 -#define DISCO_RESP_LEN_ERR DISCO_FLEN_CMD -#define DISCO_RESP_LEN_INIT DISCO_FLEN_CMD -#define DISCO_RESP_LEN_DONE DISCO_FLEN_CMD -#define DISCO_RESP_LEN_WRITE (DISCO_FLEN_CMD + DISCO_FLEN_ADDR) -#define DISCO_RESP_LEN_SWITCH (DISCO_FLEN_CMD + DISCO_FLEN_IMG) - -/* Tell BooTTy! what to do after we jump: - * BOOTY_CMD - * [7:5]: Command - * [5:4]: Reserved - * [4:0]: Image number - */ -#define BOOTTY_CMD_LOCATION 0xFEFF - -#define BOOTTY_CMD_JUMP_TO_APP 0x80 -#define BOOTTY_CMD_COPY_IMAGE 0x40 - -#define SECTOR_UNPROTECTED 0 -#define SECTOR_PROTECTED 1 -/*---------------------------------------------------------------------------*/ -PROCESS_NAME(disco_process); -/*---------------------------------------------------------------------------*/ -struct disco_request_pdu { - uint8_t cmd; - uint8_t addr[3]; - uint8_t data[DATA_CHUNK_LEN]; -}; - -struct disco_response_pdu { - uint8_t status; - uint8_t addr[3]; -}; - -struct disco_seed { - uip_ipaddr_t addr; - uint16_t port; -}; -/*---------------------------------------------------------------------------*/ -#endif /* DISCO_H_ */ diff --git a/platform/sensinode/putchar.c b/platform/sensinode/putchar.c deleted file mode 100644 index 8d19ef4d3..000000000 --- a/platform/sensinode/putchar.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * \file - * hardware-specific putchar() routine for sensinode motes - * - * \author - * George Oikonomou - - */ - -#include "contiki-conf.h" -#include "dev/uart1.h" - -/*---------------------------------------------------------------------------*/ -void -putchar(char c) -{ -#if SLIP_ARCH_CONF_ENABLE -#define SLIP_END 0300 - static char debug_frame = 0; - - if(!debug_frame) { /* Start of debug output */ - uart1_writeb(SLIP_END); - uart1_writeb('\r'); /* Type debug line == '\r' */ - debug_frame = 1; - } -#endif - - uart1_writeb((char)c); - -#if SLIP_ARCH_CONF_ENABLE - /* - * Line buffered output, a newline marks the end of debug output and - * implicitly flushes debug output. - */ - if(c == '\n') { - uart1_writeb(SLIP_END); - debug_frame = 0; - } -#endif -} diff --git a/platform/sensinode/segment.rules b/platform/sensinode/segment.rules deleted file mode 100644 index 0dc7a4a60..000000000 --- a/platform/sensinode/segment.rules +++ /dev/null @@ -1,13 +0,0 @@ -# segment.rules - platform/sensinode - -# segment.rules file for code in platform/sensinode -# Please see cpu/cc2430/segment.rules for more info on code segments -# and for rules of thumb on what to do and what not to do - -# Keep main() in HOME -HOME contiki-sensinode-main.c - -# Files with ISRs must be in HOME -HOME platform/sensinode/dev/button-sensor.c - -# segment.rules - platform/sensinode - end diff --git a/platform/sensinode/uip-debug.c b/platform/sensinode/uip-debug.c deleted file mode 100644 index 5f5b23ca8..000000000 --- a/platform/sensinode/uip-debug.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/** - * \file - * A set of debugging tools - * \author - * Nicolas Tsiftes - * Niclas Finne - * Joakim Eriksson - */ - -#include "net/ip/uip-debug.h" -#include "debug.h" -/*---------------------------------------------------------------------------*/ -void -uip_debug_ipaddr_print(const uip_ipaddr_t *addr) -{ -#if NETSTACK_CONF_WITH_IPV6 - uint16_t a; - unsigned int i; - int f; - for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { - a = (addr->u8[i] << 8) + addr->u8[i + 1]; - if(a == 0 && f >= 0) { - if(f++ == 0) { - putstring("::"); - } - } else { - if(f > 0) { - f = -1; - } else if(i > 0) { - putstring(":"); - } - puthex(a >> 8); - puthex(a & 0xFF); - } - } -#else /* NETSTACK_CONF_WITH_IPV6 */ - PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]); -#endif /* NETSTACK_CONF_WITH_IPV6 */ -} -/*---------------------------------------------------------------------------*/ -void -uip_debug_lladdr_print(const uip_lladdr_t *addr) -{ - unsigned int i; - for(i = 0; i < sizeof(uip_lladdr_t); i++) { - if(i > 0) { - putstring(":"); - } - puthex(addr->addr[i]); - } -} -/*---------------------------------------------------------------------------*/ diff --git a/platform/sensinode/viztool.c b/platform/sensinode/viztool.c deleted file mode 100644 index e6b2fbed3..000000000 --- a/platform/sensinode/viztool.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010, Loughborough University - Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - */ - -/** - * \file - * Small UDP app used to retrieve neighbor cache and routing table - * entries and send them to an external endpoint - * - * \author - * George Oikonomou - - */ - -#include "contiki.h" -#include "contiki-lib.h" -#include "contiki-net.h" -#include "net/ipv6/uip-ds6-route.h" - -#include - -#define DEBUG DEBUG_NONE -#include "net/ip/uip-debug.h" - -#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) -#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) - -#ifndef VIZTOOL_MAX_PAYLOAD_LEN -#define VIZTOOL_MAX_PAYLOAD_LEN 60 -#endif - -static struct uip_udp_conn *server_conn; -static unsigned char buf[VIZTOOL_MAX_PAYLOAD_LEN]; -static int8_t len; - -#define VIZTOOL_UDP_PORT 60001 - -/* Request Bits */ -#define REQUEST_TYPE_ND 1 -#define REQUEST_TYPE_RT 2 -#define REQUEST_TYPE_DRT 3 -#define REQUEST_TYPE_ADDR 4 -#define REQUEST_TYPE_TOTALS 0xFF - -extern uip_ds6_netif_t uip_ds6_if; -static uip_ds6_route_t *rt; -static uip_ds6_defrt_t *defrt; -static uip_ipaddr_t *addr; -/*---------------------------------------------------------------------------*/ -static uint8_t -process_request() CC_NON_BANKED -{ - uint8_t len; - uint8_t count; /* How many did we pack? */ - uint8_t i; - uint8_t left; - uint8_t entry_size; - uip_ds6_nbr_t *nbr; - - left = VIZTOOL_MAX_PAYLOAD_LEN - 1; - len = 2; /* start filling the buffer from position [2] */ - count = 0; - if(buf[0] == REQUEST_TYPE_ND) { - /* Neighbors */ - PRINTF("Neighbors\n"); - for(nbr = nbr_table_head(ds6_neighbors); - nbr != NULL; - nbr = nbr_table_next(ds6_neighbors, nbr)) { - entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) - + sizeof(nbr->state); - PRINTF("%02u: ", i); - PRINT6ADDR(&nbr->ipaddr); - PRINTF(" - "); - PRINTLLADDR(&nbr->lladdr); - PRINTF(" - %u\n", nbr->state); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, uip_ds6_nbr_get_ipaddr(nbr), sizeof(uip_ipaddr_t)); - len += sizeof(uip_ipaddr_t); - memcpy(buf + len, uip_ds6_nbr_get_ll(nbr), sizeof(uip_lladdr_t)); - len += sizeof(uip_lladdr_t); - memcpy(buf + len, &nbr->state, - sizeof(nbr->state)); - len += sizeof(nbr->state); - - count++; - left -= entry_size; - - if(left < entry_size) { - break; - } - } - } else if(buf[0] == REQUEST_TYPE_RT) { - uint32_t flip = 0; - - PRINTF("Routing table\n"); - rt = uip_ds6_route_head(); - - for(i = buf[1]; i < uip_ds6_route_num_routes(); i++) { - if(rt != NULL) { - entry_size = sizeof(i) + sizeof(rt->ipaddr) - + sizeof(rt->length) - + sizeof(rt->state.lifetime) - + sizeof(rt->state.learned_from); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &rt->ipaddr, sizeof(rt->ipaddr)); - len += sizeof(rt->ipaddr); - memcpy(buf + len, &rt->length, sizeof(rt->length)); - len += sizeof(rt->length); - - PRINT6ADDR(&rt->ipaddr); - PRINTF(" - %02x", rt->length); - PRINTF(" - "); - PRINT6ADDR(uip_ds6_route_nexthop(rt)); - - flip = uip_htonl(rt->state.lifetime); - memcpy(buf + len, &flip, sizeof(flip)); - len += sizeof(flip); - PRINTF(" - %08lx", rt->state.lifetime); - - memcpy(buf + len, &rt->state.learned_from, - sizeof(rt->state.learned_from)); - len += sizeof(rt->state.learned_from); - - PRINTF(" - %02x [%u]\n", rt->state.learned_from, entry_size); - - count++; - left -= entry_size; - - rt = uip_ds6_route_next(rt); - - if(left < entry_size) { - break; - } - } - } - } else if(buf[0] == REQUEST_TYPE_DRT) { - uint32_t flip = 0; - - PRINTF("Default Route\n"); - addr = uip_ds6_defrt_choose(); - if(addr != NULL) { - defrt = uip_ds6_defrt_lookup(addr); - } - - i = buf[1]; - - if(defrt != NULL && i < 1) { - entry_size = sizeof(i) + sizeof(defrt->ipaddr) - + sizeof(defrt->isinfinite); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &defrt->ipaddr, sizeof(defrt->ipaddr)); - len += sizeof(defrt->ipaddr); - memcpy(buf + len, &defrt->isinfinite, sizeof(defrt->isinfinite)); - len += sizeof(defrt->isinfinite); - - PRINT6ADDR(&defrt->ipaddr); - PRINTF(" - %u\n", defrt->isinfinite); - count++; - left -= entry_size; - } - } else if(buf[0] == REQUEST_TYPE_ADDR) { - PRINTF("Unicast Addresses\n"); - for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) { - if(uip_ds6_if.addr_list[i].isused) { - entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr); - - memcpy(buf + len, &i, sizeof(i)); - len += sizeof(i); - memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr, - sizeof(uip_ds6_if.addr_list[i].ipaddr)); - len += sizeof(uip_ds6_if.addr_list[i].ipaddr); - - PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); - PRINTF("\n"); - count++; - left -= entry_size; - - if(left < entry_size) { - break; - } - } - } - } else if(buf[0] == REQUEST_TYPE_TOTALS) { - memset(&buf[2], 0, 4); - for(i = 0; i < UIP_DS6_ADDR_NB; i++) { - if(uip_ds6_if.addr_list[i].isused) { - buf[2]++; - } - } - for(nbr = nbr_table_head(ds6_neighbors); - nbr != NULL; - nbr = nbr_table_next(ds6_neighbors, nbr)) { - buf[3]++; - } - - buf[4] = uip_ds6_route_num_routes(); - buf[5] = 1; - - len += 4; - count = 4; - } else { - return 0; - } - buf[1] = count; - return len; -} -/*---------------------------------------------------------------------------*/ -PROCESS(viztool_process, "Network Visualization Tool Process"); -/*---------------------------------------------------------------------------*/ -static void -tcpip_handler(void) CC_NON_BANKED -{ - if(uip_newdata()) { - memset(buf, 0, VIZTOOL_MAX_PAYLOAD_LEN); - - PRINTF("%u bytes from [", uip_datalen()); - PRINT6ADDR(&UIP_IP_BUF->srcipaddr); - PRINTF("]:%u\n", UIP_HTONS(UIP_UDP_BUF->srcport)); - - memcpy(buf, uip_appdata, uip_datalen()); - - len = process_request(); - if(len) { - server_conn->rport = UIP_UDP_BUF->srcport; - uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr); - uip_udp_packet_send(server_conn, buf, len); - PRINTF("Sent %u bytes\n", len); - } - - /* Restore server connection to allow data from any node */ - uip_create_unspecified(&server_conn->ripaddr); - server_conn->rport = 0; - } - return; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(viztool_process, ev, data) -{ - - PROCESS_BEGIN(); - - server_conn = udp_new(NULL, UIP_HTONS(0), NULL); - udp_bind(server_conn, UIP_HTONS(VIZTOOL_UDP_PORT)); - - while(1) { - PROCESS_YIELD(); - if(ev == tcpip_event) { - tcpip_handler(); - } - } - - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ diff --git a/tools/sensinode/nano_programmer/Makefile b/tools/sensinode/nano_programmer/Makefile deleted file mode 100644 index 06c0fb979..000000000 --- a/tools/sensinode/nano_programmer/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -EXE_MAKE=$(notdir $(shell which "make.exe" 2>/dev/null)) -ifeq "$(EXE_MAKE)" "make.exe" -PLATFORM=windows -else -PLATFORM=linux -endif - -OBJECTS = ihex.o $(PLATFORM)/port.o programmer.o cdi_program.o -SUBDIRS = - -ifeq "$(PLATFORM)" "linux" -CFLAGS = -Wall -D_REENTRANT -I. -LDFLAGS = -L. -D_REENTRANT -lpthread -SUFFIX= -else -CFLAGS=-I. -I../nano_usb_programmer/ftdi_win32 -CFLAGS+= -L. -L../nano_usb_programmer/ftdi_win32 -DPLATFORM_WINDOWS -CFLAGS+= -mwin32 -LDFLAGS=../nano_usb_programmer/ftdi_win32/ftd2xx.lib -lkernel32 -SUFFIX=.exe -endif - -TARGET = nano_programmer$(SUFFIX) - -all: binary - -binary: $(TARGET) - strip $(TARGET) - -$(TARGET): $(OBJECTS) - gcc -o $(TARGET) $(OBJECTS) $(LDFLAGS) - -.c.o: - gcc -c -o $(<:.c=.o) -O2 -Wall $(CFLAGS) $< - -platform-test: - @echo $(PLATFORM) - -old-strip: - if [ -x $(TARGET).exe ]; then $(PLATFORM)strip $(TARGET).exe; else $(PLATFORM)strip $(TARGET); fi - -clean: - rm -f $(TARGET) $(OBJECTS) diff --git a/tools/sensinode/nano_programmer/README.md b/tools/sensinode/nano_programmer/README.md deleted file mode 100755 index f85a6a2aa..000000000 --- a/tools/sensinode/nano_programmer/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Nano Programmer - -Programming tool for the Sensinode Nano series using Dxxx development boards. - -Copyright 2007-2008 Sensinode Ltd. - -## Installation - -### Linux - -No external libraries required. - -### Windows/Cygwin - -See the nano_usb_programmer README file on how to install FTDI library -for nano_usb_programmer. The nano_programmer build system will fetch -the library from there. - -## Usage - -Usage info for the Nano Programmer is available with command - - ./nano_programmer --help - -Note that use might require root/administrator privileges - depending on system configuration. - -## Known problems - -Occasional timing failures resulting in "Reinit failed."-messages do come -up in some PC configurations. If you experience programming failures (the programmer -is not able to recover), please report your system configuration to Sensinode. -On Linux, it is known that the "brltty" program causes problems with the FTDI -serial driver. Uninstalling brltty resolves the problem. - -## Version - -v1.3 2008-01-31 Martti Huttunen Multi-platform build and created instructions diff --git a/tools/sensinode/nano_programmer/cdi_program.c b/tools/sensinode/nano_programmer/cdi_program.c deleted file mode 100644 index 3b2ecd255..000000000 --- a/tools/sensinode/nano_programmer/cdi_program.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include - -#include "port.h" -#include "programmer.h" -#include "ihex.h" - -#include - -extern void crc_add(unsigned char *crc, unsigned char byte); - -int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer); -int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex); - -int cdi_programmer(conf_opts_t *conf, char *filename) -{ - int error = 0; - port_t *port = 0; - unsigned char buffer[256]; - int length = 0; - FILE *ihex = 0; - - error = programmer_init(conf->device, &port); - - if (error < 0) - { - return error; - } - - if((!error) && (conf->action != 'b')) - { - length = port_write_echo(port, "CDI\r"); - bzero(buffer, sizeof(buffer)); - if (length >= 4) - { - length = port_readline(port, buffer, sizeof(buffer), 100); - } - else length = 0; - - if(memcmp(buffer, "OK", 2) == 0) - { - error = 0; - } - else - { - printf("Programming mode selection failed.\n"); - error = -1; - } - } - - if((!error) && (conf->action != 'b')) - { - printf("Initialize.\n"); - // Succesfully in mode 1 - sleep(1); - port_write_echo(port, "i\r"); - - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "85", 2) == 0) - { /*Found CC2430 device*/ - printf("Found CC2430 device revision %c%c.\n", buffer[2], buffer[3]); - } - else if (memcmp(buffer, "89", 2) == 0) - { - printf("Found CC2431 device revision %c%c.\n", buffer[2], buffer[3]); - } - else - { - printf("CC2430 not found.\n"); - error = -1; - } - } - - if (error) conf->action = ' '; - - switch(conf->action) - { - case 'e': - // Erase programming - port_write_echo(port, "e\r"); - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "OK", 2) == 0) - { - // Erase successful - printf("Erase successful.\n"); - error = 0; - } - else - { - // Erase failed - printf("Erase failed: %s.\n", buffer); - error = -1; - } - if ((conf->action != 'P') || error) - break; - - case 'P': - case 'w': - ihex = fopen(conf->ihex_file, "rb"); - if(ihex == NULL) - { - printf("Failed to open ihex file %s.\n", conf->ihex_file); - error = -1; - } - else error = 0; - - if (!error) - { - error = cdi_write(port, conf, ihex); - if (error) printf("Programming failed.\n"); - } - - - - if (ihex != NULL) fclose(ihex); - break; - - case 'b': - length = port_write_echo(port, "V\r"); - bzero(buffer, sizeof(buffer)); - if (length >= 2) - { - length = port_readline(port, buffer, sizeof(buffer), 100); - } - else length = 0; - - if(length > 4) - { - buffer[length] = 0; - printf("BIOS: %s\n", buffer); - error = 0; - } - else - { - printf("Failed to get BIOS version. Upgrade recommended.\n"); - error = -1; - } - break; - - case 'v': - break; - - case 'r': - ihex = fopen(conf->ihex_file, "wb"); - if(ihex == NULL) - { - printf("Failed to open ihex file %s.\n", conf->ihex_file); - error = -1; - } - else - { - port_write_echo(port, "a000000\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint32_t address = 0; - uint8_t check = 0; - for (address = 0; address < 128*1024; address += 64) - { - uint8_t i; - - if ((address) && ((address & 0xFFFF)==0)) - { - fprintf(ihex, ":02000004%4.4X%2.2X\r\n", - (int)(address>>16), (int)(0xFA-(address>>16))); - } - port_write_echo(port, "r\r"); - bzero(buffer, 256); - length = 0; - while (length < 64) - { - length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100); - } - for (i=0; i<64; i++) - { - if ((i & 0x0F) == 0) - { - check = 0; - check -= 0x10; - check -= (uint8_t) (address >> 8); - check -= (uint8_t) (address + i); - printf("%4.4X", (int) address + i); - fprintf(ihex, ":10%4.4X00", (int) (address + i) & 0xFFFF); - } - fprintf(ihex, "%2.2X", buffer[i]); - check -= buffer[i]; - if ((i & 0x0F) == 0x0F) - { - fprintf(ihex, "%2.2X\r\n", check); - if (i > 0x30) printf("\n"); - else printf(" "); - } - } - } - fprintf(ihex, ":00000001FF\r\n"); - } - else - { - printf("Failed to set read address.\n"); - error = -1; - } - fclose(ihex); - } - break; - /*skip for error case*/ - case ' ': - break; - - case 'm': - port_write_echo(port, "a01F800\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint8_t i; - uint32_t address = 0; - - for (address = 0x01F800; address < 128*1024; address += 64) - { - - port_write_echo(port, "r\r"); - bzero(buffer, 256); - length = 0; - while (length < 64) - { - length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100); - } - if ((address & 0xff) == 0) - { printf("."); - fflush(stdout); - } - } - printf("\nDevice MAC: "); - for (i=56; i<64; i++) - { - if (i != 56) printf(":"); - printf("%2.2X", buffer[i]); - } - printf("\n"); - } - break; - - case 'Q': - port_write_echo(port, "a01F800\r"); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 200); - if (length <0) length = 0; - if(memcmp(buffer, "OK", 2) == 0) - { - uint8_t p_buffer[2048]; - int error; - - memset(p_buffer, 0xff, sizeof(p_buffer)); - memcpy(&p_buffer[2040], conf->write_mac, 8); - - printf("\rWriting MAC: "); - error = cdi_page_write(port, 0x01F800, p_buffer); - if (!error) - { - printf("Write complete.\n"); - } - else - { - printf("Write failed.\n"); - } - } - break; - - default: - printf("Unknown CDI action.\n"); - break; - } - - printf("Close programmer.\n"); - usleep(100000); - port_write_echo(port, "q\r"); - programmer_close(port); - return error; -} - -int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex) -{ - int error = 0; - unsigned char buffer[256]; - int length; - int i; - int pages; - - unsigned long ext_addr=0; - unsigned short int addr=0; - unsigned char page_buffer[128*1024]; - unsigned char page_table[64]; - - bzero(buffer, sizeof(buffer)); - - /*initialize page data*/ - memset(page_table, 0, 64); - memset(page_buffer, 0xFF, sizeof(page_buffer)); - pages = 0; - - error = 0; - - if (conf->page_mode == PAGE_UNDEFINED) - { - int retval; - - while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) ) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - } - else if (memcmp(&buffer[7], "01", 2) == 0) - { /*end file*/ - printf("\nFile read complete.\n"); - break; - } - else if (memcmp(&buffer[7], "04", 2) == 0) - { - sscanf((char *)&(buffer[3]),"%4hx", &addr); - sscanf((char *)&(buffer[9]),"%4lx", &ext_addr); - - if (ext_addr >= 0x0002) - { - conf->page_mode = PAGE_SDCC; - } - else - { - if (conf->page_mode == PAGE_UNDEFINED) conf->page_mode = PAGE_LINEAR; - } - } - } - if (retval == -1) - { - printf("Read error\n"); - return -1; - } - rewind(ihex); - retval = 0; - error = 0; - } - switch (conf->page_mode) - { - case PAGE_SDCC: - printf("SDCC banked file.\n"); - break; - case PAGE_LINEAR: - printf("Linear banked file.\n"); - break; - case PAGE_UNDEFINED: - printf("Non-banked file, assuming linear.\n"); - conf->page_mode = PAGE_LINEAR; - break; - } - - while( (fscanf(ihex, "%s", buffer) == 1) && !error) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - i=0; - sscanf((char *)&buffer[1], "%2hhx", &data_len); - sscanf((char *)&(buffer[3]),"%4hx", &addr); - while(ipage_mode == PAGE_SDCC) - { - if (ext_addr) ext_addr--; - ext_addr *= 0x8000; - } - else - { - ext_addr *= 0x10000; - } - printf("\rExtended page address: 0x%8.8lX\r", ext_addr); - } - } - - if (pages) - { - int retry = 0; - // Successfully in mode 3 (programming) - printf("Starting programming.\n"); - error = 0; - for (i=0; i<64; i++) - { - if (page_table[i] != 0) - { - ext_addr = 2048*i; - - bzero(buffer, sizeof(buffer)); - - // Write the start address and check return - usleep(3000); - sprintf((char *)buffer, "a%6.6lX\r", ext_addr); - port_write_echo(port, (char *)buffer); - - if((length = port_readline(port, buffer, sizeof(buffer), 200)) < 0) - { - printf("Read from serial timed out without data.\n"); - error = -1; - break; - } - else - { - if(strncmp((char *)buffer, "OK\r\n", 4) == 0) - { - printf("\r \r"); - printf("\rWriting @ 0x%6.6lX: ", ext_addr); - fflush(stdout); - error = cdi_page_write(port, ext_addr, &page_buffer[ext_addr]); - if (error) - { - usleep(20000); - port_write_echo(port, "i\r"); - - bzero(buffer, 256); - length = port_readline(port, buffer, sizeof(buffer), 100); - - if(memcmp(buffer, "85", 2) == 0) - { /*Found CC2430 device*/ - } - else - { - printf("Reinit failed.\n"); - error = -1; - } - if (retry++ < 3) - { - error = 0; - i--; - } - } - else retry = 0; - fflush(stdout); - usleep(20000); - } - else - { - printf("Failed to set CDI programming start address.\n"); - error = -1; - break; - } - } - } - if (error) break; - } - usleep(200000); - printf("\n"); - } - - return error; -} - -int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer) -{ - int error = 0; - unsigned char buffer[80]; - unsigned char cmd[16]; - unsigned char block, i; - int length; - int retry = 0; - - // Write page - port_write_echo(port, "w\r"); - usleep(10000); - for (block=0; block<(2048/64); block++) - { - sprintf((char *)cmd, "%6.6lX", page_addr + (64*block)); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 2000); - if (length <0) - { length = 0; - printf("l!");fflush(stdout); - } - buffer[length] = 0; - if (block & 1) - { - } - if(memcmp(buffer, cmd, 6) == 0) - { -#define WRITE_SIZE 64 - for (i=0; i<64; i+=WRITE_SIZE) - { - port_write(port, &page_buffer[(unsigned int)(block*64)+i], WRITE_SIZE); - usleep(1250); - } - - bzero(buffer, sizeof(buffer)); - printf("."); - fflush(stdout); - length = port_readline(port, buffer, sizeof(buffer), 200); - if(memcmp(buffer, "OK", 2) == 0) - { - retry = 0; - } - else - { - block--; - if (retry++ >= 8) - { - error = -1; - break; - } - else - { - buffer[length] = 0; - printf("%s",buffer); - port_rts_clear(port); - usleep(300000); - port_rts_set(port); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 800); - if(memcmp(buffer, "CDI", 3) == 0) - { - printf("R"); - } - } - } - } - else - { - error = -1; - break; - } - } - - if (!error) - { - printf("w"); fflush(stdout); - bzero(buffer, sizeof(buffer)); - length = port_readline(port, buffer, sizeof(buffer), 800); - if(memcmp(buffer, "WROK", 4) == 0) - { - error = 0; - } - else - { - printf("%c%c", buffer[0], buffer[1]); - error = -1; - } - } - - if (!error) printf("OK\r"); - return error; -} - diff --git a/tools/sensinode/nano_programmer/ihex.c b/tools/sensinode/nano_programmer/ihex.c deleted file mode 100644 index 83234714e..000000000 --- a/tools/sensinode/nano_programmer/ihex.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include -#include - -#include - -int hexfile_parse(char *line, unsigned int *type, unsigned int *addr, unsigned char *buffer) -{ - unsigned int row_len = 0; - unsigned int row_index = 7; - unsigned int i; - int tmp; - - uint8_t cksum = 0; - int retval = 0; - - retval = sscanf(line, ":%2x%4x%2x", &row_len, addr, type); - - cksum += row_len; - cksum += *addr >> 8; - cksum += *addr & 0xFF; - cksum += *type; - - i = 0; - if (retval == 3) - { - while(i < row_len) - { - - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - cksum += tmp; - buffer[i++] = (unsigned char) tmp; - row_index += 2; - } - else return -1; - } - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - if ((cksum + (uint8_t) tmp) == 0) return row_len; - } - } - return -1; -} - -int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes) -{ - uint8_t cksum = 0; - uint8_t i = 0; - char tmp[8]; - - sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type); - cksum -= bytes; - cksum -= address >> 8; - cksum -= address & 0xFF; - cksum -= type; - - for (i=0; i - -#include "port.h" - -int port_open(port_t **port, char *device) -{ - port_t *new_port = (port_t *) malloc(sizeof(port_t)); - char err_string[128]; - - *port = new_port; - - new_port->device = 0; - new_port->handle = 0; - - new_port->handle = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); - - if (new_port->handle <= 0) - { - strerror_r(errno, err_string, 128); - - printf("Serial port open failed with error message: %s.\n", err_string); - return(-1); - } - else - { - tcgetattr(new_port->handle, &(new_port->old_params)); - - fcntl(new_port->handle, F_SETFL, FASYNC); - printf("Serial port %s opened succesfully.\n", device); - - return(0); - } -} - -int port_close(port_t *port) -{ - if (!port) - return(-1); - - if ((port->handle) > 0) - { - tcflush(port->handle, TCIFLUSH); - tcsetattr(port->handle,TCSANOW,&(port->old_params)); - - close(port->handle); - port->handle = 0; - } - - if (port->device) free(port->device); - port->device = 0; - free(port); - - return(1); -} - - -/** @todo port_write() function probably needs mutexes -mjs */ - -int port_write(port_t *port, unsigned char *buffer, size_t buflen) -{ - int i=0; - - if (!port) return -1; - - /** @todo The write to serial port is at the moment done one octet at a time with 10ms interval between each write operation due to some minor problems in MCU interrupts. -mjs */ - while(i < buflen) - { - write(port->handle, &(buffer[i]), 1); - tcflush(port->handle, TCIFLUSH); - i++; - } - -/* write(port->handle, &(buffer[i]), buflen);*/ - - tcflush(port->handle, TCIFLUSH); - - return(0); -} - -int port_read(port_t *port, unsigned char *buffer, size_t buflen) -{ - unsigned int l = 0; - l = read(port->handle, buffer, buflen); - return(l); -} - -int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts) -{ - int rate = B115200; - struct termios newtio; - - if (!port) return -1; - - switch (speed) - { - case 230400: - rate = B230400; - break; - - case 0: - case 115200: - rate = B115200; - break; - - case 57600: - rate = B57600; - break; - - case 38400: - rate = B38400; - break; - - case 19200: - rate = B19200; - break; - - case 9600: - rate = B9600; - break; - - default: - return -1; - - } - bzero(&newtio, sizeof(newtio)); - - if (speed == 9600) - { - newtio.c_cflag |= CS8 | CSTOPB | CLOCAL | CREAD; - } - else - { - newtio.c_cflag |= CS8 | CLOCAL | CREAD; - } - if (rtscts) - { - newtio.c_cflag |= CRTSCTS; - } - newtio.c_iflag = IGNPAR; - - cfsetispeed(&newtio, rate); - cfsetospeed(&newtio, rate); - - newtio.c_cc[VTIME] = 0; - newtio.c_cc[VMIN] = 1; - -#if 0 - newtio.c_cflag = rate | CS8 | CLOCAL | CREAD | CSTOPB; -/* if (rts_cts) newtio.c_cflag |= CRTSCTS;*/ - - newtio.c_iflag = IGNPAR; - newtio.c_oflag = 0; - - newtio.c_lflag = 0; - - newtio.c_cc[VTIME] = 0; - newtio.c_cc[VMIN] = 1; -#endif - - tcflush(port->handle, TCIFLUSH); - tcsetattr(port->handle,TCSANOW,&newtio); - - return(0); -} - -int port_dtr_set(port_t *port) -{ - int port_state = TIOCM_DTR; - - if (!port) return(-1); - -/* error = ioctl(port->handle, TIOCMGET, &port_state); - port_state |= TIOCM_RTS; - ioctl(port->handle, TIOCMSET, &port_state);*/ - - ioctl(port->handle, TIOCMBIS, &port_state); - return 0; -} - -int port_dtr_clear(port_t *port) -{ - int port_state = TIOCM_DTR; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIC, &port_state); - return 0; -} - -int port_rts_set(port_t *port) -{ - int port_state = TIOCM_RTS; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIS, &port_state); - return 0; -} - -int port_rts_clear(port_t *port) -{ - int port_state = TIOCM_RTS; - - if (!port) return(-1); - - ioctl(port->handle, TIOCMBIC, &port_state); - return 0; -} - -int port_get(port_t *port, unsigned char *buffer, int timeout) -{ - struct pollfd pfds; - unsigned int nfds = 1; - int bytes = 0; - int rval; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - rval = poll(&pfds, nfds, timeout); - - if((rval & POLLIN) != POLLIN) - { - return(-1); - } - else - { - bytes = port_read(port, buffer, 1); - } - return bytes; -} - -int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout) -{ - int length = 0; - struct pollfd pfds; - unsigned int nfds = 1; - int bytes = 0; - int rval; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - do - { - rval = poll(&pfds, nfds, timeout); - if((rval & POLLIN) != POLLIN) - { - return(length); - } - else - { - bytes = port_read(port, &(buffer[length]), 1); - if (buffer[length] == '\n') - { - buf_size = length; - } - length += bytes; - } - - }while(length < buf_size); - - buffer[length] = 0; - - if(length != 0) - return length; - else - return(-1); -} - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - - while( (string[length]) && (retry < 100) ) - { - port_write(port, (unsigned char *) &string[length], 1); - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(1000); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(1000); - } - } - - if (retry >= 100) return 0; - else return length; -} - - -int port_write_8byte_no_echo(port_t *port, int dlen, char *string) -{ - int length = 0; - int total_len; - int wrbytes = 4; - - total_len = dlen; - -/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */ - while(total_len > length) - { - if((total_len - length) >= wrbytes) - { - port_write(port, (unsigned char *)&string[length], wrbytes); - length += wrbytes; - } - else - { - port_write(port, (unsigned char *)&string[length], total_len - length); - length += total_len - length; - } - usleep(1250); - - } - - return(length); -} - diff --git a/tools/sensinode/nano_programmer/nano_programmer b/tools/sensinode/nano_programmer/nano_programmer deleted file mode 100755 index fd3e46b8a66dbbb1df54b70bac68e3c11ed4d6a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18776 zcmeHv4R}=5o%fk!fC)`HsiJ~Kd(lJ#%9z2Z5I-6rgQ8SW3DU(FhGg=glbJXld{ofj zWR&qTnr@BD`_@*lyXv-DvK3NL1A)*)*S4E=`?hT9YOG&(OteuD(j_(f`<-*|WP<41 z_IaP@ec$KV3un&xpYuQe@AE(B-no|$I zUo+d^5QwgGg@dj+YA#qy*{{2)Le8ZeoZ~<#M464kD_2#g{FFMHBd4MMn%O=N^;c2O zHsSM87od>t1t_%NIVhReR{+dJDMC3H#fdT*WjYG487LRa)~P?ze!wtoV_npVKD4ec zqe0y>uPG+*CDa$8oPm;qG7W{-Bvr}Jv&^<;*0dY1sj3pQP}7EIqU51mh(iACr;O5O z=ND*%$%{J8JZH=F=Wcwf>-i^-(~RRT+Kdy$Qc%!VM<=5feVs9KX(li%ocr3Fnw_nF+s(nwNoo%D2)Sx8yw_N0r_jZ!uwu zUXuwkUO7I`oIlTm-!sSWGU1u#_%}^{b4}Qq|AC3W!5n|ggf(;iZ%w${gwHqUKZn2~ z|D)#k56$^EnB#j*{BN7%kC@|qCcM_1f29fk%)~!o!dCn^O?sBRYt8ZhH1Ru3xY2~) zK;3n~?y#f&3ZnjRQ2*{H7VH#Rpm#81Tp<56Me0L7Zw<3gv8cLXP1P;Fx`uGX7h2%= zhQq$FsH*aXLV;kFKUnRJGz0^J=%Thd5b3P-%5NL3ZdRg=)=qH56+^wu;4 zs-j^ZuxtI%aJ>jeLe)*{g>PL$M1-3{4S`6ls0}vx0wUZ{7x4N;Q#3+`pjUlYRdxMc zRkhv**;`%j4T166hCq#|t_}Ml4dEsq2!o;@(;Iz_=o67@e0n31kZ20}{TQqXMk5f_ z9}N3Mqt_1=qzqoL4_A8wwIbLA(d$G*uo~Lbs=hj31l`a#P$!~czt7hsYS)GuB0kVp zdeoY-N2-A<`Bhb|YpR3XA=oMystPF~gG$J%DjLSLQlqyaAZkNCpSW)EqWKG|=D03( zm89EaEqA)F7+&OV$-*n!Y-iSNXCt?ceG;4hCYbd^SzEmvv7s>U*~L=S`6#R-(;ARo zCyIL!E9{%n(127qK|Ex_Uy-m~JZi%E63!Oi2h7VR|BdBwHJ+6oAH+U75s8*@Isu86 z@i+mAb_D&CNMk>0tPeYD23!$;bW>LTz8)Ok{ zXmBxWY%s;Fv4NGahJtfhBk^9v8jHG&H8#O=*4TWmXN^r~G3zs7Bi7hxma)dhvVt`> zquW_yQ(eUx8*B}0Y>@S=u|fD*WAkicjmlxTPSf3|EGwbt_`&eV)Z)RO6 z#1_`rpj%mAD8!?zu_13|JyVE^#5=df2JHrYuyRv(%N0WC-x(Pl9gV*hnPA+3UgM82 zt6>N3ij}W)k6v~Z79TAf#wX{D7SaRtY^M4#ZM0B;ay`dVeG;}4W=N#EBOLzt0-GrMY%m}LQBD_k%s|deLc&UVI z2=@^#lW;xZLxhVZ>?hn$Sd(xQVS{kKgd>E92nz|XBRoua=ugz25m=Aa3;iYBOxQuV zPr@yP^9grJcr)Rtgxe*&g|J3=n}k~l^LU(UmGGm4c|=GxOL!|`Zpo=8!0r$3NW2+) zduZvhTk19JS@p&ExOsVf|99;U;}1YM+B)t+yvGI|%~!vS{2?N_1Jh$&_8&Y0lB2I} zXQk)IUyBa(OyIcfmF`xBzdav89`A~rM!O3%a(e9r>>KR^PUZ#t+m>TRU95Yi=+RuC zeg=|(NK_2DU(+`_^opqo&+l|kej-wk-&34RB#FPS38X%?e0*CP}kVtwA zwC$vLBb=sJ^v^mw@v*bxz&y{?wfmeM-NXbEC-%I6iS`0xKIehxGBxjX%;Wr(u%TWt z*KT00wGlA5-6GZqhTPSLTzn?s4>b7&C&3CT=gtC8v)lA~-pu zNJILU6BYgX>9OJLNZxKPEsHb^(4VwVv-RzN-;um3AJXqe<`&3EWqa9hA5MA(EjFM# z47#==^5$ujPUeCp-A|w zWoS<+Fg`qi2<>{MJGn+AUqbdpzWuZ2pJ~qj@n0|>S^6{l1Apawi@)o$^Qn4$qVlL- z>F{lrvF#ahcR4#M@)ObF#Kw{M;pll%$FZPs#w)N~bl;TBgO%NzHs%T(o1HDw zF|u|Az-DY#Fq5<8kI;j|H<~a{v$`iY-W7eO*VCSrFT`GcBt1L#@P;zsc~;-}th;OE z$d61a&Xz&+>(TasGSWF<6OkS^TCzoLtFvXNN&ihnKfVO6-D~?Cir;vt-GNQ@waBDR z-*^cVo0Angx!^oIrMn{qcH>Ui2*M!H?Tn?b{^#gukLRC7kLOhzLjjY7p3RYe{UaCH zPA>QH1BWoh-IaP3%VIB%90F>xN=>6=)KP}t-fYO&np)0I-tnduGbW8IF&VNALCj?2 z0=4O}VZ~eG9V|v2W^z=fMu$g72l6u0m0G{cyw{pb_B~ynxYv3HeWe8`eNcZ$=tUG z{?#jTW1rflb@kZih@76-!Rd)1nNC`hJ8?>}&LahgE(kIVL9)|aJx7^1!6oTAN_*Z6 z_Ah`1WtfHtu>?p=r+9Y5hM~lP*ujEC-^$8vi@v%3WYWsjqf|M5EV48{8ky@p%;cJj zY>_4fI{HL1YdJnTN=YcA>dAsJ=bcC#ivE0j|NFpncf}6oO1)%$l=jWlH|EAi?{g2V zh8ko*TDGBBkDb!OfMin%nX$F}9%F_Vgywy^@zTVJnMYzLvhRDD>LYX6hHS5AOqrE2 z#U-a~_yxF|c2)V=eV98E_Md2Oucx0n#758m^TbQo`n2%=jhOE)N z=#4MZoyq8tv^5yw*b<&m=`u2lmV(eYZW}v~A@iQ_MgPsDuY3Bfbl%bx%?G>t5Qyo% zlS%rx+Z;lCfMjgA+WE-s&?@N}V+|9L^=vc2Pjz-oEcG0TXfM`4#>An4UemvpJOz*k z-R&_?zs-FZI)QnzBr9bnU3mkX+($cD`4|ge3W6?vII>#Lj(6QV&vGigau$ds7s&0^ z>Q+noT-r-6?g&tNd1EB>1$OMz(wjRzLFWP)GYCp!8^GPPY3$$>L}V+MDg3i(@EP<$ z@N!ftv#L~zfXPU)#jTaBBjF)&95erRSL=!^3g(}lfY8FajdD+7F88P5~ zYJ)n1_F-aWjCA05spfCOP6ZCz9=27XxKvNixQ8gUlHDmxvfX!HNVX4urFgH@dMCueNihY{xY`G9? z0*Cn8)`1T2%iRfn2S6F8fO9co)Y826g4Zd>4^{s}^dmnqpSwrZ9Y&?h=Mz@Jw)3G1*lt6t z%XRq(kgZNXxb#k_$LAU<2lb6r7#?^ycJ)yT;B4Xd9+sk_j!Xapz- zXI_3v!XbuW1aobUCQggY;dg_p>r~EswFKc)l#5Iz5n(P(7RLNZvp;37D+q@b1BdA-^V>LcF^u z$aP4Egi+qaB)ucut?Ddz0kW36D}LDdL|4qP&FCKZU;0G%VLB-nBLlsZMVcH57UCHl zc;cAo9@v3x*InOyJ7Z{0NbI6C!;eB^zfezm;q+BoEv_PuHk z!l5k!XC>n6_zA8PRmRH4EvIod^iJaNQ_-4;`!U`VzYm|d$!G>ik!WiIG?1gm>rp2> z&CZVRaU5q43jK8u-~ZOcr2R_72oB!;pq|{=YMe0$qM#_BJvbOc#3n)GP7LW%5_IME zO_DAxC%|1u+`rEhZIYZQpC{@S&CSnI8(ZvvEw-_FQlgE4;(X*Or4t40DLQU{R^-R z17ODes9b*=Y+1Z_#rneyV{iPKPyaLuCRjdO(Mq1`J~K_LT>@#{U3>CD6HhXd@phomHvA5UNaV(d%>|w=nd@0WeUDrhJ@Fmr5Of2-$V|2oOve9-mI0w;=ksWh z+)k2%DmIWyN_)^599eHNdJjrAcS>^3mOJ6SWal2rc?{2Qekx~VOAp|o-+}$_f2n!H z8SNtK=qW#=-G=)|dgD(#T_x>V5IfeJWzi>R;~@}tc1U684c)gRH5v3_qlY1gXnp}2?!(4(Q0)8!`^fO3Oe zAluUdpywmS)^6zNP45>UQie8qK&?<)A4M~z;wA!}ZWxwl2x-x1otz3IaikryL0Y>B z+P0t#!;P8J`EVyqm39vh<(<|_H3Vf^83_;{i6@iqu(JPhGdSK!cMl2sNqE|g-L zMzK%g1Aau=M=*w&amS^eJ)o+$S%#$@Dcj$z-cP$Yh(U#2sQfjGo4*WsZB$PC1oN^I%-#1=>o60Z5Og zo}hJP!jHW`N?Fc0H>qBk{Q;}56+uld`i+>JiejE|zA||iBfD-q$?ZIu^#E zgkJ%{x#a~Y;EdPfQ*Yyx*bAF6eYLX%5ABitNRRu%bVe{{^ZaDRCHp0>?qqxj21&$U z1~#!$Z-UT?Z095Sa@Dh22CO{Z$wN{B2c%4~-6q3IFoaEJfYUz4xN)iS5xRwO{P&Dd zOB%VJz-K%6uQthB9fQZMs%l7KN+vB}&K|$EK;<6h{#|JyrF>6-E4HX3Dk?U>PfRoD z`Iw4=obd^$E0gK>Q-heH#fEQlKKM_ViM#n>Oo2AVROC(w-z)9Scv5QjHgl4O0<0Q_ zNI9|0hciZhrn-E}L9_k@o0u{Jp(#ivnfr(IXMCE2`v+q~oiCMj+Nj-_{hlzr=>@^h z^(I)%fEcj>+r4fzRhb$S#+%U0x+U1%V#9XlBPrZPK#_wC?jWo*rn>w-|IcxW!K~V? zR>BI>xo|w4-SC2P*}mD(C4E4MConMPw{55J+toC!40YwV)B@$>rSw4;2IYxWDQw-2 z*mE&Rn-?Qgl>DDD8%95V-7@l+rCz3otwe5GYBIOElLGFTOvFQKxjFc?L5|$D)-ExzJ0(> z-2>Jq={w&HkTUr6^A}har22Ebc{Vr0lk{CYK}zo7`nZ8IXJntH&iH%SQT1I+NL1lY zU~THz0#hbR@O?Pg@)3cvWhscr?O&NjWjoWzKa;n(D$PZ5VI-Zb-oRWw_I>X^p!oe{ z@;!^mvt-gOnE>G!5Wpnf4-uR#FC)>NWTG8FXGoj_XMVnk-uT_AO*AenK;<}htCLK$ z4oAV>_#p@Y#f2LtVjEw0f4Mf+DZBAiDsYrw?!&ayFHNZ)nTKdTg=k|N8%1WCB=YSL&DM>R(!D=d61b1yt$;+^&ml}I0g9@3A0AUNfBh>Y zNKQYK=iW`2iQN4vxarc6R!IKFl=4lCI6GQg%;0((O-(7S_b9lF?*m3+cvhUuW=UJj zioe0Onw03}ndj3o^++jkBrz0w%eh%%I9qBU&=*tpD(Z?>?1VGX8{MJgaCUUjG89L? zodHowfZW_k=Ecqjim-oyHT0Fo!b87B?t>Wd_23zka+YmUKEmCjGkz@vd>Ro&(C*i1Tv_JUz~lmaN{~T)bNaKFB8S7V(H2+ zWc#Oo{|jO%AH2<2N_^b%8lJ*K+gMN8rcZg79o+w0NO!QP6 zzIZWO(P!R~HWH_JJkH&~;Zsj;R;`dQ}K8o-5$Gz`>=QYL> zsJ5wl7v7VI4dxnW{RSewm=9MbWBi=iyMHtb-}o1}kD0F&;PnBSf8@9DqmMpMEUd73 z$D^;u%y07b=>>Sz3;g)~-gf@(1K*=WPIDg~?bBl;`v4Bu(Gwkt@tZup6=vcZkcID7 z7C{WEhEE-rS7yYmDaT5T{Iz}QVet;rVu^76g$ z*^S<6ku!VwC9`Lna_3N^3?o_U!0$P;-M}NSoScfVPnuX;9rT83w4xg2AdU8$DREZ= zm&~an-bK%(InGX`yA-%4Pis(o6K)I;+I zYG`?AHxu;MD188pBbT#WVrbqvyy+f}jG3M?gfNG{9~eJloVTjsc?~}e$Z#6hL(c3* z%!MU$B(`!4ovnFmYC>2&66a>%q;0OP%owiBQL%EWi8-@&8~I#vePZ^T{y5Ya*@nfrB)K7qu^&S)NWmL-J&I0J;KEA3%N88e&->R+2mV&fp9~Bj=jkn z2qLaR4X}q5YRD36+^$P;sQj+oQT#vt@)G_l=VkI*02(|0=Vy8U!zubQ=bhYs2>AD) zEJksE!Q5#W`}7pL{tSIjX7u~fUYjQhFLzz;Um^T6-~h3pe32-uF02+yZp;(6-Lm9H zQS26z7b3lBa&cLU*(HigL}3YDaxX0LuM=|NNaqO|L#w@kyAYsEi!QNPrZjC_U*Q}C zkIb=*hC*aiY*E~wZsiYt*k`#AZI|#WA@eBKWRb`9Mw~LOc%2$4)dYS_GWRk_(hz8f zm=WZnK6zphdaz42d<(+NohKG7m{W3TvBo81?km1LwI7(9Aa_A?hcF45n`daXSg7__ zgr?kX)5%UH^`#k`pW2CCVtJlm!X$~wV(n_-EtXfFC@n^^#Z@x4wL`fOJi@JBl)8&$ z16xC>#49d#FI)(WF%j^aB;^(}6TncwnOj_(CnlSF4e}IhleU-wRlXYYrGhPiD*|@~ zf@=dBY^QmvxzEFn{Gn6YCs=}5uQvq)vooA}v4&rDMdiM)QWkOYJXW%zgRP8JO25r@ z&GoO~orVma+EB1ju3j82A`OiQ9{j*c9%ES7cq3kt6M0Byf6YZc8)Bem{u%AYk4oJp%&x)=~aek-rV+#e1?L+}GjhiYUW4U$ena`~-fsC$!CW2ip$R zr=gyTf}i`z--Y7_IJose{1^x|=i*sZ@G8J){>2ynUVt^}Dd^OJ(u4AAly^~%p-g

97NRUisYO|X@&L+XC{Lkup!A^p8s%M-V<;1K%tyHZ<#LpTD9cf5QP!Y5 zfbtm1Qz#uMJt)6Mc^Bmv%0&F_g)>nsIa%js$er2Wf%gOGD_;Csu@kTa@X>^FAOm&- z?#+Pt;@(IG%y<8OkpcSw|0)CKS^nQM;A+4(Wx&e;|3?PA8u0G{Tku#!;sg=0!D_yOqVs$hSi7IIJoT!AZz%l;6G5>E_$rY~0 zZ>}TW)xw24Mqj8&xNu7-!J`i5tsA~K`T#i_`-I)M> zyX^}3{KQv{CVzy~@so8|1UGfURSN(^K^}L6%U54jizg{Q;i`@VLt!vb)t%KK1R~zX zhH7vNVj@0VlA4;i8uzR&by$deCi*_NgSn1z&io|*?g;?qFYB__0Q>ODp2U-Xp9BM% zg@jsu=Zd-zg?W|qm}{>G-cl6y@gg3}3=}-HmU)r6cq=AcjJ}icE`cnYsP30)xt}nO+5Ne{@t81WiNufEIhvBVc|Kj zr#Q+^jrZLQJpK?jA9xlG45i!K(58*aSN=Vova!F#gD#0jzx^YM#g~6;V6beA28JXa z>HiqT!sA(Cs7#1w(Pv%6VfiVFg|`jw;cvSZK46D=X=dGtn*1pr-%4$tkH0N&3cLdt d&*&D!`}>RztI1m07&WhD -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include "windows.h" -#include -#include "ftd2xx.h" -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef PLATFORM_WINDOWS -typedef struct -{ - int handle; - char *device; - struct termios old_params; -}port_t; - -extern int port_open(port_t **port, char *device); -#else -typedef struct port_t -{ - FT_HANDLE handle; - int device; - HANDLE event_handle; -}port_t; - -extern int port_open(port_t **port, int device); -#endif - -extern int port_close(port_t *port); -extern int port_write(port_t *port, unsigned char *buffer, size_t buflen); -extern int port_read(port_t *port, unsigned char *buffer, size_t buflen); -extern int port_get(port_t *port, unsigned char *buffer, int timeout); -extern int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts); -extern int port_dtr_set(port_t *port); -extern int port_dtr_clear(port_t *port); -extern int port_rts_set(port_t *port); -extern int port_rts_clear(port_t *port); -extern int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout); -extern int port_write_echo(port_t *port, char *string); -extern int port_write_8byte_no_echo(port_t *port, int dlen, char *string); - -#ifdef __cplusplus -} -#endif -#endif /* _PORT_H */ diff --git a/tools/sensinode/nano_programmer/programmer.c b/tools/sensinode/nano_programmer/programmer.c deleted file mode 100644 index ee82c9389..000000000 --- a/tools/sensinode/nano_programmer/programmer.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include - -#include "port.h" -#include "programmer.h" - -#include - -extern int cdi_programmer(conf_opts_t *conf, char *filename); - -void usage(char *prg_name) -{ - printf("\nUsage: %s [-d device]\n", prg_name); - printf("General options:\n"); - printf(" -V/--version Get programmer version\n"); - printf(" -1/--d100 Use D100 board (default D200)\n"); - printf("Operating modes:\n"); - printf(" -b/--bios to get programmer BIOS version\n"); - printf(" -P/--program [ihex file] Do a complete programming sequence (write and verify)\n"); - printf(" -v/--verify [ihex file] Verify against ihex file\n"); - printf(" -r/--read [ihex file] Read program code into ihex file\n"); - printf(" -m/--mac Read device MAC address\n"); - printf(" -Q/--write-mac [MAC address] Write device MAC address\n"); - printf(" -e/--erase Erase flash (erases MAC address!)\n"); - printf("Programming options:\n"); - printf(" -l/--linear Force linear model for extended addresses (not SDCC file)\n"); - printf(" -s/--sdcc Force SDCC model for extended addresses (SDCC file)\n"); - printf("Defaults:\n"); -#ifndef PLATFORM_WINDOWS - printf("device /dev/ttyUSB0\n"); -#else - printf("device 0\n"); -#endif -} - -conf_opts_t conf_opts; - -static int option_index = 0; - -int do_exit = 0; - -#define OPTIONS_STRING "d:ec1lsmVbP:v:r:Q:" -/* long option list */ -static struct option long_options[] = -{ - {"device", 1, NULL, 'd'}, - {"psoc", 0, NULL, 'p'}, - {"d100", 0, NULL, '1'}, - {"erase", 0, NULL, 'e'}, - {"mac", 0, NULL, 'm'}, - {"linear", 0, NULL, 'l'}, - {"sdcc", 0, NULL, 's'}, - {"cdi", 0, NULL, 'c'}, - {"version", 0, NULL, 'V'}, - {"bios", 0, NULL, 'b'}, - {"program", 1, NULL, 'P'}, - {"verify", 1, NULL, 'v'}, - {"read", 1, NULL, 'r'}, - {"write-mac", 1, NULL, 'Q'}, - {0, 0, 0, 0} -}; - -int parse_opts(int count, char* param[]) -{ - int opt; - int error=0; - - conf_opts.target_type = CDI; - while ((opt = getopt_long(count, param, OPTIONS_STRING, - long_options, &option_index)) != -1) - { - switch(opt) - { - case 'V': - conf_opts.target_type = VERSION; - break; - - case '1': - conf_opts.prg_type = 1; - break; - - case 'c': - conf_opts.target_type = CDI; - break; - - case 'd': -#ifdef PLATFORM_WINDOWS - if (sscanf(optarg, "%d", &conf_opts.device) != 1) - { - printf("Device ID must be a positive integer.\n"); - conf_opts.action = ' '; - } -#else - printf("device:%s\n", optarg); - strcpy(conf_opts.device, optarg); -#endif - break; - - case 'P': - printf("Programming mode.\n"); - conf_opts.action = 'P'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case 's': - if (conf_opts.page_mode == PAGE_UNDEFINED) - { - conf_opts.page_mode = PAGE_SDCC; - } - else - { - printf("Only one paging option allowed.\n"); - error = -1; - } - break; - - case 'l': - if (conf_opts.page_mode == PAGE_UNDEFINED) - { - conf_opts.page_mode = PAGE_LINEAR; - } - else - { - printf("Only one paging option allowed.\n"); - error = -1; - } - break; - - case 'e': - printf("Erase.\n"); - conf_opts.action = 'e'; - break; - - case 'm': - printf("Get MAC.\n"); - conf_opts.action = 'm'; - break; - - case 'b': - printf("Get BIOS version\n"); - conf_opts.action = 'b'; - break; - - case 'Q': - printf("Write MAC.\n"); - conf_opts.action = 'Q'; - if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &conf_opts.write_mac[0], &conf_opts.write_mac[1], - &conf_opts.write_mac[2], &conf_opts.write_mac[3], - &conf_opts.write_mac[4], &conf_opts.write_mac[5], - &conf_opts.write_mac[6], &conf_opts.write_mac[7]) != 8) - { - printf("Invalid MAC.\n"); - conf_opts.action = ' '; - } - break; - - case 'v': - printf("Verify by comparing to ihex file:%s\n", optarg); - conf_opts.action = 'v'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case 'r': - printf("Read program to ihex file:%s\n", optarg); - conf_opts.action = 'r'; - strcpy(conf_opts.ihex_file, optarg); - break; - - case '?': - printf("Duh\n"); - error = -1; - break; - } - } - - if (!error && (conf_opts.target_type == CDI) ) - { -#ifdef PLATFORM_WINDOWS - printf("Setup: Device %d.\n", conf_opts.device); -#else - printf("Setup: Device %s.\n", conf_opts.device); -#endif - } - - return error; -} -/* -int port_write_8byte_echo(port_t *port, char *string) -{ - int length = 0; - int total_len; - int i, j; - struct pollfd pfds; - unsigned int nfds = 1; - int rval = 0; - - int wrbytes = 2; - unsigned char byte8[wrbytes]; - - pfds.fd = (int)(port->handle); - pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; - - total_len = strlen(string); - - while(total_len > length) - { - if(total_len - length >= wrbytes) - { - i=0; - port_write(port, (unsigned char *)&string[length], wrbytes); - - if((rval = poll(&pfds, nfds, 100)) == 0) - { - printf("Timed out...\n"); - return(-1); - } - else - { - while(i %.2x\n", string[length+j], byte8[j]); - } - - return(-1); - } - else - { - printf("8Bwok - "); - fflush(stdout); - length += wrbytes; - } - - } - } - else - { - i=0; - port_write(port, (unsigned char *)&string[length], total_len - length); - - if((rval = poll(&pfds, nfds, 100)) == 0) - { - printf("Timed out...\n"); - return(-1); - } - else - { - while(i<(total_len-length)) - { - i = port_read(port, &byte8[i], total_len - length); - } - if(i != total_len - length || memcmp(byte8, &string[length], total_len - length) != 0) - { - printf("Got wrong length or wrong bytes back.\n"); - for(j=0;j %.2x\n", string[length+j], byte8[j]); - } - - return(-1); - } - else - { - printf("<8Bwok - \n"); - fflush(stdout); - length += (total_len - length); - } - } - } - - usleep(5000); - - } - - return(length); -} -*/ -#ifdef PLATFORM_WINDOWS -int programmer_init(int device, port_t **port) -#else -int programmer_init(char *device, port_t **port) -#endif -{ - int error = port_open(port, device); - uint8_t buffer[8]; - - buffer[0] = 0; - - if (error >= 0) - { - if (conf_opts.prg_type == 1) - { - int retry = 0; - port_set_params(*port, 9600, 0); - // Activate programming... - port_dtr_clear(*port); - port_rts_clear(*port); - sleep(1); - printf("Select D100.\n"); - port_rts_set(*port); - sleep(1); - buffer[0] = '\r'; - while (retry++ < 3) - { - int length; - port_write_echo(*port, "q\r"); - length = port_readline(*port, buffer, sizeof(buffer), 800); - if (length) - { - if (*buffer == '!') - { - printf("D100 found.\n"); - return 0; - } - } - } - printf("No programmer found.\n"); - return -1; - } - else - { - port_set_params(*port, 57600, 0); - // Activate programming... - port_dtr_clear(*port); - port_rts_clear(*port); - usleep(300000); - printf("Select D200.\n"); - port_rts_set(*port); - usleep(200000); - port_set_params(*port, 57600, 1); - port_write(*port, (uint8_t *)"\r", 1); - usleep(100000); - if ((port_get(*port, buffer, 500) >= 1) && (buffer[0] == '!')) - { - printf("D200 found.\n"); - return 0; - } - printf("No programmer found.\n"); - return -1; - } - } - return error; -} - -void programmer_close(port_t *port) -{ - if (port) - { - port_rts_clear(port); - port_dtr_set(port); - sleep(1); - port_close(port); - printf("Port closed.\n"); - } -} - -int main(int argc, char *argv[]) -{ - int error = 0; - - conf_opts.target_type = 0; - conf_opts.action = 0; - conf_opts.prg_type = 2; - - -#ifndef PLATFORM_WINDOWS - strncpy(conf_opts.device, "/dev/ttyUSB0", 12); -/* Install a new handler for SIGIO. - * - * According to man 7 signal this signal is by default ignored by most systems. - * It seems that pre FC7 this was true for Fedoras also. We have noticed that at least - * on some FC7 installations the default action has changed. We avoid abnormal program - * exits by defining the SIGIO as SIG_IGN (ignore). - mjs - */ - if(signal(SIGIO, SIG_IGN) == SIG_ERR) - { - printf("%s error: failed to install SIGIO handler. Exit.\n", argv[0]); - exit(EXIT_FAILURE); - } -#else - conf_opts.device = 0; -#endif - - conf_opts.page_mode = PAGE_UNDEFINED; - - if ( (argc <= 1) || (error = parse_opts(argc, argv)) ) - { - usage(argv[0]); - if (error < 0) return error; - else return 0; - } - - if(conf_opts.target_type == CDI) - { /*CDI*/ - error = cdi_programmer(&conf_opts, conf_opts.ihex_file); - } - else - { - printf("\nSensinode Nano series programmer "PROGRAMMER_VERSION "\n"); - } - return error; -} diff --git a/tools/sensinode/nano_programmer/programmer.h b/tools/sensinode/nano_programmer/programmer.h deleted file mode 100644 index d8eab549e..000000000 --- a/tools/sensinode/nano_programmer/programmer.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#define PROGRAMMER_VERSION "v1.3" - -typedef enum -{ - PAGE_SDCC, - PAGE_LINEAR, - PAGE_UNDEFINED -}page_mode_t; - -typedef struct { -#ifdef PLATFORM_WINDOWS - int device; -#else - char device[128]; -#endif - int target_type; - int prg_type; - int action; - char ihex_file[128]; - unsigned char write_mac[8]; - page_mode_t page_mode; -}conf_opts_t; - -enum target { UNDEFINED, VERSION, CDI }; - -#ifdef PLATFORM_WINDOWS -extern int programmer_init(int device, port_t **port); -#else -extern int programmer_init(char *device, port_t **port); -#endif - -extern void programmer_close(port_t *port); - diff --git a/tools/sensinode/nano_programmer/windows/port.c b/tools/sensinode/nano_programmer/windows/port.c deleted file mode 100644 index 5b9a09f9c..000000000 --- a/tools/sensinode/nano_programmer/windows/port.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include "port.h" -#include - -int port_open(port_t **port, int device) -{ - port_t *new_port = (port_t *) malloc(sizeof(port_t)); - FT_STATUS status; - - *port = new_port; - - new_port->device = device; - new_port->handle = 0; - - status = FT_Open(device, &(new_port->handle)); - - if (status != FT_OK) - { - new_port->handle = 0; - - printf("Serial port open failed with error message: %d.\n", (int)status); - return(-1); - } - else - { - DWORD mask; - new_port->event_handle = CreateEvent(NULL, TRUE, FALSE, "SN_USB_UART_EVENTS"); - if (new_port->event_handle == NULL) - { - printf("Event handle creation failed.\n"); - FT_Close(new_port->handle); - new_port->handle = 0; - return(-1); - } - mask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS; - status = FT_SetEventNotification(new_port->handle,mask,new_port->event_handle); - if (status != FT_OK) - { - printf("Setting event notification failed.\n"); - } - FT_SetTimeouts(new_port->handle,400,0); - return(0); - } -} - -int port_close(port_t *port) -{ - if (!port) - return(-1); - - if ((port->event_handle) != NULL) - { - CloseHandle(port->event_handle); - port->event_handle = NULL; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - FT_Close(port->handle); - port->handle = 0; - } - - port->device = 0; - free(port); - - return(1); -} - -int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts) -{ - FT_STATUS status; - - if (!port) return -1; - status = FT_SetBaudRate (port->handle, speed); - if (status != FT_OK) return -1; - if (speed == 9600) - { - status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE); - } - else - { - status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE); - } - - if (status != FT_OK) return -1; - - if (rtscts) - { - status = FT_SetFlowControl(port->handle, FT_FLOW_RTS_CTS, 0, 0); - } - else - { - status = FT_SetFlowControl(port->handle, FT_FLOW_NONE, 0, 0); - } - - if (status != FT_OK) return -1; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - - return(0); -} - -int port_dtr_set(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_SetDtr(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_dtr_clear(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_ClrDtr(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_rts_set(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_SetRts(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_rts_clear(port_t *port) -{ - FT_STATUS status; - - if (!port) return(-1); - - status = FT_ClrRts(port->handle); - if (status != FT_OK) - { - printf("Control failed.\n"); - return -1; - } - return 0; -} - -int port_write(port_t *port, unsigned char *buffer, size_t buflen) -{ - FT_STATUS status; - DWORD bytes_out; - - if (!port) return -1; - -// FT_Purge(port->handle, FT_PURGE_RX); - - status = FT_Write (port->handle, (LPVOID) buffer, (DWORD) buflen,&bytes_out); - if (status != FT_OK) return -1; - - return 0; -} - -int port_read(port_t *port, unsigned char *buffer, size_t buflen) -{ - DWORD l = 0; - FT_STATUS status; - status = FT_Read(port->handle, buffer, buflen, &l); - return((int) l); -} - -int port_get(port_t *port, unsigned char *buffer, int timeout) -{ - DWORD bytes = 0; - FT_STATUS status; - - FT_SetTimeouts(port->handle, timeout, 0); - - status = FT_Read(port->handle, buffer, 1, &bytes); - if (status != FT_OK) - { - return(-1); - } - return bytes; -} - -int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout) -{ - int length = 0; - DWORD bytes = 0; - FT_STATUS status; - - FT_SetTimeouts(port->handle, timeout, 0); - - do - { - status = FT_Read(port->handle, &buffer[length], 1, &bytes); - length += bytes; - if ((status != FT_OK) || (bytes == 0)) - { - return(length); - } - else - { - if (buffer[length-1] == '\n') - { - buf_size = length; - } - } - }while(length < buf_size); - - buffer[length] = 0; - - if(length != 0) - return length; - else - return(-1); -} - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - DWORD bytes_out; - FT_STATUS status; - - FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX); - - while( (string[length]) && (retry < 100) ) - { - retry = 0; - while (retry++ < 100) - { - status = FT_Write (port->handle, (LPVOID) &string[length], (DWORD) 1,&bytes_out); - if (status != FT_OK) return -1; - if (port_get(port, &byte, 1000) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(500); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_get(port, &byte, 1000) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(500); - } - } - - if (retry >= 100) return 0; - else return length; -} - -#if 0 - -int port_write_echo(port_t *port, char *string) -{ - int length = 0; - int retry = 0; - unsigned char byte; - - while( (string[length]) && (retry < 100) ) - { - port_write(port, (unsigned char *) &string[length], 1); - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - if (byte == string[length]) - { - retry = 0; - length++; - break; - } - else retry = 100; - } - else usleep(1000); - } - } - if ((string[strlen(string)-1] == '\r') && (retry < 100) ) - { /*wait for \n*/ - retry = 0; - while (retry++ < 100) - { - if (port_read(port, &byte, 1) == 1) - { -/* printf("%c",byte);*/ - break; - } - else usleep(1000); - } - } - - if (retry >= 100) return 0; - else return length; -} - - -int port_write_8byte_no_echo(port_t *port, int dlen, char *string) -{ - int length = 0; - int total_len; - int wrbytes = 4; - - total_len = dlen; - -/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */ - while(total_len > length) - { - if((total_len - length) >= wrbytes) - { - port_write(port, (unsigned char *)&string[length], wrbytes); - length += wrbytes; - } - else - { - port_write(port, (unsigned char *)&string[length], total_len - length); - length += total_len - length; - } - usleep(1250); - - } - - return(length); -} - -#endif diff --git a/tools/sensinode/nano_usb_programmer/Makefile b/tools/sensinode/nano_usb_programmer/Makefile deleted file mode 100644 index 2c1e40988..000000000 --- a/tools/sensinode/nano_usb_programmer/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -EXE_MAKE=$(notdir $(shell which "make.exe")) -ifeq "$(EXE_MAKE)" "make.exe" -PLATFORM=windows -else -PLATFORM=linux -endif - -include Rules.make - -APP = nano_usb_programmer$(SUFFIX) -OBJS = $(SOURCES:.c=.o) - -all: $(APP) - -$(APP): $(OBJS) Makefile $(SOURCES) - $(CC) -o $(APP) $(CFLAGS) $(OBJS) $(LDFLAGS) - -platform-test: - @echo $(PLATFORM) - -clean: - rm -f *.o ; rm -f $(APP) - -.c.o: - $(CC) -c -o $(<:.c=.o) $(CFLAGS) $< - -ftd2xx.def: - echo EXPORTS > ftd2xx.def - nm ftd2xx.lib | grep ' T _' | sed 's/.* T _//' >> ftd2xx.def - -ftd2xx.dll.a: ftd2xx.def - dlltool --def ftd2xx.def --dllname ftd2xx.dll --output-lib ftd2xx.dll.a diff --git a/tools/sensinode/nano_usb_programmer/README.md b/tools/sensinode/nano_usb_programmer/README.md deleted file mode 100644 index c5ea77f8b..000000000 --- a/tools/sensinode/nano_usb_programmer/README.md +++ /dev/null @@ -1,60 +0,0 @@ -Nano USB Programmer -=================== - -An USB programmer for the Sensinode NanoRouter N600. - -Copyright 2007-2008 Sensinode Ltd. - -Installation ------------- - -### Linux - -The installation is quite simple but requires the user to obtain the FTDI -development library. The installation also requires root privileges in some -phases (the ldconfig command to be more specific). Running the -Nano_USB_Programmer executable might also require root privileges. - -- unpack the Nano_USB_Programmer-v[xxx].zip to a directory -- get the FTDI development library from - [http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz](http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz) -- unpack the ftdi archive -- copy the library static_lib/libftd2xx.a.[version] into /usr/lib -- copy the library libftd2xx.so.[version] into /usr/lib -- make a symbolic link to the library, for example: ln -s - /usr/lib/libftd2xx.so.0.4.13 /usr/lib/libftd2xx.so -- run ldconfig -- copy the header files into the nano_usb_programmer/ftdi_linux/ directory -- go to the programmer directory and run make - -### Windows/Cygwin - -- The FTDI library can be downloaded at: - -[http://www.ftdichip.com/Drivers/CDM/CDM%202.02.04%20WHQL%20Certified.zip](http://www.ftdichip.com/Drivers/CDM/CDM%202.02.04%20WHQL%20Certified.zip) - -- Copy header files (ftd2xx.h), ftd2xx.lib and ftd2xx.dll to nano_usb_programmer/ftdi_win32 -- Copy the ftd2xx.dll to your windows system32 directory - -Usage ------ - -Usage info for the Nano_USB_Programmer is available with command -./nano_usb_programmer --help. Note that use might require root/administrator -privileges depending on system configuration. - -Known problems (Linux) ----------------------- - -There's one known problem at the moment. The N600 must be unplugged and plugged -in again after it has been programmed or the MAC address has been read from it -before it can respond to the programmer again. The reason for this is the FTDI -library is not perfectly integrated with the Linux serial driver. - -README Version --------------- - -v1.0 2007-11-14 Mikko Saarnivala Initial release -v1.1 2007-11-15 Mikko Saarnivala A small error in the instructions fixed -v1.2 2007-11-19 Mikko Saarnivala Added the FTDI CBUS2 value handling -v1.3 2008-01-31 Martti Huttunen Multi-platform build and updated instructions diff --git a/tools/sensinode/nano_usb_programmer/Rules.make b/tools/sensinode/nano_usb_programmer/Rules.make deleted file mode 100644 index 034cd0321..000000000 --- a/tools/sensinode/nano_usb_programmer/Rules.make +++ /dev/null @@ -1,14 +0,0 @@ -ifeq "$(PLATFORM)" "linux" -CC=gcc -CFLAGS= -I. -I./ftdi_linux -L. -L./ftdi_linux -DPLATFORM_LINUX -LDFLAGS= -lftd2xx -Wl,-rpath /usr/local/lib -SOURCES=main.c prog.c cdi.c ihex.c -SUFFIX= -else -CC=gcc -CFLAGS=-I. -I./ftdi_win32 -L. -L./ftdi_win32 -DPLATFORM_WINDOWS -CFLAGS+= -mwin32 -LDFLAGS=ftdi_win32/ftd2xx.lib -lkernel32 -SOURCES=main.c prog.c cdi.c ihex.c -SUFFIX=.exe -endif diff --git a/tools/sensinode/nano_usb_programmer/cdi.c b/tools/sensinode/nano_usb_programmer/cdi.c deleted file mode 100644 index 2d490869f..000000000 --- a/tools/sensinode/nano_usb_programmer/cdi.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include "cdi.h" - -/*read none/8*/ -#define CDI_CHIP_ERASE 0x10 -#define CDI_WR_CONFIG 0x19 -#define CDI_SET_HW_BRKPNT 0x3B - -/*read 8*/ -#define CDI_RD_CONFIG 0x24 -#define CDI_READ_STATUS 0x34 -#define CDI_HALT 0x44 -#define CDI_RESUME 0x4C -#define CDI_STEP_INSTR 0x5C - -/*variable len, add data length to command byte*/ -#define CDI_DBGINSTR 0x54 -#define CDI_STEP_REPLACE 0x64 - -/*response = 16 bits*/ -#define CDI_GET_PC 0x28 -#define CDI_GET_CHIP_ID 0x68 - - -/* internals */ -void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits); - -void cdi_flash_bank(uint8_t bank, uint8_t unif_mode); - -void cdi_dptr_write(uint16_t value); - -uint8_t cdi_reg_read(uint8_t reg_addr); -void cdi_reg_write(uint8_t reg_addr, uint8_t value); - -void cdi_xdata_write(uint8_t value); -uint8_t cdi_xdata_read(void); - -void cdi_flash_init(void); -void cdi_flash_write_page(void); - -uint32_t cdi_addr = 0; - -#define pause_ms(x) usleep(x*1000) -#define pause_us(x) usleep(x) - -void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits) -{ - uint8_t i, val; - - for (i=0; i>= 3; - for (i=0; i> 8); /*immediateh*/ - out[3] = value; /*immediatel*/ - cdi_command_push(out, 4, &retval, 8); -} - - -uint8_t cdi_reg_read(uint8_t reg_addr) -{ - uint8_t out[3]; - uint16_t retval; - - out[0] = CDI_DBGINSTR + 2; /*command length 2 bytes*/ - out[1] = 0xE5; /*mov a, sfr*/ - out[2] = reg_addr; /*sfr = reg_addr*/ - cdi_command_push(out, 3, &retval, 8); - - return (uint8_t) retval; -} - - -void cdi_flash_bank(uint8_t bank, uint8_t unif_mode) -{ - uint8_t out; - - out = (bank << 4) + 1; - out &= 0x31; - if (unif_mode) out |= 0x40; /*set unified memory model*/ - - cdi_reg_write(0xC7, out); -} - - -void cdi_flash_read(uint8_t *ptr, uint16_t bytes) -{ - uint16_t i; - uint8_t out[4]; - uint16_t retval; - - cdi_flash_bank((cdi_addr >> 15), 0); - - cdi_dptr_write(cdi_addr | 0x8000); - - for (i=0; i> 10) & 0x7F); /*sfr = FADDRH*/ - cdi_reg_write(0xAC, (cdi_addr >> 2)); /*sfr = FADDRL*/ - - /*erase page*/ - cdi_reg_write(0xAE, 0x01); - pause_ms(40); - - /*set program counter*/ - out[0] = CDI_DBGINSTR + 3; /*command length 3 bytes*/ - out[1] = 0x02; /*ljmp immediate16*/ - out[2] = 0xE0; /*immediateh*/ - out[3] = 0x00; /*immediatel*/ - cdi_command_push(out, 4, &retval, 8); - - /*set breakpoint*/ - out[0] = CDI_SET_HW_BRKPNT; /*command length 3 bytes*/ - out[1] = 0x04; - out[2] = 0xE0; /*immediateh*/ - out[3] = sizeof(cdi_ram_code)-2; /*immediatel*/ - cdi_command_push(out, 4, &retval, 0); - - cdi_dptr_write(0xE800); /*data area, set your page data here*/ - /*execute*/ - out[0] = CDI_RESUME; /*command length 3 bytes*/ - cdi_command_push(out, 1, &retval, 8); - - pause_ms(30); - out[3]= 0; - do - { - pause_ms(20); - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - printf("-"); - fflush(stdout); - }while( ((retval & 0x20) == 0) && (out[3]++ < 200) ); -} - -int cdi_flash_write(uint8_t *ptr, uint16_t length) -{ - uint16_t i, retval; - uint8_t out[3]; - - if (length > 2048) return -1; - - cdi_addr &= 0x1F800; /*make sure address is on page boundary*/ - - printf("0x%6.6X: ", cdi_addr); - fflush(stdout); - cdi_dptr_write(0xE800); /*our page data buffer is here*/ - for (i=0; i< length; i++) - { - cdi_xdata_write(*ptr++); - if ((i & 0x3F) == 0) - { - printf("."); - } - if ((i & 0x0F) == 0x00) - { - printf("\bo"); - } - if ((i & 0x0F) == 0x08) - { - printf("\b."); - } - fflush(stdout); - } - while(i<2048) - { - cdi_xdata_write(0xFF); - if ((i & 0x3F) == 0) - { - printf("."); - } - if ((i & 0x0F) == 0x00) - { - printf("\bo"); - } - if ((i & 0x0F) == 0x08) - { - printf("\b."); - } - fflush(stdout); - i++; - } - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - out[0] = CDI_READ_STATUS; - retval = 0; - cdi_command_push(out, 1, &retval, 8); - if ((retval & 0xFF) == 0xB2) - { - /*restore config*/ - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - /*set flash timings and copy code to ram*/ - cdi_flash_init(); - /*write page*/ - cdi_flash_write_page(); - cdi_addr += 2048; /*increment page address*/ - pause_ms(10); - } - else - { - return -1; - } - return 0; -} - -int cdi_flash_write_mac(uint8_t *ptr) -{ - uint16_t i, retval; - uint8_t out[3]; - - cdi_addr = 0x1F800; /*last page*/ - - printf("0x%6.6X", cdi_addr); - fflush(stdout); - cdi_dptr_write(0xEFF8); /*our page data buffer is here*/ - for (i=0; i<8; i++) - { - cdi_xdata_write(*ptr++); - if ((i & 0x0F) == 0) - { - printf("."); - fflush(stdout); - } - } - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - out[0] = CDI_READ_STATUS; - retval = 0; - cdi_command_push(out, 1, &retval, 8); - if ((retval & 0xFF) == 0xB2) - { - /*restore config*/ - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - /*set flash timings and copy code to ram*/ - cdi_flash_init(); - /*write page*/ - cdi_flash_write_page(); - cdi_addr += 2048; /*increment page address*/ - pause_ms(10); - } - else - { - return -1; - } - return 0; -} - -int cdi_start(uint16_t *chip_id) -{ - uint8_t out[3]; - uint16_t retval; - - prog_start(); /*do the CDI startup sequence*/ - - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - - printf("Status: %2.2X.\n", retval & 0xFF); - - out[0] = CDI_GET_CHIP_ID; - cdi_command_push(out, 1, &retval, 16); - - *chip_id = retval; - - out[0] = CDI_HALT; - cdi_command_push(out, 1, &retval, 8); - - pause_ms(100); - - out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/ - out[1] = 0x0E; /*write flash area*/ - cdi_command_push(out, 2, &retval, 0); - - pause_ms(10); - - cdi_reg_write(0xC6, 0xC9); /*sfr = CLKCON*/ - - pause_ms(10); - - cdi_reg_write(0xAB, 0x15); /*sfr = FWT*/ - - cdi_addr = 0; - - return 0; -} - -int cdi_erase(void) -{ - uint8_t out[3]; - uint16_t retval; - uint8_t i; - - out[0] = CDI_WR_CONFIG; - out[1] = 0x0E; - cdi_command_push(out, 2, &retval, 0); - out[0] = CDI_CHIP_ERASE; - cdi_command_push(out, 1, &retval, 0); - retval = 0; - i = 0; - do - { - pause_ms(30); - out[0] = CDI_READ_STATUS; - cdi_command_push(out, 1, &retval, 8); - }while( ((retval & 0x84) != 0x80) && (i++ < 100) ); - - cdi_addr = 0; - - if (i >= 100) - { - return -1; - } - return 0; -} - -void cdi_set_address(uint32_t address) -{ - cdi_addr = address; -} diff --git a/tools/sensinode/nano_usb_programmer/cdi.h b/tools/sensinode/nano_usb_programmer/cdi.h deleted file mode 100644 index 40e909178..000000000 --- a/tools/sensinode/nano_usb_programmer/cdi.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef _CDI_H -#define _CDI_H - -#include "prog.h" - -/* export these */ -extern int cdi_start(uint16_t *chip_id); -extern int cdi_erase(void); - -extern void cdi_set_address(uint32_t address); - -extern void cdi_flash_read(uint8_t *ptr, uint16_t bytes); -extern int cdi_flash_write(uint8_t *ptr, uint16_t length); - -#endif diff --git a/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h b/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h deleted file mode 100644 index 4def457b7..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef __WINDOWS_TYPES__ -#define __WINDOWS_TYPES__ - -#define MAX_NUM_DEVICES 50 -#include - -typedef unsigned long DWORD; -typedef unsigned long ULONG; -typedef unsigned short USHORT; -typedef short SHORT; -typedef unsigned char UCHAR; -typedef unsigned short WORD; -typedef unsigned char BYTE; -typedef unsigned char *LPBYTE; -typedef int BOOL; -typedef char BOOLEAN; -typedef char CHAR; -typedef int *LPBOOL; -typedef unsigned char *PUCHAR; -typedef const char *LPCSTR; -typedef char *PCHAR; -typedef void *PVOID; -typedef void *HANDLE; -typedef long LONG; -typedef int INT; -typedef unsigned int UINT; -typedef char *LPSTR; -typedef char *LPTSTR; -typedef DWORD *LPDWORD; -typedef WORD *LPWORD; -typedef ULONG *PULONG; -typedef PVOID LPVOID; -typedef void VOID; -typedef unsigned long long int ULONGLONG; - -typedef struct _OVERLAPPED { - DWORD Internal; - DWORD InternalHigh; - DWORD Offset; - DWORD OffsetHigh; - HANDLE hEvent; -} OVERLAPPED, *LPOVERLAPPED; - -typedef struct _SECURITY_ATTRIBUTES { - DWORD nLength; - LPVOID lpSecurityDescriptor; - BOOL bInheritHandle; -} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES; - -typedef struct timeval SYSTEMTIME; -typedef struct timeval FILETIME; -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -// -// Modem Status Flags -// -#define MS_CTS_ON ((DWORD)0x0010) -#define MS_DSR_ON ((DWORD)0x0020) -#define MS_RING_ON ((DWORD)0x0040) -#define MS_RLSD_ON ((DWORD)0x0080) - -// -// Error Flags -// - -#define CE_RXOVER 0x0001 // Receive Queue overflow -#define CE_OVERRUN 0x0002 // Receive Overrun Error -#define CE_RXPARITY 0x0004 // Receive Parity Error -#define CE_FRAME 0x0008 // Receive Framing error -#define CE_BREAK 0x0010 // Break Detected -#define CE_TXFULL 0x0100 // TX Queue is full -#define CE_PTO 0x0200 // LPTx Timeout -#define CE_IOE 0x0400 // LPTx I/O Error -#define CE_DNS 0x0800 // LPTx Device not selected -#define CE_OOP 0x1000 // LPTx Out-Of-Paper -#define CE_MODE 0x8000 // Requested mode unsupported - -#ifndef INVALID_HANDLE_VALUE -#define INVALID_HANDLE_VALUE 0xFFFFFFFF -#endif - -#endif diff --git a/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h b/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h deleted file mode 100644 index f4146f1d8..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h +++ /dev/null @@ -1,975 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -/*++ - -Copyright (c) 2001-2006 Future Technology Devices International Ltd. - -Module Name: - - ftd2xx.h - -Abstract: - - Native USB interface for FTDI FT8U232/245/2232C - FTD2XX library definitions - -Environment: - - kernel & user mode - -Revision History: - - 13/03/01 awm Created. - 13/01/03 awm Added device information support. - 19/03/03 awm Added FT_W32_CancelIo. - 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. - 18/09/03 awm Added FT_SetResetPipeRetryCount. - 10/10/03 awm Added FT_ResetPort. - /03/04 st modified for linux users - 12/10/04 st added FT_SetVIDPID - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -#ifndef _WINDOWS -#include -#define WINAPI -#endif - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#else -#define FTD2XX_API __declspec(dllimport) -#endif - -#ifndef _WINDOWS -#include "WinTypes.h" - -#ifdef FTD2XX_API -#undef FTD2XX_API -#define FTD2XX_API -#endif -#endif -typedef struct _EVENT_HANDLE{ - pthread_cond_t eCondVar; - pthread_mutex_t eMutex; - int iVar; -} EVENT_HANDLE; - -typedef DWORD *FT_HANDLE; - -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, //7 - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 -#define FT_BITS_6 (UCHAR) 6 -#define FT_BITS_5 (UCHAR) 5 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_1_5 (UCHAR) 1 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R - }; - - -#ifdef __cplusplus -extern "C" { -#endif - -FTD2XX_API -FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - -FTD2XX_API -FT_STATUS FT_SetVIDPID( - DWORD dwVID, - DWORD dwPID - ); - -FTD2XX_API -FT_STATUS FT_GetVIDPID( - DWORD * pdwVID, - DWORD * pdwPID - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten - ); - -FTD2XX_API -FT_STATUS WINAPI FT_IoCtl( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetWaitMask( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WaitOnMask( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD *Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - -// -// structure to hold program data for FT_Program function -// -typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232C extensions - // 2 = FT232R extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // FT2232C extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // FT232R extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - - UCHAR RIsVCP; // zero if using VCP drivers - -} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA lpData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA lpData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - -FTD2XX_API -FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetResetPipeRetryCount( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - DWORD dwCount - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetPort( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_CyclePort( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - - -// -// Win32-type functions -// - -FTD2XX_API -FT_HANDLE WINAPI FT_W32_CreateFile( - LPCSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetOverlappedResult( // Linux, OS X: Not supported - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CancelIo( // Linux, OS X: Not supported - FT_HANDLE ftHandle - ); - - -// -// Win32 COMM API type functions -// -typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; -} FTCOMSTAT, *LPFTCOMSTAT; - -typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ -} FTDCB, *LPFTDCB; - -typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ -} FTTIMEOUTS,*LPFTTIMEOUTS; - - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - -FTD2XX_API -BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - -// -// Device information -// - -typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; -} FT_DEVICE_LIST_INFO_NODE; - -FTD2XX_API -FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - -// -// Events -// - -#define EV_RXCHAR 0x0001 // Any Character received -#define EV_RXFLAG 0x0002 // Received certain character -#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty -#define EV_CTS 0x0008 // CTS changed state -#define EV_DSR 0x0010 // DSR changed state -#define EV_RLSD 0x0020 // RLSD changed state -#define EV_BREAK 0x0040 // BREAK received -#define EV_ERR 0x0080 // Line status error occurred -#define EV_RING 0x0100 // Ring signal detected -#define EV_PERR 0x0200 // Printer error occured -#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full -#define EV_EVENT1 0x0800 // Provider specific event 1 -#define EV_EVENT2 0x1000 // Provider specific event 2 - -// -// Escape Functions -// - -#define SETXOFF 1 // Simulate XOFF received -#define SETXON 2 // Simulate XON received -#define SETRTS 3 // Set RTS high -#define CLRRTS 4 // Set RTS low -#define SETDTR 5 // Set DTR high -#define CLRDTR 6 // Set DTR low -#define RESETDEV 7 // Reset device if possible -#define SETBREAK 8 // Set the device break line. -#define CLRBREAK 9 // Clear the device break line. - -// -// PURGE function flags. -// -#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port. -#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port. -#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there. -#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there. - - - - - - - - - - - - - - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ - - - - - - diff --git a/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h b/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h deleted file mode 100644 index 3ee1da36d..000000000 --- a/tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h +++ /dev/null @@ -1,922 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -/*++ - -Copyright (c) 2001-2006 Future Technology Devices International Ltd. - -Module Name: - - ftd2xx.h - -Abstract: - - Native USB device driver for FTDI FT8U232/245 - FTD2XX library definitions - -Environment: - - kernel & user mode - -Revision History: - - 13/03/01 awm Created. - 13/01/03 awm Added device information support. - 19/03/03 awm Added FT_W32_CancelIo. - 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. - 18/09/03 awm Added FT_SetResetPipeRetryCount. - 10/10/03 awm Added FT_ResetPort. - 23/01/04 awm Added support for open-by-location. - 16/03/04 awm Added support for FT2232C. - 23/09/04 awm Added support for FT232R. - 20/10/04 awm Added FT_CyclePort. - 18/01/05 awm Added FT_DEVICE_LIST_INFO_NODE type. - 11/02/05 awm Added LocId to FT_DEVICE_LIST_INFO_NODE. - 25/08/05 awm Added FT_SetDeadmanTimeout. - 02/12/05 awm Removed obsolete references. - 05/12/05 awm Added FT_GetVersion, FT_GetVersionEx. - 08/09/06 awm Added FT_W32_GetCommMask. - 11/09/06 awm Added FT_Rescan. - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#else -#define FTD2XX_API __declspec(dllimport) -#endif - - -typedef PVOID FT_HANDLE; -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR, - FT_DEVICE_LIST_NOT_READY, -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 -#define FT_OPEN_BY_LOCATION 4 - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 -#define FT_BITS_6 (UCHAR) 6 -#define FT_BITS_5 (UCHAR) 5 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_1_5 (UCHAR) 1 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R -}; - - -#ifdef __cplusplus -extern "C" { -#endif - - -FTD2XX_API -FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten - ); - -FTD2XX_API -FT_STATUS WINAPI FT_IoCtl( - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetWaitMask( - FT_HANDLE ftHandle, - DWORD Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WaitOnMask( - FT_HANDLE ftHandle, - DWORD *Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - -// -// structure to hold program data for FT_Program function -// -typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232C extensions - // 2 = FT232R extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // FT2232C extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // FT232R extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - - UCHAR RIsD2XX; // non-zero if using D2XX driver - -} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - -FTD2XX_API -FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetResetPipeRetryCount( - FT_HANDLE ftHandle, - DWORD dwCount - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetPort( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_CyclePort( - FT_HANDLE ftHandle - ); - - -// -// Win32-type functions -// - -FTD2XX_API -FT_HANDLE WINAPI FT_W32_CreateFile( - LPCTSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetOverlappedResult( - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CancelIo( - FT_HANDLE ftHandle - ); - - -// -// Win32 COMM API type functions -// -typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; -} FTCOMSTAT, *LPFTCOMSTAT; - -typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ -} FTDCB, *LPFTDCB; - -typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ -} FTTIMEOUTS,*LPFTTIMEOUTS; - - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - -FTD2XX_API -BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommMask( - FT_HANDLE ftHandle, - LPDWORD lpdwEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - - -// -// Device information -// - -typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; -} FT_DEVICE_LIST_INFO_NODE; - - -FTD2XX_API -FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - - -// -// Version information -// - -FTD2XX_API -FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - - -FTD2XX_API -FT_STATUS WINAPI FT_Rescan( - void - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Reload( - WORD wVid, - WORD wPid - ); - - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ diff --git a/tools/sensinode/nano_usb_programmer/ihex.c b/tools/sensinode/nano_usb_programmer/ihex.c deleted file mode 100644 index a7889e57b..000000000 --- a/tools/sensinode/nano_usb_programmer/ihex.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#include -#include - -#include - -int hexfile_build_tables(char *ihexfile, unsigned char *page_buffer, unsigned char *page_table) -{ - unsigned char buffer[256]; - int length; - int i; - int pages; - - unsigned long ext_addr=0; - unsigned short int addr=0; - FILE *ihex_fp; - - if((ihex_fp = (FILE *)fopen(ihexfile, "r")) == NULL) - { - printf("Failed to open .ihex file %s\n", ihexfile); - return(-1); - } - else - { - printf(".ihex file ok.\n"); - } - - bzero(buffer, sizeof(buffer)); - - /*initialize page data*/ - memset(page_table, 0, 64); - memset(page_buffer, 0xFF, sizeof(page_buffer)); - pages = 0; - - while((fscanf(ihex_fp, "%s", buffer) == 1)) - { - unsigned char data_len = 0; - - if (memcmp(&buffer[7], "00", 2) == 0) - { /*Data record*/ - i=0; - sscanf((char *)&buffer[1], "%2hhx", &data_len); - sscanf((char *)&(buffer[3]),"%4hx", &addr); - while(i> 8; - cksum += *addr & 0xFF; - cksum += *type; - - i = 0; - if (retval == 3) - { - while(i < row_len) - { - - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - cksum += tmp; - buffer[i++] = (unsigned char) tmp; - row_index += 2; - } - else return -1; - } - if (sscanf(&line[row_index], "%2x", &tmp) == 1) - { - if ((cksum + (uint8_t) tmp) == 0) return row_len; - } - } - return -1; -} - -int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes) -{ - uint8_t cksum = 0; - uint8_t i = 0; - char tmp[8]; - - sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type); - cksum -= bytes; - cksum -= address >> 8; - cksum -= address & 0xFF; - cksum -= type; - - for (i=0; i -#include -#include -#include -#include - -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include "prog.h" - -#define PRG_VERSION "1.3" - -typedef enum -{ - USAGE, - VERSION, - SCAN, - WRITE, - READ, - WRITE_MAC, - READ_MAC, - ERASE -}mode_t; - -typedef struct opts_t -{ - int port; - mode_t mode; - uint8_t write_mac[8]; - char *filename; -}opts_t; - -opts_t opts; - -void usage(char *prg_name) -{ - printf("\nUsage: %s [-p port] [-h] [-v] [-f file] [-r] [-w] [-m] [-M ]\n", prg_name); - printf("General options:\n"); - printf(" -p/--port [port] Select FTDI device\n"); - printf(" -f/--file [filename] File to read/write\n"); - printf("Operating modes:\n"); - printf(" -d/--devices Scan available devices\n"); - printf(" -v/--version Print program version\n"); - printf(" -r/--read Read program code into ihex file (see -f)\n"); - printf(" -w/--write Program firmware from ihex file (see -f)\n"); - printf(" -m/--read-mac Read device MAC address\n"); - printf(" -M/--write-mac xx:xx:xx:xx:xx:xx:xx:xx Write device MAC address\n"); - printf(" -e/--erase Erase flash (erases MAC address!)\n"); - printf("Defaults:\n"); - printf("mode = usage\n"); - printf("port = undefined\n"); - printf("file = stdout\n"); -} - -int main(int argc, char *argv[]) -{ - DWORD dwBytesInQueue = 0; - FT_STATUS ftStatus; - FT_HANDLE ftHandle; - unsigned char ucMode = 0x00; - int i=0; - unsigned char wr[1] = { 0x30 }; - unsigned char rd[1]; - uint16_t chip_id; - - if (opts_parse(argc, argv) < 0) - { - usage(argv[0]); - return -1; - } - switch(opts.mode) - { - case VERSION: - printf("Sensinode Nano USB Programmer version %s\n", PRG_VERSION); - return 0; - - case USAGE: - usage(argv[0]); - return 0; - - case SCAN: - prog_scan(); - return 0; - - case ERASE: - case READ: - case WRITE: - case READ_MAC: - case WRITE_MAC: - break; - } - - printf("Opening programmer.\n"); - ftHandle = prog_open(opts.port); - if (ftHandle == 0) - { - return (-1); - } - - cdi_start(&chip_id); - - printf("Chip ID = %4.4hX.\n", chip_id); - - if ((chip_id & 0xFF00) == 0x8500) - { - printf("CC2430 chip found.\n"); - } - else if ((chip_id & 0xFF00) == 0x8900) - { - printf("CC2431 chip found.\n"); - } - else - { - printf("Unknown chip found.\n"); - opts.mode = USAGE; - } - - switch(opts.mode) - { - case VERSION: - case USAGE: - break; - - case ERASE: - printf("Erase.\n"); - break; - - case READ: - printf("Read Flash.\n"); - cdi_set_address(0); - break; - - case WRITE: - { - int rval; - unsigned char page_table[64]; - unsigned char page_buffer[128*1024]; - - printf("Write Flash.\n"); - - if((rval = hexfile_build_tables(opts.filename, page_buffer, page_table)) == -1) - { - printf("Error\n"); - return(-1); - } - else if(rval == 0) - { - printf(".ihex file OK but nothing to write...\n"); - return(1); - } - - hexfile_program(page_buffer, page_table); - - break; - } - case READ_MAC: - printf("Read MAC: "); - cdi_set_address(0x1FFF8); - { - uint8_t mac[8]; - - cdi_flash_read(mac, 8); - for (i=0; i<8; i++) - { - if (i) printf(":"); - printf("%2.2X", mac[i]); - } - printf("\n"); - } - break; - - case WRITE_MAC: - printf("Write MAC: "); -/* cdi_set_address(0x1F800); - { - uint8_t block[2048]; - - memset(block, 0xFF, 2048); - for (i=0; i<8; i++) - { - block[2040+i] = opts.write_mac[i]; - } - cdi_flash_write(block, 2048); - printf("\n"); - }*/ - cdi_flash_write_mac(opts.write_mac); - printf("\n"); - break; - - default: - printf("Duh\n"); - break; - } - - - printf("Closing programmer.\n"); - prog_close(); -} - -static int option_index = 0; - -int do_exit = 0; - -#define OPTIONS_STRING "p:vdhf:rwmM:e" -/* long option list */ -static struct option long_options[] = -{ - {"port", 1, NULL, 'p'}, - {"version", 0, NULL, 'v'}, - {"devices", 0, NULL, 'd'}, - {"help", 0, NULL, 'h'}, - {"file", 1, NULL, 'f'}, - {"read", 0, NULL, 'r'}, - {"write", 0, NULL, 'w'}, - {"read-mac", 0, NULL, 'm'}, - {"write-mac", 1, NULL, 'M'}, - {"erase", 0, NULL, 'e'}, - {0, 0, 0, 0} -}; - -int opts_parse(int count, char* param[]) -{ - int opt; - int error=0; - - opts.mode = USAGE; - opts.filename = 0; - while ((opt = getopt_long(count, param, OPTIONS_STRING, - long_options, &option_index)) != -1) - { - fflush(stdout); - switch(opt) - { - case 'p': - opts.port = 0; - if (sscanf(optarg, "%d", &(opts.port)) != 1) - { - if (sscanf(optarg, "/dev/ttyUSB%d", &(opts.port)) != 1) - { - printf("Invalid port.\n"); - opts.mode = USAGE; - return 0; - } - } - printf("Port %d.\n", opts.port); - break; - - case 'v': - opts.mode = VERSION; - return 0; - - case 'd': - opts.mode = SCAN; - return 0; - - case 'h': - opts.mode = USAGE; - return 0; - - case 'e': - opts.mode = ERASE; - break; - - case 'f': - printf("Filename: %s\n", optarg); - opts.filename = malloc(strlen(optarg)+1); - strcpy(opts.filename, optarg); - break; - - case 'r': - opts.mode = READ; - break; - - case 'w': - opts.mode = WRITE; - break; - - case 'm': - opts.mode = READ_MAC; - break; - - case 'M': - opts.mode = WRITE_MAC; - if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", - &opts.write_mac[0], &opts.write_mac[1], - &opts.write_mac[2], &opts.write_mac[3], - &opts.write_mac[4], &opts.write_mac[5], - &opts.write_mac[6], &opts.write_mac[7]) != 8) - { - printf("Invalid MAC.\n"); - opts.mode = USAGE; - } - else - { - printf("MAC to write: %2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX\n", - opts.write_mac[0], opts.write_mac[1], - opts.write_mac[2], opts.write_mac[3], - opts.write_mac[4], opts.write_mac[5], - opts.write_mac[6], opts.write_mac[7]); - } - break; - - case '?': - printf("Duh\n"); - error = -1; - break; - } - } - - return error; -} - diff --git a/tools/sensinode/nano_usb_programmer/prog.c b/tools/sensinode/nano_usb_programmer/prog.c deleted file mode 100644 index 1cce8ec83..000000000 --- a/tools/sensinode/nano_usb_programmer/prog.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#include -#include -#ifdef PLATFORM_WINDOWS -#include -#endif -#include - -FT_HANDLE curr_handle = 0; -uint8_t curr_mode = 0; /* 0 = in, 1=out */ - -/* - * This function checks if the CBUS2 ise set to SLEEP and modifies it if necessary. - * The CBUS2 must be set to sleep in order the programming to succeed. - */ -int check_cbus2(FT_HANDLE fthandle) -{ - FT_PROGRAM_DATA eeprom_data; - char manufacturer_buf[32]; - char manufacturer_id[16]; - char description_buf[64]; - char serialnumber_buf[16]; - eeprom_data.Signature1 = 0x00000000; // This is a given value from the FT232R programming guide - eeprom_data.Signature2 = 0xffffffff; // This is a given value from the FT232R programming guide - eeprom_data.Version = 0x00000002; // This is a given value from the FT232R programming guide - eeprom_data.Manufacturer = manufacturer_buf; - eeprom_data.ManufacturerId = manufacturer_id; - eeprom_data.Description = description_buf; - eeprom_data.SerialNumber = serialnumber_buf; - - - if(FT_EE_Read(fthandle, &eeprom_data) != FT_OK) - { - printf("FTDI EEPROM read failed.\n"); - return(-1); - } - - if(eeprom_data.Cbus2 != 0x05) - { - printf("Need to re-program the CBUS2 to 0x05\n"); - eeprom_data.Cbus2 = 0x05; - - if(FT_EE_Program(fthandle, &eeprom_data) != FT_OK) - { - printf("FTDI EEPROM program error.\n"); - return(-1); - } - else - { - printf("FTDI EEPROM program ok\n"); - return(1); - } - } - else - { - return(1); - } - - return(1); -} - - -void prog_scan(void) -{ - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *info; - unsigned long n_devices = 0; - uint8_t out; - - ftStatus = FT_CreateDeviceInfoList(&n_devices); - if (ftStatus == FT_OK) - { - FT_DEVICE_LIST_INFO_NODE devices[n_devices]; - - ftStatus = FT_GetDeviceInfoList(devices,&n_devices); - if (ftStatus == FT_OK) - { - for (out = 0; out < n_devices; out++) - { - printf("Dev %d:",n_devices - out -1); - printf(" Type=0x%x",devices[n_devices - out -1].Type); - printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); - printf(" Description=%s\n",devices[n_devices - out -1].Description); - } - } - else - { - printf("Failed to fetch device list.\n"); - } - } - else - { - printf("Failed to fetch device list.\n"); - } -} - -FT_HANDLE prog_open(int iport) -{ - FT_HANDLE ftHandle; - FT_STATUS ftStatus; - FT_DEVICE_LIST_INFO_NODE *info; - unsigned long n_devices = 0; - uint8_t out; - - if (curr_handle) return 0; - - ftStatus = FT_CreateDeviceInfoList(&n_devices); - if (ftStatus == FT_OK) - { - FT_DEVICE_LIST_INFO_NODE devices[n_devices]; - - ftStatus = FT_GetDeviceInfoList(devices,&n_devices); - if (ftStatus == FT_OK) - { - iport = n_devices - iport - 1; - - if (iport < 0) - { - printf("Invalid port id.\n"); - for (out = 0; out < n_devices; out++) - { - printf("Dev %d:",n_devices - out -1); - printf(" Type=0x%x",devices[n_devices - out -1].Type); - printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber); - printf(" Description=%s\n",devices[n_devices - out -1].Description); - } - return 0; - } - } - } - - ftStatus = FT_Open(iport, &ftHandle); - if(ftStatus != FT_OK) { - /* - This can fail if the ftdi_sio driver is loaded - use lsmod to check this and rmmod ftdi_sio to remove - also rmmod usbserial - */ - printf("FT_Open(%d) failed\n", iport); - return 0; - } - - if(check_cbus2(ftHandle) < 0) - { - printf("Nano USB Programmer exiting...\n"); - return(0); - } - - FT_ResetDevice(ftHandle); - - FT_SetBaudRate(ftHandle, 115200); - - FT_SetUSBParameters(ftHandle, 64, 0); - - out = 0x04; - - ftStatus = FT_SetBitMode(ftHandle, out, 0x20); - if (ftStatus == FT_OK) - { - ftStatus = FT_SetLatencyTimer(ftHandle, 2); - } - if (ftStatus == FT_OK) - { - DWORD bytes; - out = 0xE0; - ftStatus = FT_SetBitMode(ftHandle, out, 0x04); - out = 0x80; - FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - curr_mode = 1; - } - if (ftStatus != FT_OK) - { - printf("Failed to set CBUS2/bit bang mode.\n"); - - FT_ResetDevice(ftHandle); - sleep(3); - FT_Close(ftHandle); - ftHandle = 0; - } - curr_handle = ftHandle; - return ftHandle; -} - -void prog_close(void) -{ - FT_STATUS ftStatus; - DWORD bytes; - - if (curr_handle) - { - FT_HANDLE ftHandle = curr_handle; - uint8_t out = 0x00; - - FT_Write(ftHandle, &out, 1, &bytes); /*write reset low*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - sleep(1); - out = 0x80; - FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/ - FT_Read(ftHandle, &out, 1, &bytes); /*read out*/ - sleep(1); - out = 0x00; - ftStatus = FT_SetBitMode(ftHandle, out, 0x04); - FT_ResetDevice(ftHandle); - FT_Close(ftHandle); - - ftHandle = 0; - curr_handle = ftHandle; - } -} - -int prog_write(uint8_t byte) -{ - FT_STATUS ftStatus; - uint8_t out[16]; - uint8_t mask = 0x80; - int i; - DWORD bytes; - - if (curr_mode == 0) - { - out[0] = 0xE0; - ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as output*/ - if (ftStatus != FT_OK) - { printf("!WR"); - fflush(stdout); - return -1; - } - curr_mode = 1; - } - i = 0; - while (mask) - { - out[i] = 0xC0; /*clock high, reset high*/ - if (byte & mask) out[i] |= 0x20; - i++; - out[i] = 0x80; /*clock low, reset high*/ - if (byte & mask) out[i] |= 0x20; - i++; - mask >>= 1; - } - ftStatus = FT_Write(curr_handle, out, 16, &bytes); /*write clock high and data bit*/ - if (ftStatus != FT_OK) - { - printf("!W"); - fflush(stdout); - return -1; - } - - if(FT_Read(curr_handle, out, 16, &bytes) != FT_OK) - { - printf("!R"); - return(-1); - } - - return 0; -} - -int prog_read(uint8_t *byte) -{ - FT_STATUS ftStatus; - uint8_t rd; - uint8_t mask = 0x80; - DWORD bytes; - uint8_t out[17]; - uint8_t i=0; - - *byte = 0; - if (curr_mode == 1) - { - out[0] = 0xC0; - ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as input*/ - if (ftStatus != FT_OK) - { printf("!RD"); - fflush(stdout); - return -1; - } - curr_mode = 0; - } - - while (mask) - { - out[i] = 0xC0; /*clock high, reset high*/ - if (*byte & mask) out[i] |= 0x20; - i++; - out[i] = 0x80; /*clock low, reset high*/ - if (*byte & mask) out[i] |= 0x20; - i++; - mask >>= 1; - } - - out[16] = out[15]; - - ftStatus = FT_Write(curr_handle, out, 17, &bytes); /*write clock high and data bit*/ - - if(FT_Read(curr_handle, out, 17, &bytes) != FT_OK) - { - printf("!R"); - return(-1); - } - - mask = 0x80; - i = 1; - while (mask) - { - if (out[i] & 0x20) *byte |= mask; - mask >>= 1; - i+=2; - } - - return 0; -} - -int prog_start(void) -{ - FT_STATUS ftStatus; - uint8_t wr; - uint8_t mask = 0x80; - DWORD bytes; - uint8_t out[16] = { 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80 }; - - printf("prog_start()\n"); - - if (curr_mode == 0) - { - wr = 0xE0; - - ftStatus = FT_SetBitMode(curr_handle, wr, 0x04); /*Set DD as output*/ - curr_mode = 1; - } - - if(FT_Write(curr_handle, out, 7, &bytes) != FT_OK) - { - printf("!W\n"); - return(-1); - } - - if(FT_Read(curr_handle, out, 7, &bytes) != FT_OK) - { - printf("!R\n"); - return(-1); - } - -} diff --git a/tools/sensinode/nano_usb_programmer/prog.h b/tools/sensinode/nano_usb_programmer/prog.h deleted file mode 100644 index fc2107d47..000000000 --- a/tools/sensinode/nano_usb_programmer/prog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - NanoStack: MCU software and PC tools for IP-based wireless sensor networking. - - Copyright (C) 2006-2007 Sensinode Ltd. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - Address: - Sensinode Ltd. - Teknologiantie 6 - 90570 Oulu, Finland - - E-mail: - info@sensinode.com -*/ - - -#ifndef _PROG_H -#define _PROG_H - -#include "ftd2xx.h" -#include - -extern FT_HANDLE prog_open(int iport); -extern void prog_close(void); - -extern int prog_write(uint8_t byte); -extern int prog_read(uint8_t *byte); - -extern int prog_start(void); - -extern int check_cbus2(FT_HANDLE fthandle); - -#endif From 37682133119026980966ca5f39a31ef4c42944ca Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 15:08:55 +0000 Subject: [PATCH 32/94] Remove sensinode build artifacts from .gitignore This is part of a set of commits that will obsolete the Sensinode platform --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6ff425546..c166681da 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,6 @@ tools/cooja/apps/avrora/lib/cooja_avrora.jar tools/cooja/apps/collect-view/cooja-collect-view.jar # sdcc build artifacts -contiki-sensinode.lib contiki-cc2530dk.lib *.ihx *.hex @@ -70,7 +69,6 @@ contiki-cc2530dk.lib *.omf *.cdb *.banks -*.sensinode *.cc2530dk # VC++ build artifacts From fa40d2b1fcae6922423541462148e759bcad1119 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 15:09:31 +0000 Subject: [PATCH 33/94] Remove documentation references to the Sensinode platform This is part of a set of commits that will obsolete the Sensinode platform --- core/net/ipv6/multicast/roll-tm.h | 4 ++-- doc/platform.txt | 5 ----- examples/cc2530dk/blink-hello.c | 2 +- platform/cc2530dk/debug.h | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/core/net/ipv6/multicast/roll-tm.h b/core/net/ipv6/multicast/roll-tm.h index 3ab22cc20..fce300f95 100644 --- a/core/net/ipv6/multicast/roll-tm.h +++ b/core/net/ipv6/multicast/roll-tm.h @@ -90,8 +90,8 @@ * settles down, the code compensates the offsets. * * We consider 125, 250ms etc because they are nice divisors of 1 sec - * (quotient is power of two). For some machines (e.g sky/msp430, - * sensinode/cc243x), this is also a nice number of clock ticks + * (quotient is power of two). For some machines (e.g sky/msp430), + * this is also a nice number of clock ticks * * After experimentation, the values of Imin leading to best performance are: * ContikiMAC: Imin=64 (500ms) diff --git a/doc/platform.txt b/doc/platform.txt index 49c255140..4c76c5aed 100644 --- a/doc/platform.txt +++ b/doc/platform.txt @@ -107,11 +107,6 @@ * \ingroup platform */ -/** - * \addtogroup sensinode Sensinode - * \ingroup platform - */ - /** * \addtogroup sky The Tmote Sky Board * \ingroup platform diff --git a/examples/cc2530dk/blink-hello.c b/examples/cc2530dk/blink-hello.c index 14bc73151..a79e938c9 100644 --- a/examples/cc2530dk/blink-hello.c +++ b/examples/cc2530dk/blink-hello.c @@ -2,7 +2,7 @@ * It aims to demonstrate the co-existence of two processes: * One of them prints a hello world message and the other blinks the LEDs * - * It is largely based on hello_world in $(CONTIKI)/examples/sensinode + * It is largely based on hello_world of the original sensinode port * * Author: George Oikonomou - */ diff --git a/platform/cc2530dk/debug.h b/platform/cc2530dk/debug.h index 94eaa4f51..592965843 100644 --- a/platform/cc2530dk/debug.h +++ b/platform/cc2530dk/debug.h @@ -32,7 +32,7 @@ /** * \file - * Header file for debugging functions used by the sensinode port. + * Header file for debugging functions used by the CC2530DK port. * * putstring() and puthex() are from msp430/watchdog.c * From eda5e0466bb3fd981aa23d210a1bcd04a02089c4 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 15:10:51 +0000 Subject: [PATCH 34/94] Remove the Sensinode nano_programmer from the tools travis job This is part of a set of commits that will obsolete the Sensinode platform --- regression-tests/20-compile-tools/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests/20-compile-tools/Makefile b/regression-tests/20-compile-tools/Makefile index 7ec956683..d73dde44d 100644 --- a/regression-tests/20-compile-tools/Makefile +++ b/regression-tests/20-compile-tools/Makefile @@ -25,8 +25,8 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -TOOLS=sky tools stm32w z80=hex2bin sensinode=nano_programmer -FAILTOOLS=stm32w=uip6_bridge sky=uip6-bridge sensinode=nano_usb_programmer +TOOLS=sky tools stm32w z80=hex2bin +FAILTOOLS=stm32w=uip6_bridge sky=uip6-bridge TOOLSDIR=../../tools From 6933b35bb5d9dbbc6d72dc49463bb2126467bcd7 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 27 Dec 2015 14:48:26 +0100 Subject: [PATCH 35/94] Rename select() in various sensortag sensor drivers This is to prevent a compile error caused by function prototype conflict between a function called `select()` (present in a number of sensortag peripheral drivers) and the one in `sys/select.h`. The error manifests itself with gcc-arm-embedded version 5.2.1 20151202 (2015-q4). To fix the error we simply rename our function. Fixes #1434 --- .../srf06-cc26xx/sensortag/bmp-280-sensor.c | 8 ++++---- platform/srf06-cc26xx/sensortag/ext-flash.c | 18 +++++++++--------- .../srf06-cc26xx/sensortag/opt-3001-sensor.c | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c index a10e86c5e..4ed9e06fc 100644 --- a/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c +++ b/platform/srf06-cc26xx/sensortag/bmp-280-sensor.c @@ -148,7 +148,7 @@ notify_ready(void *not_used) } /*---------------------------------------------------------------------------*/ static void -select(void) +select_on_bus(void) { /* Set up I2C */ board_i2c_select(BOARD_I2C_INTERFACE_0, BMP280_I2C_ADDRESS); @@ -162,7 +162,7 @@ init(void) { uint8_t val; - select(); + select_on_bus(); /* Read and store calibration data */ sensor_common_read_reg(ADDR_CALIB, calibration_data, CALIB_DATA_SIZE); @@ -183,7 +183,7 @@ enable_sensor(bool enable) { uint8_t val; - select(); + select_on_bus(); if(enable) { /* Enable forced mode */ @@ -205,7 +205,7 @@ read_data(uint8_t *data) { bool success; - select(); + select_on_bus(); success = sensor_common_read_reg(ADDR_PRESS_MSB, data, MEAS_DATA_SIZE); if(!success) { diff --git a/platform/srf06-cc26xx/sensortag/ext-flash.c b/platform/srf06-cc26xx/sensortag/ext-flash.c index c734e826a..c35bd4d0f 100644 --- a/platform/srf06-cc26xx/sensortag/ext-flash.c +++ b/platform/srf06-cc26xx/sensortag/ext-flash.c @@ -86,7 +86,7 @@ * Clear external flash CSN line */ static void -select(void) +select_on_bus(void) { ti_lib_gpio_pin_write(BOARD_FLASH_CS, 0); } @@ -110,7 +110,7 @@ wait_ready(void) bool ret; const uint8_t wbuf[1] = { BLS_CODE_READ_STATUS }; - select(); + select_on_bus(); /* Throw away all garbages */ board_spi_flush(); @@ -159,7 +159,7 @@ verify_part(void) uint8_t rbuf[2] = {0, 0}; bool ret; - select(); + select_on_bus(); ret = board_spi_write(wbuf, sizeof(wbuf)); @@ -199,7 +199,7 @@ power_down(void) } cmd = BLS_CODE_PD; - select(); + select_on_bus(); board_spi_write(&cmd, sizeof(cmd)); deselect(); @@ -227,7 +227,7 @@ power_standby(void) bool success; cmd = BLS_CODE_RPD; - select(); + select_on_bus(); success = board_spi_write(&cmd, sizeof(cmd)); if(success) { @@ -249,7 +249,7 @@ write_enable(void) bool ret; const uint8_t wbuf[] = { BLS_CODE_WRITE_ENABLE }; - select(); + select_on_bus(); ret = board_spi_write(wbuf, sizeof(wbuf)); deselect(); @@ -305,7 +305,7 @@ ext_flash_read(size_t offset, size_t length, uint8_t *buf) wbuf[2] = (offset >> 8) & 0xff; wbuf[3] = offset & 0xff; - select(); + select_on_bus(); if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ @@ -357,7 +357,7 @@ ext_flash_write(size_t offset, size_t length, const uint8_t *buf) * is not imposed here since above instructions * should be enough to delay * as much. */ - select(); + select_on_bus(); if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ @@ -411,7 +411,7 @@ ext_flash_erase(size_t offset, size_t length) wbuf[2] = (offset >> 8) & 0xff; wbuf[3] = offset & 0xff; - select(); + select_on_bus(); if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ diff --git a/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c index 86047bb14..7d903e18b 100644 --- a/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c +++ b/platform/srf06-cc26xx/sensortag/opt-3001-sensor.c @@ -132,7 +132,7 @@ static struct ctimer startup_timer; * \brief Select the sensor on the I2C bus */ static void -select(void) +select_on_bus(void) { /* Select slave and set clock rate */ board_i2c_select(BOARD_I2C_INTERFACE_0, OPT3001_I2C_ADDRESS); @@ -148,7 +148,7 @@ notify_ready(void *not_used) */ uint16_t val; - select(); + select_on_bus(); sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH); @@ -170,7 +170,7 @@ enable_sensor(bool enable) uint16_t val; uint16_t had_data_ready = state & SENSOR_STATE_DATA_READY; - select(); + select_on_bus(); if(enable) { val = CONFIG_ENABLE_SINGLE_SHOT; @@ -202,7 +202,7 @@ read_data(uint16_t *raw_data) return false; } - select(); + select_on_bus(); success = sensor_common_read_reg(REG_CONFIGURATION, (uint8_t *)&val, REGISTER_LENGTH); From b1c3941863fec7ae7bcee81362a73720fd5b1f7a Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 15:59:47 +0000 Subject: [PATCH 36/94] Compile-test the CC2650 Sensortag and Srf06+CC1310EM code --- regression-tests/18-compile-arm-ports/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 16e24bd80..c314e8360 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -8,6 +8,9 @@ webserver-ipv6/ev-aducrf101mkxz \ ipv6/multicast/ev-aducrf101mkxz \ cc2538dk/sniffer/ev-aducrf101mkxz \ cc26xx/cc26xx-web-demo/srf06-cc26xx \ +cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ +cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=srf06/cc13xx \ cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ From 0d0e44036b32a82e6280c4da9bd676e32be497f7 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 10 Jan 2016 16:07:38 +0000 Subject: [PATCH 37/94] Change travis arm tests to use gcc-arm-embedded v5 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7a9affd3c..1814ee6fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,9 +44,9 @@ before_script: ## in Ubuntu >= 14.04, but this external PPA is needed for 12.04. ## Install srecord - if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then - sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded && + sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa && sudo apt-get -qq update && - sudo apt-get -qq install gcc-arm-none-eabi srecord && + sudo apt-get -qq install gcc-arm-embedded srecord && arm-none-eabi-gcc --version ; fi From 564c3a9d28a290721d677236c99f1460b145767e Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 21:37:03 +0100 Subject: [PATCH 38/94] Fixed pressure calculation as previous temperature compensation was missing --- platform/zoul/dev/bmp085.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/platform/zoul/dev/bmp085.c b/platform/zoul/dev/bmp085.c index 6127715b5..4fed7f496 100644 --- a/platform/zoul/dev/bmp085.c +++ b/platform/zoul/dev/bmp085.c @@ -73,6 +73,7 @@ typedef struct { typedef struct { uint8_t oversampling_mode; + int32_t b5; bmp085_calibration_values calib; } bmp085_config; @@ -201,7 +202,7 @@ static int bmp085_read_temperature(int16_t *temp) { int32_t ut = 0; - int32_t x1, x2, b5; + int32_t x1, x2; if(bmp085_read_uncompensated_temperature(&ut) == BMP085_ERROR) { return BMP085_ERROR; @@ -210,8 +211,8 @@ bmp085_read_temperature(int16_t *temp) x1 = ((int32_t)ut - (int32_t)bmp085_values.calib.ac6) * (int32_t)bmp085_values.calib.ac5 >> 15; x2 = ((int32_t)bmp085_values.calib.mc << 11) / (x1 + bmp085_values.calib.md); - b5 = x1 + x2; - *temp = (int16_t)((b5 + 8) >> 4); + bmp085_values.b5 = x1 + x2; + *temp = (int16_t)((bmp085_values.b5 + 8) >> 4); return BMP085_SUCCESS; } /*---------------------------------------------------------------------------*/ @@ -220,7 +221,7 @@ bmp085_read_pressure(int32_t *pressure) { int32_t ut = 0; int32_t up = 0; - int32_t x1, x2, b5, b6, x3, b3, p; + int32_t x1, x2, b6, x3, b3, p; uint32_t b4, b7; if(bmp085_read_uncompensated_pressure(&up) == BMP085_ERROR) { @@ -231,7 +232,7 @@ bmp085_read_pressure(int32_t *pressure) return BMP085_ERROR; } - b6 = b5 - 4000; + b6 = bmp085_values.b5 - 4000; x1 = (bmp085_values.calib.b2 * (b6 * b6 >> 12)) >> 11; x2 = bmp085_values.calib.ac2 * b6 >> 11; x3 = x1 + x2; @@ -312,11 +313,20 @@ status(int type) static int bmp085_read_sensor(int32_t *value, uint8_t type) { + int16_t temp = 0; + + /* The temperature is required to compensate the pressure value */ + if(bmp085_read_temperature(&temp) != BMP085_SUCCESS) { + return BMP085_ERROR; + } + switch(type) { case BMP085_READ_PRESSURE: return bmp085_read_pressure(value); + case BMP085_READ_TEMP: - return bmp085_read_temperature((int16_t *)value); + *value = (int16_t) temp; + return BMP085_SUCCESS; } return BMP085_ERROR; From 97a7e98ac57af272793a0472d0d3e2c5db16806e Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 19:37:48 +0100 Subject: [PATCH 39/94] Fixed SHT25 sensor --- platform/zoul/dev/sht25.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/platform/zoul/dev/sht25.c b/platform/zoul/dev/sht25.c index 0ad7c31f6..df12e7f55 100644 --- a/platform/zoul/dev/sht25.c +++ b/platform/zoul/dev/sht25.c @@ -46,20 +46,30 @@ #include "dev/sht25.h" #include "lib/sensors.h" /*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ static uint8_t enabled; /*---------------------------------------------------------------------------*/ static int configure(int type, int value) { if(type != SENSORS_ACTIVE) { + PRINTF("SHT25: option not supported\n"); return SHT25_ERROR; } + if(value) { i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); } + enabled = value; - return 0; + return SHT25_SUCCESS; } /*---------------------------------------------------------------------------*/ static int @@ -76,6 +86,7 @@ status(int type) static uint16_t sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) { + i2c_master_enable(); if(i2c_single_send(SHT25_ADDR, reg) == I2C_MASTER_ERR_NONE) { if(i2c_burst_receive(SHT25_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { return SHT25_SUCCESS; @@ -110,6 +121,7 @@ sht25_read(uint8_t variable, uint16_t *rd) uint16_t raw; if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) { + PRINTF("SHT25: invalid sensor requested\n"); return SHT25_ERROR; } @@ -118,6 +130,8 @@ sht25_read(uint8_t variable, uint16_t *rd) *rd = sht25_convert(variable, raw); return SHT25_SUCCESS; } + + PRINTF("SHT25: failed to read sensor\n"); return SHT25_ERROR; } /*---------------------------------------------------------------------------*/ @@ -125,6 +139,12 @@ static int value(int type) { uint16_t val; + + if(!enabled) { + PRINTF("SHT25: sensor not started\n"); + return SHT25_ERROR; + } + if(sht25_read(type, &val) == SHT25_SUCCESS) { return val; } From d53a62187d1498e837475ec1c4e77db2fa825da8 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 21:10:40 +0100 Subject: [PATCH 40/94] Added extra features of the SHT25 sensor --- examples/zolertia/zoul/test-sht25.c | 20 ++++- platform/zoul/dev/sht25.c | 134 +++++++++++++++++++++++----- platform/zoul/dev/sht25.h | 59 ++++++------ 3 files changed, 162 insertions(+), 51 deletions(-) diff --git a/examples/zolertia/zoul/test-sht25.c b/examples/zolertia/zoul/test-sht25.c index bb403f61c..a2e264220 100644 --- a/examples/zolertia/zoul/test-sht25.c +++ b/examples/zolertia/zoul/test-sht25.c @@ -60,13 +60,29 @@ PROCESS_THREAD(remote_sht25_process, ev, data) PROCESS_BEGIN(); SENSORS_ACTIVATE(sht25); + /* Check if the sensor voltage operation is over 2.25V */ + if(sht25.value(SHT25_VOLTAGE_ALARM)) { + printf("Voltage is lower than recommended for the sensor operation\n"); + PROCESS_EXIT(); + } + + /* Configure the sensor for maximum resolution (14-bit temperature, 12-bit + * relative humidity), this will require up to 85ms for the temperature + * integration, and 29ms for the relative humidity (this is the default + * setting at power on). To achieve a faster integration time at the cost + * of a lower resolution, change the value below accordingly, see sht25.h. + */ + sht25.configure(SHT25_RESOLUTION, SHT2X_RES_14T_12RH); + + /* Let it spin and read sensor data */ + while(1) { etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); temperature = sht25.value(SHT25_VAL_TEMP); - printf("Temperature %d.%d ºC\n", temperature / 100, temperature % 100); + printf("Temperature %02d.%02d ºC, ", temperature / 100, temperature % 100); humidity = sht25.value(SHT25_VAL_HUM); - printf("Humidity %d.%d RH\n", humidity / 100, humidity % 100); + printf("Humidity %02d.%02d RH\n", humidity / 100, humidity % 100); } PROCESS_END(); } diff --git a/platform/zoul/dev/sht25.c b/platform/zoul/dev/sht25.c index df12e7f55..f46c42c89 100644 --- a/platform/zoul/dev/sht25.c +++ b/platform/zoul/dev/sht25.c @@ -46,7 +46,7 @@ #include "dev/sht25.h" #include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 0 +#define DEBUG 1 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -54,23 +54,7 @@ #endif /*---------------------------------------------------------------------------*/ static uint8_t enabled; -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int value) -{ - if(type != SENSORS_ACTIVE) { - PRINTF("SHT25: option not supported\n"); - return SHT25_ERROR; - } - - if(value) { - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); - } - - enabled = value; - return SHT25_SUCCESS; -} +static uint8_t user_reg; /*---------------------------------------------------------------------------*/ static int status(int type) @@ -84,11 +68,15 @@ status(int type) } /*---------------------------------------------------------------------------*/ static uint16_t -sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) +sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) { + if((buf == NULL) || (num <= 0)) { + return SHT25_ERROR; + } + i2c_master_enable(); if(i2c_single_send(SHT25_ADDR, reg) == I2C_MASTER_ERR_NONE) { - if(i2c_burst_receive(SHT25_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { return SHT25_SUCCESS; } } @@ -100,7 +88,10 @@ sht25_convert(uint8_t variable, uint16_t value) { int16_t rd; uint32_t buff; - buff = (uint32_t)value; + + /* Clear the status bits */ + buff = (uint32_t)(value & ~SHT25_STATUS_BITS_MASK); + if(variable == SHT25_VAL_TEMP) { buff *= 17572; buff = buff >> 16; @@ -114,7 +105,7 @@ sht25_convert(uint8_t variable, uint16_t value) return rd; } /*---------------------------------------------------------------------------*/ -static int16_t +static int sht25_read(uint8_t variable, uint16_t *rd) { uint8_t buf[2]; @@ -136,6 +127,32 @@ sht25_read(uint8_t variable, uint16_t *rd) } /*---------------------------------------------------------------------------*/ static int +sht25_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("SHT25: invalid write values\n"); + return SHT25_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return SHT25_SUCCESS; + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +sht25_read_user_register(void) +{ + if(sht25_read_reg(SHT2X_UREG_READ, &user_reg, 1) == SHT25_SUCCESS) { + PRINTF("SHT25: user register 0x%02X\n", user_reg); + return SHT25_SUCCESS; + } + PRINTF("SHT25: failed to read user register\n"); + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int value(int type) { uint16_t val; @@ -145,9 +162,78 @@ value(int type) return SHT25_ERROR; } - if(sht25_read(type, &val) == SHT25_SUCCESS) { - return val; + if((type != SHT25_VAL_TEMP) && (type != SHT25_VAL_HUM) && + (type != SHT25_VOLTAGE_ALARM)) { + PRINTF("SHT25: invalid value requested\n"); + return SHT25_ERROR; } + + if(type == SHT25_VOLTAGE_ALARM) { + if(sht25_read_user_register() == SHT25_SUCCESS) { + return ((user_reg & SHT2x_LOW_VOLTAGE_MASK) >> SHT2x_LOW_VOLTAGE_SHIFT); + } + } else { + if(sht25_read(type, &val) == SHT25_SUCCESS) { + return val; + } + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + uint8_t buf[2]; + + if((type != SHT25_ACTIVE) && (type != SHT25_SOFT_RESET) && + (type != SHT25_RESOLUTION)) { + PRINTF("SHT25: option not supported\n"); + return SHT25_ERROR; + } + + switch(type) { + case SHT25_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + /* Read the user config register */ + if(sht25_read_user_register() == SHT25_SUCCESS) { + enabled = value; + return SHT25_SUCCESS; + } + } + + case SHT25_SOFT_RESET: + buf[0] = SHT2X_SOFT_RESET; + if(sht25_write_reg(&buf[0], 1) != SHT25_SUCCESS) { + PRINTF("SHT25: failed to reset the sensor\n"); + return SHT25_ERROR; + } + clock_delay_usec(SHT25_RESET_DELAY); + return SHT25_SUCCESS; + + case SHT25_RESOLUTION: + if((value != SHT2X_RES_14T_12RH) && (value != SHT2X_RES_12T_08RH) && + (value != SHT2X_RES_13T_10RH) && (value != SHT2X_RES_11T_11RH)) { + PRINTF("SHT25: invalid resolution value\n"); + return SHT25_ERROR; + } + + user_reg &= ~SHT2X_RES_11T_11RH; + user_reg |= value; + buf[0] = SHT2X_UREG_WRITE; + buf[1] = user_reg; + + if(sht25_write_reg(buf, 2) == SHT25_SUCCESS) { + PRINTF("SHT25: new user register value 0x%02X\n", user_reg); + return SHT25_SUCCESS; + } + + default: + return SHT25_ERROR; + } + return SHT25_ERROR; } /*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/dev/sht25.h b/platform/zoul/dev/sht25.h index df7dbcc77..602dd1331 100644 --- a/platform/zoul/dev/sht25.h +++ b/platform/zoul/dev/sht25.h @@ -44,34 +44,43 @@ */ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" - +/* -------------------------------------------------------------------------- */ #ifndef SHT25_H_ #define SHT25_H_ +/* -------------------------------------------------------------------------- */ +#define SHT25_ADDR 0x40 +#define SHT25_TEMP_HOLD 0xE3 +#define SHT25_HUM_HOLD 0xE5 +#define SHT25_TEMP_NO_HOLD 0xF3 +#define SHT25_HUM_NO_HOLD 0xF5 +#define SHT2X_UREG_WRITE 0xE6 +#define SHT2X_UREG_READ 0xE7 +#define SHT2X_SOFT_RESET 0XFE +#define SHT2X_NULL 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT2X_RES_14T_12RH 0x00 +#define SHT2X_RES_12T_08RH 0x01 +#define SHT2X_RES_13T_10RH 0x80 +#define SHT2X_RES_11T_11RH 0x81 +#define SHT2X_HEATER_ON 0x04 +#define SHT2X_HEATER_OFF 0x00 +#define SHT2X_OTP_RELOAD_EN 0x00 +#define SHT2X_OTP_RELOAD_DIS 0x02 +#define SHT2x_LOW_VOLTAGE_MASK 0x40 +#define SHT2x_LOW_VOLTAGE_SHIFT 0x06 +/* -------------------------------------------------------------------------- */ +#define SHT25_ACTIVE SENSORS_ACTIVE +#define SHT25_SOFT_RESET 0x01 +#define SHT25_RESOLUTION 0x02 -/* -------------------------------------------------------------------------- */ -#define SHT25_ADDR 0x40 -#define SHT25_TEMP_HOLD 0xE3 -#define SHT25_HUM_HOLD 0xE5 -#define SHT25_TEMP_NO_HOLD 0xF3 -#define SHT25_HUM_NO_HOLD 0xF5 -#define SHT2X_UREG_WRITE 0xE6 -#define SHT2X_UREG_READ 0xE7 -#define SHT2X_SOFT_RESET 0XFE -#define SHT2X_NULL 0x00 -/* -------------------------------------------------------------------------- */ -#define SHT2X_RES_14T_12RH 0x00 -#define SHT2X_RES_12T_08RH 0x01 -#define SHT2X_RES_13T_10RH 0x80 -#define SHT2X_RES_11T_11RH 0x81 -#define SHT2X_HEATER_ON 0x04 -#define SHT2X_HEATER_OFF 0x00 -#define SHT2X_OTP_RELOAD_EN 0x00 -#define SHT2X_OTP_RELOAD_DIS 0x02 -/* -------------------------------------------------------------------------- */ -#define SHT25_VAL_TEMP SHT25_TEMP_HOLD -#define SHT25_VAL_HUM SHT25_HUM_HOLD -#define SHT25_ERROR -1 -#define SHT25_SUCCESS 0x00 +#define SHT25_VAL_TEMP SHT25_TEMP_HOLD +#define SHT25_VAL_HUM SHT25_HUM_HOLD +#define SHT25_VOLTAGE_ALARM 0x01 + +#define SHT25_ERROR (-1) +#define SHT25_SUCCESS 0x00 +#define SHT25_RESET_DELAY 15000 +#define SHT25_STATUS_BITS_MASK 0x0003 /* -------------------------------------------------------------------------- */ #define SHT25_SENSOR "SHT25 Sensor" /* -------------------------------------------------------------------------- */ From 48eb2a4fe2dca93a6f27bc909dc3bb50a8c0b9c6 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 10 Jan 2016 23:36:00 +0100 Subject: [PATCH 41/94] Uncrustify changes --- examples/zolertia/zoul/test-sht25.c | 2 +- platform/zoul/dev/sht25.c | 76 ++++++++++++++--------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/examples/zolertia/zoul/test-sht25.c b/examples/zolertia/zoul/test-sht25.c index a2e264220..ea853c30b 100644 --- a/examples/zolertia/zoul/test-sht25.c +++ b/examples/zolertia/zoul/test-sht25.c @@ -62,7 +62,7 @@ PROCESS_THREAD(remote_sht25_process, ev, data) /* Check if the sensor voltage operation is over 2.25V */ if(sht25.value(SHT25_VOLTAGE_ALARM)) { - printf("Voltage is lower than recommended for the sensor operation\n"); + printf("Voltage is lower than recommended for the sensor operation\n"); PROCESS_EXIT(); } diff --git a/platform/zoul/dev/sht25.c b/platform/zoul/dev/sht25.c index f46c42c89..38a8be12e 100644 --- a/platform/zoul/dev/sht25.c +++ b/platform/zoul/dev/sht25.c @@ -163,14 +163,14 @@ value(int type) } if((type != SHT25_VAL_TEMP) && (type != SHT25_VAL_HUM) && - (type != SHT25_VOLTAGE_ALARM)) { + (type != SHT25_VOLTAGE_ALARM)) { PRINTF("SHT25: invalid value requested\n"); return SHT25_ERROR; } if(type == SHT25_VOLTAGE_ALARM) { if(sht25_read_user_register() == SHT25_SUCCESS) { - return ((user_reg & SHT2x_LOW_VOLTAGE_MASK) >> SHT2x_LOW_VOLTAGE_SHIFT); + return (user_reg & SHT2x_LOW_VOLTAGE_MASK) >> SHT2x_LOW_VOLTAGE_SHIFT; } } else { if(sht25_read(type, &val) == SHT25_SUCCESS) { @@ -186,52 +186,52 @@ configure(int type, int value) uint8_t buf[2]; if((type != SHT25_ACTIVE) && (type != SHT25_SOFT_RESET) && - (type != SHT25_RESOLUTION)) { + (type != SHT25_RESOLUTION)) { PRINTF("SHT25: option not supported\n"); return SHT25_ERROR; } switch(type) { - case SHT25_ACTIVE: - if(value) { - i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, - I2C_SCL_NORMAL_BUS_SPEED); + case SHT25_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); - /* Read the user config register */ - if(sht25_read_user_register() == SHT25_SUCCESS) { - enabled = value; - return SHT25_SUCCESS; - } - } - - case SHT25_SOFT_RESET: - buf[0] = SHT2X_SOFT_RESET; - if(sht25_write_reg(&buf[0], 1) != SHT25_SUCCESS) { - PRINTF("SHT25: failed to reset the sensor\n"); - return SHT25_ERROR; - } - clock_delay_usec(SHT25_RESET_DELAY); - return SHT25_SUCCESS; - - case SHT25_RESOLUTION: - if((value != SHT2X_RES_14T_12RH) && (value != SHT2X_RES_12T_08RH) && - (value != SHT2X_RES_13T_10RH) && (value != SHT2X_RES_11T_11RH)) { - PRINTF("SHT25: invalid resolution value\n"); - return SHT25_ERROR; - } - - user_reg &= ~SHT2X_RES_11T_11RH; - user_reg |= value; - buf[0] = SHT2X_UREG_WRITE; - buf[1] = user_reg; - - if(sht25_write_reg(buf, 2) == SHT25_SUCCESS) { - PRINTF("SHT25: new user register value 0x%02X\n", user_reg); + /* Read the user config register */ + if(sht25_read_user_register() == SHT25_SUCCESS) { + enabled = value; return SHT25_SUCCESS; } + } - default: + case SHT25_SOFT_RESET: + buf[0] = SHT2X_SOFT_RESET; + if(sht25_write_reg(&buf[0], 1) != SHT25_SUCCESS) { + PRINTF("SHT25: failed to reset the sensor\n"); return SHT25_ERROR; + } + clock_delay_usec(SHT25_RESET_DELAY); + return SHT25_SUCCESS; + + case SHT25_RESOLUTION: + if((value != SHT2X_RES_14T_12RH) && (value != SHT2X_RES_12T_08RH) && + (value != SHT2X_RES_13T_10RH) && (value != SHT2X_RES_11T_11RH)) { + PRINTF("SHT25: invalid resolution value\n"); + return SHT25_ERROR; + } + + user_reg &= ~SHT2X_RES_11T_11RH; + user_reg |= value; + buf[0] = SHT2X_UREG_WRITE; + buf[1] = user_reg; + + if(sht25_write_reg(buf, 2) == SHT25_SUCCESS) { + PRINTF("SHT25: new user register value 0x%02X\n", user_reg); + return SHT25_SUCCESS; + } + + default: + return SHT25_ERROR; } return SHT25_ERROR; From fefb84596e944c75fc6886773a154ec5ccca8ae5 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 11 Jan 2016 17:21:23 +0100 Subject: [PATCH 42/94] Fixed filter value preventing from initializing the ADC --- platform/zoul/dev/adc-sensors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 31e81efed..848af9dae 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -87,7 +87,7 @@ * platforms, the following assumes PA0 shall not be used as ADC input, else * re-write the below definitions */ -#define ZOUL_SENSORS_ADC_MIN 4 +#define ZOUL_SENSORS_ADC_MIN 2 /* ADC phidget-like connector ADC1 */ #if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN #define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) From c644a32dc7a9a07ba5fd2d0152a4c74ba3f3954b Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 11 Jan 2016 18:28:20 +0100 Subject: [PATCH 43/94] Added support for digital presence/motion sensors --- examples/zolertia/zoul/Makefile | 4 +- examples/zolertia/zoul/project-conf.h | 7 ++ examples/zolertia/zoul/test-motion.c | 102 ++++++++++++++++++++ platform/zoul/dev/motion-sensor.c | 128 ++++++++++++++++++++++++++ platform/zoul/dev/motion-sensor.h | 76 +++++++++++++++ 5 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 examples/zolertia/zoul/test-motion.c create mode 100644 platform/zoul/dev/motion-sensor.c create mode 100644 platform/zoul/dev/motion-sensor.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 03dd8103a..dcda7321d 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,7 +1,7 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -CONTIKI_PROJECT += test-bmp085 -CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c +CONTIKI_PROJECT += test-bmp085 test-motion +CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/project-conf.h b/examples/zolertia/zoul/project-conf.h index 126ea1058..230724b2d 100644 --- a/examples/zolertia/zoul/project-conf.h +++ b/examples/zolertia/zoul/project-conf.h @@ -41,6 +41,13 @@ #define BROADCAST_CHANNEL 129 #define NETSTACK_CONF_RDC nullrdc_driver +/* Pin definition for the test-motion example, for the RE-Mote it uses the + * ADC1 pin + */ +#define MOTION_SENSOR_PORT GPIO_A_NUM +#define MOTION_SENSOR_PIN 5 +#define MOTION_SENSOR_VECTOR NVIC_INT_GPIO_PORT_A + #endif /* PROJECT_CONF_H_ */ /** @} */ diff --git a/examples/zolertia/zoul/test-motion.c b/examples/zolertia/zoul/test-motion.c new file mode 100644 index 000000000..b5c9c3f59 --- /dev/null +++ b/examples/zolertia/zoul/test-motion.c @@ -0,0 +1,102 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-motion-test Digital motion sensor test + * + * The example application shows how to use any digital motion sensor, basically + * driving a signal high when motion is detected. + * + * @{ + * + * \file + * Test application for the digital motion/presence sensor + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/motion-sensor.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define LEDS_OFF_HYSTERISIS RTIMER_SECOND +/*---------------------------------------------------------------------------*/ +static struct rtimer rt; +/*---------------------------------------------------------------------------*/ +PROCESS(test_presence_sensor, "Test digital motion sensor"); +AUTOSTART_PROCESSES(&test_presence_sensor); +/*---------------------------------------------------------------------------*/ +void +rt_callback(struct rtimer *t, void *ptr) +{ + leds_off(LEDS_RED); +} +/*---------------------------------------------------------------------------*/ +static void +presence_callback(uint8_t value) +{ + printf("*** Presence detected!\n"); + leds_on(LEDS_RED); + rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_presence_sensor, ev, data) +{ + PROCESS_BEGIN(); + + /* Register the callback handler when presence is detected */ + MOTION_REGISTER_INT(presence_callback); + + /* Enable the sensor, as default it assumes the signal pin has a pull-down + * resistor and a rising interrupt (signal goes high when motion is detected), + * this is the case of the Grove's PIR sensor v.1.0. If the sensor has an + * inverse logic, change at the motion-sensor.c driver file + * GPIO_DETECT_FALLING instead of GPIO_DETECT_RISING if using an external + * pull-up resistor + */ + SENSORS_ACTIVATE(motion_sensor); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/zoul/dev/motion-sensor.c b/platform/zoul/dev/motion-sensor.c new file mode 100644 index 000000000..eb685d27a --- /dev/null +++ b/platform/zoul/dev/motion-sensor.c @@ -0,0 +1,128 @@ +/* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-motion-sensor + * @{ + * + * \file + * Digital motion sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/motion-sensor.h" +#include "lib/sensors.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define MOTION_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(MOTION_SENSOR_PORT) +#define MOTION_SENSOR_PIN_MASK GPIO_PIN_MASK(MOTION_SENSOR_PIN) +/*---------------------------------------------------------------------------*/ +void (*presence_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +PROCESS(motion_int_process, "Motion interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(motion_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + presence_int_callback(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +motion_interrupt_handler(uint8_t port, uint8_t pin) +{ + process_poll(&motion_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return MOTION_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return GPIO_READ_PIN(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != MOTION_ACTIVE) { + PRINTF("Motion: invalid configuration option\n"); + return MOTION_ERROR; + } + + if(!value) { + presence_int_callback = NULL; + GPIO_DISABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + return MOTION_SUCCESS; + } + + /* Configure interruption */ + GPIO_SOFTWARE_CONTROL(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_SET_INPUT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + ioc_set_over(MOTION_SENSOR_PORT, MOTION_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(motion_interrupt_handler, MOTION_SENSOR_PORT, + MOTION_SENSOR_PIN); + + process_start(&motion_int_process, NULL); + + GPIO_ENABLE_INTERRUPT(MOTION_SENSOR_PORT_BASE, MOTION_SENSOR_PIN_MASK); + nvic_interrupt_enable(MOTION_SENSOR_VECTOR); + return MOTION_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(motion_sensor, MOTION_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/motion-sensor.h b/platform/zoul/dev/motion-sensor.h new file mode 100644 index 000000000..ce712cbde --- /dev/null +++ b/platform/zoul/dev/motion-sensor.h @@ -0,0 +1,76 @@ +/* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-motion-sensor Digital motion sensor + * @{ + * + * \file + * Digital motion sensor header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef SHT25_H_ +#define SHT25_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Motion sensor return and operation values + * @{ + */ +#define MOTION_ACTIVE SENSORS_ACTIVE +#define MOTION_SUCCESS 0 +#define MOTION_ERROR (-1) +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Motion sensor interrupt callback macro + * @{ + */ +#define MOTION_REGISTER_INT(ptr) presence_int_callback = ptr; +extern void (*presence_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +#define MOTION_SENSOR "Digital motion sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor motion_sensor; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef MOTION_SENSOR_H_ */ +/** + * @} + * @} + */ From c03b05c702c0f18b9cd0076315db6026bd99f338 Mon Sep 17 00:00:00 2001 From: Michael Klemm Date: Sat, 16 Jan 2016 12:25:42 +0100 Subject: [PATCH 44/94] Fixed loading SerialSocketServer plugin in Cooja using FQDN --- examples/er-rest-example/server-client-native.csc | 2 +- examples/er-rest-example/server-client.csc | 2 +- examples/er-rest-example/server-only.csc | 2 +- examples/ipv6/sky-websense/example-sky-websense.csc | 2 +- examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc | 2 +- regression-tests/13-ipv6-apps/x02-sky-coap.csc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/er-rest-example/server-client-native.csc b/examples/er-rest-example/server-client-native.csc index 2bc180592..12162c689 100644 --- a/examples/er-rest-example/server-client-native.csc +++ b/examples/er-rest-example/server-client-native.csc @@ -219,7 +219,7 @@ 182 - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 422 1 diff --git a/examples/er-rest-example/server-client.csc b/examples/er-rest-example/server-client.csc index 802a40cc0..adc621a39 100644 --- a/examples/er-rest-example/server-client.csc +++ b/examples/er-rest-example/server-client.csc @@ -188,7 +188,7 @@ true - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 422 4 diff --git a/examples/er-rest-example/server-only.csc b/examples/er-rest-example/server-only.csc index 0557a29f9..9bbea40bd 100644 --- a/examples/er-rest-example/server-only.csc +++ b/examples/er-rest-example/server-only.csc @@ -151,7 +151,7 @@ true - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 422 4 diff --git a/examples/ipv6/sky-websense/example-sky-websense.csc b/examples/ipv6/sky-websense/example-sky-websense.csc index f088c5386..f226357e1 100644 --- a/examples/ipv6/sky-websense/example-sky-websense.csc +++ b/examples/ipv6/sky-websense/example-sky-websense.csc @@ -196,7 +196,7 @@ -1 - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 422 1 diff --git a/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc b/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc index f088c5386..f226357e1 100644 --- a/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc +++ b/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc @@ -196,7 +196,7 @@ -1 - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 422 1 diff --git a/regression-tests/13-ipv6-apps/x02-sky-coap.csc b/regression-tests/13-ipv6-apps/x02-sky-coap.csc index a1b5c27d3..ad3155f3d 100644 --- a/regression-tests/13-ipv6-apps/x02-sky-coap.csc +++ b/regression-tests/13-ipv6-apps/x02-sky-coap.csc @@ -141,7 +141,7 @@ true - SerialSocketServer + org.contikios.cooja.serialsocket.SerialSocketServer 0 428 4 From ac07e848b72be1a225cc1784e0ff20dfbe13458c Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 21:52:34 +0100 Subject: [PATCH 45/94] Minor fixes to file descriptions and disable DEBUG switches --- examples/zolertia/zoul/test-bmp085.c | 2 +- examples/zolertia/zoul/test-tsl2563.c | 2 +- platform/zoul/dev/bmp085.c | 4 ++-- platform/zoul/dev/motion-sensor.c | 2 +- platform/zoul/dev/motion-sensor.h | 4 ++-- platform/zoul/dev/sht25.c | 2 +- platform/zoul/dev/sht25.h | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/zolertia/zoul/test-bmp085.c b/examples/zolertia/zoul/test-bmp085.c index 4f19fd993..6fcabedf8 100644 --- a/examples/zolertia/zoul/test-bmp085.c +++ b/examples/zolertia/zoul/test-bmp085.c @@ -38,7 +38,7 @@ * @{ * * \file - * Driver for the external BMP085 digital pressure and temperature sensor + * Test file for the BMP085 digital pressure and temperature sensor * * \author * Antonio Lignan diff --git a/examples/zolertia/zoul/test-tsl2563.c b/examples/zolertia/zoul/test-tsl2563.c index b80a76eaf..b6296b3e5 100644 --- a/examples/zolertia/zoul/test-tsl2563.c +++ b/examples/zolertia/zoul/test-tsl2563.c @@ -38,7 +38,7 @@ * @{ * * \file - * Driver for the external TSL2563 light sensor + * Test file for the external TSL2563 light sensor * * \author * Antonio Lignan diff --git a/platform/zoul/dev/bmp085.c b/platform/zoul/dev/bmp085.c index 4fed7f496..f7c8da82f 100644 --- a/platform/zoul/dev/bmp085.c +++ b/platform/zoul/dev/bmp085.c @@ -32,7 +32,7 @@ * \addtogroup zoul-bmp085-sensor * @{ * - * BMP085 driver implementation, calculations taken from Inga sensor driver + * BMP085 driver implementation * * \file * Driver for the external BMP085 light sensor @@ -48,7 +48,7 @@ #include "lib/sensors.h" #include "bmp085.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else diff --git a/platform/zoul/dev/motion-sensor.c b/platform/zoul/dev/motion-sensor.c index eb685d27a..178267edf 100644 --- a/platform/zoul/dev/motion-sensor.c +++ b/platform/zoul/dev/motion-sensor.c @@ -49,7 +49,7 @@ #include "dev/gpio.h" #include "dev/ioc.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else diff --git a/platform/zoul/dev/motion-sensor.h b/platform/zoul/dev/motion-sensor.h index ce712cbde..c52597a24 100644 --- a/platform/zoul/dev/motion-sensor.h +++ b/platform/zoul/dev/motion-sensor.h @@ -45,8 +45,8 @@ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" /* -------------------------------------------------------------------------- */ -#ifndef SHT25_H_ -#define SHT25_H_ +#ifndef MOTION_SENSOR_H_ +#define MOTION_SENSOR_H_ /* -------------------------------------------------------------------------- */ /** * \name Motion sensor return and operation values diff --git a/platform/zoul/dev/sht25.c b/platform/zoul/dev/sht25.c index 38a8be12e..6273ae0c0 100644 --- a/platform/zoul/dev/sht25.c +++ b/platform/zoul/dev/sht25.c @@ -46,7 +46,7 @@ #include "dev/sht25.h" #include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else diff --git a/platform/zoul/dev/sht25.h b/platform/zoul/dev/sht25.h index 602dd1331..11d5c61a8 100644 --- a/platform/zoul/dev/sht25.h +++ b/platform/zoul/dev/sht25.h @@ -38,7 +38,7 @@ * @{ * * \file - * SHT25 temperature and humidity sensor driver + * SHT25 temperature and humidity sensor driver header file * \author * Antonio Lignan */ From 503abb4415fbd538922051dadc4338bceab1ece3 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 12 Jan 2016 01:04:21 +0100 Subject: [PATCH 46/94] ADC wrapper for the Zoul-based platforms, allows to add analogue sensors over the existing adc interface --- examples/zolertia/zoul/Makefile | 4 +- .../zolertia/zoul/test-grove-light-sensor.c | 91 ++++++++ .../zoul/test-grove-loudness-sensor.c | 110 +++++++++ examples/zolertia/zoul/test-rotation-sensor.c | 110 +++++++++ examples/zolertia/zoul/zoul-demo.c | 1 + platform/zoul/dev/adc-sensors.c | 37 ++- platform/zoul/dev/adc-sensors.h | 34 ++- platform/zoul/dev/adc-wrapper.c | 215 ++++++++++++++++++ platform/zoul/dev/adc-wrapper.h | 85 +++++++ platform/zoul/dev/zoul-sensors.c | 3 +- platform/zoul/dev/zoul-sensors.h | 1 - platform/zoul/firefly/board.h | 3 + platform/zoul/remote/board.h | 3 + 13 files changed, 678 insertions(+), 19 deletions(-) create mode 100644 examples/zolertia/zoul/test-grove-light-sensor.c create mode 100644 examples/zolertia/zoul/test-grove-loudness-sensor.c create mode 100644 examples/zolertia/zoul/test-rotation-sensor.c create mode 100644 platform/zoul/dev/adc-wrapper.c create mode 100644 platform/zoul/dev/adc-wrapper.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index dcda7321d..8c1422549 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,7 +1,9 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -CONTIKI_PROJECT += test-bmp085 test-motion +CONTIKI_PROJECT += test-bmp085 test-motion test-rotation-sensor +CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c +CONTIKI_TARGET_SOURCEFILES += adc-wrapper.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-grove-light-sensor.c b/examples/zolertia/zoul/test-grove-light-sensor.c new file mode 100644 index 000000000..c81f7b931 --- /dev/null +++ b/examples/zolertia/zoul/test-grove-light-sensor.c @@ -0,0 +1,91 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-grove-light-sensor-test Grove's LDR sensor v.1.0 test + * + * Demonstrates the operation of the Grove's analog LDR + * @{ + * + * \file + * Grove's LDR sensor example using the ADC wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-wrapper.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_light_process, "Grove LDR test process"); +AUTOSTART_PROCESSES(&remote_grove_light_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_light_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t ldr; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_wrapper.configure(ANALOG_GROVE_LIGHT, 5); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + ldr = adc_wrapper.value(ANALOG_GROVE_LIGHT); + + if(ldr != ADC_WRAPPER_ERROR) { + printf("LDR (resistor) = %u\n", ldr); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-grove-loudness-sensor.c b/examples/zolertia/zoul/test-grove-loudness-sensor.c new file mode 100644 index 000000000..85907e3e3 --- /dev/null +++ b/examples/zolertia/zoul/test-grove-loudness-sensor.c @@ -0,0 +1,110 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-grove-loudness-sensor-test Grove's loudness sensor + * + * Demonstrates the operation of the Grove's analog loudness sensor + * @{ + * + * \file + * Grove's loudness sensor example using the ADC wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-wrapper.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_loudness_process, "Grove loudness test process"); +AUTOSTART_PROCESSES(&remote_grove_loudness_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_loudness_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t loudness; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_wrapper.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + loudness = adc_wrapper.value(ANALOG_GROVE_LOUDNESS); + + if(loudness != ADC_WRAPPER_ERROR) { + printf("%u\n", loudness); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + + if(loudness < 100) { + leds_off(LEDS_ALL); + } + + if((loudness >= 100) && (loudness < 500)) { + leds_on(LEDS_BLUE); + leds_off(LEDS_GREEN | LEDS_RED); + } + + if((loudness >= 500) && (loudness < 1000)) { + leds_on(LEDS_GREEN); + leds_off(LEDS_BLUE | LEDS_RED); + } + + if(loudness >= 1000) { + leds_on(LEDS_RED); + leds_off(LEDS_BLUE | LEDS_GREEN); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-rotation-sensor.c b/examples/zolertia/zoul/test-rotation-sensor.c new file mode 100644 index 000000000..220d86fca --- /dev/null +++ b/examples/zolertia/zoul/test-rotation-sensor.c @@ -0,0 +1,110 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-rotation-sensor-test Phidget 1109 rotation sensor example + * + * Demonstrates the operation of the analog phidget 1109 rotation sensor + * @{ + * + * \file + * Phidget analog rotation sensor example using the ADC wrapper + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-wrapper.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 5 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_rotation_process, "Phidget rotation test process"); +AUTOSTART_PROCESSES(&remote_rotation_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_rotation_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t rotation; + + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + adc_wrapper.configure(ANALOG_PHIDGET_ROTATION_1109, 5); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + rotation = adc_wrapper.value(ANALOG_PHIDGET_ROTATION_1109); + + if(rotation != ADC_WRAPPER_ERROR) { + printf("Rotation = %u\n", rotation); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + + if(rotation <= 45) { + leds_off(LEDS_ALL); + } + + if((rotation > 45) && (rotation < 150)) { + leds_on(LEDS_GREEN); + leds_off(LEDS_BLUE | LEDS_RED); + } + + if((rotation > 150) && (rotation < 250)) { + leds_on(LEDS_RED | LEDS_GREEN); + leds_off(LEDS_BLUE); + } + + if(rotation >= 250) { + leds_on(LEDS_RED); + leds_off(LEDS_BLUE | LEDS_GREEN); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/zoul-demo.c b/examples/zolertia/zoul/zoul-demo.c index ff31d5ef9..25e49235f 100644 --- a/examples/zolertia/zoul/zoul-demo.c +++ b/examples/zolertia/zoul/zoul-demo.c @@ -69,6 +69,7 @@ #include "dev/leds.h" #include "dev/uart.h" #include "dev/button-sensor.h" +#include "dev/adc-sensors.h" #include "dev/zoul-sensors.h" #include "dev/watchdog.h" #include "dev/serial-line.h" diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index 4c88ed92f..da1ca844d 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -45,9 +45,16 @@ #include "dev/adc.h" #include "adc-sensors.h" #include "zoul-sensors.h" - +#include #include /*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ static uint8_t decimation_rate; static uint8_t enabled_channels; /*---------------------------------------------------------------------------*/ @@ -80,6 +87,12 @@ get_channel_pin(int type) if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; } + if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; + } + if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; + } return ZOUL_SENSORS_ERROR; } /*---------------------------------------------------------------------------*/ @@ -90,16 +103,24 @@ value(int type) int16_t res; if(!(type & enabled_channels)) { + PRINTF("ADC: channel not enabled\n"); return ZOUL_SENSORS_ERROR; } channel = get_channel_pin(type); if(channel == ZOUL_SENSORS_ERROR) { + PRINTF("ADC: pin not active\n"); return ZOUL_SENSORS_ERROR; } - res = adc_get(channel, SOC_ADC_ADCCON_REF_AVDD5, decimation_rate); + res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); + + /* Only allow negative values if using differential input */ + if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { + res = 0; + } + return res; } /*---------------------------------------------------------------------------*/ @@ -111,12 +132,14 @@ configure(int type, int value) /* This should filter out disabled sensors as its value should be zero */ if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { + PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); return ZOUL_SENSORS_ERROR; } if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && - (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC12) && - (value != ZOUL_SENSORS_ADC13) && (value != ZOUL_SENSORS_ADC23)) { + (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && + (value != ZOUL_SENSORS_ADC5)) { + PRINTF("ADC: invalid adc pin mask\n"); return ZOUL_SENSORS_ERROR; } @@ -132,6 +155,12 @@ configure(int type, int value) if(value & ZOUL_SENSORS_ADC3) { ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); } + if(value & ZOUL_SENSORS_ADC4) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC5) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); + } adc_init(); set_decimation_rate(SOC_ADC_ADCCON_DIV_512); enabled_channels = value; diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 848af9dae..1a10c8d39 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -82,12 +82,19 @@ #define ADC_SENSORS "ADC sensors" #define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) +#ifdef ADC_SENSORS_CONF_REFERENCE +#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE +#else +#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 +#endif + /* * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia - * platforms, the following assumes PA0 shall not be used as ADC input, else + * platforms, the following assumes PA0-1 shall not be used as ADC input, else * re-write the below definitions */ -#define ZOUL_SENSORS_ADC_MIN 2 +#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ + /* ADC phidget-like connector ADC1 */ #if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN #define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) @@ -106,20 +113,25 @@ #else #define ZOUL_SENSORS_ADC3 0 #endif - +/* ADC phidget-like connector ADC4 */ +#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) +#else +#define ZOUL_SENSORS_ADC4 0 +#endif +/* ADC phidget-like connector ADC5 */ +#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) +#else +#define ZOUL_SENSORS_ADC5 0 +#endif /* * This is safe as the disabled sensors should have a zero value thus not * affecting the mask operations */ - -/* Enable all channels */ #define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ - ZOUL_SENSORS_ADC3) -/* Other allowed combinations */ -#define ZOUL_SENSORS_ADC12 (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2) -#define ZOUL_SENSORS_ADC13 (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC3) -#define ZOUL_SENSORS_ADC23 (ZOUL_SENSORS_ADC2 + ZOUL_SENSORS_ADC3) - + ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ + ZOUL_SENSORS_ADC5) /** @} */ /*---------------------------------------------------------------------------*/ extern const struct sensors_sensor adc_sensors; diff --git a/platform/zoul/dev/adc-wrapper.c b/platform/zoul/dev/adc-wrapper.c new file mode 100644 index 000000000..02cb5f77c --- /dev/null +++ b/platform/zoul/dev/adc-wrapper.c @@ -0,0 +1,215 @@ +/* + * 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 zoul-adc-wrapper + * @{ + * + * \file + * Generic driver for the Zoul ADC wrapper for analogue sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "adc-sensors.h" +#include "adc-wrapper.h" +#include "zoul-sensors.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +typedef struct { + int type; + uint8_t pin_mask; + uint8_t vdd3; +} adc_info_t; + +typedef struct { + uint8_t sensors_num; + uint8_t sensors_ports; + adc_info_t sensor[ADC_SENSORS_MAX]; +} adc_wrapper_t; + +static adc_wrapper_t sensors; +/*---------------------------------------------------------------------------*/ +static uint16_t +convert_to_value(uint8_t index) +{ + uint32_t value; + value = adc_sensors.value(sensors.sensor[index].pin_mask); + + if(value == ZOUL_SENSORS_ERROR) { + PRINTF("ADC wrapper: failed retrieving data\n"); + return ADC_WRAPPER_ERROR; + } + + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ + + if(!sensors.sensor[index].vdd3) { + value *= ADC_WRAPPER_EXTERNAL_VREF; + value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; + } + + switch(sensors.sensor[index].type) { + case ANALOG_GROVE_LIGHT: + /* Light dependant resistor (LDR) resistance value*/ + value = (10230 - (value * 10)) / value; + /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ + return (uint16_t)value; + + case ANALOG_GROVE_LOUDNESS: + /* Based on the LM2904 amplifier (blue version with potentiometer) */ + return (uint16_t)value; + + case ANALOG_PHIDGET_ROTATION_1109: + /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ + value *= 909; + value /= 100000; + return (uint16_t)value; + + default: + return ADC_WRAPPER_ERROR; + } + + return ADC_WRAPPER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +is_sensor_in_list(int type) +{ + uint8_t i; + + for(i = 0; i <= sensors.sensors_num; i++) { + if(sensors.sensor[i].type == type) { + return i + 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint8_t index; + uint16_t sensor_value; + + index = is_sensor_in_list(type); + + if(!index) { + PRINTF("ADC wrapper: sensor not registered\n"); + return ADC_WRAPPER_SUCCESS; + } + + /* Restore index value after the check */ + index -= 1; + sensor_value = convert_to_value(index); + + return sensor_value; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + uint8_t pin_mask = GPIO_PIN_MASK(value); + + if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && + (type != ANALOG_GROVE_LOUDNESS)) { + PRINTF("ADC wrapper: sensor not supported, check adc_wrapper.h header\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_num >= ADC_SENSORS_MAX) { + PRINTF("ADC wrapper: all adc channels available have been assigned\n"); + return ADC_WRAPPER_ERROR; + } + + if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { + PRINTF("ADC wrapper: invalid pin value, (PA0-PA1, PA3) are reserved\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_ports & pin_mask) { + PRINTF("ADC wrapper: a sensor has been already assigned to this pin\n"); + return ADC_WRAPPER_ERROR; + } + + switch(type) { + /* V+3.3 sensors */ + case ANALOG_GROVE_LIGHT: + case ANALOG_GROVE_LOUDNESS: + case ANALOG_PHIDGET_ROTATION_1109: + if(adc_sensors.configure(SENSORS_HW_INIT, pin_mask) == + ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 1; + break; + + default: + return ADC_WRAPPER_ERROR; + } + + PRINTF("ADC wrapper: type %u mask 0x%02X vdd3 %u\n", + sensors.sensor[sensors.sensors_num].type, + sensors.sensor[sensors.sensors_num].pin_mask, + sensors.sensor[sensors.sensors_num].vdd3); + + sensors.sensors_num++; + sensors.sensors_ports |= pin_mask; + + return ADC_WRAPPER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_wrapper, ADC_WRAPPER, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/adc-wrapper.h b/platform/zoul/dev/adc-wrapper.h new file mode 100644 index 000000000..5a9e63b19 --- /dev/null +++ b/platform/zoul/dev/adc-wrapper.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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-sensors + * @{ + * + * \defgroup zoul-adc-wrapper Zoul adc wrapper to use analogue sensors + * + * The ADC wrapper allows to use analogue sensors on top of the ADC interface, + * obscuring the ADC configuration and required calculations to obtain actual + * sensor values. The driver allows to reuse the adc-wrapper implementation and + * add sensors easily, without duplicating code, providing also a simplified + * interface and exposing the available ADC assigned channels by a given + * platform. + * + * To use a given sensor simply use: adc_wrapper.configure(SENSOR_NAME, pin_no), + * where pin_no is a given pin in the PA port, check out the board.h for more + * information on available pins. To read a value just use + * adc_wrapper.value(SENSOR_NAME), the expected result would be the sensor value + * already converted to the sensor variable type, check the adc-wrapper file + * for more information. + * + * @{ + * + * \file + * Header file for the Zoul ADC wrapper + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_WRAPPER_H_ +#define ADC_WRAPPER_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +#include "dev/adc-sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_WRAPPER_SUCCESS 0x00 +#define ADC_WRAPPER_ERROR (-1) +#define ADC_WRAPPER_EXTERNAL_VREF 5000 +#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 +/*---------------------------------------------------------------------------*/ +#define ANALOG_GROVE_LIGHT 0x01 +#define ANALOG_PHIDGET_ROTATION_1109 0x02 +#define ANALOG_GROVE_LOUDNESS 0x03 +/* -------------------------------------------------------------------------- */ +#define ADC_WRAPPER "ADC wrapper API" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor adc_wrapper; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_WRAPPER_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/zoul-sensors.c b/platform/zoul/dev/zoul-sensors.c index 52dac52c3..e6e02c258 100644 --- a/platform/zoul/dev/zoul-sensors.c +++ b/platform/zoul/dev/zoul-sensors.c @@ -43,12 +43,11 @@ #include "contiki.h" #include "dev/cc2538-sensors.h" #include "dev/button-sensor.h" -#include "adc-sensors.h" #include /*---------------------------------------------------------------------------*/ /** \brief Exports global symbols for the sensor API */ -SENSORS(&button_sensor, &vdd3_sensor, &cc2538_temp_sensor, &adc_sensors); +SENSORS(&button_sensor, &vdd3_sensor, &cc2538_temp_sensor); /*---------------------------------------------------------------------------*/ /** * @} diff --git a/platform/zoul/dev/zoul-sensors.h b/platform/zoul/dev/zoul-sensors.h index 476ec41da..5682c972c 100644 --- a/platform/zoul/dev/zoul-sensors.h +++ b/platform/zoul/dev/zoul-sensors.h @@ -49,7 +49,6 @@ #include "lib/sensors.h" #include "dev/cc2538-sensors.h" #include "dev/button-sensor.h" -#include "adc-sensors.h" /*---------------------------------------------------------------------------*/ /** * \name Zoul sensor constants diff --git a/platform/zoul/firefly/board.h b/platform/zoul/firefly/board.h index 07d5eaf10..101a95706 100644 --- a/platform/zoul/firefly/board.h +++ b/platform/zoul/firefly/board.h @@ -202,6 +202,9 @@ #define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ #define ADC_SENSORS_ADC2_PIN 4 /**< ADC2 to PA4, 3V3 */ #define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 3V3 */ +#define ADC_SENSORS_ADC4_PIN 6 /**< ADC4 to PA6, 3V3 */ +#define ADC_SENSORS_ADC5_PIN 7 /**< ADC5 to PA7, 3V3 */ +#define ADC_SENSORS_MAX 5 /**< PA2, PA4, PA5, PA6, PA7 */ /** @} */ /*---------------------------------------------------------------------------*/ /** diff --git a/platform/zoul/remote/board.h b/platform/zoul/remote/board.h index 563415f25..2ae4d8927 100644 --- a/platform/zoul/remote/board.h +++ b/platform/zoul/remote/board.h @@ -219,6 +219,9 @@ #define ADC_SENSORS_ADC1_PIN 5 /**< ADC1 to PA5, 3V3 */ #define ADC_SENSORS_ADC2_PIN (-1) /**< ADC2 to PA4, 3V3 */ #define ADC_SENSORS_ADC3_PIN 2 /**< ADC3 to PA2, 5V0 */ +#define ADC_SENSORS_ADC4_PIN (-1) /**< Not present */ +#define ADC_SENSORS_ADC5_PIN (-1) /**< Not present */ +#define ADC_SENSORS_MAX 2 /**< PA2, PA5 */ /** @} */ /*---------------------------------------------------------------------------*/ /** From 2295ecdbd949224cfcc034f3e018c27e02c26950 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 23:04:34 +0100 Subject: [PATCH 47/94] Renamed adc-sensors/adc-wrapper to adc-zoul/adc-sensors, to have a better wording reflecting the intented use --- examples/zolertia/zoul/Makefile | 4 +- .../zolertia/zoul/test-grove-light-sensor.c | 8 +- .../zoul/test-grove-loudness-sensor.c | 8 +- examples/zolertia/zoul/test-rotation-sensor.c | 8 +- examples/zolertia/zoul/zoul-demo.c | 10 +- platform/zoul/Makefile.zoul | 2 +- platform/zoul/dev/adc-sensors.c | 243 ++++++++++-------- platform/zoul/dev/adc-sensors.h | 110 ++------ platform/zoul/dev/adc-wrapper.c | 215 ---------------- platform/zoul/dev/adc-wrapper.h | 85 ------ platform/zoul/dev/adc-zoul.c | 187 ++++++++++++++ platform/zoul/dev/adc-zoul.h | 148 +++++++++++ 12 files changed, 514 insertions(+), 514 deletions(-) delete mode 100644 platform/zoul/dev/adc-wrapper.c delete mode 100644 platform/zoul/dev/adc-wrapper.h create mode 100644 platform/zoul/dev/adc-zoul.c create mode 100644 platform/zoul/dev/adc-zoul.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 8c1422549..7ead94a69 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,9 +1,11 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" + CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt CONTIKI_PROJECT += test-bmp085 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor + CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c -CONTIKI_TARGET_SOURCEFILES += adc-wrapper.c +CONTIKI_TARGET_SOURCEFILES += adc-sensors.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-grove-light-sensor.c b/examples/zolertia/zoul/test-grove-light-sensor.c index c81f7b931..b4104f2b8 100644 --- a/examples/zolertia/zoul/test-grove-light-sensor.c +++ b/examples/zolertia/zoul/test-grove-light-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Grove's LDR sensor example using the ADC wrapper + * Grove's LDR sensor example using the ADC sensors wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_grove_light_process, ev, data) uint16_t ldr; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_GROVE_LIGHT, 5); + adc_sensors.configure(ANALOG_GROVE_LIGHT, 5); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_grove_light_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - ldr = adc_wrapper.value(ANALOG_GROVE_LIGHT); + ldr = adc_sensors.value(ANALOG_GROVE_LIGHT); if(ldr != ADC_WRAPPER_ERROR) { printf("LDR (resistor) = %u\n", ldr); diff --git a/examples/zolertia/zoul/test-grove-loudness-sensor.c b/examples/zolertia/zoul/test-grove-loudness-sensor.c index 85907e3e3..b5042f814 100644 --- a/examples/zolertia/zoul/test-grove-loudness-sensor.c +++ b/examples/zolertia/zoul/test-grove-loudness-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Grove's loudness sensor example using the ADC wrapper + * Grove's loudness sensor example using the ADC sensors wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_grove_loudness_process, ev, data) uint16_t loudness; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); + adc_sensors.configure(ANALOG_GROVE_LOUDNESS, ADC_PIN); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_grove_loudness_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - loudness = adc_wrapper.value(ANALOG_GROVE_LOUDNESS); + loudness = adc_sensors.value(ANALOG_GROVE_LOUDNESS); if(loudness != ADC_WRAPPER_ERROR) { printf("%u\n", loudness); diff --git a/examples/zolertia/zoul/test-rotation-sensor.c b/examples/zolertia/zoul/test-rotation-sensor.c index 220d86fca..76fb029ec 100644 --- a/examples/zolertia/zoul/test-rotation-sensor.c +++ b/examples/zolertia/zoul/test-rotation-sensor.c @@ -38,7 +38,7 @@ * @{ * * \file - * Phidget analog rotation sensor example using the ADC wrapper + * Phidget analog rotation sensor example using the ADC sensor wrapper * * \author * Antonio Lignan @@ -47,7 +47,7 @@ #include #include "contiki.h" #include "dev/leds.h" -#include "dev/adc-wrapper.h" +#include "dev/adc-sensors.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 5 #define SENSOR_READ_INTERVAL (CLOCK_SECOND / 4) @@ -64,7 +64,7 @@ PROCESS_THREAD(remote_rotation_process, ev, data) uint16_t rotation; /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - adc_wrapper.configure(ANALOG_PHIDGET_ROTATION_1109, 5); + adc_sensors.configure(ANALOG_PHIDGET_ROTATION_1109, 5); /* And periodically poll the sensor */ @@ -72,7 +72,7 @@ PROCESS_THREAD(remote_rotation_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - rotation = adc_wrapper.value(ANALOG_PHIDGET_ROTATION_1109); + rotation = adc_sensors.value(ANALOG_PHIDGET_ROTATION_1109); if(rotation != ADC_WRAPPER_ERROR) { printf("Rotation = %u\n", rotation); diff --git a/examples/zolertia/zoul/zoul-demo.c b/examples/zolertia/zoul/zoul-demo.c index 25e49235f..127c18d50 100644 --- a/examples/zolertia/zoul/zoul-demo.c +++ b/examples/zolertia/zoul/zoul-demo.c @@ -69,7 +69,7 @@ #include "dev/leds.h" #include "dev/uart.h" #include "dev/button-sensor.h" -#include "dev/adc-sensors.h" +#include "dev/adc-zoul.h" #include "dev/zoul-sensors.h" #include "dev/watchdog.h" #include "dev/serial-line.h" @@ -132,7 +132,7 @@ PROCESS_THREAD(zoul_demo_process, ev, data) BUTTON_PRESS_EVENT_INTERVAL); /* Configure the ADC ports */ - adc_sensors.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); + adc_zoul.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC_ALL); printf("Zoul test application\n"); @@ -155,15 +155,16 @@ PROCESS_THREAD(zoul_demo_process, ev, data) cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); printf("ADC1 = %d raw\n", - adc_sensors.value(ZOUL_SENSORS_ADC1)); + adc_zoul.value(ZOUL_SENSORS_ADC1)); printf("ADC3 = %d raw\n", - adc_sensors.value(ZOUL_SENSORS_ADC3)); + adc_zoul.value(ZOUL_SENSORS_ADC3)); etimer_set(&et, LOOP_INTERVAL); rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, rt_callback, NULL); counter++; + } else if(ev == sensors_event) { if(data == &button_sensor) { if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == @@ -175,6 +176,7 @@ PROCESS_THREAD(zoul_demo_process, ev, data) printf("...and released!\n"); } } + } else if(ev == serial_line_event_message) { leds_toggle(LEDS_SERIAL_IN); } else if(ev == button_press_duration_exceeded) { diff --git a/platform/zoul/Makefile.zoul b/platform/zoul/Makefile.zoul index 027c1a79b..49e6ed13b 100644 --- a/platform/zoul/Makefile.zoul +++ b/platform/zoul/Makefile.zoul @@ -27,7 +27,7 @@ PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) ### Include CONTIKI_TARGET_SOURCEFILES += contiki-main.c CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c cc1200-zoul-arch.c -CONTIKI_TARGET_SOURCEFILES += adc-sensors.c button-sensor.c zoul-sensors.c +CONTIKI_TARGET_SOURCEFILES += adc-zoul.c button-sensor.c zoul-sensors.c CONTIKI_TARGET_SOURCEFILES += $(BOARD_SOURCEFILES) CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index da1ca844d..b69dfc8cf 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2015, Zolertia - http://www.zolertia.com - * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,7 +34,7 @@ * @{ * * \file - * Generic driver for the Zoul ADC sensors + * Generic driver for the Zoul ADC wrapper for analogue sensors */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -44,7 +43,9 @@ #include "dev/gpio.h" #include "dev/adc.h" #include "adc-sensors.h" +#include "adc-zoul.h" #include "zoul-sensors.h" + #include #include /*---------------------------------------------------------------------------*/ @@ -55,133 +56,153 @@ #define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -static uint8_t decimation_rate; -static uint8_t enabled_channels; +typedef struct { + int type; + uint8_t pin_mask; + uint8_t vdd3; +} adc_info_t; + +typedef struct { + uint8_t sensors_num; + uint8_t sensors_ports; + adc_info_t sensor[ADC_SENSORS_MAX]; +} adc_wrapper_t; + +static adc_wrapper_t sensors; /*---------------------------------------------------------------------------*/ -static int -set_decimation_rate(uint8_t rate) +static uint16_t +convert_to_value(uint8_t index) { - switch(rate) { - case SOC_ADC_ADCCON_DIV_64: - case SOC_ADC_ADCCON_DIV_128: - case SOC_ADC_ADCCON_DIV_256: - case SOC_ADC_ADCCON_DIV_512: - decimation_rate = rate; - break; - default: - return ZOUL_SENSORS_ERROR; + uint32_t value; + value = adc_zoul.value(sensors.sensor[index].pin_mask); + + if(value == ZOUL_SENSORS_ERROR) { + PRINTF("ADC sensors: failed retrieving data\n"); + return ADC_WRAPPER_ERROR; } - return decimation_rate; -} -/*---------------------------------------------------------------------------*/ -static int -get_channel_pin(int type) -{ - if((ZOUL_SENSORS_ADC1) && (type == ZOUL_SENSORS_ADC1)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC1_PIN; - } - if((ZOUL_SENSORS_ADC2) && (type == ZOUL_SENSORS_ADC2)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC2_PIN; - } - if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; - } - if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; - } - if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { - return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; - } - return ZOUL_SENSORS_ERROR; -} -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - int channel; - int16_t res; + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ - if(!(type & enabled_channels)) { - PRINTF("ADC: channel not enabled\n"); - return ZOUL_SENSORS_ERROR; + if(!sensors.sensor[index].vdd3) { + value *= ADC_WRAPPER_EXTERNAL_VREF; + value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; } - channel = get_channel_pin(type); + switch(sensors.sensor[index].type) { + case ANALOG_GROVE_LIGHT: + /* Light dependant resistor (LDR) resistance value*/ + value = (10230 - (value * 10)) / value; + /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ + return (uint16_t)value; - if(channel == ZOUL_SENSORS_ERROR) { - PRINTF("ADC: pin not active\n"); - return ZOUL_SENSORS_ERROR; - } + case ANALOG_GROVE_LOUDNESS: + /* Based on the LM2904 amplifier (blue version with potentiometer) */ + return (uint16_t)value; - res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); - - /* Only allow negative values if using differential input */ - if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { - res = 0; - } - - return res; -} -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int value) -{ - switch(type) { - case SENSORS_HW_INIT: - - /* This should filter out disabled sensors as its value should be zero */ - if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { - PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); - return ZOUL_SENSORS_ERROR; - } - - if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && - (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && - (value != ZOUL_SENSORS_ADC5)) { - PRINTF("ADC: invalid adc pin mask\n"); - return ZOUL_SENSORS_ERROR; - } - - GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); - GPIO_SET_INPUT(GPIO_A_BASE, value); - - if(value & ZOUL_SENSORS_ADC1) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC1_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC2) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC2_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC3) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC4) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); - } - if(value & ZOUL_SENSORS_ADC5) { - ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); - } - adc_init(); - set_decimation_rate(SOC_ADC_ADCCON_DIV_512); - enabled_channels = value; - break; - - case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: - return set_decimation_rate((uint8_t)value); + case ANALOG_PHIDGET_ROTATION_1109: + /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ + value *= 909; + value /= 100000; + return (uint16_t)value; default: - return ZOUL_SENSORS_ERROR; + return ADC_WRAPPER_ERROR; + } + + return ADC_WRAPPER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +is_sensor_in_list(int type) +{ + uint8_t i; + + for(i = 0; i <= sensors.sensors_num; i++) { + if(sensors.sensor[i].type == type) { + return i + 1; + } } return 0; } /*---------------------------------------------------------------------------*/ static int -status(int type) +value(int type) { - return 1; + uint8_t index; + uint16_t sensor_value; + + index = is_sensor_in_list(type); + + if(!index) { + PRINTF("ADC sensors: sensor not registered\n"); + return ADC_WRAPPER_SUCCESS; + } + + /* Restore index value after the check */ + index -= 1; + sensor_value = convert_to_value(index); + + return sensor_value; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(adc_sensors, ADC_SENSORS, value, configure, status); +static int +configure(int type, int value) +{ + uint8_t pin_mask = GPIO_PIN_MASK(value); + + if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && + (type != ANALOG_GROVE_LOUDNESS)) { + PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_num >= ADC_SENSORS_MAX) { + PRINTF("ADC sensors: all adc channels available have been assigned\n"); + return ADC_WRAPPER_ERROR; + } + + if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { + PRINTF("ADC sensors: invalid pin value, (PA0-PA1, PA3) are reserved\n"); + return ADC_WRAPPER_ERROR; + } + + if(sensors.sensors_ports & pin_mask) { + PRINTF("ADC sensors: a sensor has been already assigned to this pin\n"); + return ADC_WRAPPER_ERROR; + } + + switch(type) { + /* V+3.3 sensors */ + case ANALOG_GROVE_LIGHT: + case ANALOG_GROVE_LOUDNESS: + case ANALOG_PHIDGET_ROTATION_1109: + if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 1; + break; + + default: + return ADC_WRAPPER_ERROR; + } + + PRINTF("ADC sensors: type %u mask 0x%02X vdd3 %u\n", + sensors.sensor[sensors.sensors_num].type, + sensors.sensor[sensors.sensors_num].pin_mask, + sensors.sensor[sensors.sensors_num].vdd3); + + sensors.sensors_num++; + sensors.sensors_ports |= pin_mask; + + return ADC_WRAPPER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_sensors, ADC_SENSORS, value, configure, NULL); /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 1a10c8d39..8d29a9134 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -34,39 +34,26 @@ * \addtogroup zoul-sensors * @{ * - * \defgroup zoul-adc-sensors Zoul Generic ADC sensor + * \defgroup zoul-adc-sensors Zoul adc wrapper to use analogue sensors * - * Driver for the Zoul ADC sensors + * The ADC wrapper implement analogue sensors on top of the ADC interface, + * obscuring the ADC configuration and required calculations to obtain actual + * sensor values. The driver allows to reuse the adc-wrapper implementation and + * add sensors easily, without duplicating code, providing also a simplified + * interface and exposing the available ADC assigned channels by a given + * platform. * - * This driver supports analogue sensors connected to ADC1, ADC2 and AND3 inputs - * This is controlled by the type argument of the value() function. Possible - * choices are: - * - ZOUL_SENSORS_ADC1 - * - ZOUL_SENSORS_ADC2 - * - ZOUL_SENSORS_ADC3 + * To use a given sensor simply use: adc_sensors.configure(SENSOR_NAME, pin_no), + * where pin_no is a given pin in the PA port, check out the board.h for more + * information on available pins. To read a value just use + * adc_sensors.value(SENSOR_NAME), the expected result would be the sensor value + * already converted to the sensor variable type, check the adc-wrapper file + * for more information. * - * To initialize the ADC sensors use the configure() function, using as first - * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as - * second argument any single or combined (sum) values as below: - * - ZOUL_SENSORS_ADC1 - * - ZOUL_SENSORS_ADC2 - * - ZOUL_SENSORS_ADC3 - * - ZOUL_SENSORS_ADC_ALL (all channels above) - * - * Using an invalid combination will return ZOUL_SENSORS_ERROR. - * - * The decimation rate can be set by passing - * ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the - * configure() function and then specifying the rate through the value - * argument. Valid values are: - * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) - * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) - * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) - * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) * @{ * * \file - * Header file for the Zoul Generic Driver for ADC sensors + * Header file for the Zoul ADC sensors API */ /*---------------------------------------------------------------------------*/ #ifndef ADC_SENSORS_H_ @@ -74,66 +61,19 @@ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" #include "dev/soc-adc.h" +#include "dev/adc-zoul.h" /*---------------------------------------------------------------------------*/ -/** - * \name Generic ADC sensors - * @{ - */ -#define ADC_SENSORS "ADC sensors" -#define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) - -#ifdef ADC_SENSORS_CONF_REFERENCE -#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE -#else -#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 -#endif - -/* - * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia - * platforms, the following assumes PA0-1 shall not be used as ADC input, else - * re-write the below definitions - */ -#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ - -/* ADC phidget-like connector ADC1 */ -#if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) -#else -#define ZOUL_SENSORS_ADC1 0 -#endif -/* ADC phidget-like connector ADC2 */ -#if ADC_SENSORS_ADC2_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC2 GPIO_PIN_MASK(ADC_SENSORS_ADC2_PIN) -#else -#define ZOUL_SENSORS_ADC2 0 -#endif -/* ADC phidget-like connector ADC3 */ -#if ADC_SENSORS_ADC3_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC3 GPIO_PIN_MASK(ADC_SENSORS_ADC3_PIN) -#else -#define ZOUL_SENSORS_ADC3 0 -#endif -/* ADC phidget-like connector ADC4 */ -#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) -#else -#define ZOUL_SENSORS_ADC4 0 -#endif -/* ADC phidget-like connector ADC5 */ -#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN -#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) -#else -#define ZOUL_SENSORS_ADC5 0 -#endif -/* - * This is safe as the disabled sensors should have a zero value thus not - * affecting the mask operations - */ -#define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ - ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ - ZOUL_SENSORS_ADC5) -/** @} */ +#define ADC_WRAPPER_SUCCESS 0x00 +#define ADC_WRAPPER_ERROR (-1) +#define ADC_WRAPPER_EXTERNAL_VREF 5000 +#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 /*---------------------------------------------------------------------------*/ +#define ANALOG_GROVE_LIGHT 0x01 +#define ANALOG_PHIDGET_ROTATION_1109 0x02 +#define ANALOG_GROVE_LOUDNESS 0x03 +/* -------------------------------------------------------------------------- */ +#define ADC_SENSORS "ADC sensors API" +/* -------------------------------------------------------------------------- */ extern const struct sensors_sensor adc_sensors; /*---------------------------------------------------------------------------*/ #endif /* ADC_SENSORS_H_ */ diff --git a/platform/zoul/dev/adc-wrapper.c b/platform/zoul/dev/adc-wrapper.c deleted file mode 100644 index 02cb5f77c..000000000 --- a/platform/zoul/dev/adc-wrapper.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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 zoul-adc-wrapper - * @{ - * - * \file - * Generic driver for the Zoul ADC wrapper for analogue sensors - */ -/*---------------------------------------------------------------------------*/ -#include "contiki.h" -#include "sys/clock.h" -#include "dev/ioc.h" -#include "dev/gpio.h" -#include "dev/adc.h" -#include "adc-sensors.h" -#include "adc-wrapper.h" -#include "zoul-sensors.h" - -#include -#include -/*---------------------------------------------------------------------------*/ -#define DEBUG 1 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -/*---------------------------------------------------------------------------*/ -typedef struct { - int type; - uint8_t pin_mask; - uint8_t vdd3; -} adc_info_t; - -typedef struct { - uint8_t sensors_num; - uint8_t sensors_ports; - adc_info_t sensor[ADC_SENSORS_MAX]; -} adc_wrapper_t; - -static adc_wrapper_t sensors; -/*---------------------------------------------------------------------------*/ -static uint16_t -convert_to_value(uint8_t index) -{ - uint32_t value; - value = adc_sensors.value(sensors.sensor[index].pin_mask); - - if(value == ZOUL_SENSORS_ERROR) { - PRINTF("ADC wrapper: failed retrieving data\n"); - return ADC_WRAPPER_ERROR; - } - - /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, - * calculations below assume a decimation rate of 512 (12 bits ENOB) and - * AVVD5 voltage reference of 3.3V - */ - - if(!sensors.sensor[index].vdd3) { - value *= ADC_WRAPPER_EXTERNAL_VREF; - value /= ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL; - } - - switch(sensors.sensor[index].type) { - case ANALOG_GROVE_LIGHT: - /* Light dependant resistor (LDR) resistance value*/ - value = (10230 - (value * 10)) / value; - /* TODO: With the resistance we could calculate the lux as 63*R^(-0.7) */ - return (uint16_t)value; - - case ANALOG_GROVE_LOUDNESS: - /* Based on the LM2904 amplifier (blue version with potentiometer) */ - return (uint16_t)value; - - case ANALOG_PHIDGET_ROTATION_1109: - /* Linear sensor with 0-300º, 300/33000 = 0.00909 */ - value *= 909; - value /= 100000; - return (uint16_t)value; - - default: - return ADC_WRAPPER_ERROR; - } - - return ADC_WRAPPER_ERROR; -} -/*---------------------------------------------------------------------------*/ -static uint8_t -is_sensor_in_list(int type) -{ - uint8_t i; - - for(i = 0; i <= sensors.sensors_num; i++) { - if(sensors.sensor[i].type == type) { - return i + 1; - } - } - return 0; -} -/*---------------------------------------------------------------------------*/ -static int -value(int type) -{ - uint8_t index; - uint16_t sensor_value; - - index = is_sensor_in_list(type); - - if(!index) { - PRINTF("ADC wrapper: sensor not registered\n"); - return ADC_WRAPPER_SUCCESS; - } - - /* Restore index value after the check */ - index -= 1; - sensor_value = convert_to_value(index); - - return sensor_value; -} -/*---------------------------------------------------------------------------*/ -static int -configure(int type, int value) -{ - uint8_t pin_mask = GPIO_PIN_MASK(value); - - if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && - (type != ANALOG_GROVE_LOUDNESS)) { - PRINTF("ADC wrapper: sensor not supported, check adc_wrapper.h header\n"); - return ADC_WRAPPER_ERROR; - } - - if(sensors.sensors_num >= ADC_SENSORS_MAX) { - PRINTF("ADC wrapper: all adc channels available have been assigned\n"); - return ADC_WRAPPER_ERROR; - } - - if((value < 0x01) || (value > 0x07) || (value == BUTTON_USER_PIN)) { - PRINTF("ADC wrapper: invalid pin value, (PA0-PA1, PA3) are reserved\n"); - return ADC_WRAPPER_ERROR; - } - - if(sensors.sensors_ports & pin_mask) { - PRINTF("ADC wrapper: a sensor has been already assigned to this pin\n"); - return ADC_WRAPPER_ERROR; - } - - switch(type) { - /* V+3.3 sensors */ - case ANALOG_GROVE_LIGHT: - case ANALOG_GROVE_LOUDNESS: - case ANALOG_PHIDGET_ROTATION_1109: - if(adc_sensors.configure(SENSORS_HW_INIT, pin_mask) == - ZOUL_SENSORS_ERROR) { - return ADC_WRAPPER_ERROR; - } - sensors.sensor[sensors.sensors_num].type = type; - sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; - sensors.sensor[sensors.sensors_num].vdd3 = 1; - break; - - default: - return ADC_WRAPPER_ERROR; - } - - PRINTF("ADC wrapper: type %u mask 0x%02X vdd3 %u\n", - sensors.sensor[sensors.sensors_num].type, - sensors.sensor[sensors.sensors_num].pin_mask, - sensors.sensor[sensors.sensors_num].vdd3); - - sensors.sensors_num++; - sensors.sensors_ports |= pin_mask; - - return ADC_WRAPPER_SUCCESS; -} -/*---------------------------------------------------------------------------*/ -static int -status(int type) -{ - return 1; -} -/*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(adc_wrapper, ADC_WRAPPER, value, configure, status); -/*---------------------------------------------------------------------------*/ -/** @} */ - diff --git a/platform/zoul/dev/adc-wrapper.h b/platform/zoul/dev/adc-wrapper.h deleted file mode 100644 index 5a9e63b19..000000000 --- a/platform/zoul/dev/adc-wrapper.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015, Zolertia - http://www.zolertia.com - * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk - * 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-sensors - * @{ - * - * \defgroup zoul-adc-wrapper Zoul adc wrapper to use analogue sensors - * - * The ADC wrapper allows to use analogue sensors on top of the ADC interface, - * obscuring the ADC configuration and required calculations to obtain actual - * sensor values. The driver allows to reuse the adc-wrapper implementation and - * add sensors easily, without duplicating code, providing also a simplified - * interface and exposing the available ADC assigned channels by a given - * platform. - * - * To use a given sensor simply use: adc_wrapper.configure(SENSOR_NAME, pin_no), - * where pin_no is a given pin in the PA port, check out the board.h for more - * information on available pins. To read a value just use - * adc_wrapper.value(SENSOR_NAME), the expected result would be the sensor value - * already converted to the sensor variable type, check the adc-wrapper file - * for more information. - * - * @{ - * - * \file - * Header file for the Zoul ADC wrapper - */ -/*---------------------------------------------------------------------------*/ -#ifndef ADC_WRAPPER_H_ -#define ADC_WRAPPER_H_ -/*---------------------------------------------------------------------------*/ -#include "lib/sensors.h" -#include "dev/soc-adc.h" -#include "dev/adc-sensors.h" -/*---------------------------------------------------------------------------*/ -#define ADC_WRAPPER_SUCCESS 0x00 -#define ADC_WRAPPER_ERROR (-1) -#define ADC_WRAPPER_EXTERNAL_VREF 5000 -#define ADC_WRAPPER_EXTERNAL_VREF_CROSSVAL 3300 -/*---------------------------------------------------------------------------*/ -#define ANALOG_GROVE_LIGHT 0x01 -#define ANALOG_PHIDGET_ROTATION_1109 0x02 -#define ANALOG_GROVE_LOUDNESS 0x03 -/* -------------------------------------------------------------------------- */ -#define ADC_WRAPPER "ADC wrapper API" -/* -------------------------------------------------------------------------- */ -extern const struct sensors_sensor adc_wrapper; -/*---------------------------------------------------------------------------*/ -#endif /* ADC_WRAPPER_H_ */ -/*---------------------------------------------------------------------------*/ -/** - * @} - * @} - */ - diff --git a/platform/zoul/dev/adc-zoul.c b/platform/zoul/dev/adc-zoul.c new file mode 100644 index 000000000..4e309dcf4 --- /dev/null +++ b/platform/zoul/dev/adc-zoul.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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-adc-interface + * @{ + * + * \file + * Generic driver for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t decimation_rate; +static uint8_t enabled_channels; +/*---------------------------------------------------------------------------*/ +static int +set_decimation_rate(uint8_t rate) +{ + switch(rate) { + case SOC_ADC_ADCCON_DIV_64: + case SOC_ADC_ADCCON_DIV_128: + case SOC_ADC_ADCCON_DIV_256: + case SOC_ADC_ADCCON_DIV_512: + decimation_rate = rate; + break; + default: + return ZOUL_SENSORS_ERROR; + } + + return decimation_rate; +} +/*---------------------------------------------------------------------------*/ +static int +get_channel_pin(int type) +{ + if((ZOUL_SENSORS_ADC1) && (type == ZOUL_SENSORS_ADC1)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC1_PIN; + } + if((ZOUL_SENSORS_ADC2) && (type == ZOUL_SENSORS_ADC2)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC2_PIN; + } + if((ZOUL_SENSORS_ADC3) && (type == ZOUL_SENSORS_ADC3)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC3_PIN; + } + if((ZOUL_SENSORS_ADC4) && (type == ZOUL_SENSORS_ADC4)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC4_PIN; + } + if((ZOUL_SENSORS_ADC5) && (type == ZOUL_SENSORS_ADC5)) { + return SOC_ADC_ADCCON_CH_AIN0 + ADC_SENSORS_ADC5_PIN; + } + return ZOUL_SENSORS_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + int channel; + int16_t res; + + if(!(type & enabled_channels)) { + PRINTF("ADC: channel not enabled\n"); + return ZOUL_SENSORS_ERROR; + } + + channel = get_channel_pin(type); + + if(channel == ZOUL_SENSORS_ERROR) { + PRINTF("ADC: pin not active\n"); + return ZOUL_SENSORS_ERROR; + } + + res = adc_get(channel, ADC_SENSORS_REFERENCE, decimation_rate); + + /* Only allow negative values if using differential input */ + if((ADC_SENSORS_REFERENCE != SOC_ADC_ADCCON_REF_EXT_DIFF) && (res < 0)) { + res = 0; + } + + return res; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + + /* This should filter out disabled sensors as its value should be zero */ + if((value < ZOUL_SENSORS_ADC_MIN) || (value > ZOUL_SENSORS_ADC_ALL)) { + PRINTF("ADC: invalid adc pin mask (0x%02X)\n", value); + return ZOUL_SENSORS_ERROR; + } + + if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && + (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && + (value != ZOUL_SENSORS_ADC5)) { + PRINTF("ADC: invalid adc pin mask\n"); + return ZOUL_SENSORS_ERROR; + } + + GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); + GPIO_SET_INPUT(GPIO_A_BASE, value); + + if(value & ZOUL_SENSORS_ADC1) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC1_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC2) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC2_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC3) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC3_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC4) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC4_PIN, IOC_OVERRIDE_ANA); + } + if(value & ZOUL_SENSORS_ADC5) { + ioc_set_over(GPIO_A_NUM, ADC_SENSORS_ADC5_PIN, IOC_OVERRIDE_ANA); + } + adc_init(); + set_decimation_rate(SOC_ADC_ADCCON_DIV_512); + enabled_channels = value; + break; + + case ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: + return set_decimation_rate((uint8_t)value); + + default: + return ZOUL_SENSORS_ERROR; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(adc_zoul, ADC_ZOUL, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ + diff --git a/platform/zoul/dev/adc-zoul.h b/platform/zoul/dev/adc-zoul.h new file mode 100644 index 000000000..d47da43c7 --- /dev/null +++ b/platform/zoul/dev/adc-zoul.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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-sensors + * @{ + * + * \defgroup zoul-adc-interface Zoul Generic ADC interface + * + * Driver for the Zoul ADC interface + * + * This driver supports analogue sensors connected to ADC1, ADC2 and AND3 inputs + * This is controlled by the type argument of the value() function. Possible + * choices are: + * + * - ZOUL_SENSORS_ADC1 + * - ZOUL_SENSORS_ADC2 + * - ZOUL_SENSORS_ADC3 + * - ZOUL_SENSORS_ADC4 + * - ZOUL_SENSORS_ADC5 + * + * To initialize the ADC sensors use the configure() function, using as first + * argument SENSORS_HW_INIT, and choose which ADC channels to enable passing as + * second argument any single or combined (sum) values as below: + * + * - Either use multiple values (i.e ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2) + * - ZOUL_SENSORS_ADC_ALL (all channels above) + * + * Using an invalid combination will return ZOUL_SENSORS_ERROR. + * + * The decimation rate can be set by passing + * ZOUL_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the + * configure() function and then specifying the rate through the value + * argument. Valid values are: + * + * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) + * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) + * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) + * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) + * @{ + * + * \file + * Header file for the Zoul ADC interface + */ +/*---------------------------------------------------------------------------*/ +#ifndef ADC_ZOUL_H_ +#define ADC_ZOUL_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Generic ADC sensors + * @{ + */ +#define ADC_ZOUL "ADC sensor interface" +#define ADC_SENSORS_PORT_BASE GPIO_PORT_TO_BASE(ADC_SENSORS_PORT) + +#ifdef ADC_SENSORS_CONF_REFERENCE +#define ADC_SENSORS_REFERENCE ADC_SENSORS_CONF_REFERENCE +#else +#define ADC_SENSORS_REFERENCE SOC_ADC_ADCCON_REF_AVDD5 +#endif + +/* + * PA0-PA3 are hardcoded to UART0 and the user button for most Zolertia + * platforms, the following assumes PA0-1 shall not be used as ADC input, else + * re-write the below definitions + */ +#define ZOUL_SENSORS_ADC_MIN 2 /**< PA1 pin mask */ + +/* ADC phidget-like connector ADC1 */ +#if ADC_SENSORS_ADC1_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC1 GPIO_PIN_MASK(ADC_SENSORS_ADC1_PIN) +#else +#define ZOUL_SENSORS_ADC1 0 +#endif +/* ADC phidget-like connector ADC2 */ +#if ADC_SENSORS_ADC2_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC2 GPIO_PIN_MASK(ADC_SENSORS_ADC2_PIN) +#else +#define ZOUL_SENSORS_ADC2 0 +#endif +/* ADC phidget-like connector ADC3 */ +#if ADC_SENSORS_ADC3_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC3 GPIO_PIN_MASK(ADC_SENSORS_ADC3_PIN) +#else +#define ZOUL_SENSORS_ADC3 0 +#endif +/* ADC phidget-like connector ADC4 */ +#if ADC_SENSORS_ADC4_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC4 GPIO_PIN_MASK(ADC_SENSORS_ADC4_PIN) +#else +#define ZOUL_SENSORS_ADC4 0 +#endif +/* ADC phidget-like connector ADC5 */ +#if ADC_SENSORS_ADC5_PIN >= ZOUL_SENSORS_ADC_MIN +#define ZOUL_SENSORS_ADC5 GPIO_PIN_MASK(ADC_SENSORS_ADC5_PIN) +#else +#define ZOUL_SENSORS_ADC5 0 +#endif +/* + * This is safe as the disabled sensors should have a zero value thus not + * affecting the mask operations + */ +#define ZOUL_SENSORS_ADC_ALL (ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + \ + ZOUL_SENSORS_ADC3 + ZOUL_SENSORS_ADC4 + \ + ZOUL_SENSORS_ADC5) +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor adc_zoul; +/*---------------------------------------------------------------------------*/ +#endif /* ADC_ZOUL_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + From d0448df3b8e2f315c90aeb33379804915f877023 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 14 Sep 2015 15:55:26 +0200 Subject: [PATCH 48/94] added support for multiple reassemblies --- core/net/ipv6/sicslowpan.c | 600 +++++++++++++++++++++++-------------- 1 file changed, 371 insertions(+), 229 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 3cec1a534..f6af5d46f 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -79,15 +79,9 @@ uint8_t p; #include #define PRINTFI(...) PRINTF(__VA_ARGS__) #define PRINTFO(...) PRINTF(__VA_ARGS__) -#define PRINTPACKETBUF() PRINTF("packetbuf buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(packetbuf_ptr + p));} PRINTF("\n") -#define PRINTUIPBUF() PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n") -#define PRINTSICSLOWPANBUF() PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n") #else #define PRINTFI(...) #define PRINTFO(...) -#define PRINTPACKETBUF() -#define PRINTUIPBUF() -#define PRINTSICSLOWPANBUF() #endif /* DEBUG == 1*/ #if UIP_LOGGING @@ -145,8 +139,10 @@ void uip_log(char *msg); /** \name Pointers in the sicslowpan and uip buffer * @{ */ -#define SICSLOWPAN_IP_BUF ((struct uip_ip_hdr *)&sicslowpan_buf[UIP_LLH_LEN]) -#define SICSLOWPAN_UDP_BUF ((struct uip_udp_hdr *)&sicslowpan_buf[UIP_LLIPH_LEN]) + +/* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ +#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) +#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) @@ -165,9 +161,8 @@ void uip_log(char *msg); #endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -/** \brief Some MAC layers need a minimum payload, which is - configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD - option. */ +/** \brief Some MAC layers need a minimum payload, which is configurable + through the SICSLOWPAN_CONF_COMPRESSION_THRESHOLD option. */ #ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #else @@ -216,50 +211,232 @@ static uint8_t uncomp_hdr_len; static int last_tx_status; /** @} */ -#if SICSLOWPAN_CONF_FRAG -/** \name Fragmentation related variables - * @{ - */ +static uint16_t my_tag; -static uint16_t sicslowpan_len; +static int last_rssi; -/** - * The buffer used for the 6lowpan reassembly. - * This buffer contains only the IPv6 packet (no MAC header, 6lowpan, etc). - * It has a fix size as we do not use dynamic memory allocation. - */ -static uip_buf_t sicslowpan_aligned_buf; -#define sicslowpan_buf (sicslowpan_aligned_buf.u8) +/* ----------------------------------------------------------------- */ +/* Support for reassembling multiple packets */ +/* ----------------------------------------------------------------- */ +/* The fragmentation buffer are also possible to use for other + * temporary memory allocation. In that case the number of available + * buffers will be lower for a short time. + **/ /** The total length of the IPv6 packet in the sicslowpan_buf. */ -/** - * length of the ip packet already sent / received. - * It includes IP and transport headers. - */ -static uint16_t processed_ip_in_len; +/* This needs to be defined in NBR / Nodes depending on available RAM */ +/* and expected reassembly requirements */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#else +#define SICSLOWPAN_FRAGMENT_BUFFERS 12 +#endif -/** Datagram tag to be put in the fragments I send. */ -static uint16_t my_tag; +/* REASS_CONTEXTS corresponds to the number of simultaneous + * reassemblies that can be made. NOTE: the first buffer for each + * reassembly is stored in the context since it can be larger than the + * rest of the fragments due to header compression. + **/ +#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS +#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS +#else +#define SICSLOWPAN_REASS_CONTEXTS 2 +#endif -/** When reassembling, the tag in the fragments being merged. */ -static uint16_t reass_tag; +/* The size of each fragment (IP payload) for the 6lowpan fragmentation */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE +#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE +#else +#define SICSLOWPAN_FRAGMENT_SIZE 110 +#endif -/** When reassembling, the source address of the fragments being merged */ -linkaddr_t frag_sender; +/* Assuming that the worst growth for uncompression is 38 bytes */ +#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38) -/** Reassembly %process %timer. */ -static struct timer reass_timer; +/* all information needed for reassembly */ +struct sicslowpan_frag_info { + /** When reassembling, the source address of the fragments being merged */ + linkaddr_t sender; + /** The destination address of the fragments being merged */ + linkaddr_t receiver; + /** When reassembling, the tag in the fragments being merged. */ + uint16_t tag; + /** Total length of the fragmented packet */ + uint16_t len; + /** Current length of reassembled fragments */ + uint16_t reassembled_len; + /** Reassembly %process %timer. */ + struct timer reass_timer; -/** @} */ -#else /* SICSLOWPAN_CONF_FRAG */ -/** The buffer used for the 6lowpan processing is uip_buf. - We do not use any additional buffer.*/ -#define sicslowpan_buf uip_buf -#define sicslowpan_len uip_len -#endif /* SICSLOWPAN_CONF_FRAG */ + /** Fragment size of first fragment */ + uint16_t first_frag_len; + /** First fragment - needs a larger buffer since the size is uncompressed size + and we need to know total size to know when we have received last fragment. */ + uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE]; +}; -static int last_rssi; +static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS]; + +struct sicslowpan_frag_buf { + /* the index of the frag_info */ + uint8_t index; + /* Fragment offset */ + uint8_t offset; + /* Length of this fragment (if zero this buffer is not allocated) */ + uint8_t len; + uint8_t data[SICSLOWPAN_FRAGMENT_SIZE]; +}; + +static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS]; + +/*---------------------------------------------------------------------------*/ +static int +clear_fragments(uint8_t frag_info_index) +{ + int i, clear_count; + clear_count = 0; + frag_info[frag_info_index].len = 0; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) { + /* deallocate the buffer */ + frag_buf[i].len = 0; + clear_count++; + } + } + return clear_count; +} +/*---------------------------------------------------------------------------*/ +static int +timeout_fragments(int not_context) +{ + int i; + int count = 0; + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].len > 0 && i != not_context && + timer_expired(&frag_info[i].reass_timer)) { + /* This context can be freed */ + count += clear_fragments(i); + } + } + return count; +} +/*---------------------------------------------------------------------------*/ +static int +store_fragment(uint8_t index, uint8_t offset) +{ + int i; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len == 0) { + /* copy over the data from packetbuf into the fragment buffer and store offset and len */ + frag_buf[i].offset = offset; /* frag offset */ + frag_buf[i].len = packetbuf_datalen() - packetbuf_hdr_len; + frag_buf[i].index = index; + memcpy(frag_buf[i].data, packetbuf_ptr + packetbuf_hdr_len, + packetbuf_datalen() - packetbuf_hdr_len); + + PRINTF("Fragsize: %d\n", frag_buf[i].len); + /* return the length of the stored fragment */ + return frag_buf[i].len; + } + } + /* failed */ + return -1; +} +/*---------------------------------------------------------------------------*/ +/* add a new fragment to the buffer */ +static int8_t +add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset) +{ + int i; + int len; + int8_t found = -1; + + if(offset == 0) { + /* This is a first fragment - check if we can add this */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + /* clear all fragment info with expired timer to free all fragment buffers */ + if(frag_info[i].len > 0 && timer_expired(&frag_info[i].reass_timer)) { + clear_fragments(i); + } + + /* We use len as indication on used or not used */ + if(found < 0 && frag_info[i].len == 0) { + /* We remember the first free fragment info but must continue + the loop to free any other expired fragment buffers. */ + found = i; + } + } + + if(found < 0) { + PRINTF("*** Failed to store new fragment session - tag: %d\n", tag); + return -1; + } + + /* Found a free fragment info to store data in */ + frag_info[found].len = frag_size; + frag_info[found].tag = tag; + linkaddr_copy(&frag_info[found].sender, + packetbuf_addr(PACKETBUF_ADDR_SENDER)); + timer_set(&frag_info[found].reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); + /* first fragment can not be stored immediately but is moved into + the buffer while uncompressing */ + return found; + } + + /* This is a N-fragment - should find the info */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].tag == tag && frag_info[i].len > 0 && + linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { + /* Tag and Sender match - this must be the correct info to store in */ + found = i; + break; + } + } + + if(found < 0) { + /* no entry found for storing the new fragment */ + PRINTF("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset); + return -1; + } + + /* i is the index of the reassembly context */ + len = store_fragment(i, offset); + if(len < 0 && timeout_fragments(i) > 0) { + len = store_fragment(i, offset); + } + if(len > 0) { + frag_info[i].reassembled_len += len; + return i; + } else { + /* should we also clear all fragments since we failed to store this fragment? */ + PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); + return -1; + } +} +/*---------------------------------------------------------------------------*/ +/* Copy all the fragments that are associated with a specific context into uip */ +static void +copy_frags2uip(int context) +{ + int i; + + /* Copy from the fragment context info buffer first */ + memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag, + frag_info[context].first_frag_len); + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + /* And also copy all matching fragments */ + if(frag_buf[i].len > 0 && frag_buf[i].index == context) { + memcpy((uint8_t *)UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3), + (uint8_t *)frag_buf[i].data, frag_buf[i].len); + } + } + /* deallocate all the fragments for this context */ + clear_fragments(context); +} + + +/* -------------------------------------------------------------------------- */ /*-------------------------------------------------------------------------*/ /* Rime Sniffer support for one single listener to enable powertrace of IP */ @@ -327,7 +504,7 @@ static struct sicslowpan_addr_context *context; /** pointer to the byte where to write next inline field. */ static uint8_t *hc06_ptr; -/* Uncompression of linklocal */ +/* ession of linklocal */ /* 0 -> 16 bytes from packet */ /* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ /* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ @@ -357,7 +534,7 @@ const uint8_t llprefix[] = {0xfe, 0x80}; static const uint8_t ttl_values[] = {0, 1, 64, 255}; /*--------------------------------------------------------------------*/ -/** \name HC06 related functions +/** \name IPHC related functions * @{ */ /*--------------------------------------------------------------------*/ /** \brief find the context corresponding to prefix ipaddr */ @@ -463,8 +640,8 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * uip_buf buffer. * * - * HC-06 (draft-ietf-6lowpan-hc, version 6)\n - * http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06 + * IPHC (RFC 6282)\n + * http://tools.ietf.org/html/ * * \note We do not support ISA100_UDP header compression * @@ -490,7 +667,7 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * dest */ static void -compress_hdr_hc06(linkaddr_t *link_destaddr) +compress_hdr_iphc(linkaddr_t *link_destaddr) { uint8_t tmp, iphc0, iphc1; #if DEBUG @@ -541,7 +718,8 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) * depends on the presence of version and flow label */ - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ + tmp = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4); tmp = ((tmp & 0x03) << 6) | (tmp >> 2); @@ -585,11 +763,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) iphc0 |= SICSLOWPAN_IPHC_NH_C; } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - if(SICSLOWPAN_NH_COMPRESSOR.is_compressable(UIP_IP_BUF->proto)) { - iphc0 |= SICSLOWPAN_IPHC_NH_C; - } -#endif + if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { *hc06_ptr = UIP_IP_BUF->proto; hc06_ptr += 1; @@ -769,11 +943,11 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) /*--------------------------------------------------------------------*/ /** - * \brief Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put + * \brief Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put * them in sicslowpan_buf * * This function is called by the input function when the dispatch is - * HC06. + * IPHC. * We %process the packet in the packetbuf buffer, uncompress the header * fields, and copy the result in the sicslowpan buffer. * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len @@ -784,7 +958,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) * fragment. */ static void -uncompress_hdr_hc06(uint16_t ip_len) +uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) { uint8_t tmp, iphc0, iphc1; /* at least two byte will be used for the encoding */ @@ -804,22 +978,22 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Flow label are carried inline */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is carried inline */ - memcpy(&SICSLOWPAN_IP_BUF->tcflow, hc06_ptr + 1, 3); + memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, hc06_ptr + 1, 3); tmp = *hc06_ptr; hc06_ptr += 4; - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ /* set version, pick highest DSCP bits and set in vtc */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((tmp >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f); /* ECN rolled down two steps + lowest DSCP bits at top two bits */ - SICSLOWPAN_IP_BUF->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | - (SICSLOWPAN_IP_BUF->tcflow & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | + (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f); } else { /* Traffic class is compressed (set version and no TC)*/ - SICSLOWPAN_IP_BUF->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; /* highest flow label bits + ECN bits */ - SICSLOWPAN_IP_BUF->tcflow = (*hc06_ptr & 0x0F) | - ((*hc06_ptr >> 2) & 0x30); - memcpy(&SICSLOWPAN_IP_BUF->flow, hc06_ptr + 1, 2); + SICSLOWPAN_IP_BUF(buf)->tcflow = (*hc06_ptr & 0x0F) | + ((*hc06_ptr >> 2) & 0x30); + memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, hc06_ptr + 1, 2); hc06_ptr += 3; } } else { @@ -827,31 +1001,31 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Version and flow label are compressed */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is inline */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); - SICSLOWPAN_IP_BUF->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); + SICSLOWPAN_IP_BUF(buf)->flow = 0; hc06_ptr += 1; } else { /* Traffic class is compressed */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->tcflow = 0; + SICSLOWPAN_IP_BUF(buf)->flow = 0; } } /* Next Header */ if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ - SICSLOWPAN_IP_BUF->proto = *hc06_ptr; - PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF->proto); + SICSLOWPAN_IP_BUF(buf)->proto = *hc06_ptr; + PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto); hc06_ptr += 1; } /* Hop limit */ if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) { - SICSLOWPAN_IP_BUF->ttl = ttl_values[iphc0 & 0x03]; + SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03]; } else { - SICSLOWPAN_IP_BUF->ttl = *hc06_ptr; + SICSLOWPAN_IP_BUF(buf)->ttl = *hc06_ptr; hc06_ptr += 1; } @@ -872,12 +1046,12 @@ uncompress_hdr_hc06(uint16_t ip_len) } } /* if tmp == 0 we do not have a context and therefore no prefix */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } else { /* no compression and link local */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, llprefix, unc_llconf[tmp], + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } @@ -902,7 +1076,7 @@ uncompress_hdr_hc06(uint16_t ip_len) hc06_ptr++; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix, unc_mxconf[tmp], NULL); } } else { @@ -917,12 +1091,12 @@ uncompress_hdr_hc06(uint16_t ip_len) PRINTF("sicslowpan uncompress_hdr: error context not found\n"); return; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } else { /* not context based => link local M = 0, DAC = 0 - same as SAC */ - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, llprefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } @@ -934,59 +1108,60 @@ uncompress_hdr_hc06(uint16_t ip_len) /* The next header is compressed, NHC is following */ if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { uint8_t checksum_compressed; - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; + SICSLOWPAN_IP_BUF(buf)->proto = UIP_PROTO_UDP; checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC; PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr); switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) { case SICSLOWPAN_NHC_UDP_CS_P_00: - /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 5; - break; + /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 3, 2); + PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 5; + break; case SICSLOWPAN_NHC_UDP_CS_P_01: /* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */ - PRINTF("IPHC: Decompressing destination\n"); - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 4; - break; + PRINTF("IPHC: Decompressing destination\n"); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 4; + break; case SICSLOWPAN_NHC_UDP_CS_P_10: /* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/ - PRINTF("IPHC: Decompressing source\n"); - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + - (*(hc06_ptr + 1))); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 2, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 4; - break; + PRINTF("IPHC: Decompressing source\n"); + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + + (*(hc06_ptr + 1))); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 2, 2); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 4; + break; case SICSLOWPAN_NHC_UDP_CS_P_11: - /* 1 byte for NHC, 1 byte for ports */ - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - (*(hc06_ptr + 1) >> 4)); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - ((*(hc06_ptr + 1)) & 0x0F)); - PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 2; - break; + /* 1 byte for NHC, 1 byte for ports */ + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + (*(hc06_ptr + 1) >> 4)); + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + ((*(hc06_ptr + 1)) & 0x0F)); + PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 2; + break; default: PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); return; } if(!checksum_compressed) { /* has_checksum, default */ - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr, 2); - hc06_ptr += 2; - PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udpchksum, hc06_ptr, 2); + hc06_ptr += 2; + PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); } else { PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); } @@ -1005,17 +1180,17 @@ uncompress_hdr_hc06(uint16_t ip_len) if(ip_len == 0) { int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF; } else { /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; } /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); + if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) { + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udplen, &SICSLOWPAN_IP_BUF(buf)->len[0], 2); } return; @@ -1360,7 +1535,6 @@ static uint8_t output(const uip_lladdr_t *localdest) { int framer_hdrlen; - int max_payload; /* The MAC address of the destination of the packet */ linkaddr_t dest; @@ -1426,7 +1600,7 @@ output(const uip_lladdr_t *localdest) compress_hdr_ipv6(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 - compress_hdr_hc06(&dest); + compress_hdr_iphc(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ } else { compress_hdr_ipv6(&dest); @@ -1442,21 +1616,23 @@ output(const uip_lladdr_t *localdest) framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 21; + framer_hdrlen = 23; } #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 21; + framer_hdrlen = 23; #endif /* USE_FRAMER_HDRLEN */ max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; - if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { + if((int)uip_len - (int)uncomp_hdr_len > (int)max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG struct queuebuf *q; + uint16_t frag_tag; + /* * The outbound IPv6 packet is too large to fit into a single 15.4 * packet, so we fragment it into multiple packets and send them. * The first fragment contains frag1 dispatch, then - * IPv6/HC1/HC06/HC_UDP dispatchs/headers. + * IPv6/IPHC/HC_UDP dispatchs/headers. * The following fragments contain only the fragn dispatch. */ int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1; @@ -1472,7 +1648,10 @@ output(const uip_lladdr_t *localdest) /* Create 1st Fragment */ PRINTFO("sicslowpan output: 1rst fragment "); - /* move HC1/HC06/IPv6 header */ + /* Reset last tx status to ok in case the fragment transmissions are deferred */ + last_tx_status = MAC_TX_OK; + + /* move IPHC/IPv6 header */ memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len); /* @@ -1483,14 +1662,13 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); -/* PACKETBUF_FRAG_BUF->tag = uip_htons(my_tag); */ - SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, my_tag); - my_tag++; + frag_tag = my_tag++; + SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag); /* Copy payload and send */ packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; - packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; - PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, my_tag); + packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1525,7 +1703,7 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); - packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; @@ -1536,7 +1714,7 @@ output(const uip_lladdr_t *localdest) packetbuf_payload_len = uip_len - processed_ip_out_len; } PRINTFO("(offset %d, len %d, tag %d)\n", - processed_ip_out_len >> 3, packetbuf_payload_len, my_tag); + processed_ip_out_len >> 3, packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + processed_ip_out_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1594,8 +1772,12 @@ input(void) { /* size of the IP packet (read from fragment) */ uint16_t frag_size = 0; + int8_t frag_context = 0; /* offset of the fragment in the IP packet */ uint8_t frag_offset = 0; + uint8_t is_fragment = 0; + uint8_t *buffer; + #if SICSLOWPAN_CONF_FRAG uint8_t is_fragment = 0; /* tag of the fragment */ @@ -1610,15 +1792,15 @@ input(void) /* The MAC puts the 15.4 payload inside the packetbuf data buffer */ packetbuf_ptr = packetbuf_dataptr(); + /* This is default uip_buf since we assume that this is not fragmented */ + buffer = (uint8_t *)UIP_IP_BUF; + /* Save the RSSI of the incoming packet in case the upper layer will want to query us for it later. */ last_rssi = (signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI); + #if SICSLOWPAN_CONF_FRAG - /* if reassembly timed out, cancel it */ - if(timer_expired(&reass_timer)) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } + /* * Since we don't support the mesh and broadcast header, the first header * we look for is the fragmentation header @@ -1637,6 +1819,14 @@ input(void) /* printf("frag1 %d %d\n", reass_tag, frag_tag);*/ first_fragment = 1; is_fragment = 1; + + /* Add the fragment to the fragmentation context */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) return; + + buffer = frag_info[frag_context].first_frag; + break; case SICSLOWPAN_DISPATCH_FRAGN: /* @@ -1656,7 +1846,16 @@ input(void) PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); - if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { + /* Add the fragment to the fragmentation context (this will also copy the payload) */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) return; + + /* Ok - add_fragment will store the fragment automatically - so we should not store more */ + buffer = NULL; + + // if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { + if(frag_info[frag_context].reassembled_len >= frag_size) { last_fragment = 1; } is_fragment = 1; @@ -1665,65 +1864,7 @@ input(void) break; } - /* We are currently reassembling a packet, but have just received the first - * fragment of another packet. We can either ignore it and hope to receive - * the rest of the under-reassembly packet fragments, or we can discard the - * previous packet altogether, and start reassembling the new packet. - * - * We discard the previous packet, and start reassembling the new packet. - * This lessens the negative impacts of too high SICSLOWPAN_REASS_MAXAGE. - */ -#define PRIORITIZE_NEW_PACKETS 1 -#if PRIORITIZE_NEW_PACKETS - - if(!is_fragment) { - /* Prioritize non-fragment packets too. */ - sicslowpan_len = 0; - processed_ip_in_len = 0; - } else if(processed_ip_in_len > 0 && first_fragment - && !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } -#endif /* PRIORITIZE_NEW_PACKETS */ - - if(processed_ip_in_len > 0) { - /* reassembly is ongoing */ - /* printf("frag %d %d\n", reass_tag, frag_tag);*/ - if((frag_size > 0 && - (frag_size != sicslowpan_len || - reass_tag != frag_tag || - !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)))) || - frag_size == 0) { - /* - * the packet is a fragment that does not belong to the packet - * being reassembled or the packet is not a fragment. - */ - PRINTFI("sicslowpan input: Dropping 6lowpan packet that is not a fragment of the packet currently being reassembled\n"); - return; - } - } else { - /* - * reassembly is off - * start it if we received a fragment - */ - if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) { - /* We are currently not reassembling a packet, but have received a packet fragment - * that is not the first one. */ - if(is_fragment && !first_fragment) { - return; - } - - sicslowpan_len = frag_size; - reass_tag = frag_tag; - timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND); - PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n", - sicslowpan_len, reass_tag); - linkaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); - } - } - - if(packetbuf_hdr_len == SICSLOWPAN_FRAGN_HDR_LEN) { + if(is_fragment && !first_fragment) { /* this is a FRAGN, skip the header compression dispatch section */ goto copypayload; } @@ -1733,7 +1874,7 @@ input(void) #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 if((PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) { PRINTFI("sicslowpan input: IPHC\n"); - uncompress_hdr_hc06(frag_size); + uncompress_hdr_iphc(buffer, frag_size); } else #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { @@ -1748,7 +1889,7 @@ input(void) packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; /* Put uncompressed IP header in sicslowpan_buf. */ - memcpy(SICSLOWPAN_IP_BUF, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); + memcpy(buffer, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); /* Update uncomp_hdr_len and packetbuf_hdr_len. */ packetbuf_hdr_len += UIP_IPH_LEN; @@ -1782,16 +1923,20 @@ input(void) { int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3) + packetbuf_payload_len; - if(req_size > sizeof(sicslowpan_buf)) { + if(req_size > sizeof(uip_buf)) { PRINTF( - "SICSLOWPAN: packet dropped, minimum required SICSLOWPAN_IP_BUF size: %d+%d+%d+%d=%d (current size: %d)\n", + "SICSLOWPAN: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n", UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3), - packetbuf_payload_len, req_size, sizeof(sicslowpan_buf)); + packetbuf_payload_len, req_size, sizeof(uip_buf)); return; } } - memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); + /* copy the payload if buffer is non-null - which is only the case with first fragment + or packets that are non fragmented */ + if(buffer != NULL) { + memcpy((uint8_t *)buffer + uncomp_hdr_len, packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); + } /* update processed_ip_in_len if fragment, sicslowpan_len otherwise */ @@ -1799,44 +1944,40 @@ input(void) if(frag_size > 0) { /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { - processed_ip_in_len += uncomp_hdr_len; + frag_info[frag_context].reassembled_len = uncomp_hdr_len + packetbuf_payload_len; + frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len;; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ if(last_fragment != 0) { - processed_ip_in_len = frag_size; - } else { - processed_ip_in_len += packetbuf_payload_len; + frag_info[frag_context].reassembled_len = frag_size; + /* copy to uip */ + copy_frags2uip(frag_context); } - PRINTF("processed_ip_in_len %d, packetbuf_payload_len %d\n", processed_ip_in_len, packetbuf_payload_len); - - } else { -#endif /* SICSLOWPAN_CONF_FRAG */ - sicslowpan_len = packetbuf_payload_len + uncomp_hdr_len; -#if SICSLOWPAN_CONF_FRAG } /* * If we have a full IP packet in sicslowpan_buf, deliver it to * the IP stack */ - PRINTF("sicslowpan_init processed_ip_in_len %d, sicslowpan_len %d\n", - processed_ip_in_len, sicslowpan_len); - if(processed_ip_in_len == 0 || (processed_ip_in_len == sicslowpan_len)) { + if(!is_fragment || last_fragment) { + /* packet is in uip already - just set length */ + if(is_fragment != 0 && last_fragment != 0) { + uip_len = frag_size; + } else { + uip_len = packetbuf_payload_len + uncomp_hdr_len; + } PRINTFI("sicslowpan input: IP packet ready (length %d)\n", - sicslowpan_len); - memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len); - uip_len = sicslowpan_len; - sicslowpan_len = 0; - processed_ip_in_len = 0; + uip_len); + #endif /* SICSLOWPAN_CONF_FRAG */ #if DEBUG { uint16_t ndx; - PRINTF("after decompression %u:", SICSLOWPAN_IP_BUF->len[1]); - for (ndx = 0; ndx < SICSLOWPAN_IP_BUF->len[1] + 40; ndx++) { - uint8_t data = ((uint8_t *) (SICSLOWPAN_IP_BUF))[ndx]; + PRINTF("after decompression %u:", UIP_IP_BUF->len[1]); + for (ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) { + uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx]; PRINTF("%02x", data); } PRINTF("\n"); @@ -1926,3 +2067,4 @@ const struct network_driver sicslowpan_driver = { }; /*--------------------------------------------------------------------*/ /** @} */ + From d4dc45e09697627f690e17505584dd4e87fcd816 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 14 Sep 2015 17:34:08 +0200 Subject: [PATCH 49/94] updated sicslowpan documentation and platform configurations --- core/net/ipv6/sicslowpan.c | 10 +++--- doc/sicslowpan-doc.txt | 67 ++++++++++++++--------------------- platform/micaz/contiki-conf.h | 1 + 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index f6af5d46f..e7973d987 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -211,7 +211,6 @@ static uint8_t uncomp_hdr_len; static int last_tx_status; /** @} */ -static uint16_t my_tag; static int last_rssi; @@ -222,6 +221,8 @@ static int last_rssi; * temporary memory allocation. In that case the number of available * buffers will be lower for a short time. **/ +#if SICSLOWPAN_CONF_FRAG +static uint16_t my_tag; /** The total length of the IPv6 packet in the sicslowpan_buf. */ @@ -434,7 +435,7 @@ copy_frags2uip(int context) /* deallocate all the fragments for this context */ clear_fragments(context); } - +#endif /* SICSLOWPAN_CONF_FRAG */ /* -------------------------------------------------------------------------- */ @@ -1541,6 +1542,7 @@ output(const uip_lladdr_t *localdest) #if SICSLOWPAN_CONF_FRAG /* Number of bytes processed. */ +#if SICSLOWPAN_CONF_FRAG uint16_t processed_ip_out_len; #endif /* SICSLOWPAN_CONF_FRAG */ @@ -1772,14 +1774,14 @@ input(void) { /* size of the IP packet (read from fragment) */ uint16_t frag_size = 0; - int8_t frag_context = 0; /* offset of the fragment in the IP packet */ uint8_t frag_offset = 0; - uint8_t is_fragment = 0; uint8_t *buffer; #if SICSLOWPAN_CONF_FRAG uint8_t is_fragment = 0; + int8_t frag_context = 0; + /* tag of the fragment */ uint16_t frag_tag = 0; uint8_t first_fragment = 0, last_fragment = 0; diff --git a/doc/sicslowpan-doc.txt b/doc/sicslowpan-doc.txt index 7157be96e..37a9ea0c7 100644 --- a/doc/sicslowpan-doc.txt +++ b/doc/sicslowpan-doc.txt @@ -38,10 +38,10 @@ ArchRock and Sensinode implementations. We do not implement mesh under related features, as we target route over techniques. -\subsection hc01 draft-hui-6lowpan-hc-01 +\subsection RFC 6282 -draft-hui-6lowpan-hc-01 defines a stateful header compression mechanism -which should soon deprecate the stateless header compression mechanism +RFC6282 defines a stateful header compression mechanism +which deprecate the stateless header compression mechanism defined in RFC4944. It is much more powerfull and flexible, in particular it allows compression of some multicast addresses and of all global unicast addresses. @@ -110,8 +110,8 @@ the link-layer address. The dependency is reflected in the \subsection io Packet Input/Output -At initialization, the #input function in sicslowpan.c is set as the -function to be called by the MAC upon packet reception. The #output +At initialization, the input function in sicslowpan.c is set as the +function to be called by the MAC upon packet reception. The output function is set as the tcpip_output function.
At packet reception, the link-layer copies the 802.15.4 payload in the rime buffer, and sets its length. It also stores the source and @@ -122,19 +122,19 @@ packetbuf_set_datalen(rx_frame.payload_length); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)&rx_frame.dest_addr); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)&rx_frame.src_addr); \endcode -It then calls the sicslowpan #input function. Similarly, when the IPv6 layer +It then calls the sicslowpan input function. Similarly, when the IPv6 layer has a packet to send over the radio, it puts the packet in uip_buf, -sets uip_len and calls the sicslowpan #output function. +sets uip_len and calls the sicslowpan output function. \subsection frag Fragmentation -\li #output function: When an IP packet, after header compression, is +\li output function: When an IP packet, after header compression, is too big to fit in a 802.15.4 frame, it is fragmented in several packets which are sent successively over the radio. The packets are formatted as defined in RFC 4944. Only the first fragment contains the IP/UDP compressed or uncompressed header fields. -\li #input function: This function takes care of fragment +\li input function: This function takes care of fragment reassembly. We do not assume that the fragments are received in order. When reassembly of a packet is ongoing, we discard any non fragmented packet or fragment from another packet. Reassembly times out after @@ -143,8 +143,9 @@ packet or fragment from another packet. Reassembly times out after \note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG compilation option. -\note As we do not support complex buffer allocation mechanism, for now -we define a new 1280 bytes buffer (#sicslowpan_buf) to reassemble packets. +\note In order to make it possible to reassemble multiple packets at +the same time we have a mechanism for storing each fragment per sender +and tag until it is fully reassembled or the reassemly times out. At reception, once all the fragments are received, we copy the packet to #uip_buf, set #uip_len, and call #tcpip_input. @@ -157,49 +158,35 @@ the header 25 bytes long). Compression schemes
The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the - compression scheme supported. We support HC1, HC06, and IPv6 compression. -HC1 and IPv6 compression are defined in RFC4944, HC06 in -draft-hui-6lowpan-hc-06. What we call IPv6 compression means sending packets +compression scheme supported. We support IPHC, and IPv6 compression. +IPv6 compression are defined in RFC4944, IPHC in RFC6282. +What we call IPv6 compression means sending packets with no compression, and adding the IPv6 dispatch before the IPv6 header.
If at compile time IPv6 "compression" is chosen, packets sent will never be compressed, and compressed packets will not be processed at reception.
-If at compile time either HC1 or HC06 are chosen, we will try to compress + +If at compile time IPHC is chosen, we will try to compress all fields at sending, and will accept packets compressed with the -chosen scheme, as well as uncompressed packets.
-Note that HC1 and HC06 supports are mutually exclusive. HC06 should soon -deprecate HC1. +chosen scheme, as well as uncompressed packets.
. Compression related functions
-When a packet is received, the #input function is called. Fragmentation +When a packet is received, the input function is called. Fragmentation issues are handled, then we check the dispatch byte: if it is IPv6, we -treat the packet inline. If it is HC1 or HC06, the corresponding -decompression function (#uncompress_hdr_hc1 or #uncompress_hdr_hc06) -is called.
+treat the packet inline. If it is IPHC, the decompression function +(uncompress_hdr_iphc) is called.
When a packet needs to be sent, we try to compress it. If only the IPv6 compression support is enabled, we just add the IPv6 dispatch before the -802.15.4 payload. If HC1 or HC06 support is enabled, we call the -corresponding compression function (#compress_hdr_hc1 or #compress_hdr_hc06) +802.15.4 payload. If IPHC support is enabled, we call the +corresponding compression function (compress_hdr_iphc) to compress the packet as much as possible. -HC1 comments
-In HC1, if the IPv6 flow label is not compressed, we would need to copy -the fields after the flow label starting in the middle of a byte (the -flow label is 20 bits long). To avoid this, we compress the packets only -if all fields can be compressed. If we cannot, we use the IPv6 dispatch -and send all headers fields inline. This behavior is the one defined in -draft-hui-6lowpan-interop-00.
-In the same way, if the packet is an UDP packet, we compress the UDP -header only if all fields can be compressed.
-Note that HC1 can only compress unicast link local addresses. For this -reason, we recommend using HC01. - -HC01 comments
-HC01 uses address contexts to enable compression of global unicast +IPHC comments
+IPHC uses address contexts to enable compression of global unicast addresses. All nodes must share context (namely the global prefixes in use) to compress and uncompress such addresses successfully. The context -number is defined by 2 bits. Context 00 is reserved for the link local +number is defined by 4 bits. Context 00 is reserved for the link local context. Other contexts have to be distributed within the LoWPAN -dynamically, by means of ND extensions yet to be defined.
+dynamically, by means of ND extensions yet to be implemented.
Until then, if you want to test global address compression, you need to configure the global contexts manually. diff --git a/platform/micaz/contiki-conf.h b/platform/micaz/contiki-conf.h index 099941d85..16e74567a 100644 --- a/platform/micaz/contiki-conf.h +++ b/platform/micaz/contiki-conf.h @@ -145,6 +145,7 @@ #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 4 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 From 02e07607a705185d7c5f9592973d378c29353e8d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 18 Sep 2015 09:25:42 +0200 Subject: [PATCH 50/94] removed old HC1 code since it is not expected to be used and removed NH_COMPRESSOR --- core/net/ipv6/sicslowpan.c | 273 ------------------------------------- 1 file changed, 273 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index e7973d987..6f23a77cd 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -172,10 +172,6 @@ void uip_log(char *msg); /** \name General variables * @{ */ -#ifdef SICSLOWPAN_NH_COMPRESSOR -/** A pointer to the additional compressor */ -extern struct sicslowpan_nh_compressor SICSLOWPAN_NH_COMPRESSOR; -#endif /** * A pointer to the packetbuf buffer. @@ -929,11 +925,6 @@ compress_hdr_iphc(linkaddr_t *link_destaddr) } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - /* if nothing to compress just return zero */ - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.compress(hc06_ptr, &uncomp_hdr_len); -#endif - /* before the packetbuf_hdr_len operation */ PACKETBUF_IPHC_BUF[0] = iphc0; PACKETBUF_IPHC_BUF[1] = iphc1; @@ -1168,11 +1159,6 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) } uncomp_hdr_len += UIP_UDPH_LEN; } -#ifdef SICSLOWPAN_NH_COMPRESSOR - else { - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.uncompress(hc06_ptr, sicslowpan_buf, &uncomp_hdr_len); - } -#endif } packetbuf_hdr_len = hc06_ptr - packetbuf_ptr; @@ -1199,256 +1185,6 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) /** @} */ #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 -/*--------------------------------------------------------------------*/ -/** \name HC1 compression and uncompression functions - * @{ */ -/*--------------------------------------------------------------------*/ -/** - * \brief Compress IP/UDP header using HC1 and HC_UDP - * - * This function is called by the 6lowpan code to create a compressed - * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the - * uip_buf buffer. - * - * - * If we can compress everything, we use HC1 dispatch, if not we use - * IPv6 dispatch.\n - * We can compress everything if: - * - IP version is - * - Flow label and traffic class are 0 - * - Both src and dest ip addresses are link local - * - Both src and dest interface ID are recoverable from lower layer - * header - * - Next header is either ICMP, UDP or TCP - * - * Moreover, if next header is UDP, we try to compress it using HC_UDP. - * This is feasible is both ports are between F0B0 and F0B0 + 15. - * - * - * Resulting header structure: - * - For ICMP, TCP, non compressed UDP\n - * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP)\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * - For compressed UDP\n - * HC1 encoding = 11111011, HC_UDP encoding = 11100000\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | src p.| dst p.| UDP checksum | L4 data... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * \param link_destaddr L2 destination address, needed to compress the - * IP destination field - */ -static void -compress_hdr_hc1(linkaddr_t *link_destaddr) -{ - /* - * Check if all the assumptions for full compression - * are valid : - */ - if(UIP_IP_BUF->vtc != 0x60 || - UIP_IP_BUF->tcflow != 0 || - UIP_IP_BUF->flow != 0 || - !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) || - !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr, - (uip_lladdr_t *)link_destaddr) || - (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && - UIP_IP_BUF->proto != UIP_PROTO_UDP && - UIP_IP_BUF->proto != UIP_PROTO_TCP)) - { - /* - * IPV6 DISPATCH - * Something cannot be compressed, use IPV6 DISPATCH, - * compress nothing, copy IPv6 header in packetbuf buffer - */ - *packetbuf_ptr = SICSLOWPAN_DISPATCH_IPV6; - packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; - memcpy(packetbuf_ptr + packetbuf_hdr_len, UIP_IP_BUF, UIP_IPH_LEN); - packetbuf_hdr_len += UIP_IPH_LEN; - uncomp_hdr_len += UIP_IPH_LEN; - } else { - /* - * HC1 DISPATCH - * maximum compresssion: - * All fields in the IP header but Hop Limit are elided - * If next header is UDP, we compress UDP header using HC2 - */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] = SICSLOWPAN_DISPATCH_HC1; - uncomp_hdr_len += UIP_IPH_LEN; - switch(UIP_IP_BUF->proto) { - case UIP_PROTO_ICMP6: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFC; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case UIP_PROTO_TCP: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFE; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif /* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case UIP_PROTO_UDP: - /* - * try to compress UDP header (we do only full compression). - * This is feasible if both src and dest ports are between - * SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15 - */ - PRINTF("local/remote port %u/%u\n",UIP_UDP_BUF->srcport,UIP_UDP_BUF->destport); - if(UIP_HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && - UIP_HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { - /* HC1 encoding */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] = 0xFB; - - /* HC_UDP encoding, ttl, src and dest ports, checksum */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] = 0xE0; - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL] = UIP_IP_BUF->ttl; - - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_PORT_MIN) << 4) + - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - SICSLOWPAN_UDP_PORT_MIN)); - memcpy(&PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], &UIP_UDP_BUF->udpchksum, 2); - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - uncomp_hdr_len += UIP_UDPH_LEN; - } else { - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFA; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif /*UIP_CONF_UDP*/ - } - } - return; -} - -/*--------------------------------------------------------------------*/ -/** - * \brief Uncompress HC1 (and HC_UDP) headers and put them in - * sicslowpan_buf - * - * This function is called by the input function when the dispatch is - * HC1. - * We %process the packet in the packetbuf buffer, uncompress the header - * fields, and copy the result in the sicslowpan buffer. - * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len - * are set to the appropriate values - * - * \param ip_len Equal to 0 if the packet is not a fragment (IP length - * is then inferred from the L2 length), non 0 if the packet is a 1st - * fragment. - */ -static void -uncompress_hdr_hc1(uint16_t ip_len) -{ - /* version, traffic class, flow label */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; - - /* src and dest ip addresses */ - uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); - - uncomp_hdr_len += UIP_IPH_LEN; - - /* Next header field */ - switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] & 0x06) { - case SICSLOWPAN_HC1_NH_ICMP6: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_ICMP6; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case SICSLOWPAN_HC1_NH_TCP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_TCP; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif/* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case SICSLOWPAN_HC1_NH_UDP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] & 0x01) { - /* UDP header is compressed with HC_UDP */ - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] != - SICSLOWPAN_HC_UDP_ALL_C) { - PRINTF("sicslowpan (uncompress_hdr), packet not supported"); - return; - } - /* IP TTL */ - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL]; - /* UDP ports, len, checksum */ - SICSLOWPAN_UDP_BUF->srcport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] >> 4)); - SICSLOWPAN_UDP_BUF->destport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] & 0x0F)); - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, &PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], 2); - uncomp_hdr_len += UIP_UDPH_LEN; - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - } else { - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif/* UIP_CONF_UDP */ - default: - /* this shouldn't happen, drop */ - return; - } - - /* IP length field. */ - if(ip_len == 0) { - int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; - /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; - } else { - /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; - } - /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); - } - return; -} -/** @} */ -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ - - - /*--------------------------------------------------------------------*/ /** \name IPv6 dispatch "compression" function * @{ */ @@ -1595,9 +1331,6 @@ output(const uip_lladdr_t *localdest) if(uip_len >= COMPRESSION_THRESHOLD) { /* Try to compress the headers */ -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - compress_hdr_hc1(&dest); -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 compress_hdr_ipv6(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ @@ -1880,12 +1613,6 @@ input(void) } else #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - case SICSLOWPAN_DISPATCH_HC1: - PRINTFI("sicslowpan input: HC1\n"); - uncompress_hdr_hc1(frag_size); - break; -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ case SICSLOWPAN_DISPATCH_IPV6: PRINTFI("sicslowpan input: IPV6\n"); packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; From 103911f619af93cce70749c99b0b6a129b5d4fe0 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 00:04:32 +0100 Subject: [PATCH 51/94] Added driver for the Sparkfun's weather meter station --- examples/zolertia/zoul/Makefile | 3 +- examples/zolertia/zoul/test-weather-meter.c | 124 +++++++++ platform/zoul/dev/weather-meter.c | 262 ++++++++++++++++++++ platform/zoul/dev/weather-meter.h | 147 +++++++++++ 4 files changed, 535 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/test-weather-meter.c create mode 100644 platform/zoul/dev/weather-meter.c create mode 100644 platform/zoul/dev/weather-meter.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 7ead94a69..3cfa30021 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -3,9 +3,10 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt CONTIKI_PROJECT += test-bmp085 test-motion test-rotation-sensor CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor +CONTIKI_PROJECT += test-weather-meter CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c -CONTIKI_TARGET_SOURCEFILES += adc-sensors.c +CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c new file mode 100644 index 000000000..5f04f4015 --- /dev/null +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -0,0 +1,124 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-weather-meter-test Test the Sparkfun's weather meter + * + * The example application shows how to read data from the anemometer, wind vane + * and rain gauge, on board the Sparkfun's weater meter + * + * @{ + * + * \file + * Test application for the Sparkfun's weather meter + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "dev/leds.h" +#include "dev/weather-meter.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define READ_SENSOR_PERIOD CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS(test_weather_meter_sensors, "Test Weather meter sensors"); +AUTOSTART_PROCESSES(&test_weather_meter_sensors); +/*---------------------------------------------------------------------------*/ +static void +rain_callback(uint8_t value) +{ + printf("*** Rain\n"); +} +/*---------------------------------------------------------------------------*/ +static void +wind_speed_callback(uint8_t value) +{ + printf("*** Wind speed\n"); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_weather_meter_sensors, ev, data) +{ + PROCESS_BEGIN(); + + static uint32_t rain; + static uint16_t wind_speed; + static uint16_t wind_dir; + + /* Register the callback handler when thresholds are met */ + WEATHER_METER_REGISTER_ANEMOMETER_INT(wind_speed_callback); + WEATHER_METER_REGISTER_RAIN_GAUGE_INT(rain_callback); + + SENSORS_ACTIVATE(weather_meter); + + etimer_set(&et, READ_SENSOR_PERIOD); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + rain = weather_meter.value(WEATHER_METER_RAIN_GAUGE); + wind_speed = weather_meter.value(WEATHER_METER_ANEMOMETER); + wind_dir = weather_meter.value(WEATHER_METER_WIND_VANE); + + #if WEATHER_METER_RAIN_RETURN_TICKS + rain *= WEATHER_METER_AUX_RAIN_MM; + if(rain > (WEATHER_METER_AUX_RAIN_MM * 3)) { + printf("Rain: %lu.%lu mm\n", (rain / 10000), (rain % 10000)); + #else + if(rain >= 10) { + printf("Rain: %u.%u mm\n", (rain / 10), (rain % 10)); + #endif + } else { + printf("Rain: 0.%lu mm\n", rain); + } + + printf("Wind direction: %u metres/hour\n", wind_dir); + printf("Wind speed %u\n", wind_speed); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c new file mode 100644 index 000000000..bfb99945b --- /dev/null +++ b/platform/zoul/dev/weather-meter.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-weather-meter-sensor + * @{ + * + * The Sparkfun's weather meter comprises an anemometer, wind vane and rain + * gauge, see https://www.sparkfun.com/products/8942 + * + * \file + * Weather meter sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/adc-sensors.h" +#include "dev/weather-meter.h" +#include "lib/sensors.h" +#include "dev/sys-ctrl.h" +#include "dev/gpio.h" +#include "dev/ioc.h" +#include "sys/timer.h" +#include "sys/etimer.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 6) +/*---------------------------------------------------------------------------*/ +#define ANEMOMETER_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(ANEMOMETER_SENSOR_PORT) +#define ANEMOMETER_SENSOR_PIN_MASK GPIO_PIN_MASK(ANEMOMETER_SENSOR_PIN) +#define RAIN_GAUGE_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(RAIN_GAUGE_SENSOR_PORT) +#define RAIN_GAUGE_SENSOR_PIN_MASK GPIO_PIN_MASK(RAIN_GAUGE_SENSOR_PIN) +/*---------------------------------------------------------------------------*/ +void (*rain_gauge_int_callback)(uint8_t value); +void (*anemometer_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +process_event_t anemometer_int_event; +process_event_t rain_gauge_int_event; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint16_t ticks; + uint16_t value; +} a_ticking_sensor_t; + +typedef struct { + uint16_t wind_vane; + a_ticking_sensor_t rain_gauge; + a_ticking_sensor_t anemometer; +} weather_meter_sensors; +static weather_meter_sensors weather_sensors; +/*---------------------------------------------------------------------------*/ +PROCESS(weather_meter_int_process, "Weather meter interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(weather_meter_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + static uint32_t mph; + static uint16_t rpm; + + etimer_set(&et, CLOCK_SECOND); + + while(1) { + PROCESS_YIELD(); + + /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h + * makes the switch close every second, convert RPM to linear velocity + */ + + if(ev == PROCESS_EVENT_TIMER) { + + /* Disable to make the calculations in an interrupt-safe context */ + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + + /* Two ticks per rotation */ + rpm = weather_sensors.anemometer.ticks * 30; + + mph = rpm * WEATHER_METER_AUX_ANGULAR; + mph /= 1000; + + /* This will return values in metres per hour */ + weather_sensors.anemometer.value = (uint16_t)mph; + + /* Restart the counter */ + weather_sensors.anemometer.ticks = 0; + + /* Enable the interrupt again */ + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + etimer_restart(&et); + } + + // anemometer_int_callback(0); + // rain_gauge_int_callback(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +weather_meter_interrupt_handler(uint8_t port, uint8_t pin) +{ + uint32_t aux; + + /* Prevent bounce events */ + if(!timer_expired(&debouncetimer)) { + return; + } + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + /* We make a process_post() to check in the pollhandler any specific threshold + * value + */ + + if((port == ANEMOMETER_SENSOR_PORT) && (pin == ANEMOMETER_SENSOR_PIN)) { + weather_sensors.anemometer.ticks++; + process_post(&weather_meter_int_process, anemometer_int_event, NULL); + + } else if((port == RAIN_GAUGE_SENSOR_PORT) && (pin == RAIN_GAUGE_SENSOR_PIN)) { + weather_sensors.rain_gauge.ticks++; + aux = weather_sensors.rain_gauge.ticks * WEATHER_METER_AUX_RAIN_MM; + aux /= 1000; + weather_sensors.rain_gauge.value = (uint16_t)aux; + process_post(&weather_meter_int_process, rain_gauge_int_event, NULL); + } +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if((type != WEATHER_METER_ANEMOMETER) && (type != WEATHER_METER_RAIN_GAUGE) && + (type != WEATHER_METER_WIND_VANE)) { + PRINTF("Weather: requested an invalid sensor value\n"); + return WEATHER_METER_ERROR; + } + + switch(type) { + case WEATHER_METER_WIND_VANE: + /* FIXME: return the values in degrees */ + weather_sensors.wind_vane = adc_sensors.value(WIND_VANE_ADC); + return weather_sensors.wind_vane; + + case WEATHER_METER_ANEMOMETER: + return weather_sensors.anemometer.value; + + /* as the default return type is int, we have a lower resolution if returning + * the calculated value as it is truncated, an alternative is returning the + * ticks and calculating on your own with WEATHER_METER_AUX_RAIN_MM + */ + case WEATHER_METER_RAIN_GAUGE: + #if WEATHER_METER_RAIN_RETURN_TICKS + return weather_sensors.rain_gauge.ticks; + #else + return weather_sensors.rain_gauge.value; + #endif + + default: + return WEATHER_METER_ERROR; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != WEATHER_METER_ACTIVE) { + PRINTF("Weather: invalid configuration option\n"); + return WEATHER_METER_ERROR; + } + + weather_sensors.wind_vane = 0; + weather_sensors.anemometer.ticks = 0; + weather_sensors.anemometer.value = 0; + weather_sensors.rain_gauge.ticks = 0; + weather_sensors.rain_gauge.value = 0; + + if(!value) { + anemometer_int_callback = NULL; + rain_gauge_int_callback = NULL; + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + return WEATHER_METER_SUCCESS; + } + + /* Configure the wind vane */ + adc_sensors.configure(SENSORS_HW_INIT, WIND_VANE_ADC); + + /* Configure anemometer interruption */ + GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, + ANEMOMETER_SENSOR_PIN); + + /* Configure rain gauge interruption */ + GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, + RAIN_GAUGE_SENSOR_PIN); + + process_start(&weather_meter_int_process, NULL); + + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); + nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); + + return WEATHER_METER_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(weather_meter, WEATHER_METER_SENSOR, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h new file mode 100644 index 000000000..bda7c06ab --- /dev/null +++ b/platform/zoul/dev/weather-meter.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-weather-meter-sensor Sparkfun's weather meter + * @{ + * + * \file + * Weather meter header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef WEATHER_METER_H_ +#define WEATHER_METER_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter sensor return and operation values + * @{ + */ +#define WEATHER_METER_ANEMOMETER 0x00 +#define WEATHER_METER_RAIN_GAUGE 0x01 +#define WEATHER_METER_WIND_VANE 0x02 + +#define WEATHER_METER_ACTIVE SENSORS_ACTIVE +#define WEATHER_METER_SUCCESS 0 +#define WEATHER_METER_ERROR (-1) + +#define WEATHER_METER_ANEMOMETER_RADIUS 65 /**< 65.2 mm pin to cup centre */ +#define WEATHER_METER_AUX_CAL 377 /**< 2*pi*60 (376.992 rounded) */ +#define WEATHER_METER_AUX_ANGULAR (WEATHER_METER_ANEMOMETER_RADIUS * \ + WEATHER_METER_AUX_CAL) +#define WEATHER_METER_AUX_RAIN_MM 2794 /**< 0.2794mm per tick */ + +#ifdef WEATHER_METER_RAIN_CONF_RETURN +#define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN +#else +#define WEATHER_METER_RAIN_RETURN_TICKS 1 +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Anemometer and rain gauge sensor interrupt callback macro + * @{ + */ +#define WEATHER_METER_REGISTER_ANEMOMETER_INT(ptr) anemometer_int_callback = ptr; +#define WEATHER_METER_REGISTER_RAIN_GAUGE_INT(ptr) rain_gauge_int_callback = ptr; +extern void (*anemometer_int_callback)(uint8_t value); +extern void (*rain_gauge_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's anemometer default pin, port and interrupt vector + * @{ + */ +#ifdef WEATHER_METER_CONF_ANEMOMETER_PIN +#define ANEMOMETER_SENSOR_PIN WEATHER_METER_CONF_ANEMOMETER_PIN +#else +#define ANEMOMETER_SENSOR_PIN 1 +#endif +#ifdef WEATHER_METER_CONF_ANEMOMETER_PORT +#define ANEMOMETER_SENSOR_PORT WEATHER_METER_CONF_ANEMOMETER_PORT +#else +#define ANEMOMETER_SENSOR_PORT GPIO_D_NUM +#endif +#ifdef WEATHER_METER_CONF_ANEMOMETER_VECTOR +#define ANEMOMETER_SENSOR_VECTOR WEATHER_METER_CONF_ANEMOMETER_VECTOR +#else +#define ANEMOMETER_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's rain gauge default pin, port and interrupt vector + * @{ + */ +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_PIN +#define RAIN_GAUGE_SENSOR_PIN WEATHER_METER_CONF_RAIN_GAUGE_PIN +#else +#define RAIN_GAUGE_SENSOR_PIN 2 +#endif +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_PORT +#define RAIN_GAUGE_SENSOR_PORT WEATHER_METER_CONF_RAIN_GAUGE_PORT +#else +#define RAIN_GAUGE_SENSOR_PORT GPIO_D_NUM +#endif +#ifdef WEATHER_METER_CONF_RAIN_GAUGE_VECTOR +#define RAIN_GAUGE_SENSOR_VECTOR WEATHER_METER_CONF_RAIN_GAUGE_VECTOR +#else +#define RAIN_GAUGE_SENSOR_VECTOR NVIC_INT_GPIO_PORT_D +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Weather meter's wind vane default ADCx pin (see board.h) + * @{ + */ +#ifdef WEATHER_METER_CONF_RAIN_WIND_VANE_ADC +#define WIND_VANE_ADC WEATHER_METER_CONF_RAIN_WIND_VANE_ADC +#else +#define WIND_VANE_ADC ZOUL_SENSORS_ADC3 +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +#define WEATHER_METER_SENSOR "Sparkfun weather meter" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor weather_meter; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef WEATHER_METER_H_ */ +/** + * @} + * @} + */ From aacbcd904fd8fb06ada5e4e5a7e97d3ae899fa94 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 02:22:19 +0100 Subject: [PATCH 52/94] Added interrupt configuration for the weather meter --- examples/zolertia/zoul/test-weather-meter.c | 33 ++-- platform/zoul/dev/weather-meter.c | 168 +++++++++++++------- platform/zoul/dev/weather-meter.h | 36 +++-- 3 files changed, 155 insertions(+), 82 deletions(-) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 5f04f4015..3149404e7 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -55,7 +55,9 @@ #include #include /*---------------------------------------------------------------------------*/ -#define READ_SENSOR_PERIOD CLOCK_SECOND +#define READ_SENSOR_PERIOD CLOCK_SECOND +#define ANEMOMETER_THRESHOLD_TICK 8 +#define RAIN_GAUGE_THRESHOLD_TICK 15 /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ @@ -63,15 +65,17 @@ PROCESS(test_weather_meter_sensors, "Test Weather meter sensors"); AUTOSTART_PROCESSES(&test_weather_meter_sensors); /*---------------------------------------------------------------------------*/ static void -rain_callback(uint8_t value) +rain_callback(uint16_t value) { - printf("*** Rain\n"); + printf("*** Rain gauge over threshold (%u ticks)\n", value); + weather_meter.configure(WEATHER_METER_RAIN_GAUGE_INT_OVER, + (value + RAIN_GAUGE_THRESHOLD_TICK)); } /*---------------------------------------------------------------------------*/ static void -wind_speed_callback(uint8_t value) +wind_speed_callback(uint16_t value) { - printf("*** Wind speed\n"); + printf("*** Wind speed over threshold (%u ticks)\n", value); } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_weather_meter_sensors, ev, data) @@ -86,8 +90,17 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) WEATHER_METER_REGISTER_ANEMOMETER_INT(wind_speed_callback); WEATHER_METER_REGISTER_RAIN_GAUGE_INT(rain_callback); + /* Enable the sensors, this has to be called before any of the interrupt calls + * like the ones below + */ SENSORS_ACTIVATE(weather_meter); + /* And the upper threshold value to compare and generate an interrupt */ + weather_meter.configure(WEATHER_METER_ANEMOMETER_INT_OVER, + ANEMOMETER_THRESHOLD_TICK); + weather_meter.configure(WEATHER_METER_RAIN_GAUGE_INT_OVER, + RAIN_GAUGE_THRESHOLD_TICK); + etimer_set(&et, READ_SENSOR_PERIOD); while(1) { @@ -100,17 +113,17 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) #if WEATHER_METER_RAIN_RETURN_TICKS rain *= WEATHER_METER_AUX_RAIN_MM; if(rain > (WEATHER_METER_AUX_RAIN_MM * 3)) { - printf("Rain: %lu.%lu mm\n", (rain / 10000), (rain % 10000)); + printf("Rain: %lu.%lu mm, ", (rain / 10000), (rain % 10000)); #else if(rain >= 10) { - printf("Rain: %u.%u mm\n", (rain / 10), (rain % 10)); + printf("Rain: %u.%u mm, ", (rain / 10), (rain % 10)); #endif } else { - printf("Rain: 0.%lu mm\n", rain); + printf("Rain: 0.%lu mm, ", rain); } - printf("Wind direction: %u metres/hour\n", wind_dir); - printf("Wind speed %u\n", wind_speed); + printf("Wind (dir: %u deg, ", wind_dir); + printf("speed %u m/h)\n", wind_speed); etimer_reset(&et); } diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index bfb99945b..9e874d9e8 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -47,6 +47,7 @@ #include "contiki.h" #include "dev/adc-sensors.h" #include "dev/weather-meter.h" +#include "dev/zoul-sensors.h" #include "lib/sensors.h" #include "dev/sys-ctrl.h" #include "dev/gpio.h" @@ -54,22 +55,24 @@ #include "sys/timer.h" #include "sys/etimer.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -#define DEBOUNCE_DURATION (CLOCK_SECOND >> 6) +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) /*---------------------------------------------------------------------------*/ #define ANEMOMETER_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(ANEMOMETER_SENSOR_PORT) #define ANEMOMETER_SENSOR_PIN_MASK GPIO_PIN_MASK(ANEMOMETER_SENSOR_PIN) #define RAIN_GAUGE_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(RAIN_GAUGE_SENSOR_PORT) #define RAIN_GAUGE_SENSOR_PIN_MASK GPIO_PIN_MASK(RAIN_GAUGE_SENSOR_PIN) /*---------------------------------------------------------------------------*/ -void (*rain_gauge_int_callback)(uint8_t value); -void (*anemometer_int_callback)(uint8_t value); +void (*rain_gauge_int_callback)(uint16_t value); +void (*anemometer_int_callback)(uint16_t value); +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; /*---------------------------------------------------------------------------*/ process_event_t anemometer_int_event; process_event_t rain_gauge_int_event; @@ -80,12 +83,14 @@ static struct timer debouncetimer; typedef struct { uint16_t ticks; uint16_t value; -} a_ticking_sensor_t; + uint8_t int_en; + uint16_t int_thres; +} weather_meter_sensors_t; typedef struct { uint16_t wind_vane; - a_ticking_sensor_t rain_gauge; - a_ticking_sensor_t anemometer; + weather_meter_sensors_t rain_gauge; + weather_meter_sensors_t anemometer; } weather_meter_sensors; static weather_meter_sensors weather_sensors; /*---------------------------------------------------------------------------*/ @@ -103,9 +108,19 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) while(1) { PROCESS_YIELD(); - /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h - * makes the switch close every second, convert RPM to linear velocity - */ + if((ev == anemometer_int_event) && (weather_sensors.anemometer.int_en)) { + if(weather_sensors.anemometer.ticks >= + weather_sensors.anemometer.int_thres) { + anemometer_int_callback(weather_sensors.anemometer.ticks); + } + } + + if((ev == rain_gauge_int_event) && (weather_sensors.rain_gauge.int_en)) { + if(weather_sensors.rain_gauge.ticks >= + weather_sensors.rain_gauge.int_thres) { + rain_gauge_int_callback(weather_sensors.rain_gauge.ticks); + } + } if(ev == PROCESS_EVENT_TIMER) { @@ -113,9 +128,10 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - /* Two ticks per rotation */ + /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h + * makes the switch close every second, convert RPM to linear velocity + */ rpm = weather_sensors.anemometer.ticks * 30; - mph = rpm * WEATHER_METER_AUX_ANGULAR; mph /= 1000; @@ -130,9 +146,6 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) ANEMOMETER_SENSOR_PIN_MASK); etimer_restart(&et); } - - // anemometer_int_callback(0); - // rain_gauge_int_callback(0); } PROCESS_END(); } @@ -175,6 +188,11 @@ value(int type) return WEATHER_METER_ERROR; } + if(!enabled) { + PRINTF("Weather: module is not configured\n"); + return WEATHER_METER_ERROR; + } + switch(type) { case WEATHER_METER_WIND_VANE: /* FIXME: return the values in degrees */ @@ -203,56 +221,92 @@ value(int type) static int configure(int type, int value) { - if(type != WEATHER_METER_ACTIVE) { + if((type != WEATHER_METER_ACTIVE) && + (type != WEATHER_METER_ANEMOMETER_INT_OVER) && + (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && + (type != WEATHER_METER_ANEMOMETER_INT_DIS) && + (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { PRINTF("Weather: invalid configuration option\n"); return WEATHER_METER_ERROR; } - weather_sensors.wind_vane = 0; - weather_sensors.anemometer.ticks = 0; - weather_sensors.anemometer.value = 0; - weather_sensors.rain_gauge.ticks = 0; - weather_sensors.rain_gauge.value = 0; + if(type == WEATHER_METER_ACTIVE) { - if(!value) { - anemometer_int_callback = NULL; - rain_gauge_int_callback = NULL; - GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); - GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, - RAIN_GAUGE_SENSOR_PIN_MASK); + weather_sensors.anemometer.int_en = 0; + weather_sensors.rain_gauge.int_en = 0; + weather_sensors.anemometer.ticks = 0; + weather_sensors.rain_gauge.ticks = 0; + + if(!value) { + anemometer_int_callback = NULL; + rain_gauge_int_callback = NULL; + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DISABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + process_exit(&weather_meter_int_process); + enabled = 0; + PRINTF("Weather: disabled\n"); + return WEATHER_METER_SUCCESS; + } + + /* Configure the wind vane */ + adc_sensors.configure(SENSORS_HW_INIT, WIND_VANE_ADC); + + /* Configure anemometer interruption */ + GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, + ANEMOMETER_SENSOR_PIN); + + /* Configure rain gauge interruption */ + GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, + RAIN_GAUGE_SENSOR_PIN_MASK); + ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); + gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, + RAIN_GAUGE_SENSOR_PIN); + + process_start(&weather_meter_int_process, NULL); + + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); + GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); + nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); + nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); + + enabled = 1; + PRINTF("Weather: started\n"); return WEATHER_METER_SUCCESS; } - /* Configure the wind vane */ - adc_sensors.configure(SENSORS_HW_INIT, WIND_VANE_ADC); - - /* Configure anemometer interruption */ - GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - GPIO_SET_INPUT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - GPIO_DETECT_RISING(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - GPIO_TRIGGER_SINGLE_EDGE(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); - ioc_set_over(ANEMOMETER_SENSOR_PORT, ANEMOMETER_SENSOR_PIN, IOC_OVERRIDE_DIS); - gpio_register_callback(weather_meter_interrupt_handler, ANEMOMETER_SENSOR_PORT, - ANEMOMETER_SENSOR_PIN); - - /* Configure rain gauge interruption */ - GPIO_SOFTWARE_CONTROL(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); - GPIO_SET_INPUT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); - GPIO_DETECT_RISING(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); - GPIO_TRIGGER_SINGLE_EDGE(RAIN_GAUGE_SENSOR_PORT_BASE, - RAIN_GAUGE_SENSOR_PIN_MASK); - ioc_set_over(RAIN_GAUGE_SENSOR_PORT, RAIN_GAUGE_SENSOR_PIN, IOC_OVERRIDE_DIS); - gpio_register_callback(weather_meter_interrupt_handler, RAIN_GAUGE_SENSOR_PORT, - RAIN_GAUGE_SENSOR_PIN); - - process_start(&weather_meter_int_process, NULL); - - GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); - nvic_interrupt_enable(ANEMOMETER_SENSOR_VECTOR); - nvic_interrupt_enable(RAIN_GAUGE_SENSOR_VECTOR); + switch(type) { + case WEATHER_METER_ANEMOMETER_INT_OVER: + weather_sensors.anemometer.int_en = 1; + weather_sensors.anemometer.int_thres = value; + PRINTF("Weather: anemometer threshold %u\n", value); + break; + case WEATHER_METER_RAIN_GAUGE_INT_OVER: + weather_sensors.rain_gauge.int_en = 1; + weather_sensors.rain_gauge.int_thres = value; + PRINTF("Weather: rain gauge threshold %u\n", value); + break; + case WEATHER_METER_ANEMOMETER_INT_DIS: + PRINTF("Weather: anemometer int disabled\n"); + weather_sensors.anemometer.int_en = 0; + break; + case WEATHER_METER_RAIN_GAUGE_INT_DIS: + PRINTF("Weather: rain gauge int disabled\n"); + weather_sensors.rain_gauge.int_en = 0; + break; + default: + return WEATHER_METER_ERROR; + } return WEATHER_METER_SUCCESS; } diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h index bda7c06ab..3de2d5971 100644 --- a/platform/zoul/dev/weather-meter.h +++ b/platform/zoul/dev/weather-meter.h @@ -44,6 +44,7 @@ */ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" +#include "dev/zoul-sensors.h" /* -------------------------------------------------------------------------- */ #ifndef WEATHER_METER_H_ #define WEATHER_METER_H_ @@ -52,24 +53,29 @@ * \name Weather meter sensor return and operation values * @{ */ -#define WEATHER_METER_ANEMOMETER 0x00 -#define WEATHER_METER_RAIN_GAUGE 0x01 -#define WEATHER_METER_WIND_VANE 0x02 +#define WEATHER_METER_ANEMOMETER 0x00 +#define WEATHER_METER_RAIN_GAUGE 0x01 +#define WEATHER_METER_WIND_VANE 0x02 -#define WEATHER_METER_ACTIVE SENSORS_ACTIVE -#define WEATHER_METER_SUCCESS 0 -#define WEATHER_METER_ERROR (-1) +#define WEATHER_METER_ACTIVE SENSORS_ACTIVE +#define WEATHER_METER_ANEMOMETER_INT_OVER HW_INT_OVER_THRS +#define WEATHER_METER_ANEMOMETER_INT_DIS HW_INT_DISABLE +#define WEATHER_METER_RAIN_GAUGE_INT_OVER (HW_INT_OVER_THRS << 1) +#define WEATHER_METER_RAIN_GAUGE_INT_DIS (HW_INT_DISABLE << 1) -#define WEATHER_METER_ANEMOMETER_RADIUS 65 /**< 65.2 mm pin to cup centre */ -#define WEATHER_METER_AUX_CAL 377 /**< 2*pi*60 (376.992 rounded) */ -#define WEATHER_METER_AUX_ANGULAR (WEATHER_METER_ANEMOMETER_RADIUS * \ - WEATHER_METER_AUX_CAL) -#define WEATHER_METER_AUX_RAIN_MM 2794 /**< 0.2794mm per tick */ +#define WEATHER_METER_SUCCESS 0 +#define WEATHER_METER_ERROR (-1) + +#define WEATHER_METER_ANEMOMETER_RADIUS 65 /**< 65.2 mm pin to cup centre */ +#define WEATHER_METER_AUX_CAL 377 /**< 2*pi*60 (376.992 rounded) */ +#define WEATHER_METER_AUX_ANGULAR (WEATHER_METER_ANEMOMETER_RADIUS * \ + WEATHER_METER_AUX_CAL) +#define WEATHER_METER_AUX_RAIN_MM 2794 /**< 0.2794mm per tick */ #ifdef WEATHER_METER_RAIN_CONF_RETURN -#define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN +#define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN #else -#define WEATHER_METER_RAIN_RETURN_TICKS 1 +#define WEATHER_METER_RAIN_RETURN_TICKS 1 #endif /** @} */ /* -------------------------------------------------------------------------- */ @@ -79,8 +85,8 @@ */ #define WEATHER_METER_REGISTER_ANEMOMETER_INT(ptr) anemometer_int_callback = ptr; #define WEATHER_METER_REGISTER_RAIN_GAUGE_INT(ptr) rain_gauge_int_callback = ptr; -extern void (*anemometer_int_callback)(uint8_t value); -extern void (*rain_gauge_int_callback)(uint8_t value); +extern void (*anemometer_int_callback)(uint16_t value); +extern void (*rain_gauge_int_callback)(uint16_t value); /** @} */ /* -------------------------------------------------------------------------- */ /** From 0cb80b060588ec2947392a2a2ea140fa737bcd60 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 02:25:00 +0100 Subject: [PATCH 53/94] Prevent calculations if tick is zero --- platform/zoul/dev/weather-meter.c | 38 +++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 9e874d9e8..ea7f41331 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -123,28 +123,30 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) } if(ev == PROCESS_EVENT_TIMER) { + if(weather_sensors.anemometer.ticks) { - /* Disable to make the calculations in an interrupt-safe context */ - GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); + /* Disable to make the calculations in an interrupt-safe context */ + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); - /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h - * makes the switch close every second, convert RPM to linear velocity - */ - rpm = weather_sensors.anemometer.ticks * 30; - mph = rpm * WEATHER_METER_AUX_ANGULAR; - mph /= 1000; + /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h + * makes the switch close every second, convert RPM to linear velocity + */ + rpm = weather_sensors.anemometer.ticks * 30; + mph = rpm * WEATHER_METER_AUX_ANGULAR; + mph /= 1000; - /* This will return values in metres per hour */ - weather_sensors.anemometer.value = (uint16_t)mph; + /* This will return values in metres per hour */ + weather_sensors.anemometer.value = (uint16_t)mph; - /* Restart the counter */ - weather_sensors.anemometer.ticks = 0; + /* Restart the counter */ + weather_sensors.anemometer.ticks = 0; - /* Enable the interrupt again */ - GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); - etimer_restart(&et); + /* Enable the interrupt again */ + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + etimer_restart(&et); + } } } PROCESS_END(); @@ -236,6 +238,8 @@ configure(int type, int value) weather_sensors.rain_gauge.int_en = 0; weather_sensors.anemometer.ticks = 0; weather_sensors.rain_gauge.ticks = 0; + weather_sensors.anemometer.value = 0; + weather_sensors.rain_gauge.value = 0; if(!value) { anemometer_int_callback = NULL; From 61f151636931f71e89d87cd18935d3499db38881 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 14:56:12 +0100 Subject: [PATCH 54/94] Reworked instant wind speed calculation and extended the available wind speed return values --- examples/zolertia/zoul/test-weather-meter.c | 25 ++++- platform/zoul/dev/weather-meter.c | 117 ++++++++++++++------ platform/zoul/dev/weather-meter.h | 15 ++- 3 files changed, 111 insertions(+), 46 deletions(-) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 3149404e7..9a0adf7f7 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -56,8 +56,8 @@ #include /*---------------------------------------------------------------------------*/ #define READ_SENSOR_PERIOD CLOCK_SECOND -#define ANEMOMETER_THRESHOLD_TICK 8 -#define RAIN_GAUGE_THRESHOLD_TICK 15 +#define ANEMOMETER_THRESHOLD_TICK 13 /**< 16 Km/h */ +#define RAIN_GAUGE_THRESHOLD_TICK 15 /**< each increment of 4.19 mm */ /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ @@ -67,6 +67,7 @@ AUTOSTART_PROCESSES(&test_weather_meter_sensors); static void rain_callback(uint16_t value) { + /* To calculate ticks from mm of rain, divide by 0.2794 mm */ printf("*** Rain gauge over threshold (%u ticks)\n", value); weather_meter.configure(WEATHER_METER_RAIN_GAUGE_INT_OVER, (value + RAIN_GAUGE_THRESHOLD_TICK)); @@ -75,6 +76,12 @@ rain_callback(uint16_t value) static void wind_speed_callback(uint16_t value) { + /* This checks for instant wind speed values (over a second), the minimum + * value is 1.2 Km/h (one tick), as the reference is 2.4KM/h per rotation, and + * the anemometer makes 2 ticks per rotation. Instant speed is calculated as + * multiples of this, so if you want to check for 16Km/h, then it would be 13 + * ticks + */ printf("*** Wind speed over threshold (%u ticks)\n", value); } /*---------------------------------------------------------------------------*/ @@ -85,6 +92,9 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) static uint32_t rain; static uint16_t wind_speed; static uint16_t wind_dir; + static uint16_t wind_speed_avg; + static uint16_t wind_speed_avg_2m; + static uint16_t wind_speed_max; /* Register the callback handler when thresholds are met */ WEATHER_METER_REGISTER_ANEMOMETER_INT(wind_speed_callback); @@ -109,6 +119,9 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) rain = weather_meter.value(WEATHER_METER_RAIN_GAUGE); wind_speed = weather_meter.value(WEATHER_METER_ANEMOMETER); wind_dir = weather_meter.value(WEATHER_METER_WIND_VANE); + wind_speed_avg = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG); + wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_2M); + wind_speed_max = weather_meter.value(WEATHER_METER_ANEMOMETER_MAX); #if WEATHER_METER_RAIN_RETURN_TICKS rain *= WEATHER_METER_AUX_RAIN_MM; @@ -122,8 +135,12 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) printf("Rain: 0.%lu mm, ", rain); } - printf("Wind (dir: %u deg, ", wind_dir); - printf("speed %u m/h)\n", wind_speed); + printf("Wind dir: %u deg,\n", wind_dir); + printf("Wind speed: %u m/h ", wind_speed); + printf("(%u m/h avg, %u m/h 2m avg, %u m/h max)\n\n", wind_speed_avg, + wind_speed_avg_2m, + wind_speed_max); + etimer_reset(&et); } diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index ea7f41331..e0a97e64b 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -53,7 +53,7 @@ #include "dev/gpio.h" #include "dev/ioc.h" #include "sys/timer.h" -#include "sys/etimer.h" +#include "sys/rtimer.h" /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG @@ -62,7 +62,7 @@ #define PRINTF(...) #endif /*---------------------------------------------------------------------------*/ -#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 6) /*---------------------------------------------------------------------------*/ #define ANEMOMETER_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(ANEMOMETER_SENSOR_PORT) #define ANEMOMETER_SENSOR_PIN_MASK GPIO_PIN_MASK(ANEMOMETER_SENSOR_PIN) @@ -77,7 +77,7 @@ static uint8_t enabled; process_event_t anemometer_int_event; process_event_t rain_gauge_int_event; /*---------------------------------------------------------------------------*/ -static struct etimer et; +static struct rtimer rt; static struct timer debouncetimer; /*---------------------------------------------------------------------------*/ typedef struct { @@ -87,12 +87,65 @@ typedef struct { uint16_t int_thres; } weather_meter_sensors_t; +typedef struct { + uint16_t value_max; + uint64_t ticks_avg; + uint64_t value_avg; + uint32_t value_buf_2m; + uint16_t value_avg_2m; +} weather_meter_ext_t; + typedef struct { uint16_t wind_vane; weather_meter_sensors_t rain_gauge; weather_meter_sensors_t anemometer; } weather_meter_sensors; + static weather_meter_sensors weather_sensors; +static weather_meter_ext_t anemometer; +/*---------------------------------------------------------------------------*/ +void +rt_callback(struct rtimer *t, void *ptr) +{ + uint32_t wind_speed; + + /* Disable to make the calculations in an interrupt-safe context */ + GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + wind_speed = weather_sensors.anemometer.ticks; + wind_speed *= WEATHER_METER_ANEMOMETER_SPEED_1S; + weather_sensors.anemometer.value = (uint16_t)wind_speed; + anemometer.ticks_avg++; + anemometer.value_avg += weather_sensors.anemometer.value; + anemometer.value_buf_2m += weather_sensors.anemometer.value; + + /* Take maximum value */ + if(weather_sensors.anemometer.value > anemometer.value_max) { + anemometer.value_max = weather_sensors.anemometer.value; + } + + /* Average every 2 minutes */ + if(!(anemometer.ticks_avg % 120)) { + if(anemometer.value_buf_2m) { + anemometer.value_avg_2m = anemometer.value_buf_2m / 120; + anemometer.value_buf_2m = 0; + } else { + anemometer.value_avg_2m = 0; + } + } + + /* Check for roll-over */ + if(!anemometer.ticks_avg) { + anemometer.value_avg = 0; + } + + weather_sensors.anemometer.ticks = 0; + + /* Enable the interrupt again */ + GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, + ANEMOMETER_SENSOR_PIN_MASK); + rtimer_set(&rt, RTIMER_NOW() + RTIMER_SECOND, 1, rt_callback, NULL); +} /*---------------------------------------------------------------------------*/ PROCESS(weather_meter_int_process, "Weather meter interrupt process handler"); /*---------------------------------------------------------------------------*/ @@ -100,10 +153,6 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) { PROCESS_EXITHANDLER(); PROCESS_BEGIN(); - static uint32_t mph; - static uint16_t rpm; - - etimer_set(&et, CLOCK_SECOND); while(1) { PROCESS_YIELD(); @@ -121,33 +170,6 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) rain_gauge_int_callback(weather_sensors.rain_gauge.ticks); } } - - if(ev == PROCESS_EVENT_TIMER) { - if(weather_sensors.anemometer.ticks) { - - /* Disable to make the calculations in an interrupt-safe context */ - GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); - - /* The anemometer ticks twice per rotation, and a wind speed of 2.4 km/h - * makes the switch close every second, convert RPM to linear velocity - */ - rpm = weather_sensors.anemometer.ticks * 30; - mph = rpm * WEATHER_METER_AUX_ANGULAR; - mph /= 1000; - - /* This will return values in metres per hour */ - weather_sensors.anemometer.value = (uint16_t)mph; - - /* Restart the counter */ - weather_sensors.anemometer.ticks = 0; - - /* Enable the interrupt again */ - GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, - ANEMOMETER_SENSOR_PIN_MASK); - etimer_restart(&et); - } - } } PROCESS_END(); } @@ -184,8 +206,14 @@ weather_meter_interrupt_handler(uint8_t port, uint8_t pin) static int value(int type) { - if((type != WEATHER_METER_ANEMOMETER) && (type != WEATHER_METER_RAIN_GAUGE) && - (type != WEATHER_METER_WIND_VANE)) { + uint64_t aux; + + if((type != WEATHER_METER_ANEMOMETER) && + (type != WEATHER_METER_RAIN_GAUGE) && + (type != WEATHER_METER_WIND_VANE) && + (type != WEATHER_METER_ANEMOMETER_AVG) && + (type != WEATHER_METER_ANEMOMETER_AVG_2M) && + (type != WEATHER_METER_ANEMOMETER_MAX)) { PRINTF("Weather: requested an invalid sensor value\n"); return WEATHER_METER_ERROR; } @@ -204,6 +232,19 @@ value(int type) case WEATHER_METER_ANEMOMETER: return weather_sensors.anemometer.value; + case WEATHER_METER_ANEMOMETER_AVG: + if(anemometer.value_avg <= 0) { + return (uint16_t)anemometer.value_avg; + } + aux = anemometer.value_avg / anemometer.ticks_avg; + return (uint16_t)aux; + + case WEATHER_METER_ANEMOMETER_AVG_2M: + return anemometer.value_avg_2m; + + case WEATHER_METER_ANEMOMETER_MAX: + return anemometer.value_max; + /* as the default return type is int, we have a lower resolution if returning * the calculated value as it is truncated, an alternative is returning the * ticks and calculating on your own with WEATHER_METER_AUX_RAIN_MM @@ -234,6 +275,9 @@ configure(int type, int value) if(type == WEATHER_METER_ACTIVE) { + anemometer.value_avg = 0; + anemometer.ticks_avg = 0; + weather_sensors.anemometer.int_en = 0; weather_sensors.rain_gauge.int_en = 0; weather_sensors.anemometer.ticks = 0; @@ -278,6 +322,7 @@ configure(int type, int value) RAIN_GAUGE_SENSOR_PIN); process_start(&weather_meter_int_process, NULL); + rtimer_set(&rt, RTIMER_NOW() + RTIMER_SECOND, 1, rt_callback, NULL); GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h index 3de2d5971..47ef859f3 100644 --- a/platform/zoul/dev/weather-meter.h +++ b/platform/zoul/dev/weather-meter.h @@ -53,9 +53,12 @@ * \name Weather meter sensor return and operation values * @{ */ -#define WEATHER_METER_ANEMOMETER 0x00 #define WEATHER_METER_RAIN_GAUGE 0x01 #define WEATHER_METER_WIND_VANE 0x02 +#define WEATHER_METER_ANEMOMETER 0x03 +#define WEATHER_METER_ANEMOMETER_AVG 0x04 +#define WEATHER_METER_ANEMOMETER_AVG_2M 0x05 +#define WEATHER_METER_ANEMOMETER_MAX 0x06 #define WEATHER_METER_ACTIVE SENSORS_ACTIVE #define WEATHER_METER_ANEMOMETER_INT_OVER HW_INT_OVER_THRS @@ -66,11 +69,11 @@ #define WEATHER_METER_SUCCESS 0 #define WEATHER_METER_ERROR (-1) -#define WEATHER_METER_ANEMOMETER_RADIUS 65 /**< 65.2 mm pin to cup centre */ -#define WEATHER_METER_AUX_CAL 377 /**< 2*pi*60 (376.992 rounded) */ -#define WEATHER_METER_AUX_ANGULAR (WEATHER_METER_ANEMOMETER_RADIUS * \ - WEATHER_METER_AUX_CAL) -#define WEATHER_METER_AUX_RAIN_MM 2794 /**< 0.2794mm per tick */ +/* 2.4Km/h per tick, 2 per rotation */ +#define WEATHER_METER_ANEMOMETER_SPEED_1S (1200) + +/* 0.2794mm per tick */ +#define WEATHER_METER_AUX_RAIN_MM 2794 #ifdef WEATHER_METER_RAIN_CONF_RETURN #define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN From 0902e0fc6d413b50fe45f58a7cbfc7076a5b0170 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sun, 17 Jan 2016 21:34:52 +0100 Subject: [PATCH 55/94] Added degree converted value for the wind vane sensor. Also added a 2-minutes average wind direction value, replaced the 240 bytes buffer from the reference example, but probably there's room for efficiency improvement --- examples/zolertia/zoul/test-weather-meter.c | 6 +- platform/zoul/dev/weather-meter.c | 126 +++++++++++++++++++- platform/zoul/dev/weather-meter.h | 10 +- 3 files changed, 132 insertions(+), 10 deletions(-) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 9a0adf7f7..93998d9e8 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -92,6 +92,7 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) static uint32_t rain; static uint16_t wind_speed; static uint16_t wind_dir; + static uint16_t wind_dir_avg_2m; static uint16_t wind_speed_avg; static uint16_t wind_speed_avg_2m; static uint16_t wind_speed_max; @@ -119,6 +120,7 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) rain = weather_meter.value(WEATHER_METER_RAIN_GAUGE); wind_speed = weather_meter.value(WEATHER_METER_ANEMOMETER); wind_dir = weather_meter.value(WEATHER_METER_WIND_VANE); + wind_dir_avg_2m = weather_meter.value(WEATHER_METER_WIND_VANE_AVG_2M); wind_speed_avg = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG); wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_2M); wind_speed_max = weather_meter.value(WEATHER_METER_ANEMOMETER_MAX); @@ -135,12 +137,12 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) printf("Rain: 0.%lu mm, ", rain); } - printf("Wind dir: %u deg,\n", wind_dir); + printf("Wind dir: %u.%01u deg, ", (wind_dir / 10), (wind_dir % 10)); + printf("(%u.%01u deg avg)\n", (wind_dir_avg_2m / 10), (wind_dir_avg_2m % 10)); printf("Wind speed: %u m/h ", wind_speed); printf("(%u m/h avg, %u m/h 2m avg, %u m/h max)\n\n", wind_speed_avg, wind_speed_avg_2m, wind_speed_max); - etimer_reset(&et); } diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index e0a97e64b..98324b0d0 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -101,13 +101,96 @@ typedef struct { weather_meter_sensors_t anemometer; } weather_meter_sensors; +typedef struct { + uint32_t value_buf_2m; + uint16_t value_prev; + uint16_t value_avg_2m; +} weather_meter_wind_vane_ext_t; + static weather_meter_sensors weather_sensors; static weather_meter_ext_t anemometer; +static weather_meter_wind_vane_ext_t wind_vane; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint16_t mid_point; + uint16_t degree; +} wind_vane_mid_point_t; + + /* From the datasheet we adjusted the values for a 3V divider, using a 10K + * resistor, the check values are the following: + * --------------------+------------------+------------------------------- + * Direction (Degrees) Resistance (Ohms) Voltage (mV) + * 0 33k 2532.55 * + * 22.5 6.57k 1308.44 * + * 45 8.2k 1486.81 * + * 67.5 891 269.97 * + * 90 1k 300.00 * + * 112.5 688 212.42 * + * 135 2.2k 595.08 * + * 157.5 1.41k 407.80 * + * 180 3.9k 925.89 * + * 202.5 3.14k 788.58 * + * 225 16k 2030.76 * + * 247.5 14.12k 1930.84 * + * 270 120k 3046.15 * + * 292.5 42.12k 2666.84 * + * 315 64.9k 2859.41 * + * 337.5 21.88k 2264.86 * + * --------------------+------------------+------------------------------- + */ +static const wind_vane_mid_point_t wind_vane_table[16] = { + { 2124, 1125 }, + { 2699, 675 }, + { 3000, 900 }, + { 4078, 1575 }, + { 5950, 1350 }, + { 7885, 2025 }, + { 9258, 1800 }, + { 13084, 225 }, + { 14868, 450 }, + { 19308, 2475 }, + { 20307, 2250 }, + { 22648, 3375 }, + { 25325, 0 }, + { 26668, 2925 }, + { 28594, 3150 }, + { 30461, 2700 }, +}; +/*---------------------------------------------------------------------------*/ +static int +weather_meter_wind_vane_degrees(uint16_t value) +{ + uint8_t i; + for(i=0; i<16; i++) { + if(value <= wind_vane_table[i].mid_point) { + return (int)wind_vane_table[i].degree; + } else { + if(i == 15) { + return (int)wind_vane_table[i].degree; + } + } + } + + PRINTF("Weather: invalid wind vane value\n"); + return WEATHER_METER_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +weather_meter_get_wind_dir(void) +{ + weather_sensors.wind_vane = adc_sensors.value(WIND_VANE_ADC); + if((int16_t)weather_sensors.wind_vane < 0) { + weather_sensors.wind_vane = 0; + } + return weather_meter_wind_vane_degrees(weather_sensors.wind_vane); +} /*---------------------------------------------------------------------------*/ void rt_callback(struct rtimer *t, void *ptr) { uint32_t wind_speed; + int16_t wind_dir; + int16_t wind_dir_delta; /* Disable to make the calculations in an interrupt-safe context */ GPIO_DISABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, @@ -124,14 +207,43 @@ rt_callback(struct rtimer *t, void *ptr) anemometer.value_max = weather_sensors.anemometer.value; } - /* Average every 2 minutes */ + /* Mitsuta method to get the wind direction average */ + wind_dir = weather_meter_get_wind_dir(); + wind_dir_delta = wind_dir - wind_vane.value_prev; + + if(wind_dir_delta < -1800) { + wind_vane.value_prev += wind_dir_delta + 3600; + } else if(wind_dir_delta > 1800) { + wind_vane.value_prev += wind_dir_delta - 3600; + } else { + wind_vane.value_prev += wind_dir_delta; + } + + wind_vane.value_buf_2m += wind_vane.value_prev; + + /* Calculate the 2 minute average */ if(!(anemometer.ticks_avg % 120)) { + PRINTF("Weather: calculate the 2m averages ***\n"); + if(anemometer.value_buf_2m) { anemometer.value_avg_2m = anemometer.value_buf_2m / 120; anemometer.value_buf_2m = 0; } else { anemometer.value_avg_2m = 0; } + + wind_vane.value_buf_2m = wind_vane.value_buf_2m / 120; + wind_vane.value_avg_2m = (uint16_t)wind_vane.value_buf_2m; + if(wind_vane.value_avg_2m >= 3600) { + wind_vane.value_avg_2m -= 3600; + } + + if(wind_vane.value_avg_2m < 0) { + wind_vane.value_avg_2m += 3600; + } + + wind_vane.value_buf_2m = 0; + wind_vane.value_prev = wind_dir; } /* Check for roll-over */ @@ -211,6 +323,7 @@ value(int type) if((type != WEATHER_METER_ANEMOMETER) && (type != WEATHER_METER_RAIN_GAUGE) && (type != WEATHER_METER_WIND_VANE) && + (type != WEATHER_METER_WIND_VANE_AVG_2M) && (type != WEATHER_METER_ANEMOMETER_AVG) && (type != WEATHER_METER_ANEMOMETER_AVG_2M) && (type != WEATHER_METER_ANEMOMETER_MAX)) { @@ -225,9 +338,10 @@ value(int type) switch(type) { case WEATHER_METER_WIND_VANE: - /* FIXME: return the values in degrees */ - weather_sensors.wind_vane = adc_sensors.value(WIND_VANE_ADC); - return weather_sensors.wind_vane; + return weather_meter_get_wind_dir(); + + case WEATHER_METER_WIND_VANE_AVG_2M: + return wind_vane.value_avg_2m; case WEATHER_METER_ANEMOMETER: return weather_sensors.anemometer.value; @@ -322,6 +436,10 @@ configure(int type, int value) RAIN_GAUGE_SENSOR_PIN); process_start(&weather_meter_int_process, NULL); + + /* Initialize here prior the first second tick */ + wind_vane.value_prev = weather_meter_get_wind_dir(); + rtimer_set(&rt, RTIMER_NOW() + RTIMER_SECOND, 1, rt_callback, NULL); GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h index 47ef859f3..1ce941968 100644 --- a/platform/zoul/dev/weather-meter.h +++ b/platform/zoul/dev/weather-meter.h @@ -55,10 +55,11 @@ */ #define WEATHER_METER_RAIN_GAUGE 0x01 #define WEATHER_METER_WIND_VANE 0x02 -#define WEATHER_METER_ANEMOMETER 0x03 -#define WEATHER_METER_ANEMOMETER_AVG 0x04 -#define WEATHER_METER_ANEMOMETER_AVG_2M 0x05 -#define WEATHER_METER_ANEMOMETER_MAX 0x06 +#define WEATHER_METER_WIND_VANE_AVG_2M 0x03 +#define WEATHER_METER_ANEMOMETER 0x04 +#define WEATHER_METER_ANEMOMETER_AVG 0x05 +#define WEATHER_METER_ANEMOMETER_AVG_2M 0x06 +#define WEATHER_METER_ANEMOMETER_MAX 0x07 #define WEATHER_METER_ACTIVE SENSORS_ACTIVE #define WEATHER_METER_ANEMOMETER_INT_OVER HW_INT_OVER_THRS @@ -75,6 +76,7 @@ /* 0.2794mm per tick */ #define WEATHER_METER_AUX_RAIN_MM 2794 +/* Allows to select the return type: ticks or converted value (truncated) */ #ifdef WEATHER_METER_RAIN_CONF_RETURN #define WEATHER_METER_RAIN_RETURN_TICKS WEATHER_METER_RAIN_CONF_RETURN #else From 81bec49a40182a6ec1b195aac127c9a17ec2df68 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 19 Jan 2016 18:00:18 +0100 Subject: [PATCH 56/94] Changed fixed 2 minute integration period to allow overriding --- examples/zolertia/zoul/test-weather-meter.c | 7 ++- platform/zoul/dev/weather-meter.c | 50 ++++++++++----------- platform/zoul/dev/weather-meter.h | 11 ++++- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 93998d9e8..17417fea1 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -97,6 +97,9 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) static uint16_t wind_speed_avg_2m; static uint16_t wind_speed_max; + printf("Weather meter test example, integration period %u\n", + WEATHER_METER_AVG_PERIOD); + /* Register the callback handler when thresholds are met */ WEATHER_METER_REGISTER_ANEMOMETER_INT(wind_speed_callback); WEATHER_METER_REGISTER_RAIN_GAUGE_INT(rain_callback); @@ -120,9 +123,9 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) rain = weather_meter.value(WEATHER_METER_RAIN_GAUGE); wind_speed = weather_meter.value(WEATHER_METER_ANEMOMETER); wind_dir = weather_meter.value(WEATHER_METER_WIND_VANE); - wind_dir_avg_2m = weather_meter.value(WEATHER_METER_WIND_VANE_AVG_2M); + wind_dir_avg_2m = weather_meter.value(WEATHER_METER_WIND_VANE_AVG_X); wind_speed_avg = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG); - wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_2M); + wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_X); wind_speed_max = weather_meter.value(WEATHER_METER_ANEMOMETER_MAX); #if WEATHER_METER_RAIN_RETURN_TICKS diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 98324b0d0..f7b972180 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -91,8 +91,8 @@ typedef struct { uint16_t value_max; uint64_t ticks_avg; uint64_t value_avg; - uint32_t value_buf_2m; - uint16_t value_avg_2m; + uint32_t value_buf_xm; + uint16_t value_avg_xm; } weather_meter_ext_t; typedef struct { @@ -102,9 +102,9 @@ typedef struct { } weather_meter_sensors; typedef struct { - uint32_t value_buf_2m; + uint32_t value_buf_xm; uint16_t value_prev; - uint16_t value_avg_2m; + uint16_t value_avg_xm; } weather_meter_wind_vane_ext_t; static weather_meter_sensors weather_sensors; @@ -200,7 +200,7 @@ rt_callback(struct rtimer *t, void *ptr) weather_sensors.anemometer.value = (uint16_t)wind_speed; anemometer.ticks_avg++; anemometer.value_avg += weather_sensors.anemometer.value; - anemometer.value_buf_2m += weather_sensors.anemometer.value; + anemometer.value_buf_xm += weather_sensors.anemometer.value; /* Take maximum value */ if(weather_sensors.anemometer.value > anemometer.value_max) { @@ -219,30 +219,30 @@ rt_callback(struct rtimer *t, void *ptr) wind_vane.value_prev += wind_dir_delta; } - wind_vane.value_buf_2m += wind_vane.value_prev; + wind_vane.value_buf_xm += wind_vane.value_prev; /* Calculate the 2 minute average */ - if(!(anemometer.ticks_avg % 120)) { - PRINTF("Weather: calculate the 2m averages ***\n"); + if(!(anemometer.ticks_avg % WEATHER_METER_AVG_PERIOD)) { + PRINTF("Weather: calculate the %u averages ***\n", WEATHER_METER_AVG_PERIOD); - if(anemometer.value_buf_2m) { - anemometer.value_avg_2m = anemometer.value_buf_2m / 120; - anemometer.value_buf_2m = 0; + if(anemometer.value_buf_xm) { + anemometer.value_avg_xm = anemometer.value_buf_xm / WEATHER_METER_AVG_PERIOD; + anemometer.value_buf_xm = 0; } else { - anemometer.value_avg_2m = 0; + anemometer.value_avg_xm = 0; } - wind_vane.value_buf_2m = wind_vane.value_buf_2m / 120; - wind_vane.value_avg_2m = (uint16_t)wind_vane.value_buf_2m; - if(wind_vane.value_avg_2m >= 3600) { - wind_vane.value_avg_2m -= 3600; + wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; + wind_vane.value_avg_xm = (uint16_t)wind_vane.value_buf_xm; + if(wind_vane.value_avg_xm >= 3600) { + wind_vane.value_avg_xm -= 3600; } - if(wind_vane.value_avg_2m < 0) { - wind_vane.value_avg_2m += 3600; + if(wind_vane.value_avg_xm < 0) { + wind_vane.value_avg_xm += 3600; } - wind_vane.value_buf_2m = 0; + wind_vane.value_buf_xm = 0; wind_vane.value_prev = wind_dir; } @@ -323,9 +323,9 @@ value(int type) if((type != WEATHER_METER_ANEMOMETER) && (type != WEATHER_METER_RAIN_GAUGE) && (type != WEATHER_METER_WIND_VANE) && - (type != WEATHER_METER_WIND_VANE_AVG_2M) && + (type != WEATHER_METER_WIND_VANE_AVG_X) && (type != WEATHER_METER_ANEMOMETER_AVG) && - (type != WEATHER_METER_ANEMOMETER_AVG_2M) && + (type != WEATHER_METER_ANEMOMETER_AVG_X) && (type != WEATHER_METER_ANEMOMETER_MAX)) { PRINTF("Weather: requested an invalid sensor value\n"); return WEATHER_METER_ERROR; @@ -340,8 +340,8 @@ value(int type) case WEATHER_METER_WIND_VANE: return weather_meter_get_wind_dir(); - case WEATHER_METER_WIND_VANE_AVG_2M: - return wind_vane.value_avg_2m; + case WEATHER_METER_WIND_VANE_AVG_X: + return wind_vane.value_avg_xm; case WEATHER_METER_ANEMOMETER: return weather_sensors.anemometer.value; @@ -353,8 +353,8 @@ value(int type) aux = anemometer.value_avg / anemometer.ticks_avg; return (uint16_t)aux; - case WEATHER_METER_ANEMOMETER_AVG_2M: - return anemometer.value_avg_2m; + case WEATHER_METER_ANEMOMETER_AVG_X: + return anemometer.value_avg_xm; case WEATHER_METER_ANEMOMETER_MAX: return anemometer.value_max; diff --git a/platform/zoul/dev/weather-meter.h b/platform/zoul/dev/weather-meter.h index 1ce941968..9f6d1fc7f 100644 --- a/platform/zoul/dev/weather-meter.h +++ b/platform/zoul/dev/weather-meter.h @@ -55,12 +55,19 @@ */ #define WEATHER_METER_RAIN_GAUGE 0x01 #define WEATHER_METER_WIND_VANE 0x02 -#define WEATHER_METER_WIND_VANE_AVG_2M 0x03 +#define WEATHER_METER_WIND_VANE_AVG_X 0x03 #define WEATHER_METER_ANEMOMETER 0x04 #define WEATHER_METER_ANEMOMETER_AVG 0x05 -#define WEATHER_METER_ANEMOMETER_AVG_2M 0x06 +#define WEATHER_METER_ANEMOMETER_AVG_X 0x06 #define WEATHER_METER_ANEMOMETER_MAX 0x07 +/* Period (seconds) to calculate an average */ +#ifdef WEATHER_METER_CONF_AVG_PERIOD +#define WEATHER_METER_AVG_PERIOD WEATHER_METER_CONF_AVG_PERIOD +#else +#define WEATHER_METER_AVG_PERIOD 120 +#endif + #define WEATHER_METER_ACTIVE SENSORS_ACTIVE #define WEATHER_METER_ANEMOMETER_INT_OVER HW_INT_OVER_THRS #define WEATHER_METER_ANEMOMETER_INT_DIS HW_INT_DISABLE From 366f11d5df773b3dae5802289520e7bc5056254e Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 19 Jan 2016 18:03:16 +0100 Subject: [PATCH 57/94] Uncrustified weather meter driver and example --- examples/zolertia/zoul/test-weather-meter.c | 16 ++-- platform/zoul/dev/weather-meter.c | 91 ++++++++++----------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/examples/zolertia/zoul/test-weather-meter.c b/examples/zolertia/zoul/test-weather-meter.c index 17417fea1..2e2bcba2f 100644 --- a/examples/zolertia/zoul/test-weather-meter.c +++ b/examples/zolertia/zoul/test-weather-meter.c @@ -128,14 +128,14 @@ PROCESS_THREAD(test_weather_meter_sensors, ev, data) wind_speed_avg_2m = weather_meter.value(WEATHER_METER_ANEMOMETER_AVG_X); wind_speed_max = weather_meter.value(WEATHER_METER_ANEMOMETER_MAX); - #if WEATHER_METER_RAIN_RETURN_TICKS - rain *= WEATHER_METER_AUX_RAIN_MM; - if(rain > (WEATHER_METER_AUX_RAIN_MM * 3)) { - printf("Rain: %lu.%lu mm, ", (rain / 10000), (rain % 10000)); - #else - if(rain >= 10) { - printf("Rain: %u.%u mm, ", (rain / 10), (rain % 10)); - #endif +#if WEATHER_METER_RAIN_RETURN_TICKS + rain *= WEATHER_METER_AUX_RAIN_MM; + if(rain > (WEATHER_METER_AUX_RAIN_MM * 3)) { + printf("Rain: %lu.%lu mm, ", (rain / 10000), (rain % 10000)); +#else + if(rain >= 10) { + printf("Rain: %u.%u mm, ", (rain / 10), (rain % 10)); +#endif } else { printf("Rain: 0.%lu mm, ", rain); } diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index f7b972180..933fc975d 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -83,7 +83,7 @@ static struct timer debouncetimer; typedef struct { uint16_t ticks; uint16_t value; - uint8_t int_en; + uint8_t int_en; uint16_t int_thres; } weather_meter_sensors_t; @@ -116,28 +116,28 @@ typedef struct { uint16_t degree; } wind_vane_mid_point_t; - /* From the datasheet we adjusted the values for a 3V divider, using a 10K - * resistor, the check values are the following: - * --------------------+------------------+------------------------------- - * Direction (Degrees) Resistance (Ohms) Voltage (mV) - * 0 33k 2532.55 * - * 22.5 6.57k 1308.44 * - * 45 8.2k 1486.81 * - * 67.5 891 269.97 * - * 90 1k 300.00 * - * 112.5 688 212.42 * - * 135 2.2k 595.08 * - * 157.5 1.41k 407.80 * - * 180 3.9k 925.89 * - * 202.5 3.14k 788.58 * - * 225 16k 2030.76 * - * 247.5 14.12k 1930.84 * - * 270 120k 3046.15 * - * 292.5 42.12k 2666.84 * - * 315 64.9k 2859.41 * - * 337.5 21.88k 2264.86 * - * --------------------+------------------+------------------------------- - */ +/* From the datasheet we adjusted the values for a 3V divider, using a 10K + * resistor, the check values are the following: + * --------------------+------------------+------------------------------- + * Direction (Degrees) Resistance (Ohms) Voltage (mV) + * 0 33k 2532.55 * + * 22.5 6.57k 1308.44 * + * 45 8.2k 1486.81 * + * 67.5 891 269.97 * + * 90 1k 300.00 * + * 112.5 688 212.42 * + * 135 2.2k 595.08 * + * 157.5 1.41k 407.80 * + * 180 3.9k 925.89 * + * 202.5 3.14k 788.58 * + * 225 16k 2030.76 * + * 247.5 14.12k 1930.84 * + * 270 120k 3046.15 * + * 292.5 42.12k 2666.84 * + * 315 64.9k 2859.41 * + * 337.5 21.88k 2264.86 * + * --------------------+------------------+------------------------------- + */ static const wind_vane_mid_point_t wind_vane_table[16] = { { 2124, 1125 }, { 2699, 675 }, @@ -161,7 +161,7 @@ static int weather_meter_wind_vane_degrees(uint16_t value) { uint8_t i; - for(i=0; i<16; i++) { + for(i = 0; i < 16; i++) { if(value <= wind_vane_table[i].mid_point) { return (int)wind_vane_table[i].degree; } else { @@ -232,13 +232,13 @@ rt_callback(struct rtimer *t, void *ptr) anemometer.value_avg_xm = 0; } - wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; + wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; wind_vane.value_avg_xm = (uint16_t)wind_vane.value_buf_xm; - if(wind_vane.value_avg_xm >= 3600) { + if(wind_vane.value_avg_xm >= 3600) { wind_vane.value_avg_xm -= 3600; } - if(wind_vane.value_avg_xm < 0) { + if(wind_vane.value_avg_xm < 0) { wind_vane.value_avg_xm += 3600; } @@ -271,14 +271,14 @@ PROCESS_THREAD(weather_meter_int_process, ev, data) if((ev == anemometer_int_event) && (weather_sensors.anemometer.int_en)) { if(weather_sensors.anemometer.ticks >= - weather_sensors.anemometer.int_thres) { + weather_sensors.anemometer.int_thres) { anemometer_int_callback(weather_sensors.anemometer.ticks); } } if((ev == rain_gauge_int_event) && (weather_sensors.rain_gauge.int_en)) { if(weather_sensors.rain_gauge.ticks >= - weather_sensors.rain_gauge.int_thres) { + weather_sensors.rain_gauge.int_thres) { rain_gauge_int_callback(weather_sensors.rain_gauge.ticks); } } @@ -305,7 +305,6 @@ weather_meter_interrupt_handler(uint8_t port, uint8_t pin) if((port == ANEMOMETER_SENSOR_PORT) && (pin == ANEMOMETER_SENSOR_PIN)) { weather_sensors.anemometer.ticks++; process_post(&weather_meter_int_process, anemometer_int_event, NULL); - } else if((port == RAIN_GAUGE_SENSOR_PORT) && (pin == RAIN_GAUGE_SENSOR_PIN)) { weather_sensors.rain_gauge.ticks++; aux = weather_sensors.rain_gauge.ticks * WEATHER_METER_AUX_RAIN_MM; @@ -321,12 +320,12 @@ value(int type) uint64_t aux; if((type != WEATHER_METER_ANEMOMETER) && - (type != WEATHER_METER_RAIN_GAUGE) && - (type != WEATHER_METER_WIND_VANE) && - (type != WEATHER_METER_WIND_VANE_AVG_X) && - (type != WEATHER_METER_ANEMOMETER_AVG) && - (type != WEATHER_METER_ANEMOMETER_AVG_X) && - (type != WEATHER_METER_ANEMOMETER_MAX)) { + (type != WEATHER_METER_RAIN_GAUGE) && + (type != WEATHER_METER_WIND_VANE) && + (type != WEATHER_METER_WIND_VANE_AVG_X) && + (type != WEATHER_METER_ANEMOMETER_AVG) && + (type != WEATHER_METER_ANEMOMETER_AVG_X) && + (type != WEATHER_METER_ANEMOMETER_MAX)) { PRINTF("Weather: requested an invalid sensor value\n"); return WEATHER_METER_ERROR; } @@ -364,11 +363,11 @@ value(int type) * ticks and calculating on your own with WEATHER_METER_AUX_RAIN_MM */ case WEATHER_METER_RAIN_GAUGE: - #if WEATHER_METER_RAIN_RETURN_TICKS - return weather_sensors.rain_gauge.ticks; - #else - return weather_sensors.rain_gauge.value; - #endif +#if WEATHER_METER_RAIN_RETURN_TICKS + return weather_sensors.rain_gauge.ticks; +#else + return weather_sensors.rain_gauge.value; +#endif default: return WEATHER_METER_ERROR; @@ -378,11 +377,11 @@ value(int type) static int configure(int type, int value) { - if((type != WEATHER_METER_ACTIVE) && - (type != WEATHER_METER_ANEMOMETER_INT_OVER) && - (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && - (type != WEATHER_METER_ANEMOMETER_INT_DIS) && - (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { + if((type != WEATHER_METER_ACTIVE) && + (type != WEATHER_METER_ANEMOMETER_INT_OVER) && + (type != WEATHER_METER_RAIN_GAUGE_INT_OVER) && + (type != WEATHER_METER_ANEMOMETER_INT_DIS) && + (type != WEATHER_METER_RAIN_GAUGE_INT_DIS)) { PRINTF("Weather: invalid configuration option\n"); return WEATHER_METER_ERROR; } From 6ef8f477643345d70c43ecdb30a62718ed41111d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 18 Sep 2015 14:22:17 +0200 Subject: [PATCH 58/94] Style fixes, LLSEC.overhead and MAC_MAX_PAYLOAD --- core/net/ipv6/sicslowpan.c | 51 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 6f23a77cd..869379489 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -213,10 +213,7 @@ static int last_rssi; /* ----------------------------------------------------------------- */ /* Support for reassembling multiple packets */ /* ----------------------------------------------------------------- */ -/* The fragmentation buffer are also possible to use for other - * temporary memory allocation. In that case the number of available - * buffers will be lower for a short time. - **/ + #if SICSLOWPAN_CONF_FRAG static uint16_t my_tag; @@ -406,13 +403,15 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset) frag_info[i].reassembled_len += len; return i; } else { - /* should we also clear all fragments since we failed to store this fragment? */ + /* should we also clear all fragments since we failed to store + this fragment? */ PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); return -1; } } /*---------------------------------------------------------------------------*/ -/* Copy all the fragments that are associated with a specific context into uip */ +/* Copy all the fragments that are associated with a specific context + into uip */ static void copy_frags2uip(int context) { @@ -501,7 +500,7 @@ static struct sicslowpan_addr_context *context; /** pointer to the byte where to write next inline field. */ static uint8_t *hc06_ptr; -/* ession of linklocal */ +/* Uncompression of linklocal */ /* 0 -> 16 bytes from packet */ /* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ /* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ @@ -945,6 +944,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr) * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len * are set to the appropriate values * + * \param buf Pointer to the buffer to uncompress the packet into. * \param ip_len Equal to 0 if the packet is not a fragment (IP length * is then inferred from the L2 length), non 0 if the packet is a 1st * fragment. @@ -1272,13 +1272,13 @@ static uint8_t output(const uip_lladdr_t *localdest) { int framer_hdrlen; + int max_payload; /* The MAC address of the destination of the packet */ linkaddr_t dest; #if SICSLOWPAN_CONF_FRAG /* Number of bytes processed. */ -#if SICSLOWPAN_CONF_FRAG uint16_t processed_ip_out_len; #endif /* SICSLOWPAN_CONF_FRAG */ @@ -1351,14 +1351,14 @@ output(const uip_lladdr_t *localdest) framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 23; + framer_hdrlen = 21; } #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 23; + framer_hdrlen = 21; #endif /* USE_FRAMER_HDRLEN */ - max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; - if((int)uip_len - (int)uncomp_hdr_len > (int)max_payload - (int)packetbuf_hdr_len) { + max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; + if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG struct queuebuf *q; uint16_t frag_tag; @@ -1402,7 +1402,7 @@ output(const uip_lladdr_t *localdest) /* Copy payload and send */ packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len); @@ -1438,7 +1438,7 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; @@ -1558,7 +1558,9 @@ input(void) /* Add the fragment to the fragmentation context */ frag_context = add_fragment(frag_tag, frag_size, frag_offset); - if(frag_context == -1) return; + if(frag_context == -1) { + return; + } buffer = frag_info[frag_context].first_frag; @@ -1581,15 +1583,18 @@ input(void) PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); - /* Add the fragment to the fragmentation context (this will also copy the payload) */ + /* Add the fragment to the fragmentation context (this will also + copy the payload) */ frag_context = add_fragment(frag_tag, frag_size, frag_offset); - if(frag_context == -1) return; + if(frag_context == -1) { + return; + } - /* Ok - add_fragment will store the fragment automatically - so we should not store more */ + /* Ok - add_fragment will store the fragment automatically - so + we should not store more */ buffer = NULL; - // if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { if(frag_info[frag_context].reassembled_len >= frag_size) { last_fragment = 1; } @@ -1674,7 +1679,7 @@ input(void) /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { frag_info[frag_context].reassembled_len = uncomp_hdr_len + packetbuf_payload_len; - frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len;; + frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ @@ -1696,11 +1701,12 @@ input(void) } else { uip_len = packetbuf_payload_len + uncomp_hdr_len; } +#else + uip_len = packetbuf_payload_len + uncomp_hdr_len; +#endif /* SICSLOWPAN_CONF_FRAG */ PRINTFI("sicslowpan input: IP packet ready (length %d)\n", uip_len); -#endif /* SICSLOWPAN_CONF_FRAG */ - #if DEBUG { uint16_t ndx; @@ -1736,6 +1742,7 @@ sicslowpan_init(void) * Set out output function as the function to be called from uIP to * send a packet. */ + tcpip_set_outputfunc(output); #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 From a6c30b4e09546686aad1bc9d9f340d77e80a6a0a Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 19 Jan 2016 22:23:30 +0100 Subject: [PATCH 59/94] Fixed missing static keyword in both zoul-demo and weather meter driver --- examples/zolertia/zoul/zoul-demo.c | 2 +- platform/zoul/dev/weather-meter.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/zolertia/zoul/zoul-demo.c b/examples/zolertia/zoul/zoul-demo.c index 127c18d50..a88e7c48c 100644 --- a/examples/zolertia/zoul/zoul-demo.c +++ b/examples/zolertia/zoul/zoul-demo.c @@ -108,7 +108,7 @@ broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) static const struct broadcast_callbacks bc_rx = { broadcast_recv }; static struct broadcast_conn bc; /*---------------------------------------------------------------------------*/ -void +static void rt_callback(struct rtimer *t, void *ptr) { leds_off(LEDS_PERIODIC); diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 933fc975d..8d3ee07f1 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -185,7 +185,7 @@ weather_meter_get_wind_dir(void) return weather_meter_wind_vane_degrees(weather_sensors.wind_vane); } /*---------------------------------------------------------------------------*/ -void +static void rt_callback(struct rtimer *t, void *ptr) { uint32_t wind_speed; @@ -223,7 +223,7 @@ rt_callback(struct rtimer *t, void *ptr) /* Calculate the 2 minute average */ if(!(anemometer.ticks_avg % WEATHER_METER_AVG_PERIOD)) { - PRINTF("Weather: calculate the %u averages ***\n", WEATHER_METER_AVG_PERIOD); + PRINTF("\nWeather: calculate the %u averages ***\n", WEATHER_METER_AVG_PERIOD); if(anemometer.value_buf_xm) { anemometer.value_avg_xm = anemometer.value_buf_xm / WEATHER_METER_AVG_PERIOD; From 98ed8a29a0b78bdecea3c93c9ac0e032bfb6cd81 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 19 Jan 2016 22:28:09 +0100 Subject: [PATCH 60/94] Removed harsh restriction on mask values and disabled debug flags --- platform/zoul/dev/adc-sensors.c | 2 +- platform/zoul/dev/adc-zoul.c | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index b69dfc8cf..11d727dbc 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -49,7 +49,7 @@ #include #include /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else diff --git a/platform/zoul/dev/adc-zoul.c b/platform/zoul/dev/adc-zoul.c index 4e309dcf4..f31a303ed 100644 --- a/platform/zoul/dev/adc-zoul.c +++ b/platform/zoul/dev/adc-zoul.c @@ -48,7 +48,7 @@ #include #include /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -136,13 +136,6 @@ configure(int type, int value) return ZOUL_SENSORS_ERROR; } - if((value != ZOUL_SENSORS_ADC1) && (value != ZOUL_SENSORS_ADC2) && - (value != ZOUL_SENSORS_ADC3) && (value != ZOUL_SENSORS_ADC4) && - (value != ZOUL_SENSORS_ADC5)) { - PRINTF("ADC: invalid adc pin mask\n"); - return ZOUL_SENSORS_ERROR; - } - GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, value); GPIO_SET_INPUT(GPIO_A_BASE, value); From 6351462e89abbbb8b37a7625ccfcee52f7dc2582 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 22 Jan 2016 16:11:49 +0100 Subject: [PATCH 61/94] Unified BMP180 and BMP085 drivers --- examples/zolertia/zoul/Makefile | 4 +- .../{test-bmp085.c => test-bmp085-bmp180.c} | 24 +- platform/zoul/dev/{bmp085.c => bmpx8x.c} | 252 +++++++++--------- platform/zoul/dev/{bmp085.h => bmpx8x.h} | 94 +++---- 4 files changed, 187 insertions(+), 187 deletions(-) rename examples/zolertia/zoul/{test-bmp085.c => test-bmp085-bmp180.c} (81%) rename platform/zoul/dev/{bmp085.c => bmpx8x.c} (50%) rename platform/zoul/dev/{bmp085.h => bmpx8x.h} (61%) diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 3cfa30021..04bcbb724 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,11 +1,11 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -CONTIKI_PROJECT += test-bmp085 test-motion test-rotation-sensor +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 -CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmp085.c motion-sensor.c +CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-bmp085.c b/examples/zolertia/zoul/test-bmp085-bmp180.c similarity index 81% rename from examples/zolertia/zoul/test-bmp085.c rename to examples/zolertia/zoul/test-bmp085-bmp180.c index 6fcabedf8..73cf0168f 100644 --- a/examples/zolertia/zoul/test-bmp085.c +++ b/examples/zolertia/zoul/test-bmp085-bmp180.c @@ -32,13 +32,13 @@ * \addtogroup zoul-examples * @{ * - * \defgroup zoul-bmp085-test BMP085 pressure and temperature sensor test + * \defgroup zoul-bmpx8x-test BMP085/BMP180 pressure and temperature sensor test * - * Demonstrates the use of the BMP085 digital pressure and temperature sensor + * Demonstrates the use of the BMP085/BMP180 pressure and temperature sensor * @{ * * \file - * Test file for the BMP085 digital pressure and temperature sensor + * Test file for the BMP085/BMP180 digital pressure and temperature sensor * * \author * Antonio Lignan @@ -48,23 +48,23 @@ #include "contiki.h" #include "dev/i2c.h" #include "dev/leds.h" -#include "dev/bmp085.h" +#include "dev/bmpx8x.h" /*---------------------------------------------------------------------------*/ #define SENSOR_READ_INTERVAL (CLOCK_SECOND) /*---------------------------------------------------------------------------*/ -PROCESS(remote_bmp085_process, "BMP085 test process"); -AUTOSTART_PROCESSES(&remote_bmp085_process); +PROCESS(remote_bmpx8x_process, "BMP085/BMP180 test process"); +AUTOSTART_PROCESSES(&remote_bmpx8x_process); /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(remote_bmp085_process, ev, data) +PROCESS_THREAD(remote_bmpx8x_process, ev, data) { PROCESS_BEGIN(); static uint16_t pressure; static int16_t temperature; /* Use Contiki's sensor macro to enable the sensor */ - SENSORS_ACTIVATE(bmp085); + SENSORS_ACTIVATE(bmpx8x); /* And periodically poll the sensor */ @@ -72,14 +72,14 @@ PROCESS_THREAD(remote_bmp085_process, ev, data) etimer_set(&et, SENSOR_READ_INTERVAL); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); - pressure = bmp085.value(BMP085_READ_PRESSURE); - temperature = bmp085.value(BMP085_READ_TEMP); + pressure = bmpx8x.value(BMPx8x_READ_PRESSURE); + temperature = bmpx8x.value(BMPx8x_READ_TEMP); - if((pressure != BMP085_ERROR) && (temperature != BMP085_ERROR)) { + if((pressure != BMPx8x_ERROR) && (temperature != BMPx8x_ERROR)) { printf("Pressure = %u.%u(hPa), ", pressure / 10, pressure % 10); printf("Temperature = %d.%u(ºC)\n", temperature / 10, temperature % 10); } else { - printf("Error, enable the DEBUG flag in the BMP085 driver for info, "); + printf("Error, enable the DEBUG flag in the BMPx8x driver for info, "); printf("or check if the sensor is properly connected\n"); PROCESS_EXIT(); } diff --git a/platform/zoul/dev/bmp085.c b/platform/zoul/dev/bmpx8x.c similarity index 50% rename from platform/zoul/dev/bmp085.c rename to platform/zoul/dev/bmpx8x.c index f7c8da82f..41e1b2d13 100644 --- a/platform/zoul/dev/bmp085.c +++ b/platform/zoul/dev/bmpx8x.c @@ -29,13 +29,13 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup zoul-bmp085-sensor + * \addtogroup zoul-bmpx8x-sensor * @{ * - * BMP085 driver implementation + * BMP085/BMP180 driver implementation * * \file - * Driver for the external BMP085 light sensor + * Driver for the external BMP085/BMP180 atmospheric pressure sensor * * \author * Antonio Lignan @@ -46,7 +46,7 @@ #include "dev/gpio.h" #include "dev/zoul-sensors.h" #include "lib/sensors.h" -#include "bmp085.h" +#include "bmpx8x.h" /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG @@ -69,179 +69,179 @@ typedef struct { int16_t mb; int16_t mc; int16_t md; -} bmp085_calibration_values; +} bmpx8x_calibration_values; typedef struct { uint8_t oversampling_mode; int32_t b5; - bmp085_calibration_values calib; -} bmp085_config; + bmpx8x_calibration_values calib; +} bmpx8x_config; -static bmp085_config bmp085_values; +static bmpx8x_config bmpx8x_values; /*---------------------------------------------------------------------------*/ static int -bmp085_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +bmpx8x_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) { if((buf == NULL) || (num <= 0)) { - PRINTF("BMP085: invalid read values\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: invalid read values\n"); + return BMPx8x_ERROR; } i2c_master_enable(); - if(i2c_single_send(BMP085_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_single_send(BMPx8x_ADDR, reg) == I2C_MASTER_ERR_NONE) { while(i2c_master_busy()); - if(i2c_burst_receive(BMP085_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { - return BMP085_SUCCESS; + if(i2c_burst_receive(BMPx8x_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMPx8x_SUCCESS; } } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int -bmp085_write_reg(uint8_t *buf, uint8_t num) +bmpx8x_write_reg(uint8_t *buf, uint8_t num) { if((buf == NULL) || (num <= 0)) { - PRINTF("BMP085: invalid write values\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: invalid write values\n"); + return BMPx8x_ERROR; } i2c_master_enable(); - if(i2c_burst_send(BMP085_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { - return BMP085_SUCCESS; + if(i2c_burst_send(BMPx8x_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return BMPx8x_SUCCESS; } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int -bmp085_read_calib(void) +bmpx8x_read_calib(void) { - uint8_t buf[BMP085_CALIB_TABLE_SIZE]; + uint8_t buf[BMPx8x_CALIB_TABLE_SIZE]; - if(bmp085_read_reg(BMP085_AC1_CALIB, buf, - BMP085_CALIB_TABLE_SIZE) == BMP085_SUCCESS) { + if(bmpx8x_read_reg(BMPx8x_AC1_CALIB, buf, + BMPx8x_CALIB_TABLE_SIZE) == BMPx8x_SUCCESS) { /* MSB first */ - bmp085_values.calib.ac1 = ((buf[0] << 8) + buf[1]); - bmp085_values.calib.ac2 = ((buf[2] << 8) + buf[3]); - bmp085_values.calib.ac3 = ((buf[4] << 8) + buf[5]); - bmp085_values.calib.ac4 = ((buf[6] << 8) + buf[7]); - bmp085_values.calib.ac5 = ((buf[8] << 8) + buf[9]); - bmp085_values.calib.ac6 = ((buf[10] << 8) + buf[11]); - bmp085_values.calib.b1 = ((buf[12] << 8) + buf[13]); - bmp085_values.calib.b2 = ((buf[14] << 8) + buf[15]); - bmp085_values.calib.mb = ((buf[16] << 8) + buf[17]); - bmp085_values.calib.mc = ((buf[18] << 8) + buf[19]); - bmp085_values.calib.md = ((buf[20] << 8) + buf[21]); + bmpx8x_values.calib.ac1 = ((buf[0] << 8) + buf[1]); + bmpx8x_values.calib.ac2 = ((buf[2] << 8) + buf[3]); + bmpx8x_values.calib.ac3 = ((buf[4] << 8) + buf[5]); + bmpx8x_values.calib.ac4 = ((buf[6] << 8) + buf[7]); + bmpx8x_values.calib.ac5 = ((buf[8] << 8) + buf[9]); + bmpx8x_values.calib.ac6 = ((buf[10] << 8) + buf[11]); + bmpx8x_values.calib.b1 = ((buf[12] << 8) + buf[13]); + bmpx8x_values.calib.b2 = ((buf[14] << 8) + buf[15]); + bmpx8x_values.calib.mb = ((buf[16] << 8) + buf[17]); + bmpx8x_values.calib.mc = ((buf[18] << 8) + buf[19]); + bmpx8x_values.calib.md = ((buf[20] << 8) + buf[21]); - return BMP085_SUCCESS; + return BMPx8x_SUCCESS; } - PRINTF("BMP085: failed to read calibration\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: failed to read calibration\n"); + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int -bmp085_read_uncompensated_pressure(int32_t *pressure) +bmpx8x_read_uncompensated_pressure(int32_t *pressure) { uint8_t buf[3]; uint16_t delay; int32_t upres; - buf[0] = BMP085_CTRL_REG; + buf[0] = BMPx8x_CTRL_REG; - switch(bmp085_values.oversampling_mode) { - case BMP085_MODE_ULTRA_LOW_POWER: - buf[1] = BMP085_CTRL_REG_PRESS_4_5MS; - delay = BMP085_DELAY_4_5MS; + switch(bmpx8x_values.oversampling_mode) { + case BMPx8x_MODE_ULTRA_LOW_POWER: + buf[1] = BMPx8x_CTRL_REG_PRESS_4_5MS; + delay = BMPx8x_DELAY_4_5MS; break; - case BMP085_MODE_STANDARD: - buf[1] = BMP085_CTRL_REG_PRESS_7_5MS; - delay = BMP085_DELAY_7_5MS; + case BMPx8x_MODE_STANDARD: + buf[1] = BMPx8x_CTRL_REG_PRESS_7_5MS; + delay = BMPx8x_DELAY_7_5MS; break; - case BMP085_MODE_HIGH_RES: - buf[1] = BMP085_CTRL_REG_PRESS_13_5MS; - delay = BMP085_DELAY_13_5MS; + case BMPx8x_MODE_HIGH_RES: + buf[1] = BMPx8x_CTRL_REG_PRESS_13_5MS; + delay = BMPx8x_DELAY_13_5MS; break; - case BMP085_MODE_ULTRA_HIGH_RES: - buf[1] = BMP085_CTRL_REG_PRESS_25_5MS; - delay = BMP085_DELAY_25_5MS; + case BMPx8x_MODE_ULTRA_HIGH_RES: + buf[1] = BMPx8x_CTRL_REG_PRESS_25_5MS; + delay = BMPx8x_DELAY_25_5MS; break; default: - return BMP085_ERROR; + return BMPx8x_ERROR; } - if(bmp085_write_reg(buf, 2) == BMP085_SUCCESS) { + if(bmpx8x_write_reg(buf, 2) == BMPx8x_SUCCESS) { clock_delay_usec(delay); - if(bmp085_read_reg(BMP085_DATA_MSB, buf, 3) == BMP085_SUCCESS) { + if(bmpx8x_read_reg(BMPx8x_DATA_MSB, buf, 3) == BMPx8x_SUCCESS) { upres = (buf[0] << 16) + (buf[1] << 8) + buf[2]; - *pressure = (upres >> (8 - bmp085_values.oversampling_mode)); - return BMP085_SUCCESS; + *pressure = (upres >> (8 - bmpx8x_values.oversampling_mode)); + return BMPx8x_SUCCESS; } } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int -bmp085_read_uncompensated_temperature(int32_t *temp) +bmpx8x_read_uncompensated_temperature(int32_t *temp) { uint8_t buf[2]; - buf[0] = BMP085_CTRL_REG; - buf[1] = BMP085_CTRL_REG_TEMP; + buf[0] = BMPx8x_CTRL_REG; + buf[1] = BMPx8x_CTRL_REG_TEMP; - if(bmp085_write_reg(buf, 2) == BMP085_SUCCESS) { - clock_delay_usec(BMP085_DELAY_4_5MS); - if(bmp085_read_reg(BMP085_DATA_MSB, buf, 2) == BMP085_SUCCESS) { + if(bmpx8x_write_reg(buf, 2) == BMPx8x_SUCCESS) { + clock_delay_usec(BMPx8x_DELAY_4_5MS); + if(bmpx8x_read_reg(BMPx8x_DATA_MSB, buf, 2) == BMPx8x_SUCCESS) { *temp = (int32_t)((buf[0] << 8) + buf[1]); - return BMP085_SUCCESS; + return BMPx8x_SUCCESS; } } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int -bmp085_read_temperature(int16_t *temp) +bmpx8x_read_temperature(int16_t *temp) { int32_t ut = 0; int32_t x1, x2; - if(bmp085_read_uncompensated_temperature(&ut) == BMP085_ERROR) { - return BMP085_ERROR; + if(bmpx8x_read_uncompensated_temperature(&ut) == BMPx8x_ERROR) { + return BMPx8x_ERROR; } - x1 = ((int32_t)ut - (int32_t)bmp085_values.calib.ac6) - * (int32_t)bmp085_values.calib.ac5 >> 15; - x2 = ((int32_t)bmp085_values.calib.mc << 11) / (x1 + bmp085_values.calib.md); - bmp085_values.b5 = x1 + x2; - *temp = (int16_t)((bmp085_values.b5 + 8) >> 4); - return BMP085_SUCCESS; + x1 = ((int32_t)ut - (int32_t)bmpx8x_values.calib.ac6) + * (int32_t)bmpx8x_values.calib.ac5 >> 15; + x2 = ((int32_t)bmpx8x_values.calib.mc << 11) / (x1 + bmpx8x_values.calib.md); + bmpx8x_values.b5 = x1 + x2; + *temp = (int16_t)((bmpx8x_values.b5 + 8) >> 4); + return BMPx8x_SUCCESS; } /*---------------------------------------------------------------------------*/ static int -bmp085_read_pressure(int32_t *pressure) +bmpx8x_read_pressure(int32_t *pressure) { int32_t ut = 0; int32_t up = 0; int32_t x1, x2, b6, x3, b3, p; uint32_t b4, b7; - if(bmp085_read_uncompensated_pressure(&up) == BMP085_ERROR) { - return BMP085_ERROR; + if(bmpx8x_read_uncompensated_pressure(&up) == BMPx8x_ERROR) { + return BMPx8x_ERROR; } - if(bmp085_read_uncompensated_temperature(&ut) == BMP085_ERROR) { - return BMP085_ERROR; + if(bmpx8x_read_uncompensated_temperature(&ut) == BMPx8x_ERROR) { + return BMPx8x_ERROR; } - b6 = bmp085_values.b5 - 4000; - x1 = (bmp085_values.calib.b2 * (b6 * b6 >> 12)) >> 11; - x2 = bmp085_values.calib.ac2 * b6 >> 11; + b6 = bmpx8x_values.b5 - 4000; + x1 = (bmpx8x_values.calib.b2 * (b6 * b6 >> 12)) >> 11; + x2 = bmpx8x_values.calib.ac2 * b6 >> 11; x3 = x1 + x2; - b3 = ((((int32_t)bmp085_values.calib.ac1) * 4 + x3) + 2) >> 2; + b3 = ((((int32_t)bmpx8x_values.calib.ac1) * 4 + x3) + 2) >> 2; - x1 = (bmp085_values.calib.ac3 * b6) >> 13; - x2 = (bmp085_values.calib.b1 * ((b6 * b6) >> 12)) >> 16; + x1 = (bmpx8x_values.calib.ac3 * b6) >> 13; + x2 = (bmpx8x_values.calib.b1 * ((b6 * b6) >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; - b4 = (bmp085_values.calib.ac4 * ((uint32_t)(x3 + 32768))) >> 15; + b4 = (bmpx8x_values.calib.ac4 * ((uint32_t)(x3 + 32768))) >> 15; b7 = ((uint32_t)up - b3) * 50000; if(b7 < 0x80000000) { @@ -256,47 +256,47 @@ bmp085_read_pressure(int32_t *pressure) *pressure = (p + ((x1 + x2 + 3791) >> 4)); *pressure /= 10; - return BMP085_SUCCESS; + return BMPx8x_SUCCESS; } /*---------------------------------------------------------------------------*/ static int configure(int type, int value) { - if((type != BMP085_ACTIVE) && (type != BMP085_OVERSAMPLING)) { - PRINTF("BMP085: invalid start value\n"); - return BMP085_ERROR; + if((type != BMPx8x_ACTIVE) && (type != BMPx8x_OVERSAMPLING)) { + PRINTF("BMPx8x: invalid start value\n"); + return BMPx8x_ERROR; } - if(type == BMP085_ACTIVE) { + if(type == BMPx8x_ACTIVE) { if(value) { i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); /* Read the calibration values */ - if(bmp085_read_calib() != BMP085_ERROR) { - PRINTF("BMP085: sensor started\n"); + if(bmpx8x_read_calib() != BMPx8x_ERROR) { + PRINTF("BMPx8x: sensor started\n"); enabled = 1; - bmp085_values.oversampling_mode = BMP085_MODE_ULTRA_LOW_POWER; - return BMP085_SUCCESS; + bmpx8x_values.oversampling_mode = BMPx8x_MODE_ULTRA_LOW_POWER; + return BMPx8x_SUCCESS; } - PRINTF("BMP085: failed to enable\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: failed to enable\n"); + return BMPx8x_ERROR; } else { enabled = 0; - return BMP085_SUCCESS; + return BMPx8x_SUCCESS; } - } else if(type == BMP085_OVERSAMPLING) { - if((value < BMP085_MODE_ULTRA_LOW_POWER) || - (value > BMP085_MODE_ULTRA_HIGH_RES)) { - PRINTF("BMP085: invalid oversampling value\n"); - return BMP085_ERROR; + } else if(type == BMPx8x_OVERSAMPLING) { + if((value < BMPx8x_MODE_ULTRA_LOW_POWER) || + (value > BMPx8x_MODE_ULTRA_HIGH_RES)) { + PRINTF("BMPx8x: invalid oversampling value\n"); + return BMPx8x_ERROR; } - bmp085_values.oversampling_mode = value; - return BMP085_SUCCESS; + bmpx8x_values.oversampling_mode = value; + return BMPx8x_SUCCESS; } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int @@ -311,25 +311,25 @@ status(int type) } /*---------------------------------------------------------------------------*/ static int -bmp085_read_sensor(int32_t *value, uint8_t type) +bmpx8x_read_sensor(int32_t *value, uint8_t type) { int16_t temp = 0; /* The temperature is required to compensate the pressure value */ - if(bmp085_read_temperature(&temp) != BMP085_SUCCESS) { - return BMP085_ERROR; + if(bmpx8x_read_temperature(&temp) != BMPx8x_SUCCESS) { + return BMPx8x_ERROR; } switch(type) { - case BMP085_READ_PRESSURE: - return bmp085_read_pressure(value); + case BMPx8x_READ_PRESSURE: + return bmpx8x_read_pressure(value); - case BMP085_READ_TEMP: + case BMPx8x_READ_TEMP: *value = (int16_t) temp; - return BMP085_SUCCESS; + return BMPx8x_SUCCESS; } - return BMP085_ERROR; + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ static int @@ -338,23 +338,23 @@ value(int type) int32_t value; if(!enabled) { - PRINTF("BMP085: sensor not started\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: sensor not started\n"); + return BMPx8x_ERROR; } - if((type != BMP085_READ_PRESSURE) && (type != BMP085_READ_TEMP)) { - PRINTF("BMP085: invalid read value\n"); - return BMP085_ERROR; + if((type != BMPx8x_READ_PRESSURE) && (type != BMPx8x_READ_TEMP)) { + PRINTF("BMPx8x: invalid read value\n"); + return BMPx8x_ERROR; } - if(bmp085_read_sensor(&value, type) == BMP085_SUCCESS) { + if(bmpx8x_read_sensor(&value, type) == BMPx8x_SUCCESS) { return (int)value; } - PRINTF("BMP085: fail to read\n"); - return BMP085_ERROR; + PRINTF("BMPx8x: fail to read\n"); + return BMPx8x_ERROR; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(bmp085, BMP085_SENSOR, value, configure, status); +SENSORS_SENSOR(bmpx8x, BMPx8x_SENSOR, value, configure, status); /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/platform/zoul/dev/bmp085.h b/platform/zoul/dev/bmpx8x.h similarity index 61% rename from platform/zoul/dev/bmp085.h rename to platform/zoul/dev/bmpx8x.h index 88a08e51d..75f768bef 100644 --- a/platform/zoul/dev/bmp085.h +++ b/platform/zoul/dev/bmpx8x.h @@ -34,98 +34,98 @@ * \addtogroup zoul-sensors * @{ * - * \defgroup zoul-bmp085-sensor BMP085 Sensor + * \defgroup zoul-bmpx8x-sensor BMP085/BMP180 Sensor * - * Driver for the BMP085 sensor + * Driver for the BMP085/BMP180 sensor * - * BMP085 digital pressure and temperature driver + * BMP085/BMP180 digital atmospheric pressure and temperature driver * @{ * * \file - * Header file for the external BMP085 Sensor Driver + * Header file for the external BMP085/BMP180 Sensor Driver * * \author * Antonio Lignan */ /*---------------------------------------------------------------------------*/ -#ifndef BMP085_H_ -#define BMP085_H_ +#ifndef BMPX8X_H_ +#define BMPX8X_H_ #include #include "lib/sensors.h" #include "dev/zoul-sensors.h" #include "i2c.h" /* -------------------------------------------------------------------------- */ /** - * \name BMP085 address and registers + * \name BMPx8x address and registers * @{ */ /* -------------------------------------------------------------------------- */ -#define BMP085_ADDR 0x77 +#define BMPx8x_ADDR 0x77 /* -------------------------------------------------------------------------- */ /* Control register */ -#define BMP085_CTRL_REG 0xF4 +#define BMPx8x_CTRL_REG 0xF4 /* Read uncompensated temperature */ -#define BMP085_CTRL_REG_TEMP 0x2E +#define BMPx8x_CTRL_REG_TEMP 0x2E /* Read uncompensated pressure, no oversampling */ -#define BMP085_CTRL_REG_PRESS_4_5MS 0x34 +#define BMPx8x_CTRL_REG_PRESS_4_5MS 0x34 /* Read uncompensated pressure, oversampling 1*/ -#define BMP085_CTRL_REG_PRESS_7_5MS 0x74 +#define BMPx8x_CTRL_REG_PRESS_7_5MS 0x74 /* Read uncompensated pressure, oversampling 2 */ -#define BMP085_CTRL_REG_PRESS_13_5MS 0xB4 +#define BMPx8x_CTRL_REG_PRESS_13_5MS 0xB4 /* Read uncompensated pressure, oversampling 3 */ -#define BMP085_CTRL_REG_PRESS_25_5MS 0xF4 +#define BMPx8x_CTRL_REG_PRESS_25_5MS 0xF4 /* -------------------------------------------------------------------------- */ -#define BMP085_DATA_MSB 0xF6 -#define BMP085_DATA_LSB 0xF7 +#define BMPx8x_DATA_MSB 0xF6 +#define BMPx8x_DATA_LSB 0xF7 /* 19-bit resolution */ -#define BMP085_DATA_XLSB 0xF8 +#define BMPx8x_DATA_XLSB 0xF8 /* -------------------------------------------------------------------------- */ /* Calibration registers, 16-bit wide */ -#define BMP085_AC1_CALIB 0xAA -#define BMP085_AC2_CALIB 0xAC -#define BMP085_AC3_CALIB 0xAE -#define BMP085_AC4_CALIB 0xB0 -#define BMP085_AC5_CALIB 0xB2 -#define BMP085_AC6_CALIB 0xB4 -#define BMP085_B1_CALIB 0xB6 -#define BMP085_B2_CALIB 0xB8 -#define BMP085_MB_CALIB 0xBA -#define BMP085_MC_CALIB 0xBC -#define BMP085_MD_CALIB 0xBE -#define BMP085_CALIB_TABLE_SIZE 22 /**< size in bytes */ +#define BMPx8x_AC1_CALIB 0xAA +#define BMPx8x_AC2_CALIB 0xAC +#define BMPx8x_AC3_CALIB 0xAE +#define BMPx8x_AC4_CALIB 0xB0 +#define BMPx8x_AC5_CALIB 0xB2 +#define BMPx8x_AC6_CALIB 0xB4 +#define BMPx8x_B1_CALIB 0xB6 +#define BMPx8x_B2_CALIB 0xB8 +#define BMPx8x_MB_CALIB 0xBA +#define BMPx8x_MC_CALIB 0xBC +#define BMPx8x_MD_CALIB 0xBE +#define BMPx8x_CALIB_TABLE_SIZE 22 /**< size in bytes */ /** @} */ /* -------------------------------------------------------------------------- */ /** - * \name BMP085 operation modes + * \name BMPx8x operation modes * @{ */ -#define BMP085_MODE_ULTRA_LOW_POWER 0x00 -#define BMP085_MODE_STANDARD 0x01 -#define BMP085_MODE_HIGH_RES 0x02 -#define BMP085_MODE_ULTRA_HIGH_RES 0x03 +#define BMPx8x_MODE_ULTRA_LOW_POWER 0x00 +#define BMPx8x_MODE_STANDARD 0x01 +#define BMPx8x_MODE_HIGH_RES 0x02 +#define BMPx8x_MODE_ULTRA_HIGH_RES 0x03 /* -------------------------------------------------------------------------- */ -#define BMP085_DELAY_4_5MS 4700 -#define BMP085_DELAY_7_5MS 7700 -#define BMP085_DELAY_13_5MS 13700 -#define BMP085_DELAY_25_5MS 25700 +#define BMPx8x_DELAY_4_5MS 4700 +#define BMPx8x_DELAY_7_5MS 7700 +#define BMPx8x_DELAY_13_5MS 13700 +#define BMPx8x_DELAY_25_5MS 25700 /** @} */ /* -------------------------------------------------------------------------- */ /** - * \name BMP085 return and command values + * \name BMPx8x return and command values * @{ */ -#define BMP085_SUCCESS 0x00 -#define BMP085_ERROR -1 +#define BMPx8x_SUCCESS 0x00 +#define BMPx8x_ERROR -1 -#define BMP085_ACTIVE SENSORS_ACTIVE -#define BMP085_OVERSAMPLING 0x00 -#define BMP085_READ_PRESSURE 0x01 -#define BMP085_READ_TEMP 0x02 +#define BMPx8x_ACTIVE SENSORS_ACTIVE +#define BMPx8x_OVERSAMPLING 0x00 +#define BMPx8x_READ_PRESSURE 0x01 +#define BMPx8x_READ_TEMP 0x02 /** @} */ /* -------------------------------------------------------------------------- */ -#define BMP085_SENSOR "BMP085 pressure and temperature sensor" +#define BMPx8x_SENSOR "BMP085/BMP180 pressure and temperature sensor" /* -------------------------------------------------------------------------- */ -extern const struct sensors_sensor bmp085; +extern const struct sensors_sensor bmpx8x; /* -------------------------------------------------------------------------- */ #endif /* -------------------------------------------------------------------------- */ From f5b52e8094b7dd877fb820273bd6b49162932dcf Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Wed, 20 Jan 2016 13:59:57 +0100 Subject: [PATCH 62/94] Ported Grove's 3-axis gyroscope sensor (based on ITG-3200) --- examples/zolertia/zoul/Makefile | 4 +- examples/zolertia/zoul/test-grove-gyro.c | 155 +++++++ platform/zoul/dev/grove-gyro.c | 528 +++++++++++++++++++++++ platform/zoul/dev/grove-gyro.h | 176 ++++++++ 4 files changed, 861 insertions(+), 2 deletions(-) create mode 100644 examples/zolertia/zoul/test-grove-gyro.c create mode 100644 platform/zoul/dev/grove-gyro.c create mode 100644 platform/zoul/dev/grove-gyro.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 04bcbb724..190348c4b 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -3,10 +3,10 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt 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 +CONTIKI_PROJECT += test-weather-meter test-grove-gyro CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c bmpx8x.c motion-sensor.c -CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c +CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-grove-gyro.c b/examples/zolertia/zoul/test-grove-gyro.c new file mode 100644 index 000000000..29d2afc0d --- /dev/null +++ b/examples/zolertia/zoul/test-grove-gyro.c @@ -0,0 +1,155 @@ +/* + * 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 zoul-examples + * @{ + * + * \defgroup zoul-grove-gyro-test Grove's 3-axis gyroscope test application + * + * Demonstrates the use of the Grove's 3-axis gyroscope based on the ITG-3200 + * @{ + * + * \file + * Test file for the external Grove gyroscope + * + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include "dev/grove-gyro.h" +/*---------------------------------------------------------------------------*/ +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) +#define GROVE_GYRO_EXPECTED_ADDR GROVE_GYRO_ADDR +/*---------------------------------------------------------------------------*/ +PROCESS(remote_grove_gyro_process, "Grove gyro test process"); +AUTOSTART_PROCESSES(&remote_grove_gyro_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +static void +gyro_interrupt_callback(uint8_t status) +{ + /* The interrupt indicates that new data is available, the status value + * returns the outcome of the read operation, check to validate if the + * data is valid to read + */ + leds_toggle(LEDS_PURPLE); + + printf("Gyro: X_axis %u, Y_axis %u, Z_axis %u\n", gyro_values.x, + gyro_values.y, + gyro_values.z); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_grove_gyro_process, ev, data) +{ + PROCESS_BEGIN(); + + uint8_t aux; + + /* Use Contiki's sensor macro to enable the sensor */ + SENSORS_ACTIVATE(grove_gyro); + + /* The sensor itself is in low-power mode, to power on just the sensor and not + * the 3 gyroscope axis use GROVE_GYRO_SENSOR. Alternatively the value + * GROVE_GYRO_ALL could also be used to power everything at once + */ + grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_SENSOR); + + /* Read back the configured sensor I2C address to check if the sensor is + * working OK, this is the only case in which the value() returns a value + */ + aux = grove_gyro.value(GROVE_GYRO_ADDR); + if(aux == GROVE_GYRO_EXPECTED_ADDR) { + printf("Gyro sensor started with addr 0x%02X\n", GROVE_GYRO_EXPECTED_ADDR); + } else { + printf("Gyro sensor with unrecognized address 0x%02X\n", aux); + PROCESS_EXIT(); + } + + /* The gyroscope sensor should be on now but the three gyroscope axis should + * be off, to enable a single axis or any combination of the 3 you can use as + * argument either GROVE_GYRO_X, GROVE_GYRO_Y, GROVE_GYRO_Z. To enable or + * disable the three axis alternatively use GROVE_GYRO_XYZ + */ + grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_XYZ); + + /* Register the interrupt handler */ + GROVE_GYRO_REGISTER_INT(gyro_interrupt_callback); + + /* And periodically poll the sensor, values are in º/s */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* This sensor has a different operation from others using Contiki's sensor + * API, to make data acquisition we write the readings directly to the + * extern data structure, allowing to write more than 1 value at the same + * operation, and also allowing upon a data interrupt event to immediatly + * access the data. The return value of the value() call is then the status + * result of the read operation + */ + if(grove_gyro.value(GROVE_GYRO_XYZ) == GROVE_GYRO_SUCCESS) { + + /* Converted values with a 2-digit precision */ + printf("Gyro: X %u.%u, Y %u.%u, Z %u.%u\n", gyro_values.x / 100, + gyro_values.x % 100, + gyro_values.y / 100, + gyro_values.y % 100, + gyro_values.z / 100, + gyro_values.z % 100); + } else { + printf("Error, enable the DEBUG flag in the grove-gyro driver for info,"); + printf(" or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + + if(grove_gyro.value(GROVE_GYRO_TEMP) == GROVE_GYRO_SUCCESS) { + printf("Gyro: temperature %d.%02u C\n", gyro_values.temp / 100, + gyro_values.temp % 100); + } else { + printf("Error, enable the DEBUG flag in the grove-gyro driver for info,"); + printf(" or check if the sensor is properly connected\n"); + PROCESS_EXIT(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/grove-gyro.c b/platform/zoul/dev/grove-gyro.c new file mode 100644 index 000000000..e763cda9d --- /dev/null +++ b/platform/zoul/dev/grove-gyro.c @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-grove-gyro-sensor + * @{ + * + * \file + * Grove's 3-axis gyroscope driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/grove-gyro.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#define GROVE_GYRO_INT_PORT_BASE GPIO_PORT_TO_BASE(I2C_INT_PORT) +#define GROVE_GYRO_INT_PIN_MASK GPIO_PIN_MASK(I2C_INT_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +static uint8_t power_mgmt; +/*---------------------------------------------------------------------------*/ +grove_gyro_values_t gyro_values; +/*---------------------------------------------------------------------------*/ +void (*grove_gyro_int_callback)(uint8_t value); +/*---------------------------------------------------------------------------*/ +static uint16_t +grove_gyro_read_reg(uint8_t reg, uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + return GROVE_GYRO_ERROR; + } + + i2c_master_enable(); + if(i2c_single_send(GROVE_GYRO_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(GROVE_GYRO_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return GROVE_GYRO_SUCCESS; + } + } + + PRINTF("Gyro: failed to read from sensor\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("Gyro: invalid write values\n"); + return GROVE_GYRO_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(GROVE_GYRO_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return GROVE_GYRO_SUCCESS; + } + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_sampdiv(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_SMPLRT_DIV; + buf[1] = value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new sampdiv 0x%02X\n", value); + return GROVE_GYRO_SUCCESS; + } + PRINTF("Gyro: failed to set sampdiv\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static void +grove_gyro_clear_interrupt(void) +{ + /* FIXME */ +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_interrupt(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_INT_CFG; + buf[1] = value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS){ + PRINTF("Gyro: interrupt cfg 0x%02X\n", value); + return GROVE_GYRO_SUCCESS; + } + PRINTF("Gyro: failed to change interrupt config\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_reset(void) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + buf[1] = power_mgmt + GROVE_GYRO_PWR_MGMT_RESET; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: restarted with 0x%02X, now with default values\n", buf[1]); + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: failed to restart\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_osc(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + power_mgmt &= ~GROVE_GYRO_PWR_MGMT_CLK_SEL_MASK; + buf[1] = power_mgmt + value; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new clock source 0x%02X\n", buf[1]); + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: failed to change the clock source\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_power_mgmt(uint8_t value, uint8_t type) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_PWR_MGMT; + + if((type != GROVE_GYRO_POWER_ON) && (type != GROVE_GYRO_POWER_OFF)) { + PRINTF("Gyro: invalid power command type\n"); + return GROVE_GYRO_ERROR; + } + + /* Read the power management status as well to force sync */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt, 1) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: current power mgmt 0x%02X\n", power_mgmt); + + if(type == GROVE_GYRO_POWER_ON) { + power_mgmt &= ~value; + } else { + power_mgmt |= value; + } + + buf[1] = power_mgmt; + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: new power management register value 0x%02X\n", power_mgmt); + + /* Power-up delay */ + if(type == GROVE_GYRO_POWER_ON) { + // clock_delay_usec(50000); + } + + return GROVE_GYRO_SUCCESS; + } + } + PRINTF("Gyro: power management fail\n"); + + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_dlpf(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = GROVE_GYRO_DLPF_FS; + buf[1] = GROVE_GYRO_DLPF_FS_SEL + value; + + if(grove_gyro_write_reg(buf, 2) == GROVE_GYRO_SUCCESS) { + /* Double-check */ + if(grove_gyro_read_reg(GROVE_GYRO_DLPF_FS, &buf[0], 1) == + GROVE_GYRO_SUCCESS) { + if(buf[0] == buf[1]) { + PRINTF("Gyro: updated lp/sr 0x%02X\n", buf[0]); + return GROVE_GYRO_SUCCESS; + } else { + PRINTF("Gyro: DLPF register value mismatch\n"); + return GROVE_GYRO_ERROR; + } + } + } + + PRINTF("Gyro: failed to change the lp/sr\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +grove_gyro_convert_to_value(uint16_t val) +{ + uint32_t aux; + + /* Convert from 2C's to 10's, as we care about º/s negative quantifier doesn't + * matter, so we ommit flaging the sign + */ + if(val & 0x8000) { + val = (~val + 1); + } + + /* ITG-3200 datasheet: sensitivity 14.375 LSB/(º/s) to get º/s */ + aux = val * 6956; + aux /= 1000; + + return (uint16_t)aux; +} +/*---------------------------------------------------------------------------*/ +static void +grove_gyro_convert(uint8_t *buf, uint8_t type) +{ + uint16_t aux; + + if(type & GROVE_GYRO_X) { + aux = (buf[0] << 8) + buf[1]; + PRINTF("Gyro: X_axis (raw) 0x%02X\n", aux); + gyro_values.x = grove_gyro_convert_to_value(aux); + } + + if(type & GROVE_GYRO_Y) { + aux = (buf[2] << 8) + buf[3]; + PRINTF("Gyro: Y_axis (raw) 0x%02X\n", aux); + gyro_values.y = grove_gyro_convert_to_value(aux); + } + + if(type & GROVE_GYRO_Z) { + aux = (buf[4] << 8) + buf[5]; + PRINTF("Gyro: Z_axis (raw) 0x%02X\n", aux); + gyro_values.z = grove_gyro_convert_to_value(aux); + } + + if(type == GROVE_GYRO_TEMP) { + aux = (buf[0] << 8) + buf[1]; + PRINTF("Gyro: Temp (raw) 0x%02X\n", aux); + /* ITG-3200 datasheet: offset -13200, sensitivity 280 LSB/ºC */ + aux = (aux + 13200) / 28; + aux += 350; + gyro_values.temp = (int16_t)aux; + } +} +/*---------------------------------------------------------------------------*/ +static int +grove_gyro_read(int type) +{ + uint8_t reg; + uint8_t len; + uint8_t buf_ptr; + uint8_t buf[GROVE_GYRO_MAX_DATA]; + + len = (type == GROVE_GYRO_XYZ) ? GROVE_GYRO_MAX_DATA : 2; + + switch(type) { + case GROVE_GYRO_X: + case GROVE_GYRO_XYZ: + buf_ptr = 0; + reg = GROVE_GYRO_XOUT_H; + break; + case GROVE_GYRO_Y: + buf_ptr = 2; + reg = GROVE_GYRO_YOUT_H; + break; + case GROVE_GYRO_Z: + buf_ptr = 4; + reg = GROVE_GYRO_ZOUT_H; + break; + case GROVE_GYRO_TEMP: + buf_ptr = 0; + reg = GROVE_GYRO_TEMP_OUT_H; + break; + case GROVE_GYRO_ADDR: + buf_ptr = 0; + len = 1; + reg = GROVE_GYRO_WHO_AM_I; + break; + default: + PRINTF("Gyro: invalid value requested\n"); + return GROVE_GYRO_ERROR; + } + + if(grove_gyro_read_reg(reg, &buf[buf_ptr], len) == GROVE_GYRO_SUCCESS) { + if(type == GROVE_GYRO_ADDR) { + PRINTF("Gyro: I2C_addr 0x%02X\n", buf[0]); + return buf[0]; + } + grove_gyro_convert(buf, type); + return GROVE_GYRO_SUCCESS; + } + + PRINTF("Gyro: failed to change the lp/sr\n"); + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +PROCESS(grove_gyro_int_process, "Grove gyroscope interrupt process handler"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(grove_gyro_int_process, ev, data) +{ + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + grove_gyro_clear_interrupt(); + grove_gyro_int_callback(0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +grove_gyro_interrupt_handler(uint8_t port, uint8_t pin) +{ + process_poll(&grove_gyro_int_process); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if(!enabled) { + PRINTF("Gyro: sensor not started\n"); + return GROVE_GYRO_ERROR; + } + + if((type != GROVE_GYRO_X) && (type != GROVE_GYRO_Y) && + (type != GROVE_GYRO_Z) && (type != GROVE_GYRO_XYZ) && + (type != GROVE_GYRO_TEMP) && (type != GROVE_GYRO_ADDR)) { + PRINTF("Gyro: invalid value requested 0x%02X\n", type); + return GROVE_GYRO_ERROR; + } + + if((type != GROVE_GYRO_TEMP) && (type != GROVE_GYRO_ADDR) && + (type & power_mgmt)) { + PRINTF("Gyro: axis not enabled (0x%02X vs 0x%02X)\n", power_mgmt, type); + return GROVE_GYRO_ERROR; + } + + return grove_gyro_read(type); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if((type != GROVE_GYRO_ACTIVE) && (type != GROVE_GYRO_SAMPLE_RATE) && + (type != GROVE_GYRO_SAMPLE_RATE_DIVIDER) && (type != GROVE_GYRO_POWER_ON) && + (type != GROVE_GYRO_POWER_OFF) && (type != GROVE_GYRO_DATA_INTERRUPT)) { + PRINTF("Gyro: option not supported\n"); + return GROVE_GYRO_ERROR; + } + + switch(type) { + case GROVE_GYRO_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_FAST_BUS_SPEED); + + /* Make sure the sensor is on */ + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_ON) != + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: failed to power on the sensor\n"); + return GROVE_GYRO_ERROR; + } + + /* Reset and configure as default with internal oscillator, 8KHz @ 2000 + * degrees/s, no divider (full scale) + */ + if(grove_gyro_reset() == GROVE_GYRO_SUCCESS) { + if(grove_gyro_osc(GROVE_GYRO_DEFAULT_OSC) == GROVE_GYRO_SUCCESS) { + if(grove_gyro_dlpf(GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: started and configured\n"); + /* Disable interrupts as default */ + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == + GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: interrupts disabled\n"); + /* And finally put the device in SLEEP mode, set also X, Y and Z + * in stand-by mode, whenever an axis is not used it should stay + * in this state to save power + */ + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_OFF) == + GROVE_GYRO_SUCCESS) { + enabled = 1; + PRINTF("Gyro: axis and gyroscope in low-power mode now\n"); + + return GROVE_GYRO_SUCCESS; + } + } + } + } + } + return GROVE_GYRO_ERROR; + + } else { + enabled = 0; + GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + grove_gyro_int_callback = NULL; + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == + GROVE_GYRO_SUCCESS) { + return grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_OFF); + } + PRINTF("Gyro: hw interrupt disabled but failed to disable sensor\n"); + return GROVE_GYRO_ERROR; + } + + if(!enabled) { + PRINTF("Gyro: sensor not started\n"); + return GROVE_GYRO_ERROR; + } + + case GROVE_GYRO_DATA_INTERRUPT: + + if(!value) { + + /* 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(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + return grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE); + } + + /* Enable interrupt and latch the pin until cleared */ + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_RAW_READY_EN + + GROVE_GYRO_INT_CFG_LATCH_CLR_ANY + + GROVE_GYRO_INT_CFG_LATCH_EN) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to enable the interrupt\n"); + return GROVE_GYRO_ERROR; + } + + /* Default register configuration is active high, push-pull */ + GPIO_SOFTWARE_CONTROL(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_SET_INPUT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_DETECT_EDGE(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_TRIGGER_SINGLE_EDGE(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + GPIO_DETECT_FALLING(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + gpio_register_callback(grove_gyro_interrupt_handler, I2C_INT_PORT, + I2C_INT_PIN); + + /* Spin process until an interrupt is received */ + process_start(&grove_gyro_int_process, NULL); + + /* Enable interrupts */ + GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(I2C_INT_VECTOR); + + PRINTF("Gyro: Data interrupt configured\n"); + return GROVE_GYRO_SUCCESS; + + case GROVE_GYRO_SAMPLE_RATE: + if((value < GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ) || + (value > GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP5HZ)) { + PRINTF("Gyro: invalid sample rate/filter configuration\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_dlpf(value); + + case GROVE_GYRO_SAMPLE_RATE_DIVIDER: + if((value < 0) && (value > 0xFF)) { + PRINTF("Gyro: invalid sampling rate div, it must be an 8-bit value\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_sampdiv((uint8_t)value); + + case GROVE_GYRO_POWER_ON: + case GROVE_GYRO_POWER_OFF: + /* We accept mask values to enable more than one axis at the same time */ + if((value < GROVE_GYRO_Z) || (value > GROVE_GYRO_ALL)) { + PRINTF("Gyro: invalid power management setting\n"); + return GROVE_GYRO_ERROR; + } + return grove_gyro_power_mgmt(value, type); + + default: + return GROVE_GYRO_ERROR; + } + + return GROVE_GYRO_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(grove_gyro, GROVE_GYRO_STRING, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/grove-gyro.h b/platform/zoul/dev/grove-gyro.h new file mode 100644 index 000000000..56649a2f1 --- /dev/null +++ b/platform/zoul/dev/grove-gyro.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-grove-gyro-sensor Grove 3-axis gyroscope based on ITG-3200 + * @{ + * + * \file + * Grove 3-axis gyroscope header file + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef GROVE_GYRO_H_ +#define GROVE_GYRO_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name Callback function to handle the interrupt + * @{ + */ +#define GROVE_GYRO_REGISTER_INT(ptr) grove_gyro_int_callback = ptr; +extern void (*grove_gyro_int_callback)(uint8_t value); +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Gyroscope data values structure + * @{ + */ +typedef struct { + uint16_t x; + uint16_t y; + uint16_t z; + int16_t temp; +} grove_gyro_values_t; + +extern grove_gyro_values_t gyro_values; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Grove 3-axis gyroscope address and registers + * @{ + */ +#define GROVE_GYRO_ADDR 0x68 + +#define GROVE_GYRO_WHO_AM_I 0x00 +#define GROVE_GYRO_SMPLRT_DIV 0x15 +#define GROVE_GYRO_DLPF_FS 0x16 +#define GROVE_GYRO_INT_CFG 0x17 +#define GROVE_GYRO_INT_STATUS 0x1A +#define GROVE_GYRO_TEMP_OUT_H 0x1B +#define GROVE_GYRO_TEMP_OUT_L 0x1C +#define GROVE_GYRO_XOUT_H 0x1D +#define GROVE_GYRO_XOUT_L 0x1E +#define GROVE_GYRO_YOUT_H 0x1F +#define GROVE_GYRO_YOUT_L 0x20 +#define GROVE_GYRO_ZOUT_H 0x21 +#define GROVE_GYRO_ZOUT_L 0x22 +#define GROVE_GYRO_PWR_MGMT 0x3E +/** @} */ +/*--------------------------------------------------------------------------*/ +/** + * \name Grove 3-axis gyroscope bitmasks and config + * @{ + */ +#define GROVE_GYRO_DLPF_FS_SEL 0x18 +#define GROVE_GYRO_DLPF_FS_CGF_8KHZ_LP256HZ 0x00 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP188HZ 0x01 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP98HZ 0x02 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP42HZ 0x03 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP20HZ 0x04 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP10HZ 0x05 +#define GROVE_GYRO_DLPF_FS_CGF_1KHZ_LP5HZ 0x06 + +#define GROVE_GYRO_INT_CFG_RAW_READY_EN 0x01 +#define GROVE_GYRO_INT_CFG_READY_EN 0x04 +#define GROVE_GYRO_INT_CFG_LATCH_CLR_ANY 0x10 +#define GROVE_GYRO_INT_CFG_LATCH_EN 0x20 +#define GROVE_GYRO_INT_CFG_PIN_OPEN 0x40 +#define GROVE_GYRO_INT_CFG_PIN_ACTL 0x80 +#define GROVE_GYRO_INT_CFG_DISABLE 0x00 + +#define GROVE_GYRO_INT_STATUS_DATA_RDY_MASK 0x01 +#define GROVE_GYRO_INT_STATUS_PLL_RDY_MASK 0x04 + +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_INTOSC 0x00 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_X 0x01 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_Y 0x02 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_PLL_Z 0x03 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_EXT_32K 0x04 +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_EXT_19K 0x05 +#define GROVE_GYRO_PWR_MGMT_STBY_ZG 0x08 +#define GROVE_GYRO_PWR_MGMT_STBY_YG 0x10 +#define GROVE_GYRO_PWR_MGMT_STBY_XG 0x20 +#define GROVE_GYRO_PWR_MGMT_SLEEP 0x40 +#define GROVE_GYRO_PWR_MGMT_RESET 0x80 + +#ifdef GROVE_GYRO_CONF_OSC +#define GROVE_GYRO_DEFAULT_OSC GROVE_GYRO_CONF_OSC +#else +#define GROVE_GYRO_DEFAULT_OSC GROVE_GYRO_PWR_MGMT_CLK_SEL_INTOSC +#endif + +#define GROVE_GYRO_PWR_MGMT_CLK_SEL_MASK 0x07 +#define GROVE_GYRO_MAX_DATA 0x06 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name Grove 3-axis gyroscope operation values + * @{ + */ +/* Configure request type */ +#define GROVE_GYRO_ACTIVE SENSORS_ACTIVE +#define GROVE_GYRO_DATA_INTERRUPT 0x01 +#define GROVE_GYRO_SAMPLE_RATE 0x02 +#define GROVE_GYRO_SAMPLE_RATE_DIVIDER 0x03 +#define GROVE_GYRO_POWER_ON 0x04 +#define GROVE_GYRO_POWER_OFF 0x05 + +/* Sensor value request type, match to the stand-by mask to check if enabled */ +#define GROVE_GYRO_X GROVE_GYRO_PWR_MGMT_STBY_XG +#define GROVE_GYRO_Y GROVE_GYRO_PWR_MGMT_STBY_YG +#define GROVE_GYRO_Z GROVE_GYRO_PWR_MGMT_STBY_ZG +#define GROVE_GYRO_SENSOR GROVE_GYRO_PWR_MGMT_SLEEP +#define GROVE_GYRO_XYZ (GROVE_GYRO_X + GROVE_GYRO_Y + \ + GROVE_GYRO_Z) +#define GROVE_GYRO_ALL (GROVE_GYRO_XYZ + GROVE_GYRO_SENSOR) +#define GROVE_GYRO_TEMP 0x06 + +/* Return types */ +#define GROVE_GYRO_ERROR (-1) +#define GROVE_GYRO_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define GROVE_GYRO_STRING "Grove 3-axis gyroscope Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor grove_gyro; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef GROVE_GYRO_H_ */ +/** + * @} + * @} + */ From 426fa24e507975f13a1fc8732901beb0b8a03318 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 21 Jan 2016 16:21:00 +0100 Subject: [PATCH 63/94] Clear interrupt and trigger callback if new data is generated --- examples/zolertia/zoul/test-grove-gyro.c | 23 +++++++++++------ platform/zoul/dev/grove-gyro.c | 32 ++++++++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/examples/zolertia/zoul/test-grove-gyro.c b/examples/zolertia/zoul/test-grove-gyro.c index 29d2afc0d..012188e31 100644 --- a/examples/zolertia/zoul/test-grove-gyro.c +++ b/examples/zolertia/zoul/test-grove-gyro.c @@ -98,6 +98,9 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) PROCESS_EXIT(); } + /* Register the interrupt handler */ + GROVE_GYRO_REGISTER_INT(gyro_interrupt_callback); + /* The gyroscope sensor should be on now but the three gyroscope axis should * be off, to enable a single axis or any combination of the 3 you can use as * argument either GROVE_GYRO_X, GROVE_GYRO_Y, GROVE_GYRO_Z. To enable or @@ -105,8 +108,12 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) */ grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_XYZ); - /* Register the interrupt handler */ - GROVE_GYRO_REGISTER_INT(gyro_interrupt_callback); + /* Enabling the data interrupt will feed data directly to the extern data + * structure and notify us about it, depending on the sampling rate and + * divisor this could generate many interrupts/second. A zero argument would + * disable the interrupts + */ + grove_gyro.configure(GROVE_GYRO_DATA_INTERRUPT, 1); /* And periodically poll the sensor, values are in º/s */ @@ -124,12 +131,12 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) if(grove_gyro.value(GROVE_GYRO_XYZ) == GROVE_GYRO_SUCCESS) { /* Converted values with a 2-digit precision */ - printf("Gyro: X %u.%u, Y %u.%u, Z %u.%u\n", gyro_values.x / 100, - gyro_values.x % 100, - gyro_values.y / 100, - gyro_values.y % 100, - gyro_values.z / 100, - gyro_values.z % 100); + printf("Gyro: X: %u.%u, Y: %u.%u, Z: %u.%u\n", gyro_values.x / 100, + gyro_values.x % 100, + gyro_values.y / 100, + gyro_values.y % 100, + gyro_values.z / 100, + gyro_values.z % 100); } else { printf("Error, enable the DEBUG flag in the grove-gyro driver for info,"); printf(" or check if the sensor is properly connected\n"); diff --git a/platform/zoul/dev/grove-gyro.c b/platform/zoul/dev/grove-gyro.c index e763cda9d..7f6723d49 100644 --- a/platform/zoul/dev/grove-gyro.c +++ b/platform/zoul/dev/grove-gyro.c @@ -46,7 +46,7 @@ #include "dev/grove-gyro.h" #include "lib/sensors.h" /*---------------------------------------------------------------------------*/ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -110,10 +110,19 @@ grove_gyro_sampdiv(uint8_t value) return GROVE_GYRO_ERROR; } /*---------------------------------------------------------------------------*/ -static void +static uint8_t grove_gyro_clear_interrupt(void) { - /* FIXME */ + uint8_t aux = 0; + + /* Clear interrupt */ + grove_gyro_read_reg(GROVE_GYRO_INT_STATUS, &aux, 1); + + if(aux & GROVE_GYRO_INT_STATUS_DATA_RDY_MASK) { + return GROVE_GYRO_INT_STATUS_DATA_RDY_MASK; + } + + return 0; } /*---------------------------------------------------------------------------*/ static int @@ -199,7 +208,7 @@ grove_gyro_power_mgmt(uint8_t value, uint8_t type) /* Power-up delay */ if(type == GROVE_GYRO_POWER_ON) { - // clock_delay_usec(50000); + clock_delay_usec(25000); } return GROVE_GYRO_SUCCESS; @@ -345,10 +354,20 @@ PROCESS_THREAD(grove_gyro_int_process, ev, data) PROCESS_EXITHANDLER(); PROCESS_BEGIN(); + static uint8_t axis_to_read = 0; + while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); - grove_gyro_clear_interrupt(); - grove_gyro_int_callback(0); + if(grove_gyro_clear_interrupt() == GROVE_GYRO_INT_STATUS_DATA_RDY_MASK) { + + axis_to_read += (power_mgmt & GROVE_GYRO_X) ? 0: GROVE_GYRO_X; + axis_to_read += (power_mgmt & GROVE_GYRO_Y) ? 0: GROVE_GYRO_Y; + axis_to_read += (power_mgmt & GROVE_GYRO_Z) ? 0: GROVE_GYRO_Z; + + if(grove_gyro_read(axis_to_read) == GROVE_GYRO_SUCCESS) { + grove_gyro_int_callback(GROVE_GYRO_SUCCESS); + } + } } PROCESS_END(); } @@ -466,7 +485,6 @@ configure(int type, int value) /* Enable interrupt and latch the pin until cleared */ if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_RAW_READY_EN + - GROVE_GYRO_INT_CFG_LATCH_CLR_ANY + GROVE_GYRO_INT_CFG_LATCH_EN) == GROVE_GYRO_ERROR) { PRINTF("Gyro: failed to enable the interrupt\n"); return GROVE_GYRO_ERROR; From 9a80c0098f950fcaa543405e385b8178e4ba63cc Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 21 Jan 2016 18:06:51 +0100 Subject: [PATCH 64/94] Added zero-calibration function and added offset values to the structure --- examples/zolertia/zoul/test-grove-gyro.c | 5 ++ platform/zoul/dev/grove-gyro.c | 103 ++++++++++++++++++++++- platform/zoul/dev/grove-gyro.h | 8 ++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/examples/zolertia/zoul/test-grove-gyro.c b/examples/zolertia/zoul/test-grove-gyro.c index 012188e31..24baa360f 100644 --- a/examples/zolertia/zoul/test-grove-gyro.c +++ b/examples/zolertia/zoul/test-grove-gyro.c @@ -108,6 +108,11 @@ PROCESS_THREAD(remote_grove_gyro_process, ev, data) */ grove_gyro.configure(GROVE_GYRO_POWER_ON, GROVE_GYRO_XYZ); + /* Calibrate the sensor taking 200 samples every 5ms for the zero-point offset + * value, this has to be done manually and is up to the user + */ + grove_gyro.configure(GROVE_GYRO_CALIBRATE_ZERO, 1); + /* Enabling the data interrupt will feed data directly to the extern data * structure and notify us about it, depending on the sampling rate and * divisor this could generate many interrupts/second. A zero argument would diff --git a/platform/zoul/dev/grove-gyro.c b/platform/zoul/dev/grove-gyro.c index 7f6723d49..56f79d9b3 100644 --- a/platform/zoul/dev/grove-gyro.c +++ b/platform/zoul/dev/grove-gyro.c @@ -45,6 +45,7 @@ #include "dev/i2c.h" #include "dev/grove-gyro.h" #include "lib/sensors.h" +#include "dev/watchdog.h" /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG @@ -58,6 +59,7 @@ /*---------------------------------------------------------------------------*/ static uint8_t enabled; static uint8_t power_mgmt; +static uint8_t int_en; /*---------------------------------------------------------------------------*/ grove_gyro_values_t gyro_values; /*---------------------------------------------------------------------------*/ @@ -347,6 +349,89 @@ grove_gyro_read(int type) return GROVE_GYRO_ERROR; } /*---------------------------------------------------------------------------*/ +static int +grove_gyro_calibrate(void) +{ + uint8_t i; + uint8_t buf[GROVE_GYRO_MAX_DATA]; + uint8_t power_mgmt_backup; + uint32_t x, y, z; + + /* Disable interrupts */ + if(int_en) { + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to disable the interrupts\n"); + return GROVE_GYRO_ERROR; + } + GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + } + + /* Turn on the 3-axis, save the current config */ + if(grove_gyro_read_reg(GROVE_GYRO_PWR_MGMT, &power_mgmt_backup, 1) == + GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to read power mgmt config\n"); + return GROVE_GYRO_ERROR; + } + + if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_ON) == + GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to bring sensor up\n"); + return GROVE_GYRO_ERROR; + } + + x = 0; + y = 0; + z = 0; + + for (i = 0; i < GROVE_GYRO_CALIB_SAMPLES; i++){ + clock_delay_usec(GROVE_GYRO_CALIB_TIME_US); + watchdog_periodic(); + if(grove_gyro_read_reg(GROVE_GYRO_XOUT_H, buf, GROVE_GYRO_MAX_DATA) == + GROVE_GYRO_SUCCESS) { + x += (buf[0] << 8) + buf[1]; + y += (buf[2] << 8) + buf[3]; + z += (buf[4] << 8) + buf[5]; + } + } + + gyro_values.x_offset = ABS(x)/GROVE_GYRO_CALIB_SAMPLES; + gyro_values.y_offset = ABS(y)/GROVE_GYRO_CALIB_SAMPLES; + gyro_values.z_offset = ABS(z)/GROVE_GYRO_CALIB_SAMPLES; + + PRINTF("Gyro: x_offset (RAW) 0x%02X\n", gyro_values.x_offset); + PRINTF("Gyro: y_offset (RAW) 0x%02X\n", gyro_values.y_offset); + PRINTF("Gyro: z_offset (RAW) 0x%02X\n", gyro_values.z_offset); + + gyro_values.x_offset = grove_gyro_convert_to_value(gyro_values.x_offset); + gyro_values.y_offset = grove_gyro_convert_to_value(gyro_values.y_offset); + gyro_values.z_offset = grove_gyro_convert_to_value(gyro_values.z_offset); + + PRINTF("Gyro: x_offset (converted) %d\n", gyro_values.x_offset); + PRINTF("Gyro: y_offset (converted) %d\n", gyro_values.y_offset); + PRINTF("Gyro: z_offset (converted) %d\n", gyro_values.z_offset); + + /* Cleaning up */ + buf[0] = GROVE_GYRO_PWR_MGMT; + buf[1] = power_mgmt_backup; + + if(grove_gyro_write_reg(&buf[0], 2) != GROVE_GYRO_SUCCESS) { + PRINTF("Gyro: failed restoring power mgmt (0x%02X)\n", power_mgmt_backup); + return GROVE_GYRO_ERROR; + } + + if(int_en) { + if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_RAW_READY_EN + + GROVE_GYRO_INT_CFG_LATCH_EN) == GROVE_GYRO_ERROR) { + PRINTF("Gyro: failed to enable the interrupt\n"); + return GROVE_GYRO_ERROR; + } + + GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); + } + + return GROVE_GYRO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ PROCESS(grove_gyro_int_process, "Grove gyroscope interrupt process handler"); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(grove_gyro_int_process, ev, data) @@ -407,7 +492,8 @@ configure(int type, int value) { if((type != GROVE_GYRO_ACTIVE) && (type != GROVE_GYRO_SAMPLE_RATE) && (type != GROVE_GYRO_SAMPLE_RATE_DIVIDER) && (type != GROVE_GYRO_POWER_ON) && - (type != GROVE_GYRO_POWER_OFF) && (type != GROVE_GYRO_DATA_INTERRUPT)) { + (type != GROVE_GYRO_POWER_OFF) && (type != GROVE_GYRO_DATA_INTERRUPT) && + (type != GROVE_GYRO_CALIBRATE_ZERO)) { PRINTF("Gyro: option not supported\n"); return GROVE_GYRO_ERROR; } @@ -418,6 +504,15 @@ configure(int type, int value) i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_FAST_BUS_SPEED); + /* Initialize the data structure values */ + gyro_values.x = 0; + gyro_values.y = 0; + gyro_values.z = 0; + gyro_values.temp = 0; + gyro_values.x_offset = 0; + gyro_values.y_offset = 0; + gyro_values.z_offset = 0; + /* Make sure the sensor is on */ if(grove_gyro_power_mgmt(GROVE_GYRO_ALL, GROVE_GYRO_POWER_ON) != GROVE_GYRO_SUCCESS) { @@ -456,6 +551,7 @@ configure(int type, int value) } else { enabled = 0; + int_en = 0; GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); grove_gyro_int_callback = NULL; if(grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE) == @@ -479,6 +575,7 @@ configure(int type, int value) * I2C digital sensors using the bus and sharing this pin, so an user may * comment the line below */ + int_en = 0; GPIO_DISABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); return grove_gyro_interrupt(GROVE_GYRO_INT_CFG_DISABLE); } @@ -503,6 +600,7 @@ configure(int type, int value) process_start(&grove_gyro_int_process, NULL); /* Enable interrupts */ + int_en = 1; GPIO_ENABLE_INTERRUPT(GROVE_GYRO_INT_PORT_BASE, GROVE_GYRO_INT_PIN_MASK); ioc_set_over(I2C_INT_PORT, I2C_INT_PIN, IOC_OVERRIDE_PUE); nvic_interrupt_enable(I2C_INT_VECTOR); @@ -534,6 +632,9 @@ configure(int type, int value) } return grove_gyro_power_mgmt(value, type); + case GROVE_GYRO_CALIBRATE_ZERO: + return grove_gyro_calibrate(); + default: return GROVE_GYRO_ERROR; } diff --git a/platform/zoul/dev/grove-gyro.h b/platform/zoul/dev/grove-gyro.h index 56649a2f1..8ab84ba7e 100644 --- a/platform/zoul/dev/grove-gyro.h +++ b/platform/zoul/dev/grove-gyro.h @@ -64,6 +64,9 @@ typedef struct { uint16_t x; uint16_t y; uint16_t z; + uint16_t x_offset; + uint16_t y_offset; + uint16_t z_offset; int16_t temp; } grove_gyro_values_t; @@ -149,6 +152,7 @@ extern grove_gyro_values_t gyro_values; #define GROVE_GYRO_SAMPLE_RATE_DIVIDER 0x03 #define GROVE_GYRO_POWER_ON 0x04 #define GROVE_GYRO_POWER_OFF 0x05 +#define GROVE_GYRO_CALIBRATE_ZERO 0x06 /* Sensor value request type, match to the stand-by mask to check if enabled */ #define GROVE_GYRO_X GROVE_GYRO_PWR_MGMT_STBY_XG @@ -163,6 +167,10 @@ extern grove_gyro_values_t gyro_values; /* Return types */ #define GROVE_GYRO_ERROR (-1) #define GROVE_GYRO_SUCCESS 0x00 + +/* Calibration constants */ +#define GROVE_GYRO_CALIB_SAMPLES 200 +#define GROVE_GYRO_CALIB_TIME_US 5000 /** @} */ /* -------------------------------------------------------------------------- */ #define GROVE_GYRO_STRING "Grove 3-axis gyroscope Sensor" From 66ebca3ade235f5be042dab691d63aacb9767b39 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sat, 23 Jan 2016 15:42:13 +0100 Subject: [PATCH 65/94] Updated to new adc-zoul renaming --- platform/zoul/dev/weather-meter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 8d3ee07f1..9c46a520a 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -45,7 +45,7 @@ /*---------------------------------------------------------------------------*/ #include #include "contiki.h" -#include "dev/adc-sensors.h" +#include "dev/adc-zoul.h" #include "dev/weather-meter.h" #include "dev/zoul-sensors.h" #include "lib/sensors.h" @@ -178,7 +178,7 @@ weather_meter_wind_vane_degrees(uint16_t value) static int weather_meter_get_wind_dir(void) { - weather_sensors.wind_vane = adc_sensors.value(WIND_VANE_ADC); + weather_sensors.wind_vane = adc_zoul.value(WIND_VANE_ADC); if((int16_t)weather_sensors.wind_vane < 0) { weather_sensors.wind_vane = 0; } @@ -412,7 +412,7 @@ configure(int type, int value) } /* Configure the wind vane */ - adc_sensors.configure(SENSORS_HW_INIT, WIND_VANE_ADC); + adc_zoul.configure(SENSORS_HW_INIT, WIND_VANE_ADC); /* Configure anemometer interruption */ GPIO_SOFTWARE_CONTROL(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); From 246b01095f8d7138e42846e039d2120b6d117807 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Wed, 13 Jan 2016 18:56:16 +0100 Subject: [PATCH 66/94] Ported Grove LCD with RGB backlight for the Zoul platforms --- examples/zolertia/zoul/Makefile | 3 +- examples/zolertia/zoul/test-lcd.c | 129 ++++++++++ platform/zoul/dev/rgb-bl-lcd.c | 377 ++++++++++++++++++++++++++++++ platform/zoul/dev/rgb-bl-lcd.h | 168 +++++++++++++ 4 files changed, 676 insertions(+), 1 deletion(-) create mode 100644 examples/zolertia/zoul/test-lcd.c create mode 100644 platform/zoul/dev/rgb-bl-lcd.c create mode 100644 platform/zoul/dev/rgb-bl-lcd.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 190348c4b..0b9eef673 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -3,10 +3,11 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt 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 +CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd CONTIKI_TARGET_SOURCEFILES += tsl2563.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 all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-lcd.c b/examples/zolertia/zoul/test-lcd.c new file mode 100644 index 000000000..6a17df99c --- /dev/null +++ b/examples/zolertia/zoul/test-lcd.c @@ -0,0 +1,129 @@ +/* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \addtogroup zoul-examples + * @{ + * + * \defgroup zoul-rgb-lcd-test Test the LCD with RGB backlight + * + * Demonstrates the use of the LCD with on-board RGB backlight + * @{ + * + * \file + * A quick program for testing the Grove's LCD with RGB backlight + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/rgb-bl-lcd.h" +#include "dev/button-sensor.h" +/*---------------------------------------------------------------------------*/ +#define SCROLL_PERIOD (CLOCK_SECOND / 6) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_lcd_process, "Grove LCD backlight test"); +AUTOSTART_PROCESSES(&remote_lcd_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_lcd_process, ev, data) +{ + PROCESS_BEGIN(); + + static uint8_t i = 0; + static char buf[16]; + static uint16_t counter; + + /* Enable the LCD, default configuration is 2 rows and 16 columns, RGB + * backlight on with red color, no cursor/blink */ + SENSORS_ACTIVATE(rgb_bl_lcd); + + /* Set the cursor to column 17 and row 0 to not make it visible yet */ + lcd_set_cursor(17, LCD_RGB_1ST_ROW); + lcd_write("Hello Contiki!"); + + /* Now make the text appear from right to left and stay aligned left */ + while(i < 16) { + etimer_set(&et, SCROLL_PERIOD); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + lcd_scroll_display(LCD_RGB_CURSOR_MOVE_LEFT, 1); + i++; + etimer_restart(&et); + } + + /* wait 2 seconds */ + etimer_set(&et, (CLOCK_SECOND * 2)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + /* Clear the welcome message */ + lcd_clear_display(); + + /* Spin the timer and print the counter value on the LCD */ + etimer_set(&et, CLOCK_SECOND); + + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Press the button!"); + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + snprintf(buf, 15, "Counter: %05u", counter); + lcd_set_cursor(0, LCD_RGB_2ND_ROW); + lcd_write(buf); + printf("Counter: %05u\n", counter); + counter++; + etimer_restart(&et); + } else if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + printf("Button pressed!!\n"); + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Button pressed!!"); + } else { + lcd_set_cursor(0, LCD_RGB_1ST_ROW); + lcd_write("Press the button!"); + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/rgb-bl-lcd.c b/platform/zoul/dev/rgb-bl-lcd.c new file mode 100644 index 000000000..c0c79ebe8 --- /dev/null +++ b/platform/zoul/dev/rgb-bl-lcd.c @@ -0,0 +1,377 @@ +/* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-lcd-backlight-lcd + * @{ + * + * \file + * Grove LCD with RGB backlight driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/rgb-bl-lcd.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +typedef struct { + uint8_t display_func; + uint8_t display_ctrl; + uint8_t display_mode; + uint8_t num_lines; + uint8_t cur_line; +} rgb_lcd_config_t; + +static rgb_lcd_config_t lcd; +/*---------------------------------------------------------------------------*/ +static const unsigned char rgb_color[7][3] = +{ + { 0xFF, 0xFF, 0xFF }, /**< White */ + { 0xFF, 0x00, 0x00 }, /**< Red */ + { 0x00, 0xFF, 0x00 }, /**< Green */ + { 0x00, 0x00, 0xFF }, /**< Blue */ + { 0xFF, 0xFF, 0x00 }, /**< Yellow */ + { 0x00, 0xFF, 0xFF }, /**< Purple */ + { 0x00, 0x00, 0x00 }, /**< Black (off) */ +}; +/*---------------------------------------------------------------------------*/ +static int +lcd_backlight_write_reg(uint8_t addr, uint8_t val) +{ + uint8_t buf[2]; + buf[0] = addr; + buf[1] = val; + + i2c_master_enable(); + if(i2c_burst_send(LCD_RGB_ADDR, buf, 2) == I2C_MASTER_ERR_NONE) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_backlight_color(uint8_t color) +{ + lcd_backlight_write_reg(LCD_RGB_LED_RED, rgb_color[color][0]); + lcd_backlight_write_reg(LCD_RGB_LED_GREEN, rgb_color[color][1]); + lcd_backlight_write_reg(LCD_RGB_LED_BLUE, rgb_color[color][2]); + + return LCD_RGB_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_write_reg(uint8_t *buf, uint8_t num) +{ + if((buf == NULL) || (num <= 0)) { + PRINTF("LCD: invalid write values\n"); + return LCD_RGB_ERROR; + } + + i2c_master_enable(); + if(i2c_burst_send(LCD_ADDR, buf, num) == I2C_MASTER_ERR_NONE) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_cmd(uint8_t value) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_COMMAND_BYTE; + buf[1] = value; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + + PRINTF("LCD: failed to send command 0x%02X\n", value); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_clear_display(void) +{ + if(lcd_cmd(LCD_RGB_CLEAR_DISPLAY) == LCD_RGB_SUCCESS) { + clock_delay_usec(LCD_RGB_DELAY_2MS); + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to clear LCD\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_return_home(void) +{ + if(lcd_cmd(LCD_RGB_RETURN_HOME) == LCD_RGB_SUCCESS) { + clock_delay_usec(LCD_RGB_DELAY_2MS); + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to return home\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_set_cursor(uint8_t col, uint8_t row) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_SETDDRAM_ADDR; + buf[1] = col; + buf[1] += (!row) ? LCD_RGB_START_1ST_ROW : LCD_RGB_START_2ND_ROW; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + + PRINTF("LCD: failed to set cursor\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_display(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set display\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_cursor(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_CURSOR_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_CURSOR_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set cursor\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_blink(uint8_t state) +{ + lcd.display_ctrl &= ~LCD_RGB_DISPLAY_BLINK_ON; + if(state) { + lcd.display_ctrl |= LCD_RGB_DISPLAY_BLINK_ON; + } + + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set blink\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_scroll_display(uint8_t direction, uint8_t num) +{ + uint8_t i; + + /* FIXME: add check for num */ + + for(i = 0; i < num; i++) { + if(lcd_cmd(LCD_RGB_CURSOR_SHIFT + LCD_RGB_CURSOR_DISPLAY_MOVE + + direction) != LCD_RGB_SUCCESS) { + PRINTF("LCD: failed to set scroll\n"); + return LCD_RGB_ERROR; + } + } + return LCD_RGB_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +lcd_text_direction(uint8_t direction) +{ + lcd.display_mode &= ~LCD_RGB_ENTRY_MODE_LEFT; + if(direction) { + lcd.display_mode |= LCD_RGB_ENTRY_MODE_LEFT; + } + + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set text direction\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +int +lcd_autoscroll(uint8_t state) +{ + lcd.display_mode &= ~LCD_RGB_ENTRY_SHIFT_INCREMENT; + if(state) { + lcd.display_mode |= LCD_RGB_ENTRY_SHIFT_INCREMENT; + } + + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + PRINTF("LCD: failed to set autoscroll\n"); + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +lcd_write_byte(int c) +{ + uint8_t buf[2]; + buf[0] = LCD_RGB_SETCGRAM_ADDR; + buf[1] = c; + + if(lcd_write_reg(buf, 2) == LCD_RGB_SUCCESS) { + return LCD_RGB_SUCCESS; + } + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +uint8_t +lcd_write(const char *s) +{ + uint8_t i = 0; + while(s && *s != 0) { + lcd_write_byte(*s++); + i++; + } + + PRINTF("LCD: wrote %u bytes\n", i); + return i; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + + if(type != LCD_RGB_ACTIVE) { + PRINTF("LCD: option not supported\n"); + return LCD_RGB_ERROR; + } + + switch(type) { + + /* Default initialization value is 16 columns and 2 rows */ + case LCD_RGB_ACTIVE: + if(value) { + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + lcd.display_func = LCD_RGB_FUNCTION_SET_2_LINE + + LCD_RGB_FUNCTION_SET_5x8_DOTS; + + /* wait at least 50ms for the LCD to initialize */ + clock_delay_usec(LCD_RGB_DELAY_50MS); + + /* Send function set command sequence */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + clock_delay_usec(LCD_RGB_DELAY_4_5MS); + + /* Datasheet instructs to repeat a second time... */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + clock_delay_usec(LCD_RGB_DELAY_150US); + + /* and a third... */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Now we can configure everything */ + if(lcd_cmd(LCD_RGB_FUNCTION_SET + lcd.display_func) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Turn on the display */ + lcd.display_ctrl = LCD_RGB_DISPLAY_ON + LCD_RGB_DISPLAY_CURSOR_OFF + + LCD_RGB_DISPLAY_BLINK_OFF; + if(lcd_cmd(LCD_RGB_DISPLAY_CONTROL + lcd.display_ctrl) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Clear the display */ + if(lcd_clear_display() == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Initialize text direction (the LCD supports japanese, cool! */ + lcd.display_mode = LCD_RGB_ENTRY_MODE_LEFT + LCD_RGB_ENTRY_SHIFT_DECREMENT; + + /* configure the entry mode */ + if(lcd_cmd(LCD_RGB_ENTRY_MODE_SET + lcd.display_mode) == LCD_RGB_ERROR) { + return LCD_RGB_ERROR; + } + + /* Backlight initialization */ + lcd_backlight_write_reg(LCD_RGB_LED_MODE_1, LCD_RGB_LED_MODE_DEFAULT); + lcd_backlight_write_reg(LCD_RGB_LED_MODE_2, LCD_RGB_LED_MODE_DEFAULT); + lcd_backlight_write_reg(LCD_RGB_LED_OUT, LCD_RGB_LED_OUT_PWM_CTRL); + + /* Set the backlight color */ + lcd_backlight_color(LCD_RGB_RED); + + PRINTF("LCD: initialized\n"); + enabled = 1; + return LCD_RGB_SUCCESS; + } else { + lcd_display(LCD_RGB_DISPLAY_OFF); + lcd_backlight_color(LCD_RGB_BLACK); + enabled = 0; + } + } + + return LCD_RGB_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(rgb_bl_lcd, RGB_BACKLIGHT_LCD, NULL, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/rgb-bl-lcd.h b/platform/zoul/dev/rgb-bl-lcd.h new file mode 100644 index 000000000..eaf5c2761 --- /dev/null +++ b/platform/zoul/dev/rgb-bl-lcd.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the 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 SOcFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-lcd-backlight-lcd Grove LCD with RGB backlight + * @{ + * + * \file + * Grove LCD with RGB backlight header + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/* -------------------------------------------------------------------------- */ +#ifndef RGB_BL_LCD_H_ +#define RGB_BL_LCD_H_ +/* -------------------------------------------------------------------------- */ +/** + * \name LCD w/ backlight enums + * @{ + */ +enum { + LCD_RGB_WHITE = 0x00, + LCD_RGB_RED = 0x01, + LCD_RGB_GREEN = 0x02, + LCD_RGB_BLUE = 0x03, + LCD_RGB_BLACK = 0x04, + LCD_RGB_YELLOW = 0x05, + LCD_RGB_PURPLE = 0x06, +}; +/* -------------------------------------------------------------------------- */ +enum { + LCD_RGB_1ST_ROW = 0x00, + LCD_RGB_2ND_ROW = 0x01, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name LCD w/ backlight address, registers and bitmasks + * @{ + */ +#define LCD_ADDR 0x3E +#define LCD_RGB_ADDR 0x62 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_REG_MODE1 0x00 +#define LCD_RGB_REG_MODE2 0x01 +#define LCD_RGB_REG_OUTPUT 0x08 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_COMMAND_BYTE 0x80 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_CLEAR_DISPLAY 0x01 +#define LCD_RGB_RETURN_HOME 0x02 +#define LCD_RGB_ENTRY_MODE_SET 0x04 +#define LCD_RGB_DISPLAY_CONTROL 0x08 +#define LCD_RGB_CURSOR_SHIFT 0x10 +#define LCD_RGB_FUNCTION_SET 0x20 +#define LCD_RGB_SETCGRAM_ADDR 0x40 +#define LCD_RGB_SETDDRAM_ADDR 0x80 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_ENTRY_MODE_RIGHT 0x00 +#define LCD_RGB_ENTRY_MODE_LEFT 0x02 +#define LCD_RGB_ENTRY_SHIFT_INCREMENT 0x01 +#define LCD_RGB_ENTRY_SHIFT_DECREMENT 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_DISPLAY_ON 0x04 +#define LCD_RGB_DISPLAY_OFF 0x00 +#define LCD_RGB_DISPLAY_CURSOR_ON 0x02 +#define LCD_RGB_DISPLAY_CURSOR_OFF 0x00 +#define LCD_RGB_DISPLAY_BLINK_ON 0x01 +#define LCD_RGB_DISPLAY_BLINK_OFF 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_CURSOR_DISPLAY_MOVE 0x08 +#define LCD_RGB_CURSOR_MOVE 0x00 +#define LCD_RGB_CURSOR_MOVE_RIGHT 0x04 +#define LCD_RGB_CURSOR_MOVE_LEFT 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_FUNCTION_SET_8BIT 0x10 +#define LCD_RGB_FUNCTION_SET_4BIT 0x00 +#define LCD_RGB_FUNCTION_SET_2_LINE 0x08 +#define LCD_RGB_FUNCTION_SET_1_LINE 0x00 +#define LCD_RGB_FUNCTION_SET_5x10_DOTS 0x04 +#define LCD_RGB_FUNCTION_SET_5x8_DOTS 0x00 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_MODE_1 0x00 +#define LCD_RGB_LED_MODE_2 0x01 +#define LCD_RGB_LED_OUT 0x08 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_RED 0x04 +#define LCD_RGB_LED_GREEN 0x03 +#define LCD_RGB_LED_BLUE 0x02 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_LED_MODE_DEFAULT 0x00 +#define LCD_RGB_LED_OUT_PWM_CTRL 0xAA +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_DELAY_50MS 50000 +#define LCD_RGB_DELAY_4_5MS 4500 +#define LCD_RGB_DELAY_150US 150 +#define LCD_RGB_DELAY_2MS 2000 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_START_1ST_ROW 0x80 +#define LCD_RGB_START_2ND_ROW 0xC0 +/* -------------------------------------------------------------------------- */ +#define LCD_RGB_ACTIVE SENSORS_ACTIVE +#define LCD_RGB_ERROR (-1) +#define LCD_RGB_SUCCESS 0x00 +/** @} */ +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 return and command values + * @{ + */ +/* LCD functions */ +uint8_t lcd_write(const char *s); +int lcd_set_cursor(uint8_t col, uint8_t row); +int lcd_autoscroll(uint8_t state); +int lcd_scroll_display(uint8_t direction, uint8_t num); +int lcd_blink(uint8_t state); +int lcd_clear_display(void); +int lcd_return_home(void); +int lcd_display(uint8_t state); +int lcd_cursor(uint8_t state); +int lcd_text_direction(uint8_t direction); + +/* Backlight functions */ +int lcd_backlight_color(uint8_t color); +/** @} */ +/* -------------------------------------------------------------------------- */ +#define RGB_BACKLIGHT_LCD "LCD with RGB backlight" +extern const struct sensors_sensor rgb_bl_lcd; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef RGB_BL_LCD_ */ +/** + * @} + * @} + */ From 915facad2232ff68b740ad698d9cb2b8c2277f6e Mon Sep 17 00:00:00 2001 From: zq301 Date: Sun, 24 Jan 2016 14:39:48 +0800 Subject: [PATCH 67/94] a memory overflow in shell-vars.c " sprintf(numbuf, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",...)" . the formatted data wrote to "numbuf" is 39 bytes, but numbuf is 32 bytes. --- apps/shell/shell-vars.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/shell/shell-vars.c b/apps/shell/shell-vars.c index b28834f4a..1e562d944 100644 --- a/apps/shell/shell-vars.c +++ b/apps/shell/shell-vars.c @@ -90,7 +90,8 @@ PROCESS_THREAD(shell_var_process, ev, data) { int i; int j; - char numbuf[32]; + + char numbuf[39]; PROCESS_BEGIN(); From d42b1b50e58cbc9f71da3efd2f387742c6ef94de Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 13:39:02 +0000 Subject: [PATCH 68/94] Allow the caller to access the entire content of CMDSTA When sending a command to the CC13xx/CC25xx RF core, we wait for command completion by checking the LSB of CMDSTA (correctly so). However, in doing so we also zero out the 3 CMDSTA return bytes. For some commands, those bytes contain useful information (e.g. an RSSI value) and are required by the caller. This problem manifests itself e.g. in PROP mode `channel_clear()`, whereby the caller will always see an RSSI value of 0. This pull therefore fixes the logic in `rf_core_send_cmd()` to check for command completion by blocking on the CMDSTA result byte without zeroing out the 3 return bytes. Fixes #1465 --- cpu/cc26xx-cc13xx/rf-core/rf-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 932297b91..8efe41dac 100644 --- a/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -160,7 +160,7 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status) HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd; do { - *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA) & 0xFF; + *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA); if(++timeout_count > 50000) { PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd); if(!interrupts_disabled) { @@ -168,7 +168,7 @@ rf_core_send_cmd(uint32_t cmd, uint32_t *status) } return RF_CORE_CMD_ERROR; } - } while(*status == RF_CORE_CMDSTA_PENDING); + } while((*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING); if(!interrupts_disabled) { ti_lib_int_master_enable(); From 9e9e6d07b060ca3720e3d454bfaeb662c376bbdd Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jan 2016 13:53:54 +0000 Subject: [PATCH 69/94] Adjust READMEs to point explicitly to the arm-gcc version used by travis --- platform/cc2538dk/README.md | 20 +++++++------------- platform/srf06-cc26xx/README.md | 13 ++++++++----- platform/zoul/README.md | 21 +++++++-------------- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/platform/cc2538dk/README.md b/platform/cc2538dk/README.md index 809f46d6a..998a574b3 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -66,21 +66,15 @@ The platform has been developed and tested under Windows XP, Mac OS X 10.9.1 and Install a Toolchain ------------------- -The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you will have a version pre-installed in your system. To find out if this is the case, try this: +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. - $ arm-none-eabi-gcc -v - Using built-in specs. - Target: arm-none-eabi - Configured with: /scratch/julian/lite-respin/eabi/src/gcc-4.3/configure - ... - (skip) - ... - Thread model: single - gcc version 4.3.2 (Sourcery G++ Lite 2008q3-66) +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. -The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors". This is the recommended version and the one being used by Contiki's regression tests on Travis. - -The older version (Sourcery G++ Lite 2008q3-66) shown above should still work, but the port is no longer being tested with it. + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Drivers ------- diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index f17d50a61..32071745c 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -58,12 +58,15 @@ To use the port you need: Note that uploading over serial doesn't work for the Sensortag, you can use TI's SmartRF Flash Programmer in this case. * A toolchain to build firmware: The port has been developed and tested with - GNU Tools for ARM Embedded Processors . - The port was developed and tested using this version: + GNU Tools for ARM Embedded Processors (). + The current recommended version and the one being used by Contiki's regression + tests on Travis is shown below. - $ arm-none-eabi-gcc -v - [...] - gcc version 4.9.3 20141119 (release) [ARM/embedded-4_9-branch revision 218278] (GNU Tools for ARM Embedded Processors) + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * srecord (http://srecord.sourceforge.net/) * You may also need other drivers so that the SmartRF can communicate with your diff --git a/platform/zoul/README.md b/platform/zoul/README.md index d8eb07bfd..dc2960909 100644 --- a/platform/zoul/README.md +++ b/platform/zoul/README.md @@ -74,22 +74,15 @@ To start using Contiki, the following is required: Install a Toolchain ------------------- -The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you will have a version pre-installed in your system. To find out if this is the case, try this: +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you may have a version pre-installed in your system. - $ arm-none-eabi-gcc -v - Using built-in specs. - Target: arm-none-eabi - Configured with: /scratch/julian/lite-respin/eabi/src/gcc-4.3/configure - ... - (skip) - ... - Thread model: single - gcc version 4.3.2 (Sourcery G++ Lite 2008q3-66) +The platform is currently being used/tested with "GNU Tools for ARM Embedded Processors" (). The current recommended version and the one being used by Contiki's regression tests on Travis is shown below. -The platform is currently being used/tested with the following toolchains: - -* GNU Tools for ARM Embedded Processors. This is the recommended version. Works nicely on OS X. -* Alternatively, you can use this older version for Linux. At the time of writing, this is the version used by Contiki's regression tests. + $ arm-none-eabi-gcc --version + arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848] + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Drivers ------- From e7c26c57db37494560c65d5e0d45070021dcc1c4 Mon Sep 17 00:00:00 2001 From: zq301 Date: Mon, 25 Jan 2016 09:35:15 +0800 Subject: [PATCH 70/94] Update shell-vars.c --- apps/shell/shell-vars.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/shell/shell-vars.c b/apps/shell/shell-vars.c index 1e562d944..84b7724e9 100644 --- a/apps/shell/shell-vars.c +++ b/apps/shell/shell-vars.c @@ -91,7 +91,7 @@ PROCESS_THREAD(shell_var_process, ev, data) int i; int j; - char numbuf[39]; + char numbuf[40]; PROCESS_BEGIN(); From d36eab37506ba4183fbed63013933e195d6e8588 Mon Sep 17 00:00:00 2001 From: zq301 Date: Mon, 25 Jan 2016 09:35:49 +0800 Subject: [PATCH 71/94] Update shell-vars.c --- apps/shell/shell-vars.c | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/shell/shell-vars.c b/apps/shell/shell-vars.c index 84b7724e9..14b484923 100644 --- a/apps/shell/shell-vars.c +++ b/apps/shell/shell-vars.c @@ -90,7 +90,6 @@ PROCESS_THREAD(shell_var_process, ev, data) { int i; int j; - char numbuf[40]; PROCESS_BEGIN(); From 1fca3e810a4c4e1d83cc0a2f82f2c3f74f01c8c8 Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Wed, 20 Jan 2016 15:50:56 +0100 Subject: [PATCH 72/94] Added PM10 and VAC parameters to adc_sensors driver --- examples/zolertia/zoul/Makefile | 2 +- examples/zolertia/zoul/test-pm10.c | 92 +++++++++++++++++ examples/zolertia/zoul/test-vac-sensor.c | 120 +++++++++++++++++++++++ platform/zoul/dev/adc-sensors.c | 16 ++- platform/zoul/dev/adc-sensors.h | 2 + platform/zoul/dev/pm10-sensor.c | 73 ++++++++++++++ platform/zoul/dev/pm10-sensot.h | 60 ++++++++++++ 7 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 examples/zolertia/zoul/test-pm10.c create mode 100644 examples/zolertia/zoul/test-vac-sensor.c create mode 100644 platform/zoul/dev/pm10-sensor.c create mode 100644 platform/zoul/dev/pm10-sensot.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 0b9eef673..b60cf8ccf 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -4,7 +4,7 @@ CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt 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 - +CONTIKI_PROJECT += test-pm10 test-vac-sensor CONTIKI_TARGET_SOURCEFILES += tsl2563.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 diff --git a/examples/zolertia/zoul/test-pm10.c b/examples/zolertia/zoul/test-pm10.c new file mode 100644 index 000000000..d8e64067a --- /dev/null +++ b/examples/zolertia/zoul/test-pm10.c @@ -0,0 +1,92 @@ +/* + * 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 zoul-examples + * @{ + * + * Demonstrates the operation of the Sharp PM10 analog sensor + * @{ + * + * \file + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/leds.h" +#include "dev/adc-sensors.h" +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) +/*---------------------------------------------------------------------------*/ +PROCESS(remote_pm10_sensor_process, "PM10 sensor test process"); +AUTOSTART_PROCESSES(&remote_grove_loudness_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(remote_pm10_sensor_process, ev, data) +{ + PROCESS_BEGIN(); + + uint16_t pm10_value; + + /* Use pin number not mask, for example if using the PA5 pin then use 2 */ + adc_sensors.configure(ANALOG_PM10_SENSOR, ADC_PIN); + + /* And periodically poll the sensor */ + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + leds_toggle(LEDS_GREEN); + + pm10_value = adc_sensors.value(ANALOG_PM10_SENSOR); + + if(pm10_value != ADC_WRAPPER_ERROR) { + printf("%u\n", pm10_value); + } else { + printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); + PROCESS_EXIT(); + } + + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c new file mode 100644 index 000000000..4ecfcf9a6 --- /dev/null +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, 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. + */ +/* + * + * + * @{ + * + * \file + * Example demonstrating the Zoul module on the RE-Mote & VAC sensor + */ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/uart.h" +#include "dev/button-sensor.h" +#include "dev/zoul-sensors.h" +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" +#include "dev/adc-sensors.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define LOOP_PERIOD 2 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_PERIODIC LEDS_GREEN +#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(zoul_demo_process, "Zoul demo process"); +AUTOSTART_PROCESSES(&zoul_demo_process); +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(zoul_demo_process, ev, data) +{ + + PROCESS_BEGIN(); + + counter = 0; + + /* Configure the user button */ + button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, + BUTTON_PRESS_EVENT_INTERVAL); + + /* Configure the ADC ports */ + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + printf("return configure, %d \n", adc_sensors.configure(ANALOG_VAC_SENSOR, ADC_PIN)); + + printf("VAC test application\n"); + leds_on(LEDS_PERIODIC); + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_toggle(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + printf("ADC3 = %d V\n", adc_sensors.value(ANALOG_VAC_SENSOR)); + uint32_t as = (adc_sensors.value(ANALOG_VAC_SENSOR) * 0.176); + printf("ADC5V = %ld V\n", as); + //printf("AC voltage = %d V\n", vac.value(VAC_VAL)); + + etimer_set(&et, LOOP_INTERVAL); + counter++; + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index 11d727dbc..a77958bdd 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -108,6 +108,18 @@ convert_to_value(uint8_t index) value /= 100000; return (uint16_t)value; + case ANALOG_VAC_SENSOR: + /* Linear sensor from 0 to 5 V; 0.0088 resolution*/ + value *= 88; + value /= 10000; + return (uint16_t)value; + + case ANALOG_PM10_SENSOR: + /* PM10 sensor from 0 to 5 V; 0.0088 resolution*/ + value *= 88; + value /= 10000; + return (uint16_t)value; + default: return ADC_WRAPPER_ERROR; } @@ -154,7 +166,8 @@ configure(int type, int value) uint8_t pin_mask = GPIO_PIN_MASK(value); if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && - (type != ANALOG_GROVE_LOUDNESS)) { + (type != ANALOG_GROVE_LOUDNESS) && (type != ANALOG_PM10_SENSOR) && + (type != ANALOG_VAC_SENSOR) ) { PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); return ADC_WRAPPER_ERROR; } @@ -179,6 +192,7 @@ configure(int type, int value) case ANALOG_GROVE_LIGHT: case ANALOG_GROVE_LOUDNESS: case ANALOG_PHIDGET_ROTATION_1109: + case ANALOG_VAC_SENSOR: if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { return ADC_WRAPPER_ERROR; } diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 8d29a9134..44c859b22 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -71,6 +71,8 @@ #define ANALOG_GROVE_LIGHT 0x01 #define ANALOG_PHIDGET_ROTATION_1109 0x02 #define ANALOG_GROVE_LOUDNESS 0x03 +#define ANALOG_VAC_SENSOR 0x04 +#define ANALOG_PM10_SENSOR 0x05 /* -------------------------------------------------------------------------- */ #define ADC_SENSORS "ADC sensors API" /* -------------------------------------------------------------------------- */ diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c new file mode 100644 index 000000000..6c3d2c994 --- /dev/null +++ b/platform/zoul/dev/pm10-sensor.c @@ -0,0 +1,73 @@ + /* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * + * @{ + * + * \file + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "adc-sensors.h" +#include "dev/pm10-sensor.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +configure(int value) +{ + int error; + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + error = adc_sensors.configure(ANALOG_PM10_SENSORS, value); + + return error; +} +/*---------------------------------------------------------------------------*/ +static int +value(void) +{ + uint16_t val; + //TODO: Add here GPIO pulses before measuring + val = adc_sensors.value(ANALOG_PM10_SENSOR); + + return val; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pm10, PM10_SENSOR, value, configure, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/zoul/dev/pm10-sensot.h b/platform/zoul/dev/pm10-sensot.h new file mode 100644 index 000000000..22a89856a --- /dev/null +++ b/platform/zoul/dev/pm10-sensot.h @@ -0,0 +1,60 @@ +/* + * 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 Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * + * + * + * \file + * GP2Y1010AU0F PM-10 sensor driver + * \author + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" + +#ifndef PM10_SENSOR_H_ +#define PM10_SENSOR_H_ + +/* -------------------------------------------------------------------------- */ +#define PM10_ERROR -1 +#define PM10_PORT ZOUL_SENSORS_ADC3 +#define PM10_VAL 0x00 +#define PM10_SENSOR "PM10 Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor vac; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef VAC_SENSOR_H_ */ +/** + * @} + * @} + */ From 490784282133f4327ecfbcc5b96d52dbf073ee01 Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Thu, 21 Jan 2016 15:24:47 +0100 Subject: [PATCH 73/94] Added parameters of aac-sensor on adc-sensors file and adapted AAC and VAC test files for correct results --- examples/zolertia/zoul/Makefile | 1 + examples/zolertia/zoul/test-aac-sensor.c | 120 ++++++++++++++++++ examples/zolertia/zoul/test-vac-sensor.c | 8 +- platform/zoul/dev/adc-sensors.c | 20 ++- platform/zoul/dev/adc-sensors.h | 3 +- .../zoul/dev/{pm10-sensot.h => pm10-sensor.h} | 0 6 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 examples/zolertia/zoul/test-aac-sensor.c rename platform/zoul/dev/{pm10-sensot.h => pm10-sensor.h} (100%) diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index b60cf8ccf..fd9ca7b86 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -5,6 +5,7 @@ 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 CONTIKI_PROJECT += test-pm10 test-vac-sensor + CONTIKI_TARGET_SOURCEFILES += tsl2563.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 diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c new file mode 100644 index 000000000..243a835f8 --- /dev/null +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, 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. + */ +/* + * + * + * @{ + * + * \file + * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC + */ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/uart.h" +#include "dev/button-sensor.h" +#include "dev/zoul-sensors.h" +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" +#include "dev/adc-sensors.h" + + +#include +#include +/*---------------------------------------------------------------------------*/ +#define ADC_PIN 2 +#define LOOP_PERIOD 2 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_PERIODIC LEDS_GREEN +#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +static struct etimer et; + +static uint16_t counter; +/*---------------------------------------------------------------------------*/ +PROCESS(zoul_demo_process, "Zoul demo process"); +AUTOSTART_PROCESSES(&zoul_demo_process); +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(zoul_demo_process, ev, data) +{ + + PROCESS_BEGIN(); + + counter = 0; + + /* Configure the user button */ + button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, + BUTTON_PRESS_EVENT_INTERVAL); + + /* Configure the ADC ports */ + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ + printf("return configure, %d \n", adc_sensors.configure(ANALOG_AAC_SENSOR, ADC_PIN)); + + printf("AAC test application\n"); + leds_on(LEDS_PERIODIC); + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_toggle(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + //printf("ADC3 = %d raw\n", (adc_sensors.value(ANALOG_AAC_SENSOR)/1.76)); + + printf("AC Amps = %d mA\n", adc_sensors.value(ANALOG_AAC_SENSOR)); + + etimer_set(&et, LOOP_INTERVAL); + counter++; + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c index 4ecfcf9a6..aa02fd83a 100644 --- a/examples/zolertia/zoul/test-vac-sensor.c +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -100,10 +100,10 @@ PROCESS_THREAD(zoul_demo_process, ev, data) printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); - printf("ADC3 = %d V\n", adc_sensors.value(ANALOG_VAC_SENSOR)); - uint32_t as = (adc_sensors.value(ANALOG_VAC_SENSOR) * 0.176); - printf("ADC5V = %ld V\n", as); - //printf("AC voltage = %d V\n", vac.value(VAC_VAL)); + //Value in raw after voltage divisor + printf("ADC3 = %d V\n", (adc_sensors.value(ANALOG_VAC_SENSOR)/0.0088)); + //AC voltage value, with applied corresponding sensor algorithm + printf("AC voltage = %d V\n", adc_sensors.value(VAC_VAL)); etimer_set(&et, LOOP_INTERVAL); counter++; diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index a77958bdd..ecefbcff5 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -114,6 +114,11 @@ convert_to_value(uint8_t index) value /= 10000; return (uint16_t)value; + case ANALOG_AAC_SENSOR: + /* Linear sensor from 0 to 5 V;*/ + value *= 1.2; + return (uint16_t)value; + case ANALOG_PM10_SENSOR: /* PM10 sensor from 0 to 5 V; 0.0088 resolution*/ value *= 88; @@ -167,7 +172,7 @@ configure(int type, int value) if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && (type != ANALOG_GROVE_LOUDNESS) && (type != ANALOG_PM10_SENSOR) && - (type != ANALOG_VAC_SENSOR) ) { + (type != ANALOG_VAC_SENSOR) && (type != ANALOG_AAC_SENSOR) ) { PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); return ADC_WRAPPER_ERROR; } @@ -192,7 +197,6 @@ configure(int type, int value) case ANALOG_GROVE_LIGHT: case ANALOG_GROVE_LOUDNESS: case ANALOG_PHIDGET_ROTATION_1109: - case ANALOG_VAC_SENSOR: if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { return ADC_WRAPPER_ERROR; } @@ -201,6 +205,18 @@ configure(int type, int value) sensors.sensor[sensors.sensors_num].vdd3 = 1; break; + case ANALOG_VAC_SENSOR: + case ANALOG_AAC_SENSOR: + case ANALOG_PM10_SENSOR: + if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { + return ADC_WRAPPER_ERROR; + } + sensors.sensor[sensors.sensors_num].type = type; + sensors.sensor[sensors.sensors_num].pin_mask = pin_mask; + sensors.sensor[sensors.sensors_num].vdd3 = 0; + break; + + default: return ADC_WRAPPER_ERROR; } diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 44c859b22..8a3eb4047 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -72,7 +72,8 @@ #define ANALOG_PHIDGET_ROTATION_1109 0x02 #define ANALOG_GROVE_LOUDNESS 0x03 #define ANALOG_VAC_SENSOR 0x04 -#define ANALOG_PM10_SENSOR 0x05 +#define ANALOG_AAC_SENSOR 0x05 +#define ANALOG_PM10_SENSOR 0x06 /* -------------------------------------------------------------------------- */ #define ADC_SENSORS "ADC sensors API" /* -------------------------------------------------------------------------- */ diff --git a/platform/zoul/dev/pm10-sensot.h b/platform/zoul/dev/pm10-sensor.h similarity index 100% rename from platform/zoul/dev/pm10-sensot.h rename to platform/zoul/dev/pm10-sensor.h From 42e1beb93167e7aa67777e7454f844f3bb03672f Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Fri, 22 Jan 2016 12:15:33 +0100 Subject: [PATCH 74/94] Added PM10 GP2Y1010AU0F sensor driver and demo test --- examples/zolertia/zoul/test-aac-sensor.c | 33 ++----------- .../zoul/{test-pm10.c => test-pm10-sensor.c} | 23 ++++++---- examples/zolertia/zoul/test-vac-sensor.c | 36 +++------------ platform/zoul/dev/adc-sensors.c | 8 ++-- platform/zoul/dev/pm10-sensor.c | 46 ++++++++++++++++--- platform/zoul/dev/pm10-sensor.h | 11 ++--- 6 files changed, 71 insertions(+), 86 deletions(-) rename examples/zolertia/zoul/{test-pm10.c => test-pm10-sensor.c} (82%) diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c index 243a835f8..661eadf69 100644 --- a/examples/zolertia/zoul/test-aac-sensor.c +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ - * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,28 +29,17 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * - * + * \addtogroup zoul-examples * @{ * * \file * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC */ #include "contiki.h" -#include "cpu.h" #include "sys/etimer.h" #include "sys/rtimer.h" #include "dev/leds.h" -#include "dev/uart.h" -#include "dev/button-sensor.h" -#include "dev/zoul-sensors.h" -#include "dev/watchdog.h" -#include "dev/serial-line.h" -#include "dev/sys-ctrl.h" -#include "net/rime/broadcast.h" #include "dev/adc-sensors.h" - - #include #include /*---------------------------------------------------------------------------*/ @@ -65,24 +53,16 @@ static struct etimer et; static uint16_t counter; /*---------------------------------------------------------------------------*/ -PROCESS(zoul_demo_process, "Zoul demo process"); -AUTOSTART_PROCESSES(&zoul_demo_process); +PROCESS(test_aac_sensor_process, "Test AAC sensor process"); +AUTOSTART_PROCESSES(&test_aac_sensor_process); /*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(zoul_demo_process, ev, data) +PROCESS_THREAD(test_aac_sensor_process, ev, data) { PROCESS_BEGIN(); counter = 0; - /* Configure the user button */ - button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, - BUTTON_PRESS_EVENT_INTERVAL); - /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 5 */ printf("return configure, %d \n", adc_sensors.configure(ANALOG_AAC_SENSOR, ADC_PIN)); @@ -100,8 +80,6 @@ PROCESS_THREAD(zoul_demo_process, ev, data) printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); - - //printf("ADC3 = %d raw\n", (adc_sensors.value(ANALOG_AAC_SENSOR)/1.76)); printf("AC Amps = %d mA\n", adc_sensors.value(ANALOG_AAC_SENSOR)); @@ -114,7 +92,6 @@ PROCESS_THREAD(zoul_demo_process, ev, data) } /*---------------------------------------------------------------------------*/ /** - * @} * @} * @} */ diff --git a/examples/zolertia/zoul/test-pm10.c b/examples/zolertia/zoul/test-pm10-sensor.c similarity index 82% rename from examples/zolertia/zoul/test-pm10.c rename to examples/zolertia/zoul/test-pm10-sensor.c index d8e64067a..d72ae51b4 100644 --- a/examples/zolertia/zoul/test-pm10.c +++ b/examples/zolertia/zoul/test-pm10-sensor.c @@ -36,7 +36,7 @@ * @{ * * \file - * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper * * \author * Toni Lozano @@ -46,23 +46,28 @@ #include "contiki.h" #include "dev/leds.h" #include "dev/adc-sensors.h" +#include "dev/zoul-sensors.h" +#include "lib/sensors.h" +#include "dev/pm10-sensor.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 2 -#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 8) +#define SENSOR_READ_INTERVAL (CLOCK_SECOND) /*---------------------------------------------------------------------------*/ -PROCESS(remote_pm10_sensor_process, "PM10 sensor test process"); -AUTOSTART_PROCESSES(&remote_grove_loudness_process); +PROCESS(test_pm10_sensor_process, "Test PM10 sensor process"); +AUTOSTART_PROCESSES(&test_pm10_sensor_process); /*---------------------------------------------------------------------------*/ static struct etimer et; /*---------------------------------------------------------------------------*/ -PROCESS_THREAD(remote_pm10_sensor_process, ev, data) +PROCESS_THREAD(test_pm10_sensor_process, ev, data) { PROCESS_BEGIN(); + SENSORS_ACTIVATE(pm10); - uint16_t pm10_value; + static uint16_t pm10_value; + /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 2 */ - adc_sensors.configure(ANALOG_PM10_SENSOR, ADC_PIN); + printf("return configure, %d \n", pm10.configure(SENSORS_ACTIVE, ADC_PIN)); /* And periodically poll the sensor */ @@ -72,10 +77,10 @@ PROCESS_THREAD(remote_pm10_sensor_process, ev, data) leds_toggle(LEDS_GREEN); - pm10_value = adc_sensors.value(ANALOG_PM10_SENSOR); + pm10_value = pm10.value(NULL); if(pm10_value != ADC_WRAPPER_ERROR) { - printf("%u\n", pm10_value); + printf("PM10 value = %u ppm\n", pm10_value); } else { printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); PROCESS_EXIT(); diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c index aa02fd83a..0f1f9a4eb 100644 --- a/examples/zolertia/zoul/test-vac-sensor.c +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ - * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2016, Zolertia - http://www.zolertia.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,27 +29,17 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * - * + * \addtogroup zoul-examples * @{ * * \file * Example demonstrating the Zoul module on the RE-Mote & VAC sensor */ #include "contiki.h" -#include "cpu.h" #include "sys/etimer.h" #include "sys/rtimer.h" #include "dev/leds.h" -#include "dev/uart.h" -#include "dev/button-sensor.h" -#include "dev/zoul-sensors.h" -#include "dev/watchdog.h" -#include "dev/serial-line.h" -#include "dev/sys-ctrl.h" -#include "net/rime/broadcast.h" #include "dev/adc-sensors.h" - #include #include /*---------------------------------------------------------------------------*/ @@ -64,24 +53,16 @@ static struct etimer et; static uint16_t counter; /*---------------------------------------------------------------------------*/ -PROCESS(zoul_demo_process, "Zoul demo process"); -AUTOSTART_PROCESSES(&zoul_demo_process); +PROCESS(test_vac_sensor_process, "test VAC sensor process"); +AUTOSTART_PROCESSES(&test_vac_sensor_process); /*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(zoul_demo_process, ev, data) +PROCESS_THREAD(test_vac_sensor_process, ev, data) { PROCESS_BEGIN(); counter = 0; - /* Configure the user button */ - button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, - BUTTON_PRESS_EVENT_INTERVAL); - /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 5 */ printf("return configure, %d \n", adc_sensors.configure(ANALOG_VAC_SENSOR, ADC_PIN)); @@ -100,10 +81,8 @@ PROCESS_THREAD(zoul_demo_process, ev, data) printf("-----------------------------------------\n" "Counter = 0x%08x\n", counter); - //Value in raw after voltage divisor - printf("ADC3 = %d V\n", (adc_sensors.value(ANALOG_VAC_SENSOR)/0.0088)); - //AC voltage value, with applied corresponding sensor algorithm - printf("AC voltage = %d V\n", adc_sensors.value(VAC_VAL)); + /*AC voltage value, with applied corresponding sensor algorithm*/ + printf("AC voltage = %d V\n", adc_sensors.value(ANALOG_VAC_SENSOR)); etimer_set(&et, LOOP_INTERVAL); counter++; @@ -114,7 +93,6 @@ PROCESS_THREAD(zoul_demo_process, ev, data) } /*---------------------------------------------------------------------------*/ /** - * @} * @} * @} */ diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index ecefbcff5..220a8dc88 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -45,7 +45,6 @@ #include "adc-sensors.h" #include "adc-zoul.h" #include "zoul-sensors.h" - #include #include /*---------------------------------------------------------------------------*/ @@ -108,6 +107,7 @@ convert_to_value(uint8_t index) value /= 100000; return (uint16_t)value; + /* VDD+5 sensors */ case ANALOG_VAC_SENSOR: /* Linear sensor from 0 to 5 V; 0.0088 resolution*/ value *= 88; @@ -116,13 +116,10 @@ convert_to_value(uint8_t index) case ANALOG_AAC_SENSOR: /* Linear sensor from 0 to 5 V;*/ - value *= 1.2; return (uint16_t)value; case ANALOG_PM10_SENSOR: - /* PM10 sensor from 0 to 5 V; 0.0088 resolution*/ - value *= 88; - value /= 10000; + /* PM10 sensor from 0 to 3.9 V;*/ return (uint16_t)value; default: @@ -205,6 +202,7 @@ configure(int type, int value) sensors.sensor[sensors.sensors_num].vdd3 = 1; break; + /*V+5 sensors*/ case ANALOG_VAC_SENSOR: case ANALOG_AAC_SENSOR: case ANALOG_PM10_SENSOR: diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c index 6c3d2c994..aa8704c50 100644 --- a/platform/zoul/dev/pm10-sensor.c +++ b/platform/zoul/dev/pm10-sensor.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Zolertia + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * + * \addtogroup zoul-pm10-sensor * @{ * * \file - * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper * \author * Toni Lozano */ @@ -44,26 +44,58 @@ #include "contiki.h" #include "adc-sensors.h" #include "dev/pm10-sensor.h" +#include "dev/sys-ctrl.h" #include "lib/sensors.h" +#include "dev/gpio.h" +#include "dev/ioc.h" /*---------------------------------------------------------------------------*/ static uint8_t enabled; /*---------------------------------------------------------------------------*/ +#ifdef PM10_SENSOR_CONF_CTRL_PIN +#define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN +#else +#define PM10_SENSOR_CTRL_PIN 0x07 +#endif + +#define PM10_SENSOR_PORT GPIO_A_BASE + static int -configure(int value) +configure(int type, int value) { int error; + if(type != SENSORS_ACTIVE) { + return PM10_ERROR; + } + /*Set PA7 as output, used as pulse-driven wave*/ + ioc_set_over(PM10_SENSOR_PORT, PM10_SENSOR_CTRL_PIN, IOC_OVERRIDE_DIS); + GPIO_SOFTWARE_CONTROL(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + GPIO_SET_OUTPUT(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + + GPIO_CLR_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - error = adc_sensors.configure(ANALOG_PM10_SENSORS, value); + error = adc_sensors.configure(ANALOG_PM10_SENSOR, value); return error; } /*---------------------------------------------------------------------------*/ static int -value(void) +value(int type) { uint16_t val; - //TODO: Add here GPIO pulses before measuring + /*Set Pulse Wave pin before measure*/ + GPIO_SET_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + /*Pulse wave delay*/ + clock_delay_usec(280); + /*Data acquisition*/ val = adc_sensors.value(ANALOG_PM10_SENSOR); + /*Clear pulse wave pin*/ + GPIO_CLR_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + + /*Applied constant conversion from UAir project*/ + /*to obtain value in ppm (value in mV * 0.28)*/ + val *= 28; + val /= 1000; return val; } diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h index 22a89856a..c411428b5 100644 --- a/platform/zoul/dev/pm10-sensor.h +++ b/platform/zoul/dev/pm10-sensor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Zolertia + * Copyright (c) 2016, Zolertia * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,11 +31,8 @@ */ /*---------------------------------------------------------------------------*/ /** - * - * - * * \file - * GP2Y1010AU0F PM-10 sensor driver + * GP2Y1010AU0F PM10 sensor driver * \author * Toni Lozano */ @@ -47,11 +44,9 @@ /* -------------------------------------------------------------------------- */ #define PM10_ERROR -1 -#define PM10_PORT ZOUL_SENSORS_ADC3 -#define PM10_VAL 0x00 #define PM10_SENSOR "PM10 Sensor" /* -------------------------------------------------------------------------- */ -extern const struct sensors_sensor vac; +extern const struct sensors_sensor pm10; /* -------------------------------------------------------------------------- */ #endif /* ifndef VAC_SENSOR_H_ */ /** From 31e6cc48ca0bb37aa7d900d08fd7d987bb4890f5 Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Mon, 25 Jan 2016 12:20:36 +0100 Subject: [PATCH 75/94] Solved doxygen comments information from VAC, AAC and PM10 sensor files --- examples/zolertia/zoul/Makefile | 7 ++++--- examples/zolertia/zoul/test-aac-sensor.c | 10 ++++++++-- examples/zolertia/zoul/test-pm10-sensor.c | 12 ++++++------ examples/zolertia/zoul/test-vac-sensor.c | 10 ++++++++-- platform/zoul/dev/pm10-sensor.c | 1 + platform/zoul/dev/pm10-sensor.h | 5 +++++ 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index fd9ca7b86..95e4a4e1f 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,14 +1,15 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor +ONTIKI_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 -CONTIKI_PROJECT += test-pm10 test-vac-sensor +CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor + CONTIKI_TARGET_SOURCEFILES += tsl2563.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 +CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c index 661eadf69..0884f9200 100644 --- a/examples/zolertia/zoul/test-aac-sensor.c +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -31,9 +31,16 @@ /* * \addtogroup zoul-examples * @{ + * \defgroup zoul-aac-sensor-test Test AAC sensor + * + * Demonstrates the operation of the current AAC analog sensor + * @{ * * \file - * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC + * Example demonstrating the Zoul module on the RE-Mote & AAC sensor 0-5V 50Amps AC + * + * \author + * Javier Sánchez */ #include "contiki.h" #include "sys/etimer.h" @@ -87,7 +94,6 @@ PROCESS_THREAD(test_aac_sensor_process, ev, data) counter++; } } - PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/examples/zolertia/zoul/test-pm10-sensor.c b/examples/zolertia/zoul/test-pm10-sensor.c index d72ae51b4..7aedbf60c 100644 --- a/examples/zolertia/zoul/test-pm10-sensor.c +++ b/examples/zolertia/zoul/test-pm10-sensor.c @@ -31,23 +31,26 @@ /** * \addtogroup zoul-examples * @{ + * \defgroup zoul-pm10-sensor-test Test PM10 sensor * * Demonstrates the operation of the Sharp PM10 analog sensor * @{ * * \file - * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper + * GP2Y1010AU0F PM10 sensor example using the ADC sensors wrapper * * \author * Toni Lozano */ /*---------------------------------------------------------------------------*/ #include +#include "cpu.h" #include "contiki.h" #include "dev/leds.h" #include "dev/adc-sensors.h" #include "dev/zoul-sensors.h" #include "lib/sensors.h" +#include "dev/sys-ctrl.h" #include "dev/pm10-sensor.h" /*---------------------------------------------------------------------------*/ #define ADC_PIN 2 @@ -76,16 +79,14 @@ PROCESS_THREAD(test_pm10_sensor_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); leds_toggle(LEDS_GREEN); - - pm10_value = pm10.value(NULL); - + printf("PM10 value\n"); + pm10_value = pm10.value(1); if(pm10_value != ADC_WRAPPER_ERROR) { printf("PM10 value = %u ppm\n", pm10_value); } else { printf("Error, enable the DEBUG flag in adc-wrapper.c for info\n"); PROCESS_EXIT(); } - } PROCESS_END(); } @@ -94,4 +95,3 @@ PROCESS_THREAD(test_pm10_sensor_process, ev, data) * @} * @} */ - diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c index 0f1f9a4eb..289a0e839 100644 --- a/examples/zolertia/zoul/test-vac-sensor.c +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -31,9 +31,16 @@ /* * \addtogroup zoul-examples * @{ + * \defgroup zoul-vac-sensor-test Test VAC sensor + * + * Demonstrates the operation of the voltage VAC analog sensor + * @{ * * \file - * Example demonstrating the Zoul module on the RE-Mote & VAC sensor + * Example demonstrating the Zoul module on the RE-Mote & VAC sensor 0-5V 250V AC + * + * \author + * Javier Sánchez */ #include "contiki.h" #include "sys/etimer.h" @@ -88,7 +95,6 @@ PROCESS_THREAD(test_vac_sensor_process, ev, data) counter++; } } - PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c index aa8704c50..015852c93 100644 --- a/platform/zoul/dev/pm10-sensor.c +++ b/platform/zoul/dev/pm10-sensor.c @@ -66,6 +66,7 @@ configure(int type, int value) if(type != SENSORS_ACTIVE) { return PM10_ERROR; } + /*Set PA7 as output, used as pulse-driven wave*/ ioc_set_over(PM10_SENSOR_PORT, PM10_SENSOR_CTRL_PIN, IOC_OVERRIDE_DIS); GPIO_SOFTWARE_CONTROL(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h index c411428b5..e090f8202 100644 --- a/platform/zoul/dev/pm10-sensor.h +++ b/platform/zoul/dev/pm10-sensor.h @@ -31,6 +31,11 @@ */ /*---------------------------------------------------------------------------*/ /** + * \addtogroup zoul-sensors + * @{ + * + * \defgroup zoul-pm10-sensor Analog PM10 sensor + * @{ * \file * GP2Y1010AU0F PM10 sensor driver * \author From 6557194fc5b5708ecc5654fe3a121b8fc4ac012b Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Tue, 15 Dec 2015 14:10:42 -0800 Subject: [PATCH 76/94] galileo: Revise include flags for LLVM Clang This patch revises the compiler flags when LLVM Clang is in use to cause Clang to automatically use its built-in header files rather than those for GCC. --- platform/galileo/Makefile.galileo | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/galileo/Makefile.galileo b/platform/galileo/Makefile.galileo index 189471fc2..8be977bc8 100644 --- a/platform/galileo/Makefile.galileo +++ b/platform/galileo/Makefile.galileo @@ -16,7 +16,12 @@ PROJECT_SOURCEFILES += newlib-syscalls.c CONTIKI_CPU=$(CONTIKI)/cpu/x86 include $(CONTIKI)/cpu/x86/Makefile.x86_quarkX1000 -CFLAGS += -fno-stack-protector -nostdinc -I$(LIBC)/include -isystem $(LIBGCC_PATH)/include -isystem $(LIBGCC_PATH)/include-fixed +CFLAGS += -fno-stack-protector -I$(LIBC)/include +ifeq (clang,$(findstring clang,$(CC))) + CFLAGS += -nostdlibinc +else + CFLAGS += -nostdinc -isystem $(LIBGCC_PATH)/include -isystem $(LIBGCC_PATH)/include-fixed +endif LDFLAGS += -nostdlib -L$(LIBC)/lib -L$(LIBGCC_PATH)/32 TARGET_LIBFILES += -lm -lc -lgcc From 8337843d691ec9e7fefc60d457024c31059d21b9 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Mon, 25 Jan 2016 22:58:06 +0100 Subject: [PATCH 77/94] Minor fixes --- examples/zolertia/zoul/test-pm10-sensor.c | 6 +-- platform/zoul/dev/pm10-sensor.c | 56 ++++++++++++----------- platform/zoul/dev/pm10-sensor.h | 22 +++++++-- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/examples/zolertia/zoul/test-pm10-sensor.c b/examples/zolertia/zoul/test-pm10-sensor.c index 7aedbf60c..d307f9050 100644 --- a/examples/zolertia/zoul/test-pm10-sensor.c +++ b/examples/zolertia/zoul/test-pm10-sensor.c @@ -64,13 +64,11 @@ static struct etimer et; PROCESS_THREAD(test_pm10_sensor_process, ev, data) { PROCESS_BEGIN(); - SENSORS_ACTIVATE(pm10); static uint16_t pm10_value; - /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 2 */ - printf("return configure, %d \n", pm10.configure(SENSORS_ACTIVE, ADC_PIN)); + pm10.configure(SENSORS_ACTIVE, ADC_PIN); /* And periodically poll the sensor */ @@ -79,8 +77,8 @@ PROCESS_THREAD(test_pm10_sensor_process, ev, data) PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); leds_toggle(LEDS_GREEN); - printf("PM10 value\n"); pm10_value = pm10.value(1); + if(pm10_value != ADC_WRAPPER_ERROR) { printf("PM10 value = %u ppm\n", pm10_value); } else { diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c index 015852c93..8f94eb04f 100644 --- a/platform/zoul/dev/pm10-sensor.c +++ b/platform/zoul/dev/pm10-sensor.c @@ -49,52 +49,54 @@ #include "dev/gpio.h" #include "dev/ioc.h" /*---------------------------------------------------------------------------*/ +#define PM10_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(PM10_SENSOR_CTRL_PORT) +#define PM10_SENSOR_PIN_MASK GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN) +/*---------------------------------------------------------------------------*/ static uint8_t enabled; /*---------------------------------------------------------------------------*/ -#ifdef PM10_SENSOR_CONF_CTRL_PIN -#define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN -#else -#define PM10_SENSOR_CTRL_PIN 0x07 -#endif - -#define PM10_SENSOR_PORT GPIO_A_BASE - static int configure(int type, int value) { - int error; if(type != SENSORS_ACTIVE) { return PM10_ERROR; } - /*Set PA7 as output, used as pulse-driven wave*/ - ioc_set_over(PM10_SENSOR_PORT, PM10_SENSOR_CTRL_PIN, IOC_OVERRIDE_DIS); - GPIO_SOFTWARE_CONTROL(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); - GPIO_SET_OUTPUT(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + if(value) { + /* Set as output, used as pulse-driven wave */ + GPIO_SOFTWARE_CONTROL(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + ioc_set_over(PM10_SENSOR_CTRL_PORT, PM10_SENSOR_CTRL_PIN, IOC_OVERRIDE_DIS); + GPIO_SET_OUTPUT(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); - GPIO_CLR_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + enabled = 1; + return adc_sensors.configure(ANALOG_PM10_SENSOR, value); + } - /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - error = adc_sensors.configure(ANALOG_PM10_SENSOR, value); - - return error; + enabled = 0; + return PM10_SUCCESS; } /*---------------------------------------------------------------------------*/ static int value(int type) { uint16_t val; - /*Set Pulse Wave pin before measure*/ - GPIO_SET_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); - /*Pulse wave delay*/ - clock_delay_usec(280); - /*Data acquisition*/ + + if(!enabled) { + return PM10_ERROR; + } + + /* Set Pulse Wave pin before measure */ + GPIO_SET_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + /* Pulse wave delay */ + clock_delay_usec(PM10_SENSOR_PULSE_DELAY); + /* Data acquisition */ val = adc_sensors.value(ANALOG_PM10_SENSOR); - /*Clear pulse wave pin*/ - GPIO_CLR_PIN(PM10_SENSOR_PORT, GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN)); + /* Clear pulse wave pin */ + GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); - /*Applied constant conversion from UAir project*/ - /*to obtain value in ppm (value in mV * 0.28)*/ + /* Applied constant conversion from UAir project + * to obtain value in ppm (value in mV * 0.28) + */ val *= 28; val /= 1000; diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h index e090f8202..61057e0d1 100644 --- a/platform/zoul/dev/pm10-sensor.h +++ b/platform/zoul/dev/pm10-sensor.h @@ -43,17 +43,29 @@ */ /*---------------------------------------------------------------------------*/ #include "lib/sensors.h" - +/*---------------------------------------------------------------------------*/ #ifndef PM10_SENSOR_H_ #define PM10_SENSOR_H_ - /* -------------------------------------------------------------------------- */ -#define PM10_ERROR -1 -#define PM10_SENSOR "PM10 Sensor" +#define PM10_ERROR (-1) +#define PM10_SUCCESS 0 +#define PM10_SENSOR "PM10 Sensor" +#define PM10_SENSOR_PULSE_DELAY 280 +/* -------------------------------------------------------------------------- */ +#ifdef PM10_SENSOR_CONF_CTRL_PIN +#define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN +#else +#define PM10_SENSOR_CTRL_PIN 7 +#endif +#ifdef PM10_SENSOR_CONF_CTRL_PORT +#define PM10_SENSOR_CTRL_PORT PM10_SENSOR_CONF_CTRL_PORT +#else +#define PM10_SENSOR_CTRL_PORT GPIO_A_NUM +#endif /* -------------------------------------------------------------------------- */ extern const struct sensors_sensor pm10; /* -------------------------------------------------------------------------- */ -#endif /* ifndef VAC_SENSOR_H_ */ +#endif /* ifndef PM10_SENSOR_H_ */ /** * @} * @} From 1f6dafecb097b73c367036df30901259abfaa85f Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Tue, 26 Jan 2016 14:08:17 +0100 Subject: [PATCH 78/94] Modified ADC measurement of PM10 driver to include adc-zoul direct access --- examples/zolertia/zoul/Makefile | 3 +- examples/zolertia/zoul/test-aac-sensor.c | 3 +- examples/zolertia/zoul/test-vac-sensor.c | 2 +- platform/zoul/dev/pm10-sensor.c | 39 ++++++++++++++++-------- platform/zoul/dev/pm10-sensor.h | 2 ++ 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 95e4a4e1f..a0a8dee0d 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,12 +1,11 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt -ONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor +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 CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor - CONTIKI_TARGET_SOURCEFILES += tsl2563.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 diff --git a/examples/zolertia/zoul/test-aac-sensor.c b/examples/zolertia/zoul/test-aac-sensor.c index 0884f9200..bbda23955 100644 --- a/examples/zolertia/zoul/test-aac-sensor.c +++ b/examples/zolertia/zoul/test-aac-sensor.c @@ -54,7 +54,6 @@ #define LOOP_PERIOD 2 #define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) #define LEDS_PERIODIC LEDS_GREEN -#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) /*---------------------------------------------------------------------------*/ static struct etimer et; @@ -72,7 +71,7 @@ PROCESS_THREAD(test_aac_sensor_process, ev, data) /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - printf("return configure, %d \n", adc_sensors.configure(ANALOG_AAC_SENSOR, ADC_PIN)); + adc_sensors.configure(ANALOG_AAC_SENSOR, ADC_PIN); printf("AAC test application\n"); leds_on(LEDS_PERIODIC); diff --git a/examples/zolertia/zoul/test-vac-sensor.c b/examples/zolertia/zoul/test-vac-sensor.c index 289a0e839..37db59edf 100644 --- a/examples/zolertia/zoul/test-vac-sensor.c +++ b/examples/zolertia/zoul/test-vac-sensor.c @@ -72,7 +72,7 @@ PROCESS_THREAD(test_vac_sensor_process, ev, data) /* Configure the ADC ports */ /* Use pin number not mask, for example if using the PA5 pin then use 5 */ - printf("return configure, %d \n", adc_sensors.configure(ANALOG_VAC_SENSOR, ADC_PIN)); + adc_sensors.configure(ANALOG_VAC_SENSOR, ADC_PIN); printf("VAC test application\n"); leds_on(LEDS_PERIODIC); diff --git a/platform/zoul/dev/pm10-sensor.c b/platform/zoul/dev/pm10-sensor.c index 8f94eb04f..3ec10de62 100644 --- a/platform/zoul/dev/pm10-sensor.c +++ b/platform/zoul/dev/pm10-sensor.c @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2016, Zolertia * All rights reserved. * @@ -43,6 +43,8 @@ #include #include "contiki.h" #include "adc-sensors.h" +#include "adc-zoul.h" +#include "zoul-sensors.h" #include "dev/pm10-sensor.h" #include "dev/sys-ctrl.h" #include "lib/sensors.h" @@ -52,7 +54,7 @@ #define PM10_SENSOR_PORT_BASE GPIO_PORT_TO_BASE(PM10_SENSOR_CTRL_PORT) #define PM10_SENSOR_PIN_MASK GPIO_PIN_MASK(PM10_SENSOR_CTRL_PIN) /*---------------------------------------------------------------------------*/ -static uint8_t enabled; +static int pm10_channel; /*---------------------------------------------------------------------------*/ static int configure(int type, int value) @@ -68,20 +70,20 @@ configure(int type, int value) GPIO_SET_OUTPUT(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); - enabled = 1; - return adc_sensors.configure(ANALOG_PM10_SENSOR, value); + pm10_channel = (1 << value); + return adc_zoul.configure(SENSORS_HW_INIT, pm10_channel); } - enabled = 0; + pm10_channel = 0; return PM10_SUCCESS; } /*---------------------------------------------------------------------------*/ static int value(int type) { - uint16_t val; + uint32_t val; - if(!enabled) { + if(!pm10_channel) { return PM10_ERROR; } @@ -90,17 +92,30 @@ value(int type) /* Pulse wave delay */ clock_delay_usec(PM10_SENSOR_PULSE_DELAY); /* Data acquisition */ - val = adc_sensors.value(ANALOG_PM10_SENSOR); - /* Clear pulse wave pin */ - GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); - + val = (uint32_t)adc_zoul.value(pm10_channel); + + if(val == ZOUL_SENSORS_ERROR) { + printf("PM10 sensor: failed retrieving data\n"); + return PM10_ERROR; + } + + /* Default voltage divisor relation is 5/3 aprox, change at adc_wrapper.h, + * calculations below assume a decimation rate of 512 (12 bits ENOB) and + * AVVD5 voltage reference of 3.3V + */ + val *= PM10_EXTERNAL_VREF; + val /= PM10_EXTERNAL_VREF_CROSSVAL; + /* Applied constant conversion from UAir project * to obtain value in ppm (value in mV * 0.28) */ val *= 28; val /= 1000; - return val; + /* Clear pulse wave pin */ + GPIO_CLR_PIN(PM10_SENSOR_PORT_BASE, PM10_SENSOR_PIN_MASK); + + return (uint16_t)val; } /*---------------------------------------------------------------------------*/ SENSORS_SENSOR(pm10, PM10_SENSOR, value, configure, NULL); diff --git a/platform/zoul/dev/pm10-sensor.h b/platform/zoul/dev/pm10-sensor.h index 61057e0d1..d43256e44 100644 --- a/platform/zoul/dev/pm10-sensor.h +++ b/platform/zoul/dev/pm10-sensor.h @@ -51,6 +51,8 @@ #define PM10_SUCCESS 0 #define PM10_SENSOR "PM10 Sensor" #define PM10_SENSOR_PULSE_DELAY 280 +#define PM10_EXTERNAL_VREF 5000 +#define PM10_EXTERNAL_VREF_CROSSVAL 3300 /* -------------------------------------------------------------------------- */ #ifdef PM10_SENSOR_CONF_CTRL_PIN #define PM10_SENSOR_CTRL_PIN PM10_SENSOR_CONF_CTRL_PIN From 35345cdb40c89b222eca7796e46c920d1455cbbd Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sat, 30 Jan 2016 00:15:21 +0100 Subject: [PATCH 79/94] Fixed casts and calculations for the wind direction circular averaging --- platform/zoul/dev/weather-meter.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 9c46a520a..1f01d2c31 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -102,9 +102,9 @@ typedef struct { } weather_meter_sensors; typedef struct { - uint32_t value_buf_xm; - uint16_t value_prev; - uint16_t value_avg_xm; + int32_t value_buf_xm; + int16_t value_prev; + int16_t value_avg_xm; } weather_meter_wind_vane_ext_t; static weather_meter_sensors weather_sensors; @@ -232,13 +232,18 @@ rt_callback(struct rtimer *t, void *ptr) anemometer.value_avg_xm = 0; } - wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; - wind_vane.value_avg_xm = (uint16_t)wind_vane.value_buf_xm; - if(wind_vane.value_avg_xm >= 3600) { - wind_vane.value_avg_xm -= 3600; + if(wind_vane.value_buf_xm >= 0) { + wind_vane.value_buf_xm = wind_vane.value_buf_xm / WEATHER_METER_AVG_PERIOD; + wind_vane.value_avg_xm = wind_vane.value_buf_xm; + } else { + wind_vane.value_buf_xm = ABS(wind_vane.value_buf_xm) / WEATHER_METER_AVG_PERIOD; + wind_vane.value_avg_xm = wind_vane.value_buf_xm; + wind_vane.value_avg_xm = ~wind_vane.value_avg_xm + 1; } - if(wind_vane.value_avg_xm < 0) { + if(wind_vane.value_avg_xm >= 3600) { + wind_vane.value_avg_xm -= 3600; + } else if(wind_vane.value_avg_xm < 0) { wind_vane.value_avg_xm += 3600; } From 7c3108bf3bb1154952eb42cc8af449c4f183e6b2 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 1 Feb 2016 13:36:18 +0100 Subject: [PATCH 80/94] jn516x: flush only uart Tx FIFO in main loop, leaving Rx FIFO intact --- platform/jn516x/contiki-jn516x-main.c | 2 +- platform/jn516x/dev/uart-driver.c | 6 ++++-- platform/jn516x/dev/uart-driver.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/jn516x/contiki-jn516x-main.c b/platform/jn516x/contiki-jn516x-main.c index 3192b0ee5..14c1e0460 100644 --- a/platform/jn516x/contiki-jn516x-main.c +++ b/platform/jn516x/contiki-jn516x-main.c @@ -463,7 +463,7 @@ main_loop(void) #endif /* DCOSYNCH_CONF_ENABLED */ /* flush standard output before sleeping */ - uart_driver_flush(E_AHI_UART_0); + uart_driver_flush(E_AHI_UART_0, TRUE, FALSE); /* calculate the time to the next etimer and rtimer */ time_to_etimer = clock_arch_time_to_etimer(); diff --git a/platform/jn516x/dev/uart-driver.c b/platform/jn516x/dev/uart-driver.c index 922c067ab..8719004a7 100644 --- a/platform/jn516x/dev/uart-driver.c +++ b/platform/jn516x/dev/uart-driver.c @@ -589,19 +589,21 @@ uart_driver_tx_in_progress(uint8_t uart_dev) * * PARAMETERS: Name RW Usage * uart_dev R UART to disable, eg, E_AHI_UART_0 + * reset_tx R to reset the transmit FIFO + * reset_rx R to reset the receive FIFO * * RETURNS: * void * ****************************************************************************/ void -uart_driver_flush(uint8_t uart_dev) +uart_driver_flush(uint8_t uart_dev, bool_t reset_tx, bool_t reset_rx) { /* Disable TX Fifo empty and Rx data interrupts */ uart_driver_disable_interrupts(uart_dev); /* flush hardware buffer */ - vAHI_UartReset(uart_dev, TRUE, TRUE); + vAHI_UartReset(uart_dev, reset_tx, reset_rx); vAHI_UartReset(uart_dev, FALSE, FALSE); /* Re-enable TX Fifo empty and Rx data interrupts */ diff --git a/platform/jn516x/dev/uart-driver.h b/platform/jn516x/dev/uart-driver.h index 1953926a3..6ac0c2614 100644 --- a/platform/jn516x/dev/uart-driver.h +++ b/platform/jn516x/dev/uart-driver.h @@ -58,7 +58,7 @@ void uart_driver_restore_interrupts(uint8_t uart_dev); uint8_t uart_driver_tx_in_progress(uint8_t uart_dev); #ifdef UART_EXTRAS -void uart_driver_flush(uint8_t uart_dev); +void uart_driver_flush(uint8_t uart_dev, bool_t reset_tx, bool_t reset_rx); #endif #endif /* UARTDRIVER_H */ From 15a5f27080a1c4c8f8212a636e2959373911afe5 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 1 Feb 2016 10:57:49 +0100 Subject: [PATCH 81/94] Adding TSCH to examples/jn516x/rpl --- examples/jn516x/rpl/common-conf.h | 71 ++++++++++++++++++++++++++++++- examples/jn516x/rpl/node/node.c | 2 +- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/examples/jn516x/rpl/common-conf.h b/examples/jn516x/rpl/common-conf.h index 5c936ff7f..299fd0e79 100644 --- a/examples/jn516x/rpl/common-conf.h +++ b/examples/jn516x/rpl/common-conf.h @@ -36,8 +36,9 @@ #define MAC_CONFIG_NULLRDC 0 #define MAC_CONFIG_CONTIKIMAC 1 +#define MAC_CONFIG_TSCH 2 /* Select a MAC configuration */ -#define MAC_CONFIG MAC_CONFIG_NULLRDC +#define MAC_CONFIG MAC_CONFIG_TSCH #undef NETSTACK_CONF_MAC #undef NETSTACK_CONF_RDC @@ -57,6 +58,74 @@ #undef MICROMAC_CONF_AUTOACK #define MICROMAC_CONF_AUTOACK 1 +#elif MAC_CONFIG == MAC_CONFIG_TSCH + +/* Set to run orchestra */ +#ifndef WITH_ORCHESTRA +#define WITH_ORCHESTRA 0 +#endif /* WITH_ORCHESTRA */ + +/* Set to enable TSCH security */ +#ifndef WITH_SECURITY +#define WITH_SECURITY 0 +#endif /* WITH_SECURITY */ + +#define NETSTACK_CONF_MAC tschmac_driver +#define NETSTACK_CONF_RDC nordc_driver +#define NETSTACK_CONF_FRAMER framer_802154 + +/* IEEE802.15.4 frame version */ +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +/* TSCH and RPL callbacks */ +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval +#define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network +#define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network + +/* TSCH logging. 0: disabled. 1: basic log. 2: with delayed + * log messages from interrupt */ +#undef TSCH_LOG_CONF_LEVEL +#define TSCH_LOG_CONF_LEVEL 2 + +/* Do not start TSCH at init, wait for NETSTACK_MAC.on() */ +#undef TSCH_CONF_AUTOSTART +#define TSCH_CONF_AUTOSTART 0 + +/* 6TiSCH minimal schedule length. + * Larger values result in less frequent active slots: reduces capacity and saves energy. */ +#undef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH +#define TSCH_SCHEDULE_CONF_DEFAULT_LENGTH 3 + +#if WITH_SECURITY + +/* Enable security */ +#undef LLSEC802154_CONF_SECURITY_LEVEL +#define LLSEC802154_CONF_SECURITY_LEVEL 1 +/* TSCH uses explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN rather than frame counter to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 + +#endif /* WITH_SECURITY */ + +#if WITH_ORCHESTRA + +/* See apps/orchestra/README.md for more Orchestra configuration options */ +#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 /* No 6TiSCH minimal schedule */ +#define TSCH_CONF_WITH_LINK_SELECTOR 1 /* Orchestra requires per-packet link selection */ +/* Orchestra callbacks */ +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed + +#endif /* WITH_ORCHESTRA */ + + #else #error Unsupported MAC configuration diff --git a/examples/jn516x/rpl/node/node.c b/examples/jn516x/rpl/node/node.c index 143abc18f..59b812357 100644 --- a/examples/jn516x/rpl/node/node.c +++ b/examples/jn516x/rpl/node/node.c @@ -71,7 +71,7 @@ PROCESS_THREAD(node_process, ev, data) #if CONFIG_VIA_BUTTON { -#define CONFIG_WAIT_TIME 10 +#define CONFIG_WAIT_TIME 5 SENSORS_ACTIVATE(button_sensor); etimer_set(&et, CLOCK_SECOND * CONFIG_WAIT_TIME); From f0d1b6c5bb963774371be914eea153cf7321c88a Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 2 Feb 2016 17:18:45 +0100 Subject: [PATCH 82/94] Fix PRINTF statement in sicslowpan --- core/net/ipv6/sicslowpan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 869379489..d0bf14799 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -1580,8 +1580,8 @@ input(void) /* If this is the last fragment, we may shave off any extrenous bytes at the end. We must be liberal in what we accept. */ - PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", - processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); + PRINTFI("last_fragment?: packetbuf_payload_len %d frag_size %d\n", + packetbuf_datalen() - packetbuf_hdr_len, frag_size); /* Add the fragment to the fragmentation context (this will also copy the payload) */ @@ -1661,7 +1661,7 @@ input(void) PRINTF( "SICSLOWPAN: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n", UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3), - packetbuf_payload_len, req_size, sizeof(uip_buf)); + packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf)); return; } } From 658cf0d2cc873eea410d1a5f297997af37a72d37 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 3 Feb 2016 10:35:48 +0100 Subject: [PATCH 83/94] Reworking jn516x default configuration and examples --- examples/jn516x/rime/project-conf.h | 8 +------- examples/jn516x/rpl/border-router/Makefile | 1 + examples/jn516x/rpl/coap-dongle-node/Makefile | 1 + examples/jn516x/rpl/coap-dr1175-node/Makefile | 1 + examples/jn516x/rpl/coap-dr1199-node/Makefile | 1 + examples/jn516x/rpl/common-conf.h | 4 ++-- examples/jn516x/rpl/node/Makefile | 1 + examples/jn516x/tsch/common-conf.h | 4 ++-- platform/jn516x/Makefile.jn516x | 2 +- platform/jn516x/contiki-conf.h | 8 ++------ platform/jn516x/platform-conf.h | 4 ---- 11 files changed, 13 insertions(+), 22 deletions(-) diff --git a/examples/jn516x/rime/project-conf.h b/examples/jn516x/rime/project-conf.h index 84e1cae06..3a7b0c44c 100644 --- a/examples/jn516x/rime/project-conf.h +++ b/examples/jn516x/rime/project-conf.h @@ -53,14 +53,8 @@ #undef UIP_CONF_IPV6 #define UIP_CONF_IPV6 0 -#undef RF_CHANNEL -#define RF_CHANNEL 25 - #undef MICROMAC_CONF_CHANNEL -#define MICROMAC_CONF_CHANNEL RF_CHANNEL - -#undef CC2420_CONF_CHANNEL -#define CC2420_CONF_CHANNEL RF_CHANNEL +#define MICROMAC_CONF_CHANNEL 25 #undef MICROMAC_CONF_AUTOACK #define MICROMAC_CONF_AUTOACK 1 diff --git a/examples/jn516x/rpl/border-router/Makefile b/examples/jn516x/rpl/border-router/Makefile index 53598e492..de68ecde8 100644 --- a/examples/jn516x/rpl/border-router/Makefile +++ b/examples/jn516x/rpl/border-router/Makefile @@ -7,6 +7,7 @@ CONTIKI=../../../.. CONTIKI_WITH_IPV6 = 1 +MODULES += core/net/mac/tsch PROJECTDIRS += .. ../tools PROJECT_SOURCEFILES += rpl-tools.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/jn516x/rpl/coap-dongle-node/Makefile b/examples/jn516x/rpl/coap-dongle-node/Makefile index 1a4afa652..747331845 100644 --- a/examples/jn516x/rpl/coap-dongle-node/Makefile +++ b/examples/jn516x/rpl/coap-dongle-node/Makefile @@ -8,6 +8,7 @@ CONTIKI=../../../.. CONTIKI_WITH_IPV6 = 1 +MODULES += core/net/mac/tsch PROJECTDIRS += .. ../tools PROJECT_SOURCEFILES += rpl-tools.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/jn516x/rpl/coap-dr1175-node/Makefile b/examples/jn516x/rpl/coap-dr1175-node/Makefile index f7960dcd1..d00fc9b9c 100644 --- a/examples/jn516x/rpl/coap-dr1175-node/Makefile +++ b/examples/jn516x/rpl/coap-dr1175-node/Makefile @@ -8,6 +8,7 @@ CONTIKI=../../../.. CONTIKI_WITH_IPV6 = 1 +MODULES += core/net/mac/tsch PROJECTDIRS += .. ../tools PROJECT_SOURCEFILES += rpl-tools.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/jn516x/rpl/coap-dr1199-node/Makefile b/examples/jn516x/rpl/coap-dr1199-node/Makefile index 5a649e429..9dc391e52 100644 --- a/examples/jn516x/rpl/coap-dr1199-node/Makefile +++ b/examples/jn516x/rpl/coap-dr1199-node/Makefile @@ -8,6 +8,7 @@ CONTIKI=../../../.. CONTIKI_WITH_IPV6 = 1 +MODULES += core/net/mac/tsch PROJECTDIRS += .. ../tools PROJECT_SOURCEFILES += rpl-tools.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/jn516x/rpl/common-conf.h b/examples/jn516x/rpl/common-conf.h index 299fd0e79..bef5407d5 100644 --- a/examples/jn516x/rpl/common-conf.h +++ b/examples/jn516x/rpl/common-conf.h @@ -137,8 +137,8 @@ #undef IEEE802154_CONF_PANID #define IEEE802154_CONF_PANID 0xabcd -#undef RF_CHANNEL -#define RF_CHANNEL 26 +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 /* UART Configuration */ diff --git a/examples/jn516x/rpl/node/Makefile b/examples/jn516x/rpl/node/Makefile index 8096152ee..44cd68d8d 100644 --- a/examples/jn516x/rpl/node/Makefile +++ b/examples/jn516x/rpl/node/Makefile @@ -7,6 +7,7 @@ CONTIKI=../../../.. CONTIKI_WITH_IPV6 = 1 +MODULES += core/net/mac/tsch PROJECTDIRS += .. ../tools PROJECT_SOURCEFILES += rpl-tools.c CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" diff --git a/examples/jn516x/tsch/common-conf.h b/examples/jn516x/tsch/common-conf.h index 3fbd8ad4b..b42e6c810 100644 --- a/examples/jn516x/tsch/common-conf.h +++ b/examples/jn516x/tsch/common-conf.h @@ -176,8 +176,8 @@ #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC nullrdc_driver -#undef RF_CHANNEL -#define RF_CHANNEL 26 +#undef MICROMAC_CONF_CHANNEL +#define MICROMAC_CONF_CHANNEL 26 #undef MICROMAC_CONF_AUTOACK #define MICROMAC_CONF_AUTOACK 1 diff --git a/platform/jn516x/Makefile.jn516x b/platform/jn516x/Makefile.jn516x index 412a1cbd4..27587ccaf 100644 --- a/platform/jn516x/Makefile.jn516x +++ b/platform/jn516x/Makefile.jn516x @@ -145,7 +145,7 @@ CLEAN += *.jn516x.bin MODULES += core/net \ core/net/mac \ - core/net/mac/contikimac core/net/mac/tsch \ + core/net/mac/contikimac \ core/net/llsec core/net/llsec/noncoresec CONTIKI_TARGET_SOURCEFILES += $(ARCH) diff --git a/platform/jn516x/contiki-conf.h b/platform/jn516x/contiki-conf.h index a1e74b251..8b702a56e 100644 --- a/platform/jn516x/contiki-conf.h +++ b/platform/jn516x/contiki-conf.h @@ -44,11 +44,11 @@ #endif /* CCM_STAR_CONF */ #ifndef NETSTACK_CONF_MAC -#define NETSTACK_CONF_MAC tschmac_driver +#define NETSTACK_CONF_MAC csma_driver #endif /* NETSTACK_CONF_MAC */ #ifndef NETSTACK_CONF_RDC -#define NETSTACK_CONF_RDC nordc_driver +#define NETSTACK_CONF_RDC nullrdc_driver #endif /* NETSTACK_CONF_RDC */ #ifndef NETSTACK_CONF_RADIO @@ -59,10 +59,6 @@ #define NETSTACK_CONF_FRAMER framer_802154 #endif /* NETSTACK_CONF_FRAMER */ -/* IEEE802.15.4 frame version */ -#undef FRAME802154_CONF_VERSION -#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 - #define PACKETBUF_CONF_ATTRS_INLINE 1 #ifndef IEEE802154_CONF_PANID diff --git a/platform/jn516x/platform-conf.h b/platform/jn516x/platform-conf.h index da85202d8..c1c372b64 100644 --- a/platform/jn516x/platform-conf.h +++ b/platform/jn516x/platform-conf.h @@ -57,10 +57,6 @@ #define MICROMAC_CONF_CHANNEL 26 #endif -#ifdef RF_CHANNEL -#define MICROMAC_CONF_CHANNEL RF_CHANNEL -#endif - /* 32kHz or 16MHz rtimers? */ #ifdef RTIMER_CONF_USE_32KHZ #define RTIMER_USE_32KHZ RTIMER_CONF_USE_32KHZ From 521cc7600d1a06b2bd2104a20a1c6eca08b20212 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 3 Feb 2016 17:10:24 +0100 Subject: [PATCH 84/94] Minor debug output fixes --- core/net/ipv6/uip6.c | 2 +- core/net/rpl/rpl-dag.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index e86a33911..5cbf39203 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -1428,7 +1428,7 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.chkerr); UIP_LOG("icmpv6: bad checksum."); - PRINTF("icmpv6: bad checksum."); + PRINTF("icmpv6: bad checksum.\n"); goto drop; } #endif /*UIP_CONF_IPV6_CHECKS*/ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 20507449d..46f2936ef 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1274,10 +1274,10 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) if(dag != NULL && instance != NULL) { if(lollipop_greater_than(dio->version, dag->version)) { if(dag->rank == ROOT_RANK(instance)) { - PRINTF("RPL: Root received inconsistent DIO version number\n"); - dag->version = dio->version; - RPL_LOLLIPOP_INCREMENT(dag->version); - rpl_reset_dio_timer(instance); + PRINTF("RPL: Root received inconsistent DIO version number (current: %u, received: %u)\n", dag->version, dio->version); + dag->version = dio->version; + RPL_LOLLIPOP_INCREMENT(dag->version); + rpl_reset_dio_timer(instance); } else { PRINTF("RPL: Global repair\n"); if(dio->prefix_info.length != 0) { @@ -1286,7 +1286,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) rpl_set_prefix(dag, &dio->prefix_info.prefix, dio->prefix_info.length); } } - global_repair(from, dag, dio); + global_repair(from, dag, dio); } return; } @@ -1302,7 +1302,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } if(instance == NULL) { - PRINTF("RPL: New instance detected: Joining...\n"); + PRINTF("RPL: New instance detected (ID=%u): Joining...\n", dio->instance_id); rpl_join_instance(from, dio); return; } From f87f7e7eddd094e50570799c4d3f02ee42b8fe42 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 3 Feb 2016 17:53:29 +0100 Subject: [PATCH 85/94] jn516x enable serial input whenever there is no fallback interface --- platform/jn516x/contiki-jn516x-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/jn516x/contiki-jn516x-main.c b/platform/jn516x/contiki-jn516x-main.c index 14c1e0460..8c88a10df 100644 --- a/platform/jn516x/contiki-jn516x-main.c +++ b/platform/jn516x/contiki-jn516x-main.c @@ -369,10 +369,10 @@ main(void) PRINTF("%s %s %s\n", NETSTACK_LLSEC.name, NETSTACK_MAC.name, NETSTACK_RDC.name); -#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6 +#ifndef UIP_FALLBACK_INTERFACE uart0_set_input(serial_line_input_byte); serial_line_init(); -#endif +#endif /* UIP_FALLBACK_INTERFACE */ #if TIMESYNCH_CONF_ENABLED timesynch_init(); From fa078381cf3efbd2eb5234ca9a97def84affcec6 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 3 Feb 2016 18:01:25 +0100 Subject: [PATCH 86/94] Fix compiler warnings in shell --- apps/shell/shell-base64.c | 2 +- apps/shell/shell.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/shell/shell-base64.c b/apps/shell/shell-base64.c index ca723748c..30d921d34 100644 --- a/apps/shell/shell-base64.c +++ b/apps/shell/shell-base64.c @@ -86,7 +86,7 @@ base64_decode_char(char c) static int base64_add_char(struct base64_decoder_state *s, char c) { - if(isspace(c)) { + if(isspace((int)c)) { return 0; } diff --git a/apps/shell/shell.c b/apps/shell/shell.c index 62bf7a4d7..b02f45c31 100644 --- a/apps/shell/shell.c +++ b/apps/shell/shell.c @@ -532,7 +532,7 @@ shell_strtolong(const char *str, const char **retstr) ++strptr; } - for(i = 0; i < 10 && isdigit(strptr[i]); ++i) { + for(i = 0; i < 10 && isdigit((int)strptr[i]); ++i) { num = num * 10 + strptr[i] - '0'; } if(retstr != NULL) { From c924567d86bdeed514f127bb74e251467f0a567c Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Thu, 4 Feb 2016 00:25:53 +0100 Subject: [PATCH 87/94] Fix ip64 warnings --- core/net/ip64/ip64-eth-interface.c | 3 ++- core/net/ip64/ip64.c | 4 +++- dev/enc28j60/enc28j60-ip64-driver.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/net/ip64/ip64-eth-interface.c b/core/net/ip64/ip64-eth-interface.c index 026467137..437fbe24d 100644 --- a/core/net/ip64/ip64-eth-interface.c +++ b/core/net/ip64/ip64-eth-interface.c @@ -89,7 +89,6 @@ output(void) { int len, ret; - printf("ip64-interface: output source "); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF(" destination "); @@ -117,6 +116,8 @@ output(void) return IP64_ETH_DRIVER.output(ip64_packet_buffer, len); } } + + return 0; } /*---------------------------------------------------------------------------*/ const struct uip_fallback_interface ip64_eth_interface = { diff --git a/core/net/ip64/ip64.c b/core/net/ip64/ip64.c index 8483d9388..07d94db1b 100644 --- a/core/net/ip64/ip64.c +++ b/core/net/ip64/ip64.c @@ -897,11 +897,13 @@ interface_init(void) IP64_UIP_FALLBACK_INTERFACE.init(); } /*---------------------------------------------------------------------------*/ -static void +static int interface_output(void) { PRINTF("ip64: interface_output len %d\n", uip_len); IP64_UIP_FALLBACK_INTERFACE.output(); + + return 0; } /*---------------------------------------------------------------------------*/ const struct uip_fallback_interface ip64_uip_fallback_interface = { diff --git a/dev/enc28j60/enc28j60-ip64-driver.c b/dev/enc28j60/enc28j60-ip64-driver.c index f1804d998..71ed22739 100644 --- a/dev/enc28j60/enc28j60-ip64-driver.c +++ b/dev/enc28j60/enc28j60-ip64-driver.c @@ -35,6 +35,7 @@ #include "ip64.h" #include "ip64-eth.h" +#include "rime.h" #include #include From 45c125949ae64d450b69b533349cae77b29beeca Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 29 Jan 2016 23:13:01 +0100 Subject: [PATCH 88/94] Unified cc2538 examples into single cc2538-common placeholder --- examples/cc2538-common/Makefile | 8 ++++ .../crypto => cc2538-common}/Makefile.target | 0 examples/cc2538-common/README.md | 18 ++++++++ .../crypto/Makefile | 0 .../crypto}/Makefile.target | 0 .../crypto/cbc-mac-test.c | 6 +-- .../crypto/cbc-test.c | 6 +-- .../crypto/ccm-test.c | 6 +-- .../crypto/ctr-test.c | 6 +-- .../crypto/ecb-test.c | 6 +-- .../crypto/gcm-test.c | 6 +-- .../crypto/sha256-test.c | 6 +-- .../mqtt-demo/Makefile | 2 +- .../mqtt-demo}/Makefile.target | 0 .../mqtt-demo/README.md | 0 .../mqtt-demo/mqtt-demo.c | 4 +- .../mqtt-demo/project-conf.h | 0 .../{cc2538dk => cc2538-common}/pka/Makefile | 0 .../pka}/Makefile.target | 0 .../pka/ecc-ecdh.c | 6 +-- .../pka/ecc-sign.c | 6 +-- .../pka/ecc-verify.c | 6 +-- examples/cc2538-common/project-conf.h | 45 +++++++++++++++++++ .../sniffer/Makefile | 0 .../cc2538-common/sniffer/Makefile.target | 1 + .../sniffer/netstack.c | 0 .../sniffer/project-conf.h | 0 .../sniffer/sniffer.c | 4 +- .../sniffer/stub-rdc.c | 0 .../zoul => cc2538-common}/test-pwm.c | 6 +-- .../{cc2538dk => cc2538-common}/timer-test.c | 2 +- examples/cc2538dk/Makefile | 2 +- examples/zolertia/zoul/Makefile | 2 +- .../18-compile-arm-ports/Makefile | 17 ++++--- 34 files changed, 124 insertions(+), 47 deletions(-) create mode 100644 examples/cc2538-common/Makefile rename examples/{cc2538dk/crypto => cc2538-common}/Makefile.target (100%) create mode 100644 examples/cc2538-common/README.md rename examples/{cc2538dk => cc2538-common}/crypto/Makefile (100%) rename examples/{cc2538dk/mqtt-demo => cc2538-common/crypto}/Makefile.target (100%) rename examples/{cc2538dk => cc2538-common}/crypto/cbc-mac-test.c (99%) rename examples/{cc2538dk => cc2538-common}/crypto/cbc-test.c (99%) rename examples/{cc2538dk => cc2538-common}/crypto/ccm-test.c (99%) rename examples/{cc2538dk => cc2538-common}/crypto/ctr-test.c (98%) rename examples/{cc2538dk => cc2538-common}/crypto/ecb-test.c (99%) rename examples/{cc2538dk => cc2538-common}/crypto/gcm-test.c (99%) rename examples/{cc2538dk => cc2538-common}/crypto/sha256-test.c (97%) rename examples/{cc2538dk => cc2538-common}/mqtt-demo/Makefile (87%) rename examples/{cc2538dk/pka => cc2538-common/mqtt-demo}/Makefile.target (100%) rename examples/{cc2538dk => cc2538-common}/mqtt-demo/README.md (100%) rename examples/{cc2538dk => cc2538-common}/mqtt-demo/mqtt-demo.c (99%) rename examples/{cc2538dk => cc2538-common}/mqtt-demo/project-conf.h (100%) rename examples/{cc2538dk => cc2538-common}/pka/Makefile (100%) rename examples/{cc2538dk/sniffer => cc2538-common/pka}/Makefile.target (100%) rename examples/{cc2538dk => cc2538-common}/pka/ecc-ecdh.c (97%) rename examples/{cc2538dk => cc2538-common}/pka/ecc-sign.c (96%) rename examples/{cc2538dk => cc2538-common}/pka/ecc-verify.c (95%) create mode 100644 examples/cc2538-common/project-conf.h rename examples/{cc2538dk => cc2538-common}/sniffer/Makefile (100%) create mode 100644 examples/cc2538-common/sniffer/Makefile.target rename examples/{cc2538dk => cc2538-common}/sniffer/netstack.c (100%) rename examples/{cc2538dk => cc2538-common}/sniffer/project-conf.h (100%) rename examples/{cc2538dk => cc2538-common}/sniffer/sniffer.c (95%) rename examples/{cc2538dk => cc2538-common}/sniffer/stub-rdc.c (100%) rename examples/{zolertia/zoul => cc2538-common}/test-pwm.c (97%) rename examples/{cc2538dk => cc2538-common}/timer-test.c (99%) diff --git a/examples/cc2538-common/Makefile b/examples/cc2538-common/Makefile new file mode 100644 index 000000000..08ae0d42e --- /dev/null +++ b/examples/cc2538-common/Makefile @@ -0,0 +1,8 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = test-pwm timer-test + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2538dk/crypto/Makefile.target b/examples/cc2538-common/Makefile.target similarity index 100% rename from examples/cc2538dk/crypto/Makefile.target rename to examples/cc2538-common/Makefile.target diff --git a/examples/cc2538-common/README.md b/examples/cc2538-common/README.md new file mode 100644 index 000000000..eec7a4af3 --- /dev/null +++ b/examples/cc2538-common/README.md @@ -0,0 +1,18 @@ +README file for CC2538 common examples +========= + +The `cc2538-commmon` groups examples common to all cc2538-based platforms. +The examples in this folder are known to work on: + +* cc2538dk (default) +* zoul + +To change the default target at compilation time you can add the following: + +make TARGET=zoul + +Or to define the default platform permanently: + +make TARGET=zoul savetarget + +This will create a `Makefile.target` file with the TARGET predefined. diff --git a/examples/cc2538dk/crypto/Makefile b/examples/cc2538-common/crypto/Makefile similarity index 100% rename from examples/cc2538dk/crypto/Makefile rename to examples/cc2538-common/crypto/Makefile diff --git a/examples/cc2538dk/mqtt-demo/Makefile.target b/examples/cc2538-common/crypto/Makefile.target similarity index 100% rename from examples/cc2538dk/mqtt-demo/Makefile.target rename to examples/cc2538-common/crypto/Makefile.target diff --git a/examples/cc2538dk/crypto/cbc-mac-test.c b/examples/cc2538-common/crypto/cbc-mac-test.c similarity index 99% rename from examples/cc2538dk/crypto/cbc-mac-test.c rename to examples/cc2538-common/crypto/cbc-mac-test.c index ff355fc1f..98ac8483e 100644 --- a/examples/cc2538dk/crypto/cbc-mac-test.c +++ b/examples/cc2538-common/crypto/cbc-mac-test.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-cbc-mac-test cc2538dk AES-CBC-MAC Test Project + * \defgroup cc2538-cbc-mac-test cc2538 AES-CBC-MAC Test Project * - * AES-CBC-MAC access example for CC2538 on SmartRF06EB. + * AES-CBC-MAC access example for CC2538-based platforms * * This example shows how AES-CBC-MAC should be used. The example also * verifies the AES-CBC-MAC functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating AES-CBC-MAC on the cc2538dk platform + * Example demonstrating AES-CBC-MAC */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/cbc-test.c b/examples/cc2538-common/crypto/cbc-test.c similarity index 99% rename from examples/cc2538dk/crypto/cbc-test.c rename to examples/cc2538-common/crypto/cbc-test.c index ff7c429f3..108b6a775 100644 --- a/examples/cc2538dk/crypto/cbc-test.c +++ b/examples/cc2538-common/crypto/cbc-test.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-cbc-test cc2538dk AES-CBC Test Project + * \defgroup cc2538-cbc-test cc2538 AES-CBC Test Project * - * AES-CBC access example for CC2538 on SmartRF06EB. + * AES-CBC access example for CC2538-based platforms * * This example shows how AES-CBC should be used. The example also verifies * the AES-CBC functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating AES-CBC on the cc2538dk platform + * Example demonstrating AES-CBC */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/ccm-test.c b/examples/cc2538-common/crypto/ccm-test.c similarity index 99% rename from examples/cc2538dk/crypto/ccm-test.c rename to examples/cc2538-common/crypto/ccm-test.c index 4b7287104..93cad977c 100644 --- a/examples/cc2538dk/crypto/ccm-test.c +++ b/examples/cc2538-common/crypto/ccm-test.c @@ -37,9 +37,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ccm-test cc2538dk AES-CCM Test Project + * \defgroup cc2538-ccm-test cc2538 AES-CCM Test Project * - * AES-CCM access example for CC2538 on SmartRF06EB. + * AES-CCM access example for CC2538-based platforms * * This example shows how AES-CCM should be used. The example also verifies * the AES-CCM functionality. @@ -47,7 +47,7 @@ * @{ * * \file - * Example demonstrating AES-CCM on the cc2538dk platform + * Example demonstrating AES-CCM */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/ctr-test.c b/examples/cc2538-common/crypto/ctr-test.c similarity index 98% rename from examples/cc2538dk/crypto/ctr-test.c rename to examples/cc2538-common/crypto/ctr-test.c index 4a20c9095..83ad242c7 100644 --- a/examples/cc2538dk/crypto/ctr-test.c +++ b/examples/cc2538-common/crypto/ctr-test.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ctr-test cc2538dk AES-CTR Test Project + * \defgroup cc2538-ctr-test cc2538d AES-CTR Test Project * - * AES-CTR access example for CC2538 on SmartRF06EB. + * AES-CTR access example for CC2538-based platforms * * This example shows how AES-CTR should be used. The example also verifies * the AES-CTR functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating AES-CTR on the cc2538dk platform + * Example demonstrating AES-CTR */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/ecb-test.c b/examples/cc2538-common/crypto/ecb-test.c similarity index 99% rename from examples/cc2538dk/crypto/ecb-test.c rename to examples/cc2538-common/crypto/ecb-test.c index 54a7a566b..d7d2841cb 100644 --- a/examples/cc2538dk/crypto/ecb-test.c +++ b/examples/cc2538-common/crypto/ecb-test.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ecb-test cc2538dk AES-ECB Test Project + * \defgroup cc2538-ecb-test cc2538 AES-ECB Test Project * - * AES-ECB access example for CC2538 on SmartRF06EB. + * AES-ECB access example for CC2538-based platforms * * This example shows how AES-ECB should be used. The example also verifies * the AES-ECB functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating AES-ECB on the cc2538dk platform + * Example demonstrating AES-ECB */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/gcm-test.c b/examples/cc2538-common/crypto/gcm-test.c similarity index 99% rename from examples/cc2538dk/crypto/gcm-test.c rename to examples/cc2538-common/crypto/gcm-test.c index 53c476fb1..a58158d33 100644 --- a/examples/cc2538dk/crypto/gcm-test.c +++ b/examples/cc2538-common/crypto/gcm-test.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-gcm-test cc2538dk AES-GCM Test Project + * \defgroup cc2538-gcm-test cc2538 AES-GCM Test Project * - * AES-GCM access example for CC2538 on SmartRF06EB. + * AES-GCM access example for CC2538-based platforms * * This example shows how AES-GCM should be used. The example also verifies * the AES-GCM functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating AES-GCM on the cc2538dk platform + * Example demonstrating AES-GCM */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/crypto/sha256-test.c b/examples/cc2538-common/crypto/sha256-test.c similarity index 97% rename from examples/cc2538dk/crypto/sha256-test.c rename to examples/cc2538-common/crypto/sha256-test.c index f690ed27d..c9498b881 100644 --- a/examples/cc2538dk/crypto/sha256-test.c +++ b/examples/cc2538-common/crypto/sha256-test.c @@ -37,9 +37,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-sha256-test cc2538dk SHA-256 Test Project + * \defgroup cc2538-sha256-test cc2538 SHA-256 Test Project * - * SHA-256 access example for CC2538 on SmartRF06EB. + * SHA-256 access example for CC2538-based platforms * * This example shows how SHA-256 should be used. The example also verifies * the SHA-256 functionality. @@ -47,7 +47,7 @@ * @{ * * \file - * Example demonstrating SHA-256 on the cc2538dk platform + * Example demonstrating SHA-256 */ #include "contiki.h" #include "sys/rtimer.h" diff --git a/examples/cc2538dk/mqtt-demo/Makefile b/examples/cc2538-common/mqtt-demo/Makefile similarity index 87% rename from examples/cc2538dk/mqtt-demo/Makefile rename to examples/cc2538-common/mqtt-demo/Makefile index 850bdc609..7db9716a6 100644 --- a/examples/cc2538dk/mqtt-demo/Makefile +++ b/examples/cc2538-common/mqtt-demo/Makefile @@ -6,5 +6,5 @@ CONTIKI_WITH_IPV6 = 1 APPS += mqtt -CONTIKI=../../.. +CONTIKI = ../../.. include $(CONTIKI)/Makefile.include diff --git a/examples/cc2538dk/pka/Makefile.target b/examples/cc2538-common/mqtt-demo/Makefile.target similarity index 100% rename from examples/cc2538dk/pka/Makefile.target rename to examples/cc2538-common/mqtt-demo/Makefile.target diff --git a/examples/cc2538dk/mqtt-demo/README.md b/examples/cc2538-common/mqtt-demo/README.md similarity index 100% rename from examples/cc2538dk/mqtt-demo/README.md rename to examples/cc2538-common/mqtt-demo/README.md diff --git a/examples/cc2538dk/mqtt-demo/mqtt-demo.c b/examples/cc2538-common/mqtt-demo/mqtt-demo.c similarity index 99% rename from examples/cc2538dk/mqtt-demo/mqtt-demo.c rename to examples/cc2538-common/mqtt-demo/mqtt-demo.c index 691d4deed..42d840430 100644 --- a/examples/cc2538dk/mqtt-demo/mqtt-demo.c +++ b/examples/cc2538-common/mqtt-demo/mqtt-demo.c @@ -31,14 +31,14 @@ /** \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-mqtt-demo CC2538DK MQTT Demo Project + * \defgroup cc2538-mqtt-demo CC2538 MQTT Demo Project * * Demonstrates MQTT functionality. Works with IBM Quickstart as well as * mosquitto. * @{ * * \file - * An MQTT example for the cc2538dk platform + * An MQTT example for the cc2538-based platforms */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" diff --git a/examples/cc2538dk/mqtt-demo/project-conf.h b/examples/cc2538-common/mqtt-demo/project-conf.h similarity index 100% rename from examples/cc2538dk/mqtt-demo/project-conf.h rename to examples/cc2538-common/mqtt-demo/project-conf.h diff --git a/examples/cc2538dk/pka/Makefile b/examples/cc2538-common/pka/Makefile similarity index 100% rename from examples/cc2538dk/pka/Makefile rename to examples/cc2538-common/pka/Makefile diff --git a/examples/cc2538dk/sniffer/Makefile.target b/examples/cc2538-common/pka/Makefile.target similarity index 100% rename from examples/cc2538dk/sniffer/Makefile.target rename to examples/cc2538-common/pka/Makefile.target diff --git a/examples/cc2538dk/pka/ecc-ecdh.c b/examples/cc2538-common/pka/ecc-ecdh.c similarity index 97% rename from examples/cc2538dk/pka/ecc-ecdh.c rename to examples/cc2538-common/pka/ecc-ecdh.c index 623dbcc6c..a1614b8e4 100644 --- a/examples/cc2538dk/pka/ecc-ecdh.c +++ b/examples/cc2538-common/pka/ecc-ecdh.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ecdh-test cc2538dk ECDH Test Project + * \defgroup cc2538-ecdh-test cc2538 ECDH Test Project * - * ECDH example for CC2538 on SmartRF06EB. + * ECDH example for CC2538-based platforms * * This example shows how ECDH should be used. The example also verifies * the ECDH functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating ECDH on the cc2538dk platform + * Example demonstrating ECDH */ #include "contiki.h" #include "dev/ecc-algorithm.h" diff --git a/examples/cc2538dk/pka/ecc-sign.c b/examples/cc2538-common/pka/ecc-sign.c similarity index 96% rename from examples/cc2538dk/pka/ecc-sign.c rename to examples/cc2538-common/pka/ecc-sign.c index f5dff50fb..2b45854db 100644 --- a/examples/cc2538dk/pka/ecc-sign.c +++ b/examples/cc2538-common/pka/ecc-sign.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ecdsa-sign-test cc2538dk ECDSA-Sign Test Project + * \defgroup cc2538-ecdsa-sign-test cc2538 ECDSA-Sign Test Project * - * ECDSA-Sign example for CC2538 on SmartRF06EB. + * ECDSA-Sign example for CC2538-based platforms * * This example shows how ECDSA-Sign should be used. The example also verifies * the ECDSA-Sign functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating ECDSA-Sign on the cc2538dk platform + * Example demonstrating ECDSA-Sign */ #include "contiki.h" #include "dev/ecc-algorithm.h" diff --git a/examples/cc2538dk/pka/ecc-verify.c b/examples/cc2538-common/pka/ecc-verify.c similarity index 95% rename from examples/cc2538dk/pka/ecc-verify.c rename to examples/cc2538-common/pka/ecc-verify.c index 84f20f24b..ff61b88c1 100644 --- a/examples/cc2538dk/pka/ecc-verify.c +++ b/examples/cc2538-common/pka/ecc-verify.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-ecdsa-verify-test cc2538dk ECDSA-Verify Test Project + * \defgroup cc2538-ecdsa-verify-test cc2538 ECDSA-Verify Test Project * - * ECDSA-Verify example for CC2538 on SmartRF06EB. + * ECDSA-Verify example for CC2538-based platforms * * This example shows how ECDSA-Verify should be used. The example also verifies * the ECDSA-Verify functionality. @@ -42,7 +42,7 @@ * @{ * * \file - * Example demonstrating ECDSA-Verify on the cc2538dk platform + * Example demonstrating ECDSA-Verify */ #include "contiki.h" #include "dev/ecc-algorithm.h" diff --git a/examples/cc2538-common/project-conf.h b/examples/cc2538-common/project-conf.h new file mode 100644 index 000000000..b0a3b8231 --- /dev/null +++ b/examples/cc2538-common/project-conf.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 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 cc2538-examples + * @{ + * + * \file + * Project specific configuration defines for the basic cc2538dk examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/cc2538dk/sniffer/Makefile b/examples/cc2538-common/sniffer/Makefile similarity index 100% rename from examples/cc2538dk/sniffer/Makefile rename to examples/cc2538-common/sniffer/Makefile diff --git a/examples/cc2538-common/sniffer/Makefile.target b/examples/cc2538-common/sniffer/Makefile.target new file mode 100644 index 000000000..777593c88 --- /dev/null +++ b/examples/cc2538-common/sniffer/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2538dk diff --git a/examples/cc2538dk/sniffer/netstack.c b/examples/cc2538-common/sniffer/netstack.c similarity index 100% rename from examples/cc2538dk/sniffer/netstack.c rename to examples/cc2538-common/sniffer/netstack.c diff --git a/examples/cc2538dk/sniffer/project-conf.h b/examples/cc2538-common/sniffer/project-conf.h similarity index 100% rename from examples/cc2538dk/sniffer/project-conf.h rename to examples/cc2538-common/sniffer/project-conf.h diff --git a/examples/cc2538dk/sniffer/sniffer.c b/examples/cc2538-common/sniffer/sniffer.c similarity index 95% rename from examples/cc2538dk/sniffer/sniffer.c rename to examples/cc2538-common/sniffer/sniffer.c index 3f042bf07..fe20b9c76 100644 --- a/examples/cc2538dk/sniffer/sniffer.c +++ b/examples/cc2538-common/sniffer/sniffer.c @@ -32,9 +32,9 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-sniffer cc2538dk Sniffer + * \defgroup cc2538-sniffer cc2538 Sniffer * - * Sniffer for the cc2538dk platform. Originally based on the sensinode + * Sniffer for the CC2538-based platforms. Originally based on the sensinode * and cc2530dk sniffers. * * This example is to be used combined with the sensniff host-side tool, diff --git a/examples/cc2538dk/sniffer/stub-rdc.c b/examples/cc2538-common/sniffer/stub-rdc.c similarity index 100% rename from examples/cc2538dk/sniffer/stub-rdc.c rename to examples/cc2538-common/sniffer/stub-rdc.c diff --git a/examples/zolertia/zoul/test-pwm.c b/examples/cc2538-common/test-pwm.c similarity index 97% rename from examples/zolertia/zoul/test-pwm.c rename to examples/cc2538-common/test-pwm.c index a19412a9d..a1fa8c727 100644 --- a/examples/zolertia/zoul/test-pwm.c +++ b/examples/cc2538-common/test-pwm.c @@ -29,12 +29,12 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** - * \addtogroup remote-examples + * \addtogroup cc2538-examples * @{ * - * \defgroup remote-test-pwm Test the CC2538 PWM driver + * \defgroup cc2538-test-pwm Test the CC2538 PWM driver * - * Demonstrates the use of the CC2538 PWM driver for the Zolertia's Zoul boards + * Demonstrates the use of the CC2538 PWM driver * * @{ * diff --git a/examples/cc2538dk/timer-test.c b/examples/cc2538-common/timer-test.c similarity index 99% rename from examples/cc2538dk/timer-test.c rename to examples/cc2538-common/timer-test.c index d9cac2520..01cf7eede 100644 --- a/examples/cc2538dk/timer-test.c +++ b/examples/cc2538-common/timer-test.c @@ -32,7 +32,7 @@ * \addtogroup cc2538-examples * @{ * - * \defgroup cc2538-timers cc2538dk Timer Test Project + * \defgroup cc2538-timers cc2538 Timer Test Project * * This example tests the correct functionality of clocks and timers. * diff --git a/examples/cc2538dk/Makefile b/examples/cc2538dk/Makefile index 338b0a55c..4cb4d4979 100644 --- a/examples/cc2538dk/Makefile +++ b/examples/cc2538dk/Makefile @@ -1,5 +1,5 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -CONTIKI_PROJECT = cc2538-demo timer-test +CONTIKI_PROJECT = cc2538-demo all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index 0b9eef673..23808f45d 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -1,6 +1,6 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" -CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt +CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-power-mgmt 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 diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index a292bb3e3..dbac11d43 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -6,7 +6,7 @@ hello-world/ev-aducrf101mkxz \ ipv6/rpl-border-router/ev-aducrf101mkxz \ webserver-ipv6/ev-aducrf101mkxz \ ipv6/multicast/ev-aducrf101mkxz \ -cc2538dk/sniffer/ev-aducrf101mkxz \ +cc2538-common/sniffer/ev-aducrf101mkxz \ cc26xx/cc26xx-web-demo/srf06-cc26xx \ cc26xx/very-sleepy-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ cc26xx/cc26xx-web-demo/srf06-cc26xx:BOARD=sensortag/cc2650 \ @@ -19,17 +19,22 @@ ipso-objects/cc2538dk \ webserver-ipv6/cc2538dk \ cc2538dk/cc2538dk \ cc2538dk/udp-ipv6-echo-server/cc2538dk \ -cc2538dk/sniffer/cc2538dk \ -cc2538dk/mqtt-demo/cc2538dk \ -cc2538dk/crypto/cc2538dk \ -cc2538dk/pka/cc2538dk \ ipv6/multicast/cc2538dk \ +cc2538-common/cc2538dk \ +cc2538-common/sniffer/cc2538dk \ +cc2538-common/mqtt-demo/cc2538dk \ +cc2538-common/crypto/cc2538dk \ +cc2538-common/pka/cc2538dk \ +cc2538-common/zoul \ +cc2538-common/sniffer/zoul \ +cc2538-common/mqtt-demo/zoul \ +cc2538-common/crypto/zoul \ +cc2538-common/pka/zoul \ zolertia/zoul/zoul \ zolertia/zoul/cc1200-demo/zoul \ er-rest-example/zoul \ ipso-objects/zoul \ hello-world/zoul \ -cc2538dk/mqtt-demo/zoul \ er-rest-example/stm32nucleo-spirit1 \ ipv6/rpl-border-router/stm32nucleo-spirit1 \ ipv6/rpl-udp/stm32nucleo-spirit1 \ From ba6419cc25464262b8f10fee914ce5358627b159 Mon Sep 17 00:00:00 2001 From: Amit Geron Date: Sun, 7 Feb 2016 11:58:31 +0200 Subject: [PATCH 89/94] Typo * route_discovery_expicit_open --> route_discovery_explicit_open --- core/net/rime/route-discovery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/rime/route-discovery.c b/core/net/rime/route-discovery.c index 4a471bbbc..4ab2ee138 100644 --- a/core/net/rime/route-discovery.c +++ b/core/net/rime/route-discovery.c @@ -271,7 +271,7 @@ static const struct unicast_callbacks rrep_callbacks = {rrep_packet_received}; static const struct netflood_callbacks rreq_callbacks = {rreq_packet_received, NULL, NULL}; /*---------------------------------------------------------------------------*/ void -route_discovery_expicit_open(struct route_discovery_conn *c, +route_discovery_explicit_open(struct route_discovery_conn *c, clock_time_t time, uint16_t netflood_channel, uint16_t unicast_channel, @@ -288,7 +288,7 @@ route_discovery_open(struct route_discovery_conn *c, uint16_t channels, const struct route_discovery_callbacks *callbacks) { - route_discovery_expicit_open(c, time, channels + 0, channels + 1, callbacks); + route_discovery_explicit_open(c, time, channels + 0, channels + 1, callbacks); } /*---------------------------------------------------------------------------*/ void From 910f7b1ac8936de7af08d74deb44ad1ea7c6ff13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 7 Feb 2016 18:11:12 +0100 Subject: [PATCH 90/94] travis: Force AAPCS toolchain version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make Travis CI use the GNU ARM Embedded toolchain version specified by the READMEs, instead of automatically using the latest version provided by the PPA. In this way, the READMEs will still be correct after a PPA upgrade, and the version used by Contiki is under control. Signed-off-by: Benoît Thébaudeau --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1814ee6fa..3a035fd2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,7 @@ before_script: - if [ ${BUILD_ARCH:-0} = arm-aapcs ] ; then sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa && sudo apt-get -qq update && - sudo apt-get -qq install gcc-arm-embedded srecord && + sudo apt-get -qq install gcc-arm-embedded=5-2015q4-1~precise1 srecord && arm-none-eabi-gcc --version ; fi From b2b573e9e7a9c75b7d5c1a6f58ff92f3d15c2f3c Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Fri, 12 Feb 2016 19:10:02 +0100 Subject: [PATCH 91/94] Fix z1-websense example --- .../zolertia/z1/ipv6/z1-websense/Makefile | 6 +-- .../z1/ipv6/z1-websense/Makefile.target | 1 + .../zolertia/z1/ipv6/z1-websense/README.md | 3 +- ...y-websense.csc => example-z1-websense.csc} | 46 ++++++++----------- 4 files changed, 26 insertions(+), 30 deletions(-) create mode 100644 examples/zolertia/z1/ipv6/z1-websense/Makefile.target rename examples/zolertia/z1/ipv6/z1-websense/{example-sky-websense.csc => example-z1-websense.csc} (79%) diff --git a/examples/zolertia/z1/ipv6/z1-websense/Makefile b/examples/zolertia/z1/ipv6/z1-websense/Makefile index 45cd84bea..717802ae9 100644 --- a/examples/zolertia/z1/ipv6/z1-websense/Makefile +++ b/examples/zolertia/z1/ipv6/z1-websense/Makefile @@ -1,14 +1,14 @@ all: z1-websense -CONTIKI=../../../../.. +CONTIKI = ../../../../.. -SMALL=1 +SMALL = 1 APPS += webserver webbrowser CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" CONTIKI_SOURCEFILES += wget.c -PROJECTDIRS += ../../../ipv6/rpl-border-router +PROJECTDIRS += ../../../../ipv6/rpl-border-router PROJECT_SOURCEFILES += httpd-simple.c CONTIKI_WITH_IPV6 = 1 diff --git a/examples/zolertia/z1/ipv6/z1-websense/Makefile.target b/examples/zolertia/z1/ipv6/z1-websense/Makefile.target new file mode 100644 index 000000000..ff66066d4 --- /dev/null +++ b/examples/zolertia/z1/ipv6/z1-websense/Makefile.target @@ -0,0 +1 @@ +TARGET = z1 diff --git a/examples/zolertia/z1/ipv6/z1-websense/README.md b/examples/zolertia/z1/ipv6/z1-websense/README.md index c3883bb00..af373adc6 100644 --- a/examples/zolertia/z1/ipv6/z1-websense/README.md +++ b/examples/zolertia/z1/ipv6/z1-websense/README.md @@ -18,6 +18,7 @@ To test the example in COOJA under Linux make connect-router-cooja 3. You should now be able to browse to the nodes using your web browser: + Router: http://[aaaa::0212:7401:0001:0101]/ Node 2: http://[aaaa::0212:7402:0002:0202]/ @@ -31,7 +32,7 @@ To run the example on real nodes under Linux 2. Disconnect the nodes and program one node with the RPL border router - cd ../rpl-border-router && make TARGET=z1 border-router.upload + cd examples/ipv6/rpl-border-router && make TARGET=z1 border-router.upload 3. Connect to the border router using tunslip6: diff --git a/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc b/examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc similarity index 79% rename from examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc rename to examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc index f226357e1..87a20f781 100644 --- a/examples/zolertia/z1/ipv6/z1-websense/example-sky-websense.csc +++ b/examples/zolertia/z1/ipv6/z1-websense/example-z1-websense.csc @@ -5,7 +5,7 @@ [CONTIKI_DIR]/tools/cooja/apps/avrora [CONTIKI_DIR]/tools/cooja/apps/serial_socket - Sky Websense with RPL router + Z1 Websense with RPL router 0 123456 1000000 @@ -20,12 +20,12 @@ 40000 - org.contikios.cooja.mspmote.SkyMoteType + org.contikios.cooja.mspmote.Z1MoteType rplroot - Sky RPL Root + Z1 RPL Root [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c - make border-router.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.sky + make border-router.z1 TARGET=z1 + [CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.z1 org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.RimeAddress org.contikios.cooja.interfaces.IPAddress @@ -33,22 +33,19 @@ org.contikios.cooja.interfaces.MoteAttributes org.contikios.cooja.mspmote.interfaces.MspClock org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.MspButton org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspLED org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature - org.contikios.cooja.mspmote.SkyMoteType - skyweb - Sky Websense - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.c - make sky-websense.sky TARGET=sky - [CONTIKI_DIR]/examples/ipv6/sky-websense/sky-websense.sky + org.contikios.cooja.mspmote.Z1MoteType + Z1web + Z1 Websense + [CONTIKI_DIR]/examples/zolertia/z1/ipv6/z1-websense/z1-websense.c + make z1-websense.z1 TARGET=z1 + [CONTIKI_DIR]/examples/zolertia/z1/ipv6/z1-websense/z1-websense.z1 org.contikios.cooja.interfaces.Position org.contikios.cooja.interfaces.RimeAddress org.contikios.cooja.interfaces.IPAddress @@ -56,14 +53,11 @@ org.contikios.cooja.interfaces.MoteAttributes org.contikios.cooja.mspmote.interfaces.MspClock org.contikios.cooja.mspmote.interfaces.MspMoteID - org.contikios.cooja.mspmote.interfaces.SkyButton - org.contikios.cooja.mspmote.interfaces.SkyFlash - org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem + org.contikios.cooja.mspmote.interfaces.MspButton org.contikios.cooja.mspmote.interfaces.Msp802154Radio org.contikios.cooja.mspmote.interfaces.MspSerial - org.contikios.cooja.mspmote.interfaces.SkyLED + org.contikios.cooja.mspmote.interfaces.MspLED org.contikios.cooja.mspmote.interfaces.MspDebugOutput - org.contikios.cooja.mspmote.interfaces.SkyTemperature @@ -91,7 +85,7 @@ org.contikios.cooja.mspmote.interfaces.MspMoteID 2 - skyweb + Z1web @@ -105,7 +99,7 @@ org.contikios.cooja.mspmote.interfaces.MspMoteID 3 - skyweb + Z1web @@ -119,7 +113,7 @@ org.contikios.cooja.mspmote.interfaces.MspMoteID 4 - skyweb + Z1web @@ -133,7 +127,7 @@ org.contikios.cooja.mspmote.interfaces.MspMoteID 5 - skyweb + Z1web @@ -147,7 +141,7 @@ org.contikios.cooja.mspmote.interfaces.MspMoteID 6 - skyweb + Z1web From 25ff850a43f22d1cbd5f4117e6308ad98c7d0f3b Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Sat, 13 Feb 2016 20:10:16 +0100 Subject: [PATCH 92/94] Weather meter: replaced rtimer by ctimer as it was breaking contikimac --- platform/zoul/dev/weather-meter.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/zoul/dev/weather-meter.c b/platform/zoul/dev/weather-meter.c index 1f01d2c31..a0d2b1e90 100644 --- a/platform/zoul/dev/weather-meter.c +++ b/platform/zoul/dev/weather-meter.c @@ -53,7 +53,7 @@ #include "dev/gpio.h" #include "dev/ioc.h" #include "sys/timer.h" -#include "sys/rtimer.h" +#include "sys/ctimer.h" /*---------------------------------------------------------------------------*/ #define DEBUG 0 #if DEBUG @@ -77,7 +77,7 @@ static uint8_t enabled; process_event_t anemometer_int_event; process_event_t rain_gauge_int_event; /*---------------------------------------------------------------------------*/ -static struct rtimer rt; +static struct ctimer ct; static struct timer debouncetimer; /*---------------------------------------------------------------------------*/ typedef struct { @@ -186,7 +186,7 @@ weather_meter_get_wind_dir(void) } /*---------------------------------------------------------------------------*/ static void -rt_callback(struct rtimer *t, void *ptr) +ct_callback(void *ptr) { uint32_t wind_speed; int16_t wind_dir; @@ -261,7 +261,8 @@ rt_callback(struct rtimer *t, void *ptr) /* Enable the interrupt again */ GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); - rtimer_set(&rt, RTIMER_NOW() + RTIMER_SECOND, 1, rt_callback, NULL); + + ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); } /*---------------------------------------------------------------------------*/ PROCESS(weather_meter_int_process, "Weather meter interrupt process handler"); @@ -444,7 +445,7 @@ configure(int type, int value) /* Initialize here prior the first second tick */ wind_vane.value_prev = weather_meter_get_wind_dir(); - rtimer_set(&rt, RTIMER_NOW() + RTIMER_SECOND, 1, rt_callback, NULL); + ctimer_set(&ct, CLOCK_SECOND, ct_callback, NULL); GPIO_ENABLE_INTERRUPT(ANEMOMETER_SENSOR_PORT_BASE, ANEMOMETER_SENSOR_PIN_MASK); GPIO_ENABLE_INTERRUPT(RAIN_GAUGE_SENSOR_PORT_BASE, RAIN_GAUGE_SENSOR_PIN_MASK); @@ -485,3 +486,4 @@ configure(int type, int value) SENSORS_SENSOR(weather_meter, WEATHER_METER_SENSOR, value, configure, NULL); /*---------------------------------------------------------------------------*/ /** @} */ + From cb1e7c2c4551515c027f88badeb32525036dc14b Mon Sep 17 00:00:00 2001 From: Aitor Mejias Date: Thu, 28 Jan 2016 10:12:19 +0100 Subject: [PATCH 93/94] Added VOC (iAQ-Core) drivers and test application --- examples/zolertia/zoul/Makefile | 4 +- examples/zolertia/zoul/test-iaq.c | 112 +++++++++++++++++ platform/zoul/dev/iaq.c | 202 ++++++++++++++++++++++++++++++ platform/zoul/dev/iaq.h | 125 ++++++++++++++++++ 4 files changed, 441 insertions(+), 2 deletions(-) create mode 100644 examples/zolertia/zoul/test-iaq.c create mode 100644 platform/zoul/dev/iaq.c create mode 100644 platform/zoul/dev/iaq.h diff --git a/examples/zolertia/zoul/Makefile b/examples/zolertia/zoul/Makefile index a0a8dee0d..fe3a6ddf8 100644 --- a/examples/zolertia/zoul/Makefile +++ b/examples/zolertia/zoul/Makefile @@ -3,12 +3,12 @@ DEFINES+=PROJECT_CONF_H=\"project-conf.h\" CONTIKI_PROJECT = zoul-demo test-tsl2563 test-sht25 test-pwm test-power-mgmt 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 +CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor CONTIKI_TARGET_SOURCEFILES += tsl2563.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 +CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c all: $(CONTIKI_PROJECT) diff --git a/examples/zolertia/zoul/test-iaq.c b/examples/zolertia/zoul/test-iaq.c new file mode 100644 index 000000000..147ecd8a7 --- /dev/null +++ b/examples/zolertia/zoul/test-iaq.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, Zolertia - http://www.zolertia.com + * + * 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-iaq-test + * + * RE-Mote external IAQ test application + * Example of iAQ-Core implementation and simple operation reading the value + * of CO2, TVOC sensor and Status. The test checks for a each 5 minutes in + * order to get the first true measurement as datasheet recomendation + * (standard result of 0x82 is obtained in first time). + * Then, once initialized, periodically each 5 seconds reads + * the values of the IAQ sensor and shows in the screen, toggling the LED + * red if CO2 was not initialized and LED green if the reading was succeed. + * + * @{ + * \file + * RE-Mote implementation of external IAQ-CORE-C test application + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "iaq.h" +#include "dev/i2c.h" +#include "dev/leds.h" +#include +#include +/*---------------------------------------------------------------------------*/ +/* Standard warm up time iAQ Sensor */ +#define IAQ_INIT_WAIT 325L +#define LOOP_PERIOD 5L +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +/*---------------------------------------------------------------------------*/ +PROCESS(test_remote_iaq_process, "Test IAQ driver process"); +AUTOSTART_PROCESSES(&test_remote_iaq_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_remote_iaq_process, ev, data) +{ + static uint16_t count_delay = 0; + static uint16_t status = 0; + + PROCESS_BEGIN(); + + /* Configure IAQ and return structure with all parameters */ + SENSORS_ACTIVATE(iaq); + + while(1) { + /* Wait a bit */ + etimer_set(&et, (LOOP_INTERVAL)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + status = iaq.status(IAQ_DRIVER_STATUS); + + if(status == IAQ_INIT_STATE) { + count_delay += LOOP_PERIOD; + leds_toggle(LEDS_RED); + printf("Test-IAQ: Initializing Time-elapsed: %u seconds of aprox. %lu sec.\n", + count_delay, IAQ_INIT_WAIT); + } else if(status == IAQ_ACTIVE) { + leds_off(LEDS_RED); + leds_toggle(LEDS_GREEN); + + /* Get data from sensor: VOC, CO2 and internal status */ + printf("CO2 current value is: %d ppm\n", iaq.value(IAQ_VOC_VALUE)); + printf("TIAQ current value is: %d ppb\n", iaq.value(IAQ_CO2_VALUE)); + printf("Status is: 0x%0X\n", iaq.value(IAQ_STATUS)); + } + else { + printf("iAQ-Core Error: 0x%02X\n", status); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/platform/zoul/dev/iaq.c b/platform/zoul/dev/iaq.c new file mode 100644 index 000000000..7bc929a26 --- /dev/null +++ b/platform/zoul/dev/iaq.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup zoul-iaq-sensor + * @{ + * Driver for the RE-Mote IAQ iAQ-Core (Indoor Air Quality Sensor) + * \file + * Driver for the RE-Mote RF IAQ iAQ-Core sensor (IAQ) + * \author + * Aitor Mejias + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/gpio.h" +#include "dev/i2c.h" +#include "iaq.h" +#include "sys/timer.h" +#include "sys/etimer.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Callback pointers when interrupt occurs */ +void (*iaq_enable_callback)(uint16_t value); +/*---------------------------------------------------------------------------*/ +static int16_t enabled; +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static simple_iaq_data iaq_data; +static uint8_t iaq_buffer[IAQ_FRAME_SIZE+1]; +/*---------------------------------------------------------------------------*/ +PROCESS(iaq_process, "IAQ process handler"); +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ +/* Return the status of the iAQ-Core or the status of the driver */ + if (type == IAQ_STATUS) { + return (uint16_t)iaq_data.status; + } else if (type == IAQ_DRIVER_STATUS) { + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(iaq_process, ev, data) +{ + #if DEBUG + uint8_t i = 0; + #endif + + PROCESS_EXITHANDLER(); + PROCESS_BEGIN(); + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + + while(1) { + etimer_set(&et, (IAQ_POLLING_TIME)); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + i2c_master_enable(); + if(i2c_burst_receive(IAQ_ADDR, &iaq_buffer[0], IAQ_FRAME_SIZE) != + I2C_MASTER_ERR_NONE) { + PRINTF("IAQ: Failed to retrieve data from IAQ\n"); + enabled = IAQ_ERROR; + iaq_data.status = IAQ_INTERNAL_ERROR; + } else { + #if DEBUG + PRINTF("IAQ: Buffer "); + for (i=1;i<10;i++) { + PRINTF("[%d] %x, ", i-1, iaq_buffer[i-1]); + } + PRINTF("\n"); + #endif + /* Update the status of the sensor. This value readed represents the + internal status of the external driver. */ + switch (iaq_buffer[2]) { + case IAQ_INTERNAL_SUCCESS: + enabled = IAQ_ACTIVE; + break; + case IAQ_INTERNAL_RUNIN: + enabled = IAQ_INIT_STATE; + break; + case IAQ_INTERNAL_BUSY: + case IAQ_INTERNAL_ERROR: + enabled = IAQ_ERROR; + break; + default: + enabled = IAQ_ERROR; + break; + } + + iaq_data.tvoc = ((uint16_t)iaq_buffer[0] << 8) + iaq_buffer[1]; + iaq_data.co2 = ((uint16_t)iaq_buffer[7] << 8) + iaq_buffer[8]; + iaq_data.status = iaq_buffer[2]; + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + if (!enabled) { + PRINTF("IAQ: Sensor not enabled\n"); + return IAQ_ERROR; + } + if (enabled == IAQ_INIT_STATE) { + PRINTF("IAQ: Sensor initializing\n"); + return IAQ_INIT_STATE; + } + if (type == IAQ_CO2_VALUE) { + return iaq_data.co2; + } + if (type == IAQ_VOC_VALUE) { + return iaq_data.tvoc; + } + if (type == IAQ_STATUS) { + #if DEBUG + switch (iaq_data.status) { + case IAQ_INTERNAL_SUCCESS: + PRINTF("IAQ Status: SUCCESS\n"); + break; + case IAQ_INTERNAL_RUNIN: + PRINTF("IAQ Status: WARM UP\n"); + break; + case IAQ_INTERNAL_BUSY: + case IAQ_INTERNAL_ERROR: + PRINTF("IAQ Status: ERROR\n"); + break; + default: + PRINTF("IAQ Status: UNKNOWN STATUS %d\n", iaq_data.status); + break; + } + #endif + return iaq_data.status; + } + + return IAQ_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + /* Check the current status. If is initialized or is active, return the same + state */ + if ((enabled == IAQ_INIT_STATE) || (enabled == IAQ_ACTIVE)) { + return IAQ_ERROR; + } + + /* Fix the status in initial wait status */ + enabled = IAQ_INIT_STATE; + + /* Start Internal process to measure the iAQ Sensor */ + process_start(&iaq_process, NULL); + + return enabled; +} +/*---------------------------------------------------------------------------*/ +/* name, type, value, configure, status */ +SENSORS_SENSOR(iaq, IAQ_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** + * @} + */ + diff --git a/platform/zoul/dev/iaq.h b/platform/zoul/dev/iaq.h new file mode 100644 index 000000000..92562dfd7 --- /dev/null +++ b/platform/zoul/dev/iaq.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016, Zolertia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup zoul-sensors + * @{ + * \defgroup zoul-iaq-sensor IAQ driver (Indoor Air Quality) Sensor Module + * IAQ driver RE-Mote Indoor Air Quality Sensor Module + * Driver for the RE-Mote Sensor pack: Air Quality Sensor Module (IAQ) + * @{ + * \file + * Header file for the RE-Mote Sensor IAQ + */ +/* -------------------------------------------------------------------------- */ +#ifndef IAQ_H_ +#define IAQ_H_ +/* -------------------------------------------------------------------------- */ +#include +#include "lib/sensors.h" +#include "dev/zoul-sensors.h" +#include "iaq.h" +#include "i2c.h" +#include "sys/timer.h" +#include "sys/rtimer.h" +/* -------------------------------------------------------------------------- */ +/** \name IAQ address and definition + * @{ + */ +/* Address of the sensor: 1011010(1) Addr (R/W bit) */ +#define IAQ_ADDR 0x5A +#define IAQ_SENSOR "iAQ" +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ sensor types in iAQ-Core module + * @{ + */ +extern const struct sensors_sensor iaq; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ error values and definitions + * @{ + */ +#define IAQ_ACTIVE SENSORS_ACTIVE +#define IAQ_INIT_STATE SENSORS_HW_INIT +#define IAQ_ERROR (-1) +#define IAQ_SUCCESS 0x00 +#define IAQ_FRAME_SIZE 0x09 + +/* Variables used by external driver to get the state */ +#define IAQ_INTERNAL_SUCCESS 0x00 +#define IAQ_INTERNAL_RUNIN 0x10 +#define IAQ_INTERNAL_BUSY 0x01 +#define IAQ_INTERNAL_ERROR 0x80 + +/* Value types for the sensor readings */ +#define IAQ_CO2_VALUE 0x00 +#define IAQ_VOC_VALUE 0x01 +#define IAQ_STATUS 0x02 +#define IAQ_DRIVER_STATUS 0x03 + +/* Definition that corresponds with the two models of iAQ Sensor */ +#ifdef IAQ_PULSE_MODE +#define IAQ_POLLING_TIME (CLOCK_SECOND * 11) +#else +#define IAQ_POLLING_TIME (CLOCK_SECOND) +#endif +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name IAQ enumeration and options + * @{ + */ +enum { + IAQ_INIT = 0, + IAQ_STARTED, +}; +/** @} */ +/* -------------------------------------------------------------------------- */ +/** \name Readable IAQ-Core interface result conversion implementation as + * datasheet specification. + * + * @{ + */ +typedef struct iaq_struct_simple_td_reg { + uint16_t co2; + uint8_t status; + int32_t resistance; + uint16_t tvoc; +} __attribute__ ((packed)) simple_iaq_data; +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ From 2cbde75b02b33d82183d1785fb2ed349a3f6ed89 Mon Sep 17 00:00:00 2001 From: Toni Lozano Date: Mon, 15 Feb 2016 14:45:26 +0100 Subject: [PATCH 94/94] Removed PM10 code lines from adc-sensors driver --- platform/zoul/dev/adc-sensors.c | 9 ++------- platform/zoul/dev/adc-sensors.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/platform/zoul/dev/adc-sensors.c b/platform/zoul/dev/adc-sensors.c index 220a8dc88..c38455f19 100644 --- a/platform/zoul/dev/adc-sensors.c +++ b/platform/zoul/dev/adc-sensors.c @@ -118,10 +118,6 @@ convert_to_value(uint8_t index) /* Linear sensor from 0 to 5 V;*/ return (uint16_t)value; - case ANALOG_PM10_SENSOR: - /* PM10 sensor from 0 to 3.9 V;*/ - return (uint16_t)value; - default: return ADC_WRAPPER_ERROR; } @@ -168,8 +164,8 @@ configure(int type, int value) uint8_t pin_mask = GPIO_PIN_MASK(value); if((type != ANALOG_GROVE_LIGHT) && (type != ANALOG_PHIDGET_ROTATION_1109) && - (type != ANALOG_GROVE_LOUDNESS) && (type != ANALOG_PM10_SENSOR) && - (type != ANALOG_VAC_SENSOR) && (type != ANALOG_AAC_SENSOR) ) { + (type != ANALOG_GROVE_LOUDNESS) && (type != ANALOG_VAC_SENSOR) && + (type != ANALOG_AAC_SENSOR) ) { PRINTF("ADC sensors: sensor not supported, check adc_wrapper.h header\n"); return ADC_WRAPPER_ERROR; } @@ -205,7 +201,6 @@ configure(int type, int value) /*V+5 sensors*/ case ANALOG_VAC_SENSOR: case ANALOG_AAC_SENSOR: - case ANALOG_PM10_SENSOR: if(adc_zoul.configure(SENSORS_HW_INIT, pin_mask) == ZOUL_SENSORS_ERROR) { return ADC_WRAPPER_ERROR; } diff --git a/platform/zoul/dev/adc-sensors.h b/platform/zoul/dev/adc-sensors.h index 8a3eb4047..501eaa564 100644 --- a/platform/zoul/dev/adc-sensors.h +++ b/platform/zoul/dev/adc-sensors.h @@ -73,7 +73,6 @@ #define ANALOG_GROVE_LOUDNESS 0x03 #define ANALOG_VAC_SENSOR 0x04 #define ANALOG_AAC_SENSOR 0x05 -#define ANALOG_PM10_SENSOR 0x06 /* -------------------------------------------------------------------------- */ #define ADC_SENSORS "ADC sensors API" /* -------------------------------------------------------------------------- */