Inline timer init functions, no static storage
Hardware init function profit a great deal from being inlined if the given parameters are constant -- which is the common use-case, we could probably call this for all timers and still have less overhead. The hwtimer_pwm_ini (which calls hwtimer_ini) gets completely computed at compile-time resulting only in the register settings of hwtimer_ini. This is now possible because we get rid of static storage for the max_ticks and instead compute this in hwtimer_pwm_max_ticks from the timer register settings.
This commit is contained in:
parent
c46d6afa39
commit
fd54bc9ca4
|
@ -14,8 +14,7 @@ CONTIKI_CPU=$(CONTIKI)/cpu/avr
|
||||||
### TARGETLIBS are platform-specific routines in the contiki library path
|
### TARGETLIBS are platform-specific routines in the contiki library path
|
||||||
CONTIKI_CPU_DIRS = . dev
|
CONTIKI_CPU_DIRS = . dev
|
||||||
AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c \
|
AVR = clock.c mtarch.c eeprom.c flash.c rs232.c leds-arch.c \
|
||||||
watchdog.c rtimer-arch.c bootloader.c hw_timer.c \
|
watchdog.c rtimer-arch.c bootloader.c
|
||||||
hw_pwm_timer.c
|
|
||||||
ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c
|
ELFLOADER = elfloader.c elfloader-avr.c symtab-avr.c
|
||||||
TARGETLIBS = random.c leds.c
|
TARGETLIBS = random.c leds.c
|
||||||
|
|
||||||
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 hardware timer
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Alternative initialisation with period in microseconds
|
|
||||||
* \author
|
|
||||||
* Ralf Schlatterbeck <rsc@runtux.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "contiki.h"
|
|
||||||
#include "rtimer-arch.h"
|
|
||||||
#include "hw_timer.h"
|
|
||||||
|
|
||||||
/* one for each possible timer */
|
|
||||||
uint16_t hwt_max_ticks [6];
|
|
||||||
|
|
||||||
#define PERIOD_MAX (0xFFFFFFFF / (F_CPU / 1000000))
|
|
||||||
/* for 16-bit timer: */
|
|
||||||
#define TICKS_MAX 0xFFFF
|
|
||||||
#define TICKS_MIN 0xFF
|
|
||||||
|
|
||||||
int8_t
|
|
||||||
hwtimer_pwm_ini (uint8_t timer, uint32_t period_us, uint8_t pwm_type, uint8_t ocra)
|
|
||||||
{
|
|
||||||
uint32_t ticks = 0;
|
|
||||||
uint8_t clock = HWT_CLOCK_PRESCALER_1024;
|
|
||||||
uint8_t wgm = HWT_WGM_NORMAL;
|
|
||||||
HWT_CHECK_TIMER (timer);
|
|
||||||
if (period_us > PERIOD_MAX) {
|
|
||||||
period_us = PERIOD_MAX;
|
|
||||||
}
|
|
||||||
ticks = (F_CPU / 1000000) * period_us;
|
|
||||||
/* Non-fast PWM modes have half the frequency */
|
|
||||||
if (pwm_type != HWT_PWM_FAST) {
|
|
||||||
ticks >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Divisors are 1, 8, 64, 256, 1024, shifts between these are
|
|
||||||
* 3, 3, 2, 2, respectively. We modify `ticks` in place, the AVR can
|
|
||||||
* shift only one bit in one instruction, so shifting isn't cheap.
|
|
||||||
* We try to get the *maximum* prescaler that still permits a tick
|
|
||||||
* resolution of at least 8 bit.
|
|
||||||
*/
|
|
||||||
if (ticks <= (TICKS_MIN << 3)) {
|
|
||||||
clock = HWT_CLOCK_PRESCALER_1;
|
|
||||||
}
|
|
||||||
else if ((ticks >>= 3) <= (TICKS_MIN << 3)) {
|
|
||||||
clock = HWT_CLOCK_PRESCALER_8;
|
|
||||||
}
|
|
||||||
else if ((ticks >>= 3) <= (TICKS_MIN << 2)) {
|
|
||||||
clock = HWT_CLOCK_PRESCALER_64;
|
|
||||||
}
|
|
||||||
else if ((ticks >>= 2) <= (TICKS_MIN << 2)) {
|
|
||||||
clock = HWT_CLOCK_PRESCALER_256;
|
|
||||||
}
|
|
||||||
else if ((ticks >>= 2) > TICKS_MAX) {
|
|
||||||
ticks = TICKS_MAX;
|
|
||||||
}
|
|
||||||
hwt_max_ticks [timer] = ticks;
|
|
||||||
switch (pwm_type) {
|
|
||||||
case HWT_PWM_FAST:
|
|
||||||
wgm = ocra ? HWT_WGM_PWM_FAST_OCRA : HWT_WGM_PWM_FAST_ICR;
|
|
||||||
break;
|
|
||||||
case HWT_PWM_PHASE_CORRECT:
|
|
||||||
wgm = ocra ? HWT_WGM_PWM_PHASE_OCRA : HWT_WGM_PWM_PHASE_ICR;
|
|
||||||
break;
|
|
||||||
case HWT_PWM_PHASE_FRQ_CORRECT:
|
|
||||||
default:
|
|
||||||
wgm = ocra ? HWT_WGM_PWM_PHASE_FRQ_OCRA : HWT_WGM_PWM_PHASE_FRQ_ICR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Special 8- 9- 10-bit modes */
|
|
||||||
if (pwm_type == HWT_PWM_FAST || pwm_type == HWT_PWM_PHASE_CORRECT) {
|
|
||||||
if (ticks == 0xFF) {
|
|
||||||
wgm = (pwm_type == HWT_PWM_FAST)
|
|
||||||
? HWT_WGM_PWM_FAST_8_BIT
|
|
||||||
: HWT_WGM_PWM_PHASE_8_BIT;
|
|
||||||
}
|
|
||||||
else if (ticks == 0x1FF) {
|
|
||||||
wgm = (pwm_type == HWT_PWM_FAST)
|
|
||||||
? HWT_WGM_PWM_FAST_9_BIT
|
|
||||||
: HWT_WGM_PWM_PHASE_9_BIT;
|
|
||||||
}
|
|
||||||
else if (ticks == 0x3FF) {
|
|
||||||
wgm = (pwm_type == HWT_PWM_FAST)
|
|
||||||
? HWT_WGM_PWM_FAST_10_BIT
|
|
||||||
: HWT_WGM_PWM_PHASE_10_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hwtimer_ini (timer, wgm, clock, ticks);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t hwtimer_pwm_max_ticks (uint8_t timer)
|
|
||||||
{
|
|
||||||
if (timer > 5) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return hwt_max_ticks [timer];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ex:ts=8:et:sw=2
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 hardware timer
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Header file for hardware timer of AVR microcontrollers
|
|
||||||
* \author
|
|
||||||
* Ralf Schlatterbeck <rsc@runtux.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include "contiki.h"
|
|
||||||
#include "rtimer-arch.h"
|
|
||||||
#include "hw_timer.h"
|
|
||||||
|
|
||||||
#ifndef PLAT_TIMER
|
|
||||||
#define PLAT_TIMER 0xFF /* invalid timer for comparison */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int8_t hwtimer_ini (uint8_t timer, uint8_t wgm, uint8_t clock, uint16_t maxt)
|
|
||||||
{
|
|
||||||
int8_t i;
|
|
||||||
HWT_CHECK_TIMER (timer);
|
|
||||||
if (wgm > HWT_WGM_MASK || wgm == HWT_WGM_RESERVED) {
|
|
||||||
return HWT_ERR_INVALID_WGM;
|
|
||||||
}
|
|
||||||
if (clock > HWT_CLOCK_MASK) {
|
|
||||||
return HWT_ERR_INVALID_CLOCK;
|
|
||||||
}
|
|
||||||
/* Turn off clock, no need to disable interrupt */
|
|
||||||
*HWT_TCCRB (timer) &= ~HWT_CLOCK_MASK;
|
|
||||||
|
|
||||||
*HWT_TCCRA (timer) &= ~(HWT_WGM_MASK_LOW << HWT_WGM_SHIFT_LOW);
|
|
||||||
*HWT_TCCRA (timer) |= ((wgm & HWT_WGM_MASK_LOW) << HWT_WGM_SHIFT_LOW);
|
|
||||||
*HWT_TCCRB (timer) &= ~(HWT_WGM_MASK_HIGH << HWT_WGM_SHIFT_HIGH);
|
|
||||||
*HWT_TCCRB (timer) |= ((wgm & HWT_WGM_MASK_HIGH) << HWT_WGM_SHIFT_HIGH);
|
|
||||||
|
|
||||||
for (i=0; i<3; i++) {
|
|
||||||
HWT_SET_COM (timer, i, HWT_COM_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( wgm == HWT_WGM_PWM_PHASE_FRQ_ICR
|
|
||||||
|| wgm == HWT_WGM_PWM_PHASE_ICR
|
|
||||||
|| wgm == HWT_WGM_CTC_ICR
|
|
||||||
|| wgm == HWT_WGM_PWM_FAST_ICR
|
|
||||||
)
|
|
||||||
{
|
|
||||||
*HWT_ICR (timer) = maxt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( wgm == HWT_WGM_CTC_OCRA
|
|
||||||
|| wgm == HWT_WGM_PWM_PHASE_FRQ_OCRA
|
|
||||||
|| wgm == HWT_WGM_PWM_PHASE_OCRA
|
|
||||||
|| wgm == HWT_WGM_PWM_FAST_OCRA
|
|
||||||
)
|
|
||||||
{
|
|
||||||
*HWT_OCRA (timer) = maxt;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set clock, finally */
|
|
||||||
*HWT_TCCRB (timer) |= clock;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ex:ts=8:et:sw=2
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -215,7 +215,57 @@
|
||||||
* Note that this sets the compare output mode COM registers to 0,
|
* Note that this sets the compare output mode COM registers to 0,
|
||||||
* turning off PWM on outputs.
|
* turning off PWM on outputs.
|
||||||
*/
|
*/
|
||||||
int8_t hwtimer_ini (uint8_t timer, uint8_t wgm, uint8_t clock, uint16_t maxt);
|
static inline int8_t
|
||||||
|
hwtimer_ini (uint8_t timer, uint8_t wgm, uint8_t clock, uint16_t maxt)
|
||||||
|
{
|
||||||
|
int8_t i;
|
||||||
|
HWT_CHECK_TIMER (timer);
|
||||||
|
if (wgm > HWT_WGM_MASK || wgm == HWT_WGM_RESERVED) {
|
||||||
|
return HWT_ERR_INVALID_WGM;
|
||||||
|
}
|
||||||
|
if (clock > HWT_CLOCK_MASK) {
|
||||||
|
return HWT_ERR_INVALID_CLOCK;
|
||||||
|
}
|
||||||
|
/* Turn off clock, no need to disable interrupt */
|
||||||
|
*HWT_TCCRB (timer) &= ~HWT_CLOCK_MASK;
|
||||||
|
|
||||||
|
*HWT_TCCRA (timer) &= ~(HWT_WGM_MASK_LOW << HWT_WGM_SHIFT_LOW);
|
||||||
|
*HWT_TCCRA (timer) |= ((wgm & HWT_WGM_MASK_LOW) << HWT_WGM_SHIFT_LOW);
|
||||||
|
*HWT_TCCRB (timer) &= ~(HWT_WGM_MASK_HIGH << HWT_WGM_SHIFT_HIGH);
|
||||||
|
*HWT_TCCRB (timer) |= ((wgm & HWT_WGM_MASK_HIGH) << HWT_WGM_SHIFT_HIGH);
|
||||||
|
|
||||||
|
for (i=0; i<3; i++) {
|
||||||
|
HWT_SET_COM (timer, i, HWT_COM_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wgm == HWT_WGM_PWM_PHASE_FRQ_ICR
|
||||||
|
|| wgm == HWT_WGM_PWM_PHASE_ICR
|
||||||
|
|| wgm == HWT_WGM_CTC_ICR
|
||||||
|
|| wgm == HWT_WGM_PWM_FAST_ICR
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*HWT_ICR (timer) = maxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wgm == HWT_WGM_CTC_OCRA
|
||||||
|
|| wgm == HWT_WGM_PWM_PHASE_FRQ_OCRA
|
||||||
|
|| wgm == HWT_WGM_PWM_PHASE_OCRA
|
||||||
|
|| wgm == HWT_WGM_PWM_FAST_OCRA
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*HWT_OCRA (timer) = maxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set clock, finally */
|
||||||
|
*HWT_TCCRB (timer) |= clock;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Needed for implementation */
|
||||||
|
#define HWT_PERIOD_MAX_ (0xFFFFFFFF / (F_CPU / 1000000))
|
||||||
|
/* for 16-bit timer: */
|
||||||
|
#define HWT_TICKS_MAX_ 0xFFFF
|
||||||
|
#define HWT_TICKS_MIN_ 0xFF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Convenience function to initialize hardware timer for PWM
|
* \brief Convenience function to initialize hardware timer for PWM
|
||||||
|
@ -248,8 +298,76 @@ int8_t hwtimer_ini (uint8_t timer, uint8_t wgm, uint8_t clock, uint16_t maxt);
|
||||||
* pin associated with this register can not be used for PWM. Instead it
|
* pin associated with this register can not be used for PWM. Instead it
|
||||||
* can be used to change the period.
|
* can be used to change the period.
|
||||||
*/
|
*/
|
||||||
int8_t
|
static inline int8_t
|
||||||
hwtimer_pwm_ini (uint8_t timer, uint32_t period_us, uint8_t pwm_type, uint8_t ocra);
|
hwtimer_pwm_ini (uint8_t timer, uint32_t period_us, uint8_t pwm_type, uint8_t ocra)
|
||||||
|
{
|
||||||
|
uint32_t ticks = 0;
|
||||||
|
uint8_t clock = HWT_CLOCK_PRESCALER_1024;
|
||||||
|
uint8_t wgm = HWT_WGM_NORMAL;
|
||||||
|
HWT_CHECK_TIMER (timer);
|
||||||
|
if (period_us > HWT_PERIOD_MAX_) {
|
||||||
|
period_us = HWT_PERIOD_MAX_;
|
||||||
|
}
|
||||||
|
ticks = (F_CPU / 1000000) * period_us;
|
||||||
|
/* Non-fast PWM modes have half the frequency */
|
||||||
|
if (pwm_type != HWT_PWM_FAST) {
|
||||||
|
ticks >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Divisors are 1, 8, 64, 256, 1024, shifts between these are
|
||||||
|
* 3, 3, 2, 2, respectively. We modify `ticks` in place, the AVR can
|
||||||
|
* shift only one bit in one instruction, so shifting isn't cheap.
|
||||||
|
* We try to get the *maximum* prescaler that still permits a tick
|
||||||
|
* resolution of at least 8 bit.
|
||||||
|
*/
|
||||||
|
if (ticks <= (HWT_TICKS_MIN_ << 3)) {
|
||||||
|
clock = HWT_CLOCK_PRESCALER_1;
|
||||||
|
}
|
||||||
|
else if ((ticks >>= 3) <= (HWT_TICKS_MIN_ << 3)) {
|
||||||
|
clock = HWT_CLOCK_PRESCALER_8;
|
||||||
|
}
|
||||||
|
else if ((ticks >>= 3) <= (HWT_TICKS_MIN_ << 2)) {
|
||||||
|
clock = HWT_CLOCK_PRESCALER_64;
|
||||||
|
}
|
||||||
|
else if ((ticks >>= 2) <= (HWT_TICKS_MIN_ << 2)) {
|
||||||
|
clock = HWT_CLOCK_PRESCALER_256;
|
||||||
|
}
|
||||||
|
else if ((ticks >>= 2) > HWT_TICKS_MAX_) {
|
||||||
|
ticks = HWT_TICKS_MAX_;
|
||||||
|
}
|
||||||
|
switch (pwm_type) {
|
||||||
|
case HWT_PWM_FAST:
|
||||||
|
wgm = ocra ? HWT_WGM_PWM_FAST_OCRA : HWT_WGM_PWM_FAST_ICR;
|
||||||
|
break;
|
||||||
|
case HWT_PWM_PHASE_CORRECT:
|
||||||
|
wgm = ocra ? HWT_WGM_PWM_PHASE_OCRA : HWT_WGM_PWM_PHASE_ICR;
|
||||||
|
break;
|
||||||
|
case HWT_PWM_PHASE_FRQ_CORRECT:
|
||||||
|
default:
|
||||||
|
wgm = ocra ? HWT_WGM_PWM_PHASE_FRQ_OCRA : HWT_WGM_PWM_PHASE_FRQ_ICR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Special 8- 9- 10-bit modes */
|
||||||
|
if (pwm_type == HWT_PWM_FAST || pwm_type == HWT_PWM_PHASE_CORRECT) {
|
||||||
|
if (ticks == 0xFF) {
|
||||||
|
wgm = (pwm_type == HWT_PWM_FAST)
|
||||||
|
? HWT_WGM_PWM_FAST_8_BIT
|
||||||
|
: HWT_WGM_PWM_PHASE_8_BIT;
|
||||||
|
}
|
||||||
|
else if (ticks == 0x1FF) {
|
||||||
|
wgm = (pwm_type == HWT_PWM_FAST)
|
||||||
|
? HWT_WGM_PWM_FAST_9_BIT
|
||||||
|
: HWT_WGM_PWM_PHASE_9_BIT;
|
||||||
|
}
|
||||||
|
else if (ticks == 0x3FF) {
|
||||||
|
wgm = (pwm_type == HWT_PWM_FAST)
|
||||||
|
? HWT_WGM_PWM_FAST_10_BIT
|
||||||
|
: HWT_WGM_PWM_PHASE_10_BIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hwtimer_ini (timer, wgm, clock, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simple init macro for sane default values
|
* Simple init macro for sane default values
|
||||||
|
@ -260,11 +378,42 @@ hwtimer_pwm_ini (uint8_t timer, uint32_t period_us, uint8_t pwm_type, uint8_t oc
|
||||||
/**
|
/**
|
||||||
* \brief Maximum timer value usable in hwtimer_set_pwm
|
* \brief Maximum timer value usable in hwtimer_set_pwm
|
||||||
* \param timer: Timer to use
|
* \param timer: Timer to use
|
||||||
* \return
|
* \return max. timer value according to current timer setup
|
||||||
*
|
* negative value if wrong timer given
|
||||||
*
|
* a positive value is guaranteed to fit into 16 bit unsigned.
|
||||||
*/
|
*/
|
||||||
uint32_t hwtimer_pwm_max_ticks (uint8_t timer);
|
static inline int32_t hwtimer_pwm_max_ticks (uint8_t timer)
|
||||||
|
{
|
||||||
|
uint8_t wgm = 0;
|
||||||
|
HWT_CHECK_TIMER (timer);
|
||||||
|
wgm = ((*HWT_TCCRA (timer) >> HWT_WGM_SHIFT_LOW) & HWT_WGM_MASK_LOW)
|
||||||
|
| ((*HWT_TCCRB (timer) >> HWT_WGM_SHIFT_HIGH) & HWT_WGM_MASK_HIGH)
|
||||||
|
;
|
||||||
|
switch (wgm) {
|
||||||
|
case HWT_WGM_PWM_PHASE_8_BIT:
|
||||||
|
case HWT_WGM_PWM_FAST_8_BIT:
|
||||||
|
return 0xFF;
|
||||||
|
case HWT_WGM_PWM_PHASE_9_BIT:
|
||||||
|
case HWT_WGM_PWM_FAST_9_BIT:
|
||||||
|
return 0x1FF;
|
||||||
|
case HWT_WGM_PWM_PHASE_10_BIT:
|
||||||
|
case HWT_WGM_PWM_FAST_10_BIT:
|
||||||
|
return 0x3FF;
|
||||||
|
case HWT_WGM_CTC_OCRA:
|
||||||
|
case HWT_WGM_PWM_PHASE_FRQ_OCRA:
|
||||||
|
case HWT_WGM_PWM_PHASE_OCRA:
|
||||||
|
case HWT_WGM_PWM_FAST_OCRA:
|
||||||
|
return *HWT_OCRA (timer);
|
||||||
|
case HWT_WGM_PWM_PHASE_FRQ_ICR:
|
||||||
|
case HWT_WGM_PWM_PHASE_ICR:
|
||||||
|
case HWT_WGM_CTC_ICR:
|
||||||
|
case HWT_WGM_PWM_FAST_ICR:
|
||||||
|
return *HWT_ICR (timer);
|
||||||
|
case HWT_WGM_NORMAL:
|
||||||
|
return 0xFFFF;
|
||||||
|
}
|
||||||
|
return HWT_ERR_INVALID_WGM;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following functions are defined inline to allow for compiler
|
* The following functions are defined inline to allow for compiler
|
||||||
|
|
Loading…
Reference in a new issue