Add Arduino compatibility layer
We can now directly compile arduino sketches (.pde) files. Arduino compatible analogWrite works now. But there is still a long way to go, serial I/O and timer stuff (delay, millis etc) currently don't work (not tested but I don't expect this to work). It can be used in an arduino sketch or in a normal contiki program. We get a PWM frequency of 490.2 Hz (a period of 2.040 ms), that's Arduino compatible. If you need different frequencies see native timer usage in examples/osd/pwm-example In a contiki program you have to call arduino_pwm_timer_init to initialize the timer before pwm works. The arduino sketch wrapper already does this. For running a sketch, see examples/osd/arduino-sketch
This commit is contained in:
parent
87903b2e89
commit
e65dabb119
22 changed files with 999 additions and 361 deletions
|
@ -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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <hw-arduino.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
@ -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
|
||||
#include "dev/arduino/arduino-compat.h"
|
||||
|
||||
#endif
|
||||
|
|
73
platform/osd-merkur/dev/hw-arduino.h
Normal file
73
platform/osd-merkur/dev/hw-arduino.h
Normal file
|
@ -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 <rsc@runtux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/** @} */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue