diff --git a/apps/arduino/Makefile.arduino b/apps/arduino/Makefile.arduino new file mode 100644 index 000000000..da7491b82 --- /dev/null +++ b/apps/arduino/Makefile.arduino @@ -0,0 +1,2 @@ +arduino_src = arduino-process.c + diff --git a/apps/arduino/Makefile.include b/apps/arduino/Makefile.include new file mode 100644 index 000000000..2a3b47d6b --- /dev/null +++ b/apps/arduino/Makefile.include @@ -0,0 +1,4 @@ +%.cpp: %.pde + echo '#include "Arduino.h"' > $@ + echo '#include "$<"' >> $@ + diff --git a/apps/arduino/README.md b/apps/arduino/README.md new file mode 100644 index 000000000..abf6924f7 --- /dev/null +++ b/apps/arduino/README.md @@ -0,0 +1,13 @@ +Arduino Compatibility +===================== + +This application contains hardware-independent implementations of +arduino compatibilty libraries and include files to be used with +contiki. + +The whole arduino compatibility library is work in progress. Note that +features having to do with timers like `millis` and `delay` are +currently untested. In Arduino they use timer 0 of the AVR +microcontroller. It should be investigated to use the hardware timer +already in use by contiki (on the OSD-merkur platform this is currently +timer 5). diff --git a/apps/arduino/arduino-process.c b/apps/arduino/arduino-process.c new file mode 100644 index 000000000..5a42ae32e --- /dev/null +++ b/apps/arduino/arduino-process.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * 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. + */ + +/** + * \addgroup Arduino Process + * + * This wraps the Arduino-API entry points `loop` and `setup` in a + * contiki process. + * + * If the normal contiki includes are used and resources initialized in + * `setup`, Contiki resources can be used in an arduino sketch. + * + * @{ + */ + +/** + * \file + * Wrapper for Arduino sketches + * \author + * Ralf Schlatterbeck + * + */ + +#include "arduino-process.h" + +PROCESS(arduino_sketch, "Arduino Sketch Wrapper"); + +PROCESS_THREAD(arduino_sketch, ev, data) +{ + PROCESS_BEGIN(); + + arduino_init (); + setup (); + while (1) { + loop (); + /* Give other processes a chance to run */ + process_post (&arduino_sketch, PROCESS_EVENT_CONTINUE, NULL); + PROCESS_WAIT_EVENT(); + } + PROCESS_END(); +} + + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + +/** @} */ diff --git a/apps/arduino/arduino-process.h b/apps/arduino/arduino-process.h new file mode 100644 index 000000000..23b00ede4 --- /dev/null +++ b/apps/arduino/arduino-process.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * 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. + */ + +/** + * \devgroup Arduino Process + * + * This wraps the Arduino-API entry points `loop` and `setup` in a + * contiki process. + * + * If the normal contiki includes are used and resources initialized in + * `setup`, Contiki resources can be used in an arduino sketch. + * + * @{ + */ + +/** + * \file + * Wrapper for Arduino sketches + * \author + * Ralf Schlatterbeck + * + */ + +#include "contiki.h" + +extern void loop (void); +extern void setup (void); +extern void arduino_init (void); + +extern struct process arduino_sketch; + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + +/** @} */ diff --git a/cpu/avr/hw_timer.h b/cpu/avr/hw_timer.h index 3b98566ce..06ac73699 100644 --- a/cpu/avr/hw_timer.h +++ b/cpu/avr/hw_timer.h @@ -137,6 +137,8 @@ #define HWT_CHANNEL_A 0 #define HWT_CHANNEL_B 1 #define HWT_CHANNEL_C 2 +#define HWT_CHANNEL_D 3 +#define HWT_CHANNEL_MASK 3 /* The following macros are defined for timer values 1,3,4,5 */ #define HWT_ICR(t) \ diff --git a/dev/arduino/arduino-compat.h b/dev/arduino/arduino-compat.h new file mode 100644 index 000000000..23e417623 --- /dev/null +++ b/dev/arduino/arduino-compat.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * 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. + */ + +/** + * \defgroup Hardware independent Arduino compatibility + * + * This file is meant to be included into a compatible Arduino.h + * + * Arduino calls the combination of an AVR timer and the corresponding + * channel a timer. So Arduinos definition of timer is different from + * that of AVR documentation. Arduino defines arbitrary TIMERXX macros + * that are later parsed in a big switch statement. + * + * We use a better representation of timer values than arduino here: + * The AVRs have max. 6 (numbered 0-5) timers. For representing these we + * need 3 bits. In addition each timer can have channels A-D (or just + * one channel in which case there is no alphabetic suffix). We can + * represent this in 2 bits. We add one bit to each for future + * compatibility and come up with 7 bits, still easily represented in 8 + * bit with room for a 'NOT_ON_TIMER' value. From these we can easily + * compute the channel and timer by shifting. No need for a big switch + * statement, and -- which is the common case -- when initializing with + * a constant for the pin, the compiler can compute everything at + * compile-time (that's why the analogWrite below is implemented as a + * static inline function). + * + * Note that Arduino also defines some TIMERX without an alphabetic + * suffix (e.g. TIMER2). I suspect this is for microcontrollers that + * only have one channel for a certain timer. So this is currently + * defined the same as TIMER2A because they are never used together. + * This may be wrong and may be a bug. + * + * Note that the hardware definition still has to define a + * digitalPinToTimer macro. We suggest to not implement this with a + * static table in program memory (as currently done by arduino) but + * instead as an if-cascade (as a C-macro). This allows the compiler to + * completely compute the if-cascade at compile-time if the used pin is + * a constant, resulting in *much* smaller code-footprint in the most + * common use-case. + * + * @{ + */ + +/** + * \file + * Header file for arduino compatibility + * \author + * Ralf Schlatterbeck + * + */ + +/* To be included by a compatible Arduino.h */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "contiki.h" +#include "hw_timer.h" + +#ifdef __cplusplus +} // extern "C" +#endif + +#define HW_TIMER_SHIFT 3 + +#define NOT_ON_TIMER 0xFF + +#define TIMER0A ((0 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER0B ((0 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) + +#define TIMER1A ((1 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER1B ((1 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) +#define TIMER1C ((1 << HW_TIMER_SHIFT) | HWT_CHANNEL_C) + +#define TIMER2 ((2 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER2A ((2 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER2B ((2 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) + +#define TIMER3A ((3 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER3B ((3 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) +#define TIMER3C ((3 << HW_TIMER_SHIFT) | HWT_CHANNEL_C) + +#define TIMER4A ((4 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER4B ((4 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) +#define TIMER4C ((4 << HW_TIMER_SHIFT) | HWT_CHANNEL_C) +#define TIMER4D ((4 << HW_TIMER_SHIFT) | HWT_CHANNEL_D) + +#define TIMER5A ((5 << HW_TIMER_SHIFT) | HWT_CHANNEL_A) +#define TIMER5B ((5 << HW_TIMER_SHIFT) | HWT_CHANNEL_B) +#define TIMER5C ((5 << HW_TIMER_SHIFT) | HWT_CHANNEL_C) + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void analogWrite(uint8_t pin, int val) +{ + /* + * Note on the timer usage: Arduino has code here that + * explicitly checks if the given val is 0 or 0xFF. + * The 16-bit timers on Arduino use the phase correct PWM + * waveform generation mode which already sets the output to + * continuous low for 0 or continuous high for 0xFF. When using + * an 8-bit timer, Arduino uses fast PWM which creates a tiny + * spike for 0, so to be Arduino-compatible in this mode we use + * digitalWrite in this case. + */ + uint8_t arduino_timer = digitalPinToTimer(pin); + pinMode(pin, OUTPUT); + if (val == 0 || arduino_timer == NOT_ON_TIMER) { + digitalWrite(pin, (val < 128) ? LOW : HIGH); + } else { + uint8_t t = arduino_timer >> HW_TIMER_SHIFT; + uint8_t c = arduino_timer & HWT_CHANNEL_MASK; + hwtimer_pwm_enable (t, c); + hwtimer_set_pwm (t, c, val); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + +/** @} */ diff --git a/examples/osd/arduino-sketch/Makefile b/examples/osd/arduino-sketch/Makefile new file mode 100644 index 000000000..315e10db8 --- /dev/null +++ b/examples/osd/arduino-sketch/Makefile @@ -0,0 +1,102 @@ +# Set this to the name of your sketch (without extension .pde) +SKETCH=sketch + +all: arduino-example \ + arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep + +# variable for this Makefile +# configure CoAP implementation (3|7|12|13) (er-coap-07 also supports CoAP draft 08) +WITH_COAP=13 + +# for some platforms +UIP_CONF_IPV6=1 +# IPv6 make config disappeared completely +CFLAGS += -DUIP_CONF_IPV6=1 + +CONTIKI=../../.. +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" + +PROJECT_SOURCEFILES += resource_led_pwm.c ${SKETCH}.cpp + +# variable for Makefile.include +ifneq ($(TARGET), minimal-net) +CFLAGS += -DUIP_CONF_IPV6_RPL=1 +else +# minimal-net does not support RPL under Linux and is mostly used to test CoAP only +${info INFO: compiling without RPL} +CFLAGS += -DUIP_CONF_IPV6_RPL=0 +CFLAGS += -DHARD_CODED_ADDRESS=\"fdfd::10\" +${info INFO: compiling with large buffers} +CFLAGS += -DUIP_CONF_BUFFER_SIZE=2048 +CFLAGS += -DREST_MAX_CHUNK_SIZE=1024 +CFLAGS += -DCOAP_MAX_HEADER_SIZE=640 +endif + +# linker optimizations +SMALL=1 + +# REST framework, requires WITH_COAP +ifeq ($(WITH_COAP), 13) +${info INFO: compiling with CoAP-13} +CFLAGS += -DWITH_COAP=13 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-13 +else ifeq ($(WITH_COAP), 12) +${info INFO: compiling with CoAP-12} +CFLAGS += -DWITH_COAP=12 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-12 +else ifeq ($(WITH_COAP), 7) +${info INFO: compiling with CoAP-08} +CFLAGS += -DWITH_COAP=7 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-07 +else ifeq ($(WITH_COAP), 3) +${info INFO: compiling with CoAP-03} +CFLAGS += -DWITH_COAP=3 +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += er-coap-03 +else +${info INFO: compiling with HTTP} +CFLAGS += -DWITH_HTTP +CFLAGS += -DREST=http_rest_implementation +CFLAGS += -DUIP_CONF_TCP=1 +APPS += er-http-engine +endif + +APPS += erbium time json arduino + +include $(CONTIKI)/Makefile.include +include $(CONTIKI)/apps/arduino/Makefile.include + +arduino-example.osd-merkur.hex: arduino-example.osd-merkur + avr-objcopy -j .text -j .data -O ihex arduino-example.osd-merkur \ + arduino-example.osd-merkur.hex + +arduino-example.osd-merkur.eep: arduino-example.osd-merkur + avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O ihex \ + arduino-example.osd-merkur arduino-example.osd-merkur.eep + +flash: arduino-example.osd-merkur.hex arduino-example.osd-merkur.eep + avrdude -pm128rfa1 -c arduino -P/dev/ttyUSB0 -b57600 -e -U \ + flash:w:arduino-example.osd-merkur.hex:a -U \ + eeprom:w:arduino-example.osd-merkur.eep:a + +.PHONY: flash + +$(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 aaaa::1/64 + +connect-minimal: + sudo ip address add fdfd::1/64 dev tap0 diff --git a/examples/osd/arduino-sketch/README.md b/examples/osd/arduino-sketch/README.md new file mode 100644 index 000000000..e1490ed05 --- /dev/null +++ b/examples/osd/arduino-sketch/README.md @@ -0,0 +1,11 @@ +Arduino compatibility example +============================= + +This example shows that it is now possible to re-use arduino sketches in +Contiki. This example documents the necessary magic. Arduino specifies +two routines, `setup` and `loop`. Before `setup` is called, the +framework initializes hardware. In original Arduino, all this is done in +a `main` function (in C). For contiki we define a process that does the +same. + +See the documentation file in apps/contiki-compat/README.md diff --git a/examples/osd/arduino-sketch/arduino-example.c b/examples/osd/arduino-sketch/arduino-example.c new file mode 100644 index 000000000..ea74dd8b8 --- /dev/null +++ b/examples/osd/arduino-sketch/arduino-example.c @@ -0,0 +1,2 @@ +#include +AUTOSTART_PROCESSES(&arduino_sketch); diff --git a/examples/osd/arduino-sketch/flash.sh b/examples/osd/arduino-sketch/flash.sh new file mode 100755 index 000000000..e9cb40bfc --- /dev/null +++ b/examples/osd/arduino-sketch/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +make TARGET=osd-merkur flash diff --git a/examples/osd/arduino-sketch/led_pwm.h b/examples/osd/arduino-sketch/led_pwm.h new file mode 100644 index 000000000..6ace57f8d --- /dev/null +++ b/examples/osd/arduino-sketch/led_pwm.h @@ -0,0 +1,30 @@ +/** + * \defgroup Arduino LED PWM example + * + * Resource definition for Arduino LED PWM module + * + * @{ + */ + +/** + * \file + * Resource definitions for the Arduino LED PWM module + * + * \author + * Ralf Schlatterbeck + */ + +#ifndef led_pwm_h +#define led_pwm_h +#include "contiki.h" +#include "contiki-net.h" +#include "erbium.h" +#include "er-coap-13.h" + +extern uint8_t pwm; +extern uint8_t period_100ms; +extern resource_t resource_led_pwm; +extern resource_t resource_led_period; + +#endif // led_pwm_h +/** @} */ diff --git a/examples/osd/arduino-sketch/project-conf.h b/examples/osd/arduino-sketch/project-conf.h new file mode 100644 index 000000000..574e15250 --- /dev/null +++ b/examples/osd/arduino-sketch/project-conf.h @@ -0,0 +1,101 @@ +/* + * 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. + * + * + */ + +#ifndef PROJECT_RPL_WEB_CONF_H_ +#define PROJECT_RPL_WEB_CONF_H_ + +#define PLATFORM_HAS_LEDS 1 +//#define PLATFORM_HAS_BUTTON 1 +#define PLATFORM_HAS_BATTERY 1 + +#define SICSLOWPAN_CONF_FRAG 1 + +/* For Debug: Dont allow MCU sleeping between channel checks */ +#undef RDC_CONF_MCU_SLEEP +#define RDC_CONF_MCU_SLEEP 0 + +/* Disabling RDC for demo purposes. Core updates often require more memory. */ +/* For projects, optimize memory and enable RDC again. */ +// #undef NETSTACK_CONF_RDC +//#define NETSTACK_CONF_RDC nullrdc_driver + +/* Increase rpl-border-router IP-buffer when using more than 64. */ +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 64 + +/* Estimate your header size, especially when using Proxy-Uri. */ +/* +#undef COAP_MAX_HEADER_SIZE +#define COAP_MAX_HEADER_SIZE 70 +*/ + +/* The IP buffer size must fit all other hops, in particular the border router. */ + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 256 + + +/* Multiplies with chunk size, be aware of memory constraints. */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +/* Must be <= open transaction number, default is COAP_MAX_OPEN_TRANSACTIONS-1. */ +/* +#undef COAP_MAX_OBSERVERS +#define COAP_MAX_OBSERVERS 2 +*/ + +/* Filtering .well-known/core per query can be disabled to save space. */ +/* +#undef COAP_LINK_FORMAT_FILTERING +#define COAP_LINK_FORMAT_FILTERING 0 +*/ + +/* Save some memory for the sky platform. */ +/* +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 10 +*/ + +/* Reduce 802.15.4 frame queue to save RAM. */ +/* +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 +*/ + +/* +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +*/ + +#endif /* PROJECT_RPL_WEB_CONF_H_ */ diff --git a/examples/osd/arduino-sketch/resource_led_pwm.c b/examples/osd/arduino-sketch/resource_led_pwm.c new file mode 100644 index 000000000..c547a6426 --- /dev/null +++ b/examples/osd/arduino-sketch/resource_led_pwm.c @@ -0,0 +1,273 @@ +/** + * \file + * Resource for Arduino PWM + * \author + * Ralf Schlatterbeck + * + * \brief get/put pwm and period for LED pin + * + * quick&dirty implementation, this should factor json parsing. + * But json format will probably change, there is a draft rfc. + */ + +#include +#include +#include +#include "contiki.h" +#include "jsonparse.h" +/* Only coap 13 for now */ +#include "er-coap-13.h" +#include "led_pwm.h" + +/* Error-handling macro */ +# define BYE(_exp, _tag) \ + do { \ + PRINTF("Expect "_exp": %d\n",_tag); \ + success=0; \ + goto bye; \ + } while(0) + +#define DEBUG 1 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +RESOURCE \ + ( led_pwm, METHOD_GET | METHOD_PUT + , "led/pwm" + , "title=\"LED PWM\";rt=\"led pwm\"" + ); + +void +led_pwm_handler + ( void* request + , void* response + , uint8_t *buffer + , uint16_t preferred_size + , int32_t *offset + ) +{ + int success = 1; + + int i; + char temp[100]; + int index = 0; + int length = 0; + int tag = 0; + const uint8_t *bytes = NULL; + size_t len = 0; + int n_acc = 0; + const uint16_t *accept = NULL; + uint16_t a_ctype = REST.type.APPLICATION_JSON; + uint16_t c_ctype = REST.get_header_content_type (request); + + /* Seems like accepted type is currently unsupported? */ + n_acc = REST.get_header_accept (request, &accept); + for (i=0; i +#include "led_pwm.h" +#define LED_PIN 5 + +uint8_t pwm = 128; +uint8_t period_100ms = 10; /* one second */ +} + +void setup (void) +{ + rest_init_engine (); + rest_activate_resource (&resource_led_pwm); + rest_activate_resource (&resource_led_period); +} + +void loop (void) +{ + static uint8_t last_pwm = 0; + if (last_pwm != pwm) { + last_pwm = pwm; + analogWrite (LED_PIN, pwm); + printf + ( "TCNT3: %04X TCCR3A: %04X TCCR3B: %04X TCCR3C: %04X OCR3C: %04X\n" + , TCNT3, TCCR3A, TCCR3B, TCCR3C, OCR3C + ); + } + + // Originally I wanted to sleep here to make the LED blink. + // Sleeping currently doesn't work, something turns off the chip. + // Maybe a mechanism to guard agains proto-threads taking too long? + //clock_wait (CLOCK_SECOND * period_100ms / 10); + //analogWrite (LED_PIN, 0); + //printf ("After write\n"); +} diff --git a/platform/osd-merkur/Makefile.osd-merkur b/platform/osd-merkur/Makefile.osd-merkur index 3fb160bdd..6dacd0fca 100644 --- a/platform/osd-merkur/Makefile.osd-merkur +++ b/platform/osd-merkur/Makefile.osd-merkur @@ -27,7 +27,7 @@ CONTIKI_TARGET_SOURCEFILES += servo.c servo-sensor.c #Needed for Relay 1 to 4 CONTIKI_TARGET_SOURCEFILES += relay.c relay-sensor.c # Arduino -CONTIKI_TARGET_SOURCEFILES += wiring_digital.c +CONTIKI_TARGET_SOURCEFILES += wiring_digital.c wiring.c wiring_analog.c CONTIKIBOARD=. BOOTLOADER_START = 0x1F000 diff --git a/platform/osd-merkur/dev/Arduino.h b/platform/osd-merkur/dev/Arduino.h index 2a5dcccba..3a0ae046b 100644 --- a/platform/osd-merkur/dev/Arduino.h +++ b/platform/osd-merkur/dev/Arduino.h @@ -1,6 +1,7 @@ #ifndef Arduino_h #define Arduino_h +#include #include #include #include @@ -88,14 +89,18 @@ typedef unsigned int word; typedef uint8_t boolean; typedef uint8_t byte; -void init(void); +/* + * This has been renamed from init to arduino_init, the original + * function name is way too generic. The arduino compatibility framework + * makes sure the correct function is called. + */ +void arduino_init(void); void pinMode(uint8_t, uint8_t); void digitalWrite(uint8_t, uint8_t); int digitalRead(uint8_t); int analogRead(uint8_t); void analogReference(uint8_t mode); -void analogWrite(uint8_t, int); unsigned long millis(void); unsigned long micros(void); @@ -126,7 +131,6 @@ extern const uint16_t PROGMEM port_to_output_PGM[]; extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; -extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; // Get the bit location within the hardware port of the given virtual pin. // This comes from the pins_*.c file for the active board configuration. @@ -135,7 +139,6 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; // #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) -#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) #define analogInPinToBit(P) (P) #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) @@ -158,35 +161,15 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; #define PL 12 #endif -#define NOT_ON_TIMER 0 -#define TIMER0A 1 -#define TIMER0B 2 -#define TIMER1A 3 -#define TIMER1B 4 -#define TIMER1C 5 -#define TIMER2 6 -#define TIMER2A 7 -#define TIMER2B 8 - -#define TIMER3A 9 -#define TIMER3B 10 -#define TIMER3C 11 -#define TIMER4A 12 -#define TIMER4B 13 -#define TIMER4C 14 -#define TIMER4D 15 -#define TIMER5A 16 -#define TIMER5B 17 -#define TIMER5C 18 - #ifdef __cplusplus } // extern "C" #endif #ifdef __cplusplus -#include "WCharacter.h" -#include "WString.h" -#include "HardwareSerial.h" +// look at this again when considering implementing serial +//#include "WCharacter.h" +//#include "WString.h" +//#include "HardwareSerial.h" uint16_t makeWord(uint16_t w); uint16_t makeWord(byte h, byte l); @@ -208,4 +191,6 @@ long map(long, long, long, long, long); #include "pins_arduino.h" -#endif \ No newline at end of file +#include "dev/arduino/arduino-compat.h" + +#endif diff --git a/platform/osd-merkur/dev/hw-arduino.h b/platform/osd-merkur/dev/hw-arduino.h new file mode 100644 index 000000000..7aa54d3d8 --- /dev/null +++ b/platform/osd-merkur/dev/hw-arduino.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Ralf Schlatterbeck Open Source Consulting + * 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. + */ + +/** + * \defgroup compatibility Arduino - Contiki + * + * This defines contiki-compatible hardware definitions for running + * arduino sketches (or just to call arduino-compatible function). + * For now only for osd hardware, a similar file should exist for each + * arduino-compatible hardware. + * + * @{ + */ + +/** + * \file + * Header file for arduino compatibility + * \author + * Ralf Schlatterbeck + * + */ + +/* + * The OSD hardware only supports timer 3 for PWM, timer 2 is used by + * contiki for sleep/wakeup timing and is not usable for PWM. + */ +#define digitalPinToTimer(pin) \ + ( (pin) == 3 \ + ? TIMER3A \ + : ( (pin) == 4 \ + ? TIMER3B \ + : ((pin == 5) ? TIMER3C : NOT_ON_TIMER) \ + ) \ + ) + +/* Only init timer 3 with phase correct pwm 8-bit and prescaler 64 */ +#define arduino_pwm_timer_init() \ + (hwtimer_ini (3, HWT_WGM_PWM_PHASE_8_BIT, HWT_CLOCK_PRESCALER_64, 0)) + +/* + * VI settings, see coding style + * ex:ts=8:et:sw=2 + */ + +/** @} */ diff --git a/platform/osd-merkur/dev/pins_arduino.h b/platform/osd-merkur/dev/pins_arduino.h index 8f6749eab..1441439aa 100644 --- a/platform/osd-merkur/dev/pins_arduino.h +++ b/platform/osd-merkur/dev/pins_arduino.h @@ -215,48 +215,6 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { // _BV( 7 ) , // PB 7 ** 35 ** D35 / LED2 / PWM }; -// !!! -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { - // TIMERS - // ------------------------------------------- - NOT_ON_TIMER , // PE 1 ** 0 ** USART0_TX - NOT_ON_TIMER , // PE 0 ** 1 ** USART0_RX - TIMER3A , // PE 3 ** 2 ** D3 / PWM - TIMER3B , // PE 4 ** 3 ** D4 / PWM - TIMER3C , // PE 5 ** 4 ** D5 / PWM - NOT_ON_TIMER , // PE 6 ** 5 ** D6 - NOT_ON_TIMER , // PD 3 ** 6 ** D21 / USART1_TX - NOT_ON_TIMER , // PD 2 ** 7 ** D20 / USART1_RX - NOT_ON_TIMER , // PD 0 ** 8 ** D15 / I2C_SCL - NOT_ON_TIMER , // PD 1 ** 9 ** D14 / I2C_SDA - NOT_ON_TIMER , // PB 0 ** 10 ** D10 / SPI_SSN - NOT_ON_TIMER , // PB 2 ** 11 ** D11 / SPI_MOSI - NOT_ON_TIMER , // PB 1 ** 12 ** D13 / SPI_SCK - NOT_ON_TIMER , // PB 3 ** 13 ** D12 / SPI_MISO - TIMER2A , // PB 4 ** 14 ** D9 / PWM - NOT_ON_TIMER , // PF 7 ** 15 ** A0 / D33 - NOT_ON_TIMER , // PF 6 ** 16 ** A1 / D32 - NOT_ON_TIMER , // PF 5 ** 17 ** A2 / D31 - NOT_ON_TIMER , // PF 4 ** 18 ** A3 / D30 - NOT_ON_TIMER , // PF 0 ** 19 ** A4 / D26 - NOT_ON_TIMER , // PF 1 ** 20 ** A5 / D27 -// NOT_ON_TIMER , // PF 2 ** 28 ** A6 / D28 -// NOT_ON_TIMER , // PF 3 ** 29 ** A7 / D29 -// NOT_ON_TIMER , // PE 2 ** 2 ** D2 -// NOT_ON_TIMER , // PE 7 ** 7 ** D7 -// TIMER1A , // PB 5 ** 8 ** D8 / PWM -// NOT_ON_TIMER , // PG 0 ** 16 ** D16 -// NOT_ON_TIMER , // PG 1 ** 17 ** D17 -// NOT_ON_TIMER , // PG 2 ** 18 ** D18 -// TIMER0B , // PG 5 ** 19 ** D19 / PWM -// NOT_ON_TIMER , // PD 4 ** 22 ** D22 -// NOT_ON_TIMER , // PD 5 ** 23 ** D23 -// NOT_ON_TIMER , // PD 6 ** 24 ** D24 -// NOT_ON_TIMER , // PD 7 ** 25 ** D25 -// TIMER1B , // PB 6 ** 34 ** D34/ PWM -// TIMER1C , // PB 7 ** 35 ** D35 / PWM -}; - #endif #endif diff --git a/platform/osd-merkur/dev/wiring.c b/platform/osd-merkur/dev/wiring.c index ac8bb6f9b..1c6abc44d 100644 --- a/platform/osd-merkur/dev/wiring.c +++ b/platform/osd-merkur/dev/wiring.c @@ -23,6 +23,7 @@ */ #include "wiring_private.h" +#include "hw-arduino.h" // the prescaler is set so that timer0 ticks every 64 clock cycles, and the // the overflow handler is called every 256 ticks. @@ -186,20 +187,23 @@ void delayMicroseconds(unsigned int us) ); } -void init() +void arduino_init() { // this needs to be called before setup() or some functions won't // work there - sei(); // on the ATmega168, timer 0 is also used for fast hardware pwm // (using phase-correct PWM would mean that timer 0 overflowed half as often // resulting in different millis() behavior on the ATmega8 and ATmega168) + /* + * RSC: Keep timer0 for now, until we decide how to implement + * millis() etc in a contiki-compatible way + */ + #if defined(TCCR0A) && defined(WGM01) sbi(TCCR0A, WGM01); sbi(TCCR0A, WGM00); #endif - // set timer 0 prescale factor to 64 #if defined(__AVR_ATmega128__) // CPU specific: different values for the ATmega128 @@ -229,96 +233,13 @@ void init() #error Timer 0 overflow interrupt not set correctly #endif - // timers 1 and 2 are used for phase-correct hardware pwm - // this is better for motors as it ensures an even waveform - // note, however, that fast pwm mode can achieve a frequency of up - // 8 MHz (with a 16 MHz clock) at 50% duty cycle + /* + * All other PCM timers are initialized here in a + * platform-specific way + */ + arduino_pwm_timer_init (); -#if defined(TCCR1B) && defined(CS11) && defined(CS10) - TCCR1B = 0; - - // set timer 1 prescale factor to 64 - sbi(TCCR1B, CS11); -#if F_CPU >= 8000000L - sbi(TCCR1B, CS10); -#endif -#elif defined(TCCR1) && defined(CS11) && defined(CS10) - sbi(TCCR1, CS11); -#if F_CPU >= 8000000L - sbi(TCCR1, CS10); -#endif -#endif - // put timer 1 in 8-bit phase correct pwm mode -#if defined(TCCR1A) && defined(WGM10) - sbi(TCCR1A, WGM10); -#elif defined(TCCR1) - #warning this needs to be finished -#endif - - // set timer 2 prescale factor to 64 -#if defined(TCCR2) && defined(CS22) - sbi(TCCR2, CS22); -#elif defined(TCCR2B) && defined(CS22) - sbi(TCCR2B, CS22); -#else - #warning Timer 2 not finished (may not be present on this CPU) -#endif - - // configure timer 2 for phase correct pwm (8-bit) -#if defined(TCCR2) && defined(WGM20) - sbi(TCCR2, WGM20); -#elif defined(TCCR2A) && defined(WGM20) - sbi(TCCR2A, WGM20); -#else - #warning Timer 2 not finished (may not be present on this CPU) -#endif - -#if defined(TCCR3B) && defined(CS31) && defined(WGM30) - sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 - sbi(TCCR3B, CS30); - sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode -#endif - -#if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ - sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 - sbi(TCCR4B, CS41); - sbi(TCCR4B, CS40); - sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode - sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A - sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D -#else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ -#if defined(TCCR4B) && defined(CS41) && defined(WGM40) - sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 - sbi(TCCR4B, CS40); - sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode -#endif -#endif /* end timer4 block for ATMEGA1280/2560 and similar */ - -#if defined(TCCR5B) && defined(CS51) && defined(WGM50) - sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 - sbi(TCCR5B, CS50); - sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode -#endif - -#if defined(ADCSRA) - // set a2d prescale factor to 128 - // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. - // XXX: this will not work properly for other clock speeds, and - // this code should use F_CPU to determine the prescale factor. - sbi(ADCSRA, ADPS2); - sbi(ADCSRA, ADPS1); - sbi(ADCSRA, ADPS0); - - // enable a2d conversions - sbi(ADCSRA, ADEN); -#endif - - // the bootloader connects pins 0 and 1 to the USART; disconnect them - // here so they can be used as normal digital i/o; they will be - // reconnected in Serial.begin() -#if defined(UCSRB) - UCSRB = 0; -#elif defined(UCSR0B) - UCSR0B = 0; -#endif + /* + * Removed the rest which manipulates the serial pins + */ } diff --git a/platform/osd-merkur/dev/wiring_analog.c b/platform/osd-merkur/dev/wiring_analog.c index 6c3dcc484..630e95721 100644 --- a/platform/osd-merkur/dev/wiring_analog.c +++ b/platform/osd-merkur/dev/wiring_analog.c @@ -43,198 +43,6 @@ int analogRead(uint8_t pin) return readADC(pin); } -// Right now, PWM output only works on the pins with -// hardware support. These are defined in the appropriate -// pins_*.c file. For the rest of the pins, we default -// to digital output. -void analogWrite(uint8_t pin, int val) -{ - // We need to make sure the PWM output is enabled for those pins - // that support it, as we turn it off when digitally reading or - // writing with them. Also, make sure the pin is in output mode - // for consistenty with Wiring, which doesn't require a pinMode - // call for the analog output pins. - pinMode(pin, OUTPUT); - if (val == 0) - { - digitalWrite(pin, LOW); - } - else if (val == 255) - { - digitalWrite(pin, HIGH); - } - else - { - switch(digitalPinToTimer(pin)) - { - // XXX fix needed for atmega8 - #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) - case TIMER0A: - // connect pwm to pin on timer 0 - sbi(TCCR0, COM00); - OCR0 = val; // set pwm duty - break; - #endif - - #if defined(TCCR0A) && defined(COM0A1) - case TIMER0A: - // connect pwm to pin on timer 0, channel A - sbi(TCCR0A, COM0A1); - OCR0A = val; // set pwm duty - break; - #endif - - #if defined(TCCR0A) && defined(COM0B1) - case TIMER0B: - // connect pwm to pin on timer 0, channel B - sbi(TCCR0A, COM0B1); - OCR0B = val; // set pwm duty - break; - #endif - - #if defined(TCCR1A) && defined(COM1A1) - case TIMER1A: - // connect pwm to pin on timer 1, channel A - sbi(TCCR1A, COM1A1); - OCR1A = val; // set pwm duty - break; - #endif - - #if defined(TCCR1A) && defined(COM1B1) - case TIMER1B: - // connect pwm to pin on timer 1, channel B - sbi(TCCR1A, COM1B1); - OCR1B = val; // set pwm duty - break; - #endif - - #if defined(TCCR1A) && defined(COM1C1) - case TIMER1C: - // connect pwm to pin on timer 1, channel C - sbi(TCCR1A, COM1C1); - OCR1C = val; // set pwm duty - break; - #endif - - #if defined(TCCR2) && defined(COM21) - case TIMER2: - // connect pwm to pin on timer 2 - sbi(TCCR2, COM21); - OCR2 = val; // set pwm duty - break; - #endif - - #if defined(TCCR2A) && defined(COM2A1) - case TIMER2A: - // connect pwm to pin on timer 2, channel A - sbi(TCCR2A, COM2A1); - OCR2A = val; // set pwm duty - break; - #endif - - #if defined(TCCR2A) && defined(COM2B1) - case TIMER2B: - // connect pwm to pin on timer 2, channel B - sbi(TCCR2A, COM2B1); - OCR2B = val; // set pwm duty - break; - #endif - - #if defined(TCCR3A) && defined(COM3A1) - case TIMER3A: - // connect pwm to pin on timer 3, channel A - sbi(TCCR3A, COM3A1); - OCR3A = val; // set pwm duty - break; - #endif - - #if defined(TCCR3A) && defined(COM3B1) - case TIMER3B: - // connect pwm to pin on timer 3, channel B - sbi(TCCR3A, COM3B1); - OCR3B = val; // set pwm duty - break; - #endif - - #if defined(TCCR3A) && defined(COM3C1) - case TIMER3C: - // connect pwm to pin on timer 3, channel C - sbi(TCCR3A, COM3C1); - OCR3C = val; // set pwm duty - break; - #endif - - #if defined(TCCR4A) - case TIMER4A: - //connect pwm to pin on timer 4, channel A - sbi(TCCR4A, COM4A1); - #if defined(COM4A0) // only used on 32U4 - cbi(TCCR4A, COM4A0); - #endif - OCR4A = val; // set pwm duty - break; - #endif - - #if defined(TCCR4A) && defined(COM4B1) - case TIMER4B: - // connect pwm to pin on timer 4, channel B - sbi(TCCR4A, COM4B1); - OCR4B = val; // set pwm duty - break; - #endif - - #if defined(TCCR4A) && defined(COM4C1) - case TIMER4C: - // connect pwm to pin on timer 4, channel C - sbi(TCCR4A, COM4C1); - OCR4C = val; // set pwm duty - break; - #endif - - #if defined(TCCR4C) && defined(COM4D1) - case TIMER4D: - // connect pwm to pin on timer 4, channel D - sbi(TCCR4C, COM4D1); - #if defined(COM4D0) // only used on 32U4 - cbi(TCCR4C, COM4D0); - #endif - OCR4D = val; // set pwm duty - break; - #endif - - - #if defined(TCCR5A) && defined(COM5A1) - case TIMER5A: - // connect pwm to pin on timer 5, channel A - sbi(TCCR5A, COM5A1); - OCR5A = val; // set pwm duty - break; - #endif - - #if defined(TCCR5A) && defined(COM5B1) - case TIMER5B: - // connect pwm to pin on timer 5, channel B - sbi(TCCR5A, COM5B1); - OCR5B = val; // set pwm duty - break; - #endif - - #if defined(TCCR5A) && defined(COM5C1) - case TIMER5C: - // connect pwm to pin on timer 5, channel C - sbi(TCCR5A, COM5C1); - OCR5C = val; // set pwm duty - break; - #endif - - case NOT_ON_TIMER: - default: - if (val < 128) { - digitalWrite(pin, LOW); - } else { - digitalWrite(pin, HIGH); - } - } - } -} - +/* + * analogWrite is now implemented in dev/arduino/arduino-compat.h + */