This commit is contained in:
Mark Qvist 2014-04-03 22:21:37 +02:00
commit c898b090dd
1049 changed files with 288572 additions and 0 deletions

View file

@ -0,0 +1,211 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
* -->
*
* \brief ADC hardware-specific definition
*
* \author Francesco Sacchi <batt@develer.com>
*
* This module is automatically included so no need to include
* in test list.
* notest: avr
*
* $WIZ$
*/
#include "adc_avr.h"
#include "cfg/cfg_adc.h"
#include "cfg/cfg_proc.h"
#include "cfg/cfg_signal.h"
#include <cfg/macros.h>
#include <cfg/compiler.h>
#include <cpu/irq.h> // IRQ_ASSERT_ENABLED()
#include <drv/adc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
/**
* ADC voltage referencese.
*
* $WIZ$ avr_adc_refs = "ADC_AVR_AREF", "ADC_AVR_AVCC", "ADC_AVR_INT256"
* \{
*/
#define ADC_AVR_AREF 0
#define ADC_AVR_AVCC 1
#define ADC_AVR_INT256 2
/* \} */
#if CONFIG_KERN
#include <cfg/module.h>
#include <kern/proc.h>
#include <kern/signal.h>
#if !CONFIG_KERN_SIGNALS
#error Signals must be active to use the ADC with kernel
#endif
/* Signal adc convertion end */
#define SIG_ADC_COMPLETE SIG_SINGLE
/* ADC waiting process */
static struct Process *adc_process;
/**
* ADC ISR.
* Simply signal the adc process that convertion is complete.
*/
ISR(ADC_vect)
{
sig_post(adc_process, SIG_ADC_COMPLETE);
}
#endif /* CONFIG_KERN */
/**
* Select mux channel \a ch.
* \todo only first 8 channels are selectable!
*/
void adc_hw_select_ch(uint8_t ch)
{
/* Set to 0 all mux registers */
#if CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA168
ADMUX &= ~(BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
#elif CPU_AVR_ATMEGA32 || CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 \
|| CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
ADMUX &= ~(BV(MUX4) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
#if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
ADCSRB &= ~(BV(MUX5));
#endif
#else
#error Unknown CPU
#endif
/* Select channel, only first 8 channel modes are supported */
ADMUX |= (ch & 0x07);
#if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
/* Select channel, all 16 channels are supported */
if (ch > 0x07)
ADCSRB |= BV(MUX5);
#endif
}
/**
* Start an ADC convertion.
* If a kernel is present, preempt until convertion is complete, otherwise
* a busy wait on ADCS bit is done.
*/
uint16_t adc_hw_read(void)
{
// Ensure another convertion is not running.
ASSERT(!(ADCSRA & BV(ADSC)));
// Start convertion
ADCSRA |= BV(ADSC);
#if CONFIG_KERN
// Ensure IRQs enabled.
IRQ_ASSERT_ENABLED();
adc_process = proc_current();
sig_wait(SIG_ADC_COMPLETE);
#else
//Wait in polling until is done
while (ADCSRA & BV(ADSC)) ;
#endif
return(ADC);
}
/**
* Init ADC hardware.
*/
void adc_hw_init(void)
{
/*
* Select channel 0 as default,
* result right adjusted.
*/
ADMUX = 0;
#if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
/* External voltage at AREF as analog ref source */
/* None */
#elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
/* AVCC as analog ref source */
ADMUX |= BV(REFS0);
#elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
/* Internal 2.56V as ref source */
ADMUX |= BV(REFS1) | BV(REFS0);
#else
#error Unsupported ADC ref value.
#endif
#if defined(ADCSRB)
/* Disable Auto trigger source: ADC in Free running mode. */
ADCSRB = 0;
#endif
/* Enable ADC, disable autotrigger mode. */
ADCSRA = BV(ADEN);
#if CONFIG_KERN
MOD_CHECK(proc);
ADCSRA |= BV(ADIE);
#endif
/* Set convertion frequency */
#if CONFIG_ADC_AVR_DIVISOR == 2
ADCSRA |= BV(ADPS0);
#elif CONFIG_ADC_AVR_DIVISOR == 4
ADCSRA |= BV(ADPS1);
#elif CONFIG_ADC_AVR_DIVISOR == 8
ADCSRA |= BV(ADPS1) | BV(ADPS0);
#elif CONFIG_ADC_AVR_DIVISOR == 16
ADCSRA |= BV(ADPS2);
#elif CONFIG_ADC_AVR_DIVISOR == 32
ADCSRA |= BV(ADPS2) | BV(ADPS0);
#elif CONFIG_ADC_AVR_DIVISOR == 64
ADCSRA |= BV(ADPS2) | BV(ADPS1);
#elif CONFIG_ADC_AVR_DIVISOR == 128
ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
#else
#error Unsupported ADC prescaler value.
#endif
/* Start a convertion to init ADC hw */
adc_hw_read();
}

View file

@ -0,0 +1,55 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
* -->
*
* \brief ADC hardware-specific definition
*
* \author Francesco Sacchi <batt@develer.com>
*/
#ifndef DRV_ADC_AVR_H
#define DRV_ADC_AVR_H
#include <cfg/compiler.h>
#if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
/* 16 channels aivailable */
#define ADC_MUX_MAXCH 15
#else
/* only 8 channels aivailable */
#define ADC_MUX_MAXCH 7
#endif
#define ADC_BITS 10
void adc_hw_select_ch(uint8_t ch);
uint16_t adc_hw_read(void);
void adc_hw_init(void);
#endif /* DRV_ADC_AVR_H */

View file

@ -0,0 +1,178 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Self programming routines.
*
* \author Francesco Sacchi <batt@develer.com>
* \author Daniele Basile <asterix@develer.com>
*
* This module implements a kfile-like access for Atmel avr internal flash.
* Internal flash writing access is controlled by BOOTSZ fuses, check
* datasheet for details.
*/
#include "flash_avr.h"
#include "cfg/cfg_emb_flash.h"
#include <cfg/macros.h> // MIN()
#include <cfg/compiler.h>
#include <cfg/debug.h>
#include <cpu/irq.h>
// Define log settings for cfg/log.h
#define LOG_LEVEL CONFIG_FLASH_EMB_LOG_LEVEL
#define LOG_FORMAT CONFIG_FLASH_EMB_LOG_FORMAT
#include <cfg/log.h>
#include <drv/wdt.h>
#include <drv/flash.h>
#include <io/kfile.h>
#include <io/kfile_block.h>
#include <io/kblock.h>
#include <avr/io.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
#include <string.h>
struct FlashHardware;
static size_t avr_flash_readDirect(struct KBlock *blk, block_idx_t idx, void *buf, size_t offset, size_t size)
{
memcpy_P(buf, (const void *)(uint16_t)(idx * blk->blk_size + offset), size);
return blk->blk_size;
}
static size_t avr_flash_writeDirect(struct KBlock *blk, block_idx_t idx, const void *_buf, size_t offset, size_t size)
{
ASSERT(offset == 0);
ASSERT(size == blk->blk_size);
uint32_t page_addr = idx * blk->blk_size;
uint32_t addr = idx * blk->blk_size;
const uint8_t *buf = (const uint8_t *)_buf;
/* Wait while the SPM instruction is busy. */
boot_spm_busy_wait();
/* Fill the temporary buffer of the AVR */
while (size)
{
uint16_t data = ((*buf + 1) << 8) | *buf;
ATOMIC(boot_page_fill(addr, data));
buf += 2;
size -= 2;
addr += 2;
}
wdt_reset();
/* Page erase */
ATOMIC(boot_page_erase(page_addr));
/* Wait until the memory is erased. */
boot_spm_busy_wait();
/* Store buffer in flash page. */
ATOMIC(boot_page_write(page_addr));
/* Wait while the SPM instruction is busy. */
boot_spm_busy_wait();
/*
* Reenable RWW-section again. We need this if we want to jump back
* to the application after bootloading.
*/
ATOMIC(boot_rww_enable());
return blk->blk_size;
}
static int avr_flash_dummy(UNUSED_ARG(struct KBlock, *blk))
{
return 0;
}
static const KBlockVTable flash_avr_buffered_vt =
{
.readDirect = avr_flash_readDirect,
.writeDirect = avr_flash_writeDirect,
.readBuf = kblock_swReadBuf,
.writeBuf = kblock_swWriteBuf,
.load = kblock_swLoad,
.store = kblock_swStore,
.error = avr_flash_dummy,
.clearerr = (kblock_clearerr_t)avr_flash_dummy,
};
static const KBlockVTable flash_avr_unbuffered_vt =
{
.readDirect = avr_flash_readDirect,
.writeDirect = avr_flash_writeDirect,
.error = avr_flash_dummy,
.clearerr = (kblock_clearerr_t)avr_flash_dummy,
};
static uint8_t flash_buf[SPM_PAGESIZE];
static void common_init(Flash *fls)
{
memset(fls, 0, sizeof(*fls));
DB(fls->blk.priv.type = KBT_FLASH);
fls->blk.blk_size = SPM_PAGESIZE;
fls->blk.blk_cnt = (FLASHEND + 1) / SPM_PAGESIZE;
}
void flash_hw_init(Flash *fls, UNUSED_ARG(int, flags))
{
common_init(fls);
fls->blk.priv.vt = &flash_avr_buffered_vt;
fls->blk.priv.flags |= KB_BUFFERED | KB_PARTIAL_WRITE;
fls->blk.priv.buf = flash_buf;
}
void flash_hw_initUnbuffered(Flash *fls, UNUSED_ARG(int, flags))
{
common_init(fls);
fls->blk.priv.vt = &flash_avr_unbuffered_vt;
}

View file

@ -0,0 +1,51 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \author Francesco Sacchi <batt@develer.com>
* \author Daniele Basile <asterix@develer.com>
*
* \brief AVR Internal flash read/write driver.
*/
#ifndef FLASH_AVR_H
#define FLASH_AVR_H
#include "cfg/cfg_emb_flash.h"
#if !CONFIG_FLASH_DISABLE_OLD_API
/* For backwards compatibility */
#define FlashAvr Flash
#define flash_avr_init(fls) flash_init(fls);
#endif /* !CONFIG_FLASH_DISABLE_OLD_API */
#endif /* DRV_FLASH_AVR_H */

View file

@ -0,0 +1,411 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Driver for the AVR ATMega TWI (implementation)
*
* \author Stefano Fedrigo <aleph@develer.com>
* \author Bernie Innocenti <bernie@codewiz.org>
* \author Daniele Basile <asterix@develer.com>
*/
#include "cfg/cfg_i2c.h"
#include <hw/hw_cpufreq.h> /* CPU_FREQ */
#define LOG_LEVEL I2C_LOG_LEVEL
#define LOG_FORMAT I2C_LOG_FORMAT
#include <cfg/log.h>
#include <cfg/debug.h>
#include <cfg/macros.h> // BV()
#include <cfg/module.h>
#include <cpu/detect.h>
#include <cpu/irq.h>
#include <drv/timer.h>
#include <drv/i2c.h>
#include <cpu/power.h>
#include <compat/twi.h>
#if !CONFIG_I2C_DISABLE_OLD_API
/* Wait for TWINT flag set: bus is ready */
#define WAIT_TWI_READY do {} while (!(TWCR & BV(TWINT)))
/**
* Send START condition on the bus.
*
* \return true on success, false otherwise.
*/
static bool i2c_builtin_start(void)
{
TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN);
WAIT_TWI_READY;
if (TW_STATUS == TW_START || TW_STATUS == TW_REP_START)
return true;
LOG_ERR("!TW_(REP)START: %x\n", TWSR);
return false;
}
/**
* Send START condition and select slave for write.
* \c id is the device id comprehensive of address left shifted by 1.
* The LSB of \c id is ignored and reset to 0 for write operation.
*
* \return true on success, false otherwise.
*/
bool i2c_builtin_start_w(uint8_t id)
{
/*
* Loop on the select write sequence: when the eeprom is busy
* writing previously sent data it will reply to the SLA_W
* control byte with a NACK. In this case, we must
* keep trying until the eeprom responds with an ACK.
*/
ticks_t start = timer_clock();
while (i2c_builtin_start())
{
TWDR = id & ~I2C_READBIT;
TWCR = BV(TWINT) | BV(TWEN);
WAIT_TWI_READY;
if (TW_STATUS == TW_MT_SLA_ACK)
return true;
else if (TW_STATUS != TW_MT_SLA_NACK)
{
LOG_ERR("!TW_MT_SLA_(N)ACK: %x\n", TWSR);
break;
}
else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
{
LOG_ERR("Timeout on TWI_MT_START\n");
break;
}
}
return false;
}
/**
* Send START condition and select slave for read.
* \c id is the device id comprehensive of address left shifted by 1.
* The LSB of \c id is ignored and set to 1 for read operation.
*
* \return true on success, false otherwise.
*/
bool i2c_builtin_start_r(uint8_t id)
{
if (i2c_builtin_start())
{
TWDR = id | I2C_READBIT;
TWCR = BV(TWINT) | BV(TWEN);
WAIT_TWI_READY;
if (TW_STATUS == TW_MR_SLA_ACK)
return true;
LOG_ERR("!TW_MR_SLA_ACK: %x\n", TWSR);
}
return false;
}
/**
* Send STOP condition.
*/
void i2c_builtin_stop(void)
{
TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO);
}
/**
* Put a single byte in master transmitter mode
* to the selected slave device through the TWI bus.
*
* \return true on success, false on error.
*/
bool i2c_builtin_put(const uint8_t data)
{
TWDR = data;
TWCR = BV(TWINT) | BV(TWEN);
WAIT_TWI_READY;
if (TW_STATUS != TW_MT_DATA_ACK)
{
LOG_ERR("!TW_MT_DATA_ACK: %x\n", TWSR);
return false;
}
return true;
}
/**
* Get 1 byte from slave in master transmitter mode
* to the selected slave device through the TWI bus.
* If \a ack is true issue a ACK after getting the byte,
* otherwise a NACK is issued.
*
* \return the byte read if ok, EOF on errors.
*/
int i2c_builtin_get(bool ack)
{
TWCR = BV(TWINT) | BV(TWEN) | (ack ? BV(TWEA) : 0);
WAIT_TWI_READY;
if (ack)
{
if (TW_STATUS != TW_MR_DATA_ACK)
{
LOG_ERR("!TW_MR_DATA_ACK: %x\n", TWSR);
return EOF;
}
}
else
{
if (TW_STATUS != TW_MR_DATA_NACK)
{
LOG_ERR("!TW_MR_DATA_NACK: %x\n", TWSR);
return EOF;
}
}
/* avoid sign extension */
return (int)(uint8_t)TWDR;
}
#endif /* !CONFIG_I2C_DISABLE_OLD_API */
/*
* New Api
*/
struct I2cHardware
{
};
/* Wait for TWINT flag set: bus is ready */
#define WAIT_READY() \
do { \
while (!(TWCR & BV(TWINT))) \
cpu_relax(); \
} while (0)
/**
* Send START condition on the bus.
*/
INLINE bool i2c_hw_start(void)
{
TWCR = BV(TWINT) | BV(TWSTA) | BV(TWEN);
WAIT_READY();
if (TW_STATUS == TW_START || TW_STATUS == TW_REP_START)
return true;
return false;
}
/**
* Send STOP condition.
*/
INLINE void i2c_hw_stop(void)
{
TWCR = BV(TWINT) | BV(TWEN) | BV(TWSTO);
}
static void i2c_avr_start(I2c *i2c, uint16_t slave_addr)
{
/*
* Loop on the select write sequence: when the eeprom is busy
* writing previously sent data it will reply to the SLA_W
* control byte with a NACK. In this case, we must
* keep trying until the slave responds with an ACK.
*/
ticks_t start = timer_clock();
while (i2c_hw_start())
{
uint8_t sla_ack = 0;
uint8_t sla_nack = 0;
if (I2C_TEST_START(i2c->flags) == I2C_START_W)
{
TWDR = slave_addr & ~I2C_READBIT;
sla_ack = TW_MT_SLA_ACK;
sla_nack = TW_MT_SLA_NACK;
}
else
{
TWDR = slave_addr | I2C_READBIT;
sla_ack = TW_MR_SLA_ACK;
sla_nack = TW_MR_SLA_NACK;
}
TWCR = BV(TWINT) | BV(TWEN);
WAIT_READY();
if (TW_STATUS == sla_ack)
return;
else if (TW_STATUS != sla_nack)
{
LOG_ERR("Start addr NACK[%x]\n", TWSR);
i2c->errors |= I2C_NO_ACK;
i2c_hw_stop();
break;
}
else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
{
LOG_ERR("Start timeout\n");
i2c->errors |= I2C_START_TIMEOUT;
i2c_hw_stop();
break;
}
}
LOG_ERR("I2c error\n");
i2c->errors |= I2C_ERR;
i2c_hw_stop();
}
static void i2c_avr_putc(I2c *i2c, const uint8_t data)
{
TWDR = data;
TWCR = BV(TWINT) | BV(TWEN);
WAIT_READY();
if (TW_STATUS != TW_MT_DATA_ACK)
{
LOG_ERR("Data nack[%x]\n", TWSR);
i2c->errors |= I2C_DATA_NACK;
i2c_hw_stop();
}
if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP))
i2c_hw_stop();
}
static uint8_t i2c_avr_getc(I2c *i2c)
{
uint8_t data_flag = 0;
if (i2c->xfer_size == 1)
{
TWCR = BV(TWINT) | BV(TWEN);
data_flag = TW_MR_DATA_NACK;
}
else
{
TWCR = BV(TWINT) | BV(TWEN) | BV(TWEA);
data_flag = TW_MR_DATA_ACK;
}
WAIT_READY();
if (TW_STATUS != data_flag)
{
LOG_ERR("Data nack[%x]\n", TWSR);
i2c->errors |= I2C_DATA_NACK;
i2c_hw_stop();
return 0xFF;
}
uint8_t data = TWDR;
if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP))
i2c_hw_stop();
return data;
}
static const I2cVT i2c_avr_vt =
{
.start = i2c_avr_start,
.getc = i2c_avr_getc,
.putc = i2c_avr_putc,
.write = i2c_genericWrite,
.read = i2c_genericRead,
};
struct I2cHardware i2c_avr_hw[] =
{
{ /* I2C0 */
},
};
/**
* Initialize I2C module.
*/
void i2c_hw_init(I2c *i2c, int dev, uint32_t clock)
{
i2c->hw = &i2c_avr_hw[dev];
i2c->vt = &i2c_avr_vt;
ATOMIC(
/*
* This is pretty useless according to AVR's datasheet,
* but it helps us driving the TWI data lines on boards
* where the bus pull-up resistors are missing. This is
* probably due to some unwanted interaction between the
* port pin and the TWI lines.
*/
#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
PORTD |= BV(PD0) | BV(PD1);
DDRD |= BV(PD0) | BV(PD1);
#elif CPU_AVR_ATMEGA8
PORTC |= BV(PC4) | BV(PC5);
DDRC |= BV(PC4) | BV(PC5);
#elif CPU_AVR_ATMEGA32
PORTC |= BV(PC1) | BV(PC0);
DDRC |= BV(PC1) | BV(PC0);
#else
#error Unsupported architecture
#endif
/*
* Set speed:
* F = CPU_FREQ / (16 + 2*TWBR * 4^TWPS)
*/
ASSERT(clock);
#define TWI_PRESC 1 /* 4 ^ TWPS */
TWBR = (CPU_FREQ / (2 * clock * TWI_PRESC)) - (8 / TWI_PRESC);
TWSR = 0;
TWCR = BV(TWEN);
);
}

View file

@ -0,0 +1,54 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2010 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Driver for the AVR ATMega TWI (implementation)
*
* \author Daniele Basile <asterix@develer.com>
*/
#ifndef I2C_AVR_H
#define I2C_AVR_H
#include <drv/i2c.h>
/**
* \name I2C devices enum
*/
enum
{
I2C0,
I2C_CNT /**< Number of serial ports */
};
#endif /* I2C_LM3S_H */

View file

@ -0,0 +1,47 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2011 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
*
* \author Luca Ottaviano <lottaviano@develer.com>
*
* \brief Low-level kdebug module for AVR (inplementation).
*/
#include <cpu/detect.h>
#if CPU_AVR_MEGA
#include "kdebug_mega.c"
#elif CPU_AVR_XMEGA
#include "kdebug_xmega.c"
#else
#error Unknown CPU
#endif

View file

@ -0,0 +1,384 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000, 2001, 2002 Bernie Innocenti <bernie@codewiz.org>
*
* -->
*
* \brief AVR debug support (implementation).
*
* \author Bernie Innocenti <bernie@codewiz.org>
* \author Stefano Fedrigo <aleph@develer.com>
* \author Francesco Sacchi <batt@develer.com>
*/
#include <hw/hw_cpufreq.h> /* for CPU_FREQ */
#include "hw/hw_ser.h" /* Required for bus macros overrides */
#include "cfg/cfg_debug.h"
#include <cfg/macros.h> /* for BV(), DIV_ROUND */
#include <cpu/types.h>
#include <cpu/attr.h>
#include <avr/io.h>
#if CONFIG_KDEBUG_PORT == 0
/*
* Support for special bus policies or external transceivers
* on UART0 (to be overridden in "hw/hw_ser.h").
*
* HACK: if we don't set TXEN, kdbg disables the transmitter
* after each output statement until the serial driver
* is initialized. These glitches confuse the debug
* terminal that ends up printing some trash.
*/
#ifndef KDBG_UART0_BUS_INIT
#define KDBG_UART0_BUS_INIT do { \
UCR = BV(TXEN0); \
} while (0)
#endif
#ifndef KDBG_UART0_BUS_RX
#define KDBG_UART0_BUS_RX do {} while (0)
#endif
#ifndef KDBG_UART0_BUS_TX
#define KDBG_UART0_BUS_TX do {} while (0)
#endif
#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 \
|| CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA2560
#define UCR UCSR0B
#define UDR UDR0
#define USR UCSR0A
#elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32
#define UCR UCSRB
#define USR UCSRA
#define TXEN0 TXEN
#define UDRE0 UDRE
#define TXC0 TXC
#define TXCIE0 TXCIE
#define UDRIE0 UDRIE
#else
#error Unknown CPU
#endif
#define KDBG_WAIT_READY() do { loop_until_bit_is_set(USR, UDRE0); } while(0)
#define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(USR, TXC0); } while(0)
/*
* We must clear the TXC flag before sending a new character to allow
* KDBG_WAIT_TXDONE() to work properly.
*
* BUG: if KDBG_WRITE_CHAR() is called after the TXC flag is set by hardware,
* a new TXC could be generated after we've cleared it and before the new
* character is written to UDR. On a 485 bus, the transceiver will be put
* in RX mode while still transmitting the last char.
*/
#define KDBG_WRITE_CHAR(c) do { USR |= BV(TXC0); UDR = (c); } while(0)
#define KDBG_MASK_IRQ(old) do { \
(old) = UCR; \
UCR |= BV(TXEN0); \
UCR &= ~(BV(TXCIE0) | BV(UDRIE0)); \
KDBG_UART0_BUS_TX; \
} while(0)
#define KDBG_RESTORE_IRQ(old) do { \
KDBG_WAIT_TXDONE(); \
KDBG_UART0_BUS_RX; \
UCR = (old); \
} while(0)
typedef uint8_t kdbg_irqsave_t;
#elif CONFIG_KDEBUG_PORT == 1
/*
* Support for special bus policies or external transceivers
* on UART1 (to be overridden in "hw/hw_ser.h").
*
* HACK: if we don't set TXEN, kdbg disables the transmitter
* after each output statement until the serial driver
* is initialized. These glitches confuse the debug
* terminal that ends up printing some trash.
*/
#ifndef KDBG_UART1_BUS_INIT
#define KDBG_UART1_BUS_INIT do { \
UCSR1B = BV(TXEN1); \
} while (0)
#endif
#ifndef KDBG_UART1_BUS_RX
#define KDBG_UART1_BUS_RX do {} while (0)
#endif
#ifndef KDBG_UART1_BUS_TX
#define KDBG_UART1_BUS_TX do {} while (0)
#endif
#define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR1A, UDRE1); } while(0)
#define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR1A, TXC1); } while(0)
#define KDBG_WRITE_CHAR(c) do { UCSR1A |= BV(TXC1); UDR1 = (c); } while(0)
#define KDBG_MASK_IRQ(old) do { \
(old) = UCSR1B; \
UCSR1B |= BV(TXEN1); \
UCSR1B &= ~(BV(TXCIE1) | BV(UDRIE1)); \
KDBG_UART1_BUS_TX; \
} while(0)
#define KDBG_RESTORE_IRQ(old) do { \
KDBG_WAIT_TXDONE(); \
KDBG_UART1_BUS_RX; \
UCSR1B = (old); \
} while(0)
typedef uint8_t kdbg_irqsave_t;
#elif CONFIG_KDEBUG_PORT == 2
/*
* Support for special bus policies or external transceivers
* on UART2 (to be overridden in "hw/hw_ser.h").
*
* HACK: if we don't set TXEN, kdbg disables the transmitter
* after each output statement until the serial driver
* is initialized. These glitches confuse the debug
* terminal that ends up printing some trash.
*/
#ifndef KDBG_UART2_BUS_INIT
#define KDBG_UART2_BUS_INIT do { \
UCSR2B = BV(TXEN2); \
} while (0)
#endif
#ifndef KDBG_UART2_BUS_RX
#define KDBG_UART2_BUS_RX do {} while (0)
#endif
#ifndef KDBG_UART2_BUS_TX
#define KDBG_UART2_BUS_TX do {} while (0)
#endif
#define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR2A, UDRE2); } while(0)
#define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR2A, TXC2); } while(0)
#define KDBG_WRITE_CHAR(c) do { UCSR2A |= BV(TXC2); UDR2 = (c); } while(0)
#define KDBG_MASK_IRQ(old) do { \
(old) = UCSR2B; \
UCSR2B |= BV(TXEN2); \
UCSR2B &= ~(BV(TXCIE2) | BV(UDRIE2)); \
KDBG_UART2_BUS_TX; \
} while(0)
#define KDBG_RESTORE_IRQ(old) do { \
KDBG_WAIT_TXDONE(); \
KDBG_UART2_BUS_RX; \
UCSR2B = (old); \
} while(0)
typedef uint8_t kdbg_irqsave_t;
#elif CONFIG_KDEBUG_PORT == 3
/*
* Support for special bus policies or external transceivers
* on UART3 (to be overridden in "hw/hw_ser.h").
*
* HACK: if we don't set TXEN, kdbg disables the transmitter
* after each output statement until the serial driver
* is initialized. These glitches confuse the debug
* terminal that ends up printing some trash.
*/
#ifndef KDBG_UART3_BUS_INIT
#define KDBG_UART3_BUS_INIT do { \
UCSR3B = BV(TXEN3); \
} while (0)
#endif
#ifndef KDBG_UART3_BUS_RX
#define KDBG_UART3_BUS_RX do {} while (0)
#endif
#ifndef KDBG_UART3_BUS_TX
#define KDBG_UART3_BUS_TX do {} while (0)
#endif
#define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR3A, UDRE3); } while(0)
#define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR3A, TXC3); } while(0)
#define KDBG_WRITE_CHAR(c) do { UCSR3A |= BV(TXC3); UDR3 = (c); } while(0)
#define KDBG_MASK_IRQ(old) do { \
(old) = UCSR3B; \
UCSR3B |= BV(TXEN3); \
UCSR3B &= ~(BV(TXCIE3) | BV(UDRIE3)); \
KDBG_UART3_BUS_TX; \
} while(0)
#define KDBG_RESTORE_IRQ(old) do { \
KDBG_WAIT_TXDONE(); \
KDBG_UART3_BUS_RX; \
UCSR3B = (old); \
} while(0)
typedef uint8_t kdbg_irqsave_t;
/*
* Special debug port for BitBanged Serial see below for details...
*/
#elif CONFIG_KDEBUG_PORT == 666
#include "hw/hw_ser.h"
#define KDBG_WAIT_READY() do { /*nop*/ } while(0)
#define KDBG_WRITE_CHAR(c) _kdebug_bitbang_putchar((c))
#define KDBG_MASK_IRQ(old) do { IRQ_SAVE_DISABLE((old)); } while(0)
#define KDBG_RESTORE_IRQ(old) do { IRQ_RESTORE((old)); } while(0)
typedef cpu_flags_t kdbg_irqsave_t;
#define KDBG_DELAY (((CPU_FREQ + CONFIG_KDEBUG_BAUDRATE / 2) / CONFIG_KDEBUG_BAUDRATE) + 7) / 14
static void _kdebug_bitbang_delay(void)
{
unsigned long i;
for (i = 0; i < KDBG_DELAY; i++)
{
NOP;
NOP;
NOP;
NOP;
NOP;
}
}
/**
* Putchar for BITBANG serial debug console.
* Sometimes, we can't permit to use a whole serial for debugging purpose.
* Since debug console is in output only it is useful to use a single generic I/O pin for debug.
* This is achieved by this simple function, that shift out the data like a UART, but
* in software :)
* The only requirement is that SER_BITBANG_* macros will be defined somewhere (usually hw_ser.h)
* \note All interrupts are disabled during debug prints!
*/
static void _kdebug_bitbang_putchar(char c)
{
int i;
uint16_t data = c;
/* Add stop bit */
data |= 0x0100;
/* Add start bit*/
data <<= 1;
/* Shift out data */
uint16_t shift = 1;
for (i = 0; i < 10; i++)
{
if (data & shift)
SER_BITBANG_HIGH;
else
SER_BITBANG_LOW;
_kdebug_bitbang_delay();
shift <<= 1;
}
}
#else
#error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 666
#endif
INLINE void kdbg_hw_init(void)
{
#if CONFIG_KDEBUG_PORT == 666
SER_BITBANG_INIT;
#else /* CONFIG_KDEBUG_PORT != 666 */
/* Compute the baud rate */
uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1;
#if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281)
#if CONFIG_KDEBUG_PORT == 0
UBRR0H = (uint8_t)(period>>8);
UBRR0L = (uint8_t)period;
KDBG_UART0_BUS_INIT;
#elif CONFIG_KDEBUG_PORT == 1
UBRR1H = (uint8_t)(period>>8);
UBRR1L = (uint8_t)period;
KDBG_UART1_BUS_INIT;
#else
#error CONFIG_KDEBUG_PORT must be either 0 or 1
#endif
#elif CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
#if CONFIG_KDEBUG_PORT == 0
UBRR0H = (uint8_t)(period>>8);
UBRR0L = (uint8_t)period;
KDBG_UART0_BUS_INIT;
#elif CONFIG_KDEBUG_PORT == 1
UBRR1H = (uint8_t)(period>>8);
UBRR1L = (uint8_t)period;
KDBG_UART1_BUS_INIT;
#elif CONFIG_KDEBUG_PORT == 2
UBRR2H = (uint8_t)(period>>8);
UBRR2L = (uint8_t)period;
KDBG_UART2_BUS_INIT;
#elif CONFIG_KDEBUG_PORT == 3
UBRR3H = (uint8_t)(period>>8);
UBRR3L = (uint8_t)period;
KDBG_UART3_BUS_INIT;
#else
#error CONFIG_KDEBUG_PORT must be either 0 or 1 or 2 or 3
#endif
#elif CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P
#if CONFIG_KDEBUG_PORT == 0
UBRR0H = (uint8_t)(period>>8);
UBRR0L = (uint8_t)period;
UCSR0A = 0; /* The Arduino Uno bootloader turns on U2X0 */
KDBG_UART0_BUS_INIT;
#else
#error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu
#endif
#elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32
#if CONFIG_KDEBUG_PORT == 0
UBRRH = (uint8_t)(period>>8);
UBRRL = (uint8_t)period;
KDBG_UART0_BUS_INIT;
#else
#error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu
#endif
#elif CPU_AVR_ATMEGA103
#if CONFIG_KDEBUG_PORT == 0
UBRR = (uint8_t)period;
KDBG_UART0_BUS_INIT;
#else
#error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu
#endif
#else
#error Unknown CPU
#endif
#endif /* CONFIG_KDEBUG_PORT == 666 */
}

View file

@ -0,0 +1,212 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000, 2001, 2002 Bernie Innocenti <bernie@codewiz.org>
* Copyright 2011 Onno <developer@gorgoz.org>
*
* -->
*
* \brief AVR XMega debug support (implementation).
*
* This file is heavily inspired by the AVR implementation for BeRTOS,
* but uses a different approach for implementing the different debug
* ports, by using the USART_t structs.
*
* \author Onno <developer@gorgoz.org>
* notest:all
*/
#include <hw/hw_cpufreq.h> /* for CPU_FREQ */
#include "hw/hw_ser.h" /* Required for bus macros overrides */
#include "cfg/cfg_debug.h" /* for debugging configuration settings */
#include <cfg/macros.h> /* for BV(), DIV_ROUND */
#include <cpu/types.h>
#include <cpu/attr.h>
#include <avr/io.h>
/* Set KDBG_USART, KDBG_USART_PORT and KDBG_USART_TX_PIN_bm
* according to the CONFIG_KDEBUG_PORT setting
* The Xmega A and D families support at least 2 UARTS
*/
#if CONFIG_KDEBUG_PORT == 0
#define KDBG_USART USARTC0
#define KDBG_USART_PORT PORTC
#define KDBG_USART_TX_PIN_bm PIN3_bm
#elif CONFIG_KDEBUG_PORT == 1
#define KDBG_USART USARTD0
#define KDBG_USART_PORT PORTD
#define KDBG_USART_TX_PIN_bm PIN3_bm
#endif
/* Allow the configuration of the extra 3 UARTS for the
* Xmega A family
*/
#ifdef CPU_AVR_XMEGA_A
#if CONFIG_KDEBUG_PORT == 2
#define KDBG_USART USARTC1
#define KDBG_USART_PORT PORTC
#define KDBG_USART_TX_PIN_bm PIN7_bm
#elif CONFIG_KDEBUG_PORT == 3
#define KDBG_USART USARTD1
#define KDBG_USART_PORT PORTD
#define KDBG_USART_TX_PIN_bm PIN7_bm
#elif CONFIG_KDEBUG_PORT == 4
#define KDBG_USART USARTE0
#define KDBG_USART_PORT PORTE
#define KDBG_USART_TX_PIN_bm PIN3_bm
#endif
#endif
/* Check if all required KDBG_ macros are defined
*/
#ifndef KDBG_USART
#if CPU_AVR_XMEGA_D
#error CONFIG_KDEBUG_PORT should be either 0 or 1
#elif CPU_AVR_XMEGA_A
#error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 4
#endif
#endif
/*
* Scalefactor to use for computing the baudrate
* this scalefactor should be an integer value between -7
* and 7
*/
#ifndef KDBG_USART_SCALE_FACTOR
#define KDBG_USART_SCALE_FACTOR (-7)
#else
#if KDBG_USART_SCALE_FACTOR > 7 || KDBG_USART_SCALE_FACTOR < -7
#error KDBG_USART_SCALE_FACTOR should be an integer between -7 and 7
#endif
#endif
/*
* \name KDBG macros
*
* Used to set or alter the KDB_USART operation,
* enable the usart or send a byte.
* Some of these methods are called/included from kdbg_hw_init()
* others are called/included from the cpu independ kdebug implementation
* These macros are heavily imspired by the examples provided by atmel
*
* \{
*/
#define KDBG_SET_FORMAT(_charSize, _parityMode, _twoStopBits) \
(KDBG_USART).CTRLC = (uint8_t) _charSize | _parityMode | \
(_twoStopBits ? USART_SBMODE_bm : 0)
#define KDBG_SET_BAUDRATE(_bselValue, _bScaleFactor) \
(KDBG_USART).BAUDCTRLA =(uint8_t)_bselValue; \
(KDBG_USART).BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
#define KDBG_TX_ENABLE() ((KDBG_USART).CTRLB |= USART_TXEN_bm)
#define KDBG_SET_MODE(_usartMode) \
((KDBG_USART).CTRLC = ((KDBG_USART).CTRLC & (~USART_CMODE_gm)) | _usartMode)
#define KDBG_WAIT_READY() do{ loop_until_bit_is_set((KDBG_USART).STATUS, USART_DREIF_bp); } while(0)
#define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set((KDBG_USART).STATUS, USART_TXCIF_bp); } while(0)
#define KDBG_WRITE_CHAR(c) do { (KDBG_USART).DATA = (c); } while(0)
#define KDBG_SET_TX_INTERRUPTLEVEL(_txdIntLevel) \
(KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
#define KDBG_SET_DRE_INTERRUPTLEVEL(_dreIntLevel) \
(KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
/*\}*/
/*
* To restore the USART state, to registers need to be restored
* These registers (CTRLA and CTRLB) can be saved to the
* kdbg_avr_xmaga_irqsave structure
*/
struct kdbg_avr_xmega_irqsave
{
uint8_t ctrlb;
uint8_t ctrla;
};
typedef struct kdbg_avr_xmega_irqsave kdbg_irqsave_t;
/*
* param is the kdbg_irqsave_t structure
*
* * Stores the current state of the USART.CTRLA and
* the USART.CTRLB registers
* * Disables Transmit Complete and Date Register Empty interrupts
* * Enabled the transmitter
*/
#define KDBG_MASK_IRQ(old) do { \
(old).ctrlb = KDBG_USART.CTRLB; \
(old).ctrla = KDBG_USART.CTRLA; \
KDBG_SET_TX_INTERRUPTLEVEL(USART_TXCINTLVL_OFF_gc); \
KDBG_SET_DRE_INTERRUPTLEVEL(USART_DREINTLVL_OFF_gc); \
KDBG_TX_ENABLE(); \
} while(0)
/*
* param is the kdbg_irqsave_t structure
*
* * waits until all data has been transmitted
* * restores the USART.CTRLA and USART.CTRLB registers
*/
#define KDBG_RESTORE_IRQ(old) do { \
KDBG_WAIT_TXDONE(); \
KDBG_USART.CTRLB = (old).ctrlb; \
KDBG_USART.CTRLA = (old).ctrla; \
} while(0)
/*
* method included from the cpu independent kdebug.c file.
* it initializes KDBG_USART by:
* * Setting the KDBG_USART_TX_PIN_bm as an outputpin
* * Setting KDBG_USART to use 8 bits, No parity, 1 stopbit
* * Setting the baudrate to 115200
* * Enabeling the transmitter
*/
INLINE void kdbg_hw_init(void)
{
//set transmit pin as output
KDBG_USART_PORT.OUT = KDBG_USART_PORT.OUT & ~KDBG_USART_TX_PIN_bm;
KDBG_USART_PORT.DIRSET = KDBG_USART_TX_PIN_bm;
//set 8 bits, no parity, 1 stop bit
KDBG_SET_FORMAT(USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
//compute and set the baud rate
/* Compute baud-rate period, this requires a valid USART_SCALE_FACTOR */
#if KDBG_USART_SCALE_FACTOR < 0
uint16_t bsel = DIV_ROUND((1 << (-(KDBG_USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * CONFIG_KDEBUG_BAUDRATE)), 16 * CONFIG_KDEBUG_BAUDRATE);
#else
uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (KDBG_USART_SCALE_FACTOR)) * 16 * CONFIG_KDEBUG_BAUDRATE) - 1;
#endif
KDBG_SET_BAUDRATE(bsel, KDBG_USART_SCALE_FACTOR);
//enable the Transmitter
KDBG_TX_ENABLE();
}

View file

@ -0,0 +1,159 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Low-level PWM module for AVR (inplementation).
*
*
* \author Daniele Basile <asterix@develer.com>
*
*/
#include "pwm_avr.h"
#include <hw/hw_cpufreq.h>
#warning TODO:This is an exmple of implementation of PWM low level channel for AVR, implemnt it!
/**
* Set PWM polarity to select pwm channel
*/
void pwm_hw_setPolarity(PwmDev dev, bool pol)
{
/*
* Put here a code to PWM polarity of select
* PWM channel
*/
//Only for test remove when implement this function
(void)dev;
(void)pol;
}
/**
* Get preiod from select channel
*
* \a dev channel
*/
pwm_period_t pwm_hw_getPeriod(PwmDev dev)
{
/*
* Put here a code to get period value of select
* PWM channel
*/
//Only for test remove when implement this function
(void)dev;
return 0;
}
/**
* Set pwm waveform frequecy.
*
* \a freq in Hz
*/
void pwm_hw_setFrequency(PwmDev dev, uint32_t freq)
{
/*
* Put here a code to set frequency of select
* PWM channel
*/
//Only for test remove when implement this function
(void)dev;
(void)freq;
}
/**
* Set pwm duty cycle.
*
* \a duty value 0 - 2^16
*/
void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty)
{
/*
* Put here a code to set duty of select
* PWM channel
*/
//Only for test remove when implement this function
(void)dev;
(void)duty;
}
/**
* Enable select pwm channel
*/
void pwm_hw_enable(PwmDev dev)
{
/*
* Put here a code to enable
* a select PWM channel
*/
//Only for test remove when implement this function
(void)dev;
}
/**
* Disable select pwm channel
*/
void pwm_hw_disable(PwmDev dev)
{
/*
* Put here a code to disable
* a select PWM channel
*/
//Only for test remove when implement this function
(void)dev;
}
/**
* Init pwm.
*/
void pwm_hw_init(void)
{
/*
* Put here a code to init
* a PWM hawdware
*/
}

View file

@ -0,0 +1,72 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Low-level PWM module for AVR (interface).
*
*
* \author Daniele Basile <asterix@develer.com>
*
*/
#ifndef DRV_PWM_AVR_H
#define DRV_PWM_AVR_H
#include "hw/pwm_map.h"
#include <cpu/types.h>
#define PWM_HW_MAX_PRESCALER_STEP 10
#define PWM_HW_MAX_PERIOD 0xFFFF
/**
* Type definition for pwm period.
*/
typedef uint16_t pwm_period_t;
/**
* Structur definition for pwm driver.
*/
typedef struct PwmChannel
{
/* */
} PwmChannel;
void pwm_hw_init(void);
void pwm_hw_setFrequency(PwmDev dev, uint32_t freq);
void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty);
void pwm_hw_disable(PwmDev dev);
void pwm_hw_enable(PwmDev dev);
void pwm_hw_setPolarity(PwmDev dev, bool pol);
pwm_period_t pwm_hw_getPeriod(PwmDev dev);
#endif /* DRV_ADC_AT91_H */

View file

@ -0,0 +1,56 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
*
* -->
*
* \brief AVR UART and SPI I/O driver (Implementation)
*
* \author Onno <developer@gorgoz.org>
*
* This module is automatically included so no need to include
* in test list.
* notest: avr
*/
#ifndef WIZ_AUTOGEN
#warning This file is deprecated, you should probably use ser_mega.c
#include <cpu/detect.h>
#if CPU_AVR_MEGA
#include "ser_mega.c"
#elif CPU_AVR_XMEGA
#include "ser_xmega.c"
/*#elif Add other AVR families here */
#else
#error Unknown CPU
#endif
#endif /* WIZ_AUTOGEN */

View file

@ -0,0 +1,53 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007, 2010 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
*
* \author Onno <developer@gorgoz.org>
*
* \brief Low-level serial module for AVR (interface).
*
*/
#ifndef SER_AVR_H_
#define SER_AVR_H_
#include <cpu/detect.h>
#if CPU_AVR_MEGA
#include "ser_mega.h"
#elif CPU_AVR_XMEGA
#include "ser_xmega.h"
/*#elif Add other AVR families here */
#else
#error Unknown CPU
#endif
#endif /* SER_AVR_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007, 2010 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
*
* \author Daniele Basile <asterix@develer.com>
* \author Luca Ottaviano <lottaviano@develer.com>
*
* \brief Low-level serial module for AVR MEGA(interface).
*
*/
#ifndef DRV_SER_MEGA_H
#define DRV_SER_MEGA_H
#include <cfg/macros.h> /* BV() */
#include <cfg/compiler.h> /* uint32_t */
typedef uint8_t serstatus_t;
/* Software errors */
#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */
#define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */
#define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */
/*
* Hardware errors.
* These flags map directly to the AVR UART Status Register (USR).
*/
#define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */
#define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */
#define SERRF_PARITYERROR BV(7) /**< Parity error */
#define SERRF_NOISEERROR 0 /**< Unsupported */
/**
* SPI clock polarity.
*
* $WIZ$ ser_spi_pol = "SPI_NORMAL_LOW", "SPI_NORMAL_HIGH"
* }
*/
#define SPI_NORMAL_LOW 0
#define SPI_NORMAL_HIGH 1
/**
* SPI clock phase.
*
* $WIZ$ ser_spi_phase = "SPI_SAMPLE_ON_FIRST_EDGE", "SPI_SAMPLE_ON_SECOND_EDGE"
* }
*/
#define SPI_SAMPLE_ON_FIRST_EDGE 0
#define SPI_SAMPLE_ON_SECOND_EDGE 1
/**
* \name Serial hw numbers
*
* \{
*/
enum
{
#if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
SER_UART0,
SER_UART1,
SER_UART2,
SER_UART3,
SER_SPI,
#elif CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281
SER_UART0,
SER_UART1,
SER_SPI,
#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32 || CPU_AVR_ATMEGA168 \
|| CPU_AVR_ATMEGA328P
SER_UART0,
SER_SPI,
#else
#error unknown architecture
#endif
SER_CNT /**< Number of serial ports */
};
/*\}*/
#endif /* DRV_SER_MEGA_H */

View file

@ -0,0 +1,171 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2004, 2005 Develer S.r.l. (http://www.develer.com/)
* All Rights Reserved.
* -->
*
* \brief Simple serial I/O driver
*
* \author Francesco Sacchi <batt@develer.com>
*/
#warning FIXME:This module is obsolete, yuo must refactor it.
#if 0
#include "ser_simple_avr.h"
#include <cfg/compiler.h>
#include <appconfig.h>
#include <cfg/macros.h> /* BV() */
#include <hw/hw_cpufreq.h>
#include <avr/io.h>
/**
* Send a character over the serial line.
*
* \return the character sent.
*/
int _ser_putchar(int c)
{
/* Disable Rx to avoid echo*/
UCSR0B &= ~BV(RXEN);
/* Enable tx*/
UCSR0B |= BV(TXEN);
/* Prepare transmission */
UDR0 = c;
/* Wait until byte sent */
while (!(UCSR0A & BV(TXC))) {}
/* Disable tx to avoid short circuit when tx and rx share the same wire. */
UCSR0B &= ~BV(TXEN);
/* Enable Rx */
UCSR0B |= BV(RXEN);
/* Delete TRANSMIT_COMPLETE_BIT flag */
UCSR0A |= BV(TXC);
return c;
}
/**
* Get a character from the serial line.
* If ther is no character in the buffer this function wait until
* one is received (no timeout).
*
* \return the character received.
*/
int _ser_getchar(void)
{
/* Wait for data */
while (!(UCSR0A & BV(RXC))) {}
return UDR0;
}
/**
* Get a character from the receiver buffer
* If the buffer is empty, ser_getchar_nowait() returns
* immediatly EOF.
*/
int _ser_getchar_nowait(void)
{
if (!(UCSR0A & BV(RXC))) return EOF;
else return UDR0;
}
void _ser_settimeouts(void)
{
}
/**
* Set the baudrate.
*/
void _ser_setbaudrate(unsigned long rate)
{
/* Compute baud-rate period */
uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, rate) - 1;
UBRR0H = (period) >> 8;
UBRR0L = (period);
}
/**
* Send a string.
*/
int _ser_print(const char *s)
{
while(*s) _ser_putchar(*s++);
return 0;
}
void _ser_setparity(int parity)
{
/* Set the new parity */
UCSR0C |= (UCSR0C & ~(BV(UPM1) | BV(UPM0))) | (parity << UPM0);
}
/**
* Dummy functions.
*/
void _ser_purge(void)
{
while (_ser_getchar_nowait() != EOF) {}
}
/**
* Initialize serial.
*/
struct Serial * _ser_open(void)
{
/*
* Set Rx and Tx pins as input to avoid short
* circuit when serial is disabled.
*/
DDRE &= ~(BV(PE0)|BV(PE1));
PORTE &= ~BV(PE0);
PORTE |= BV(PE1);
/* Enable only Rx section */
UCSR0B = BV(RXEN);
return NULL;
}
/**
* Clean up serial port, disabling the associated hardware.
*/
void _ser_close(void)
{
/* Disable Rx & Tx. */
UCSR0B &= ~(BV(RXEN) | BV(TXEN));
}
#endif

View file

@ -0,0 +1,150 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
* -->
*
* \brief Simple serial I/O driver
*
* \author Bernie Innocenti <bernie@codewiz.org>
* \author Francesco Sacchi <batt@develer.com>
*/
#ifndef DRV_SER_SIMPLE_AVR_H
#define DRV_SER_SIMPLE_AVR_H
#warning FIXME:This module is obsolete, yuo must refactor it.
#if 0
/* For checking which serial driver is linked */
#define SER_SIMPLE
#include <appconfig.h>
#include <cfg/compiler.h>
#if 0
#if CPU_AVR
typedef uint8_t serstatus_t;
/* Software errors */
#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */
#define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */
#define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */
/* Hardware errors */
#define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */
#define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */
#define SERRF_PARITYERROR BV(7) /**< Parity error */
#else
#error unknown architecture
#endif
/*\}*/
/**
* \name Serial hw numbers
*
* \{
*/
enum
{
#if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128
SER_UART0,
SER_UART1,
SER_SPI,
#elif CPU_AVR_ATMEGA103 || CPU_AVR_ATMEGA8
SER_UART0,
SER_SPI,
#else
#error unknown architecture
#endif
SER_CNT /**< Number of serial ports */
};
/*\}*/
#endif
/** \name Parity settings for ser_setparity() */
/*\{*/
#define SER_PARITY_NONE 0
#define SER_PARITY_EVEN 2
#define SER_PARITY_ODD 3
/*\}*/
/** Serial handle structure */
struct Serial;
/* Function prototypes */
extern int _ser_putchar(int c);
extern int _ser_getchar(void);
extern int _ser_getchar_nowait(void);
/*
extern int ser_write(struct Serial *port, const void *buf, size_t len);
extern int ser_read(struct Serial *port, void *buf, size_t size);
extern int ser_printf(struct Serial *port, const char *format, ...) FORMAT(__printf__, 2, 3);
extern int ser_gets(struct Serial *port, char *buf, int size);
extern int ser_gets_echo(struct Serial *port, char *buf, int size, bool echo);
*/
extern int _ser_print(const char *s);
extern void _ser_setbaudrate(unsigned long rate);
extern void _ser_setparity(int parity);
extern void _ser_settimeouts(void);
extern void _ser_setstatus(void);
/*
extern void ser_resync(struct Serial *port, time_t delay);
extern void ser_drain(struct Serial *port);
*/
extern void _ser_purge(void);
extern struct Serial *_ser_open(void);
extern void _ser_close(void);
/**
* \name Functions implemented as macros
*
* \{
*/
#define ser_putchar(c, port) _ser_putchar(c)
#define ser_getchar(port) _ser_getchar()
#define ser_getchar_nowait(port) _ser_getchar_nowait()
#define ser_print(port, s) _ser_print(s)
#define ser_setbaudrate(port, y) _ser_setbaudrate(y)
#define ser_setparity(port, par) _ser_setparity(par)
#define ser_settimeouts(port, y, z) _ser_settimeouts()
#define ser_purge(port) _ser_purge()
#define ser_open(port) _ser_open()
#define ser_getstatus(h) 0
#define ser_setstatus(h, x) do {(void)(x);} while(0)
/* \} */
#endif /* DRV_SER_SIMPLE_AVR_H */
#endif

View file

@ -0,0 +1,736 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2011 Onno <developer@gorgoz.org>
*
* -->
*
* \brief AVR XMEGA USART driver (Implementation)
*
* This file is heavily inspired by the AVR implementation for BeRTOS,
* but uses a different approach for implementing the different debug
* ports, by using the USART_t structs.
*
* \author Onno <developer@gorgoz.org>
* notest:all
*/
#include "hw/hw_ser.h" /* Required for bus macros overrides */
#include <hw/hw_cpufreq.h> /* CPU_FREQ */
#include "cfg/cfg_ser.h" /* Serialport configuration settings */
#include <cfg/macros.h> /* DIV_ROUND */
#include <cfg/debug.h> /* debug configuration */
#include <drv/ser.h>
#include <drv/ser_p.h>
#include <drv/timer.h>
#include <struct/fifobuf.h>
#include <avr/io.h> /* AVR IO ports and structures */
#include <avr/interrupt.h> /* AVR Interrupt methods */
/*
* Scalefactor to use for computing the baudrate
* this scalefactor should be an integer value between -7
* and 7
*/
#ifndef USART_SCALE_FACTOR
#define USART_SCALE_FACTOR (-7)
#else
#if USART_SCALE_FACTOR > 7 || USART_SCALE_FACTOR < -7
#error USART_SCALE_FACTOR should be an integer between -7 and 7
#endif
#endif
/* Helper macros, mostly taken from the Atmel Examples
* Slightly alterd to match the BeRTOS naming convention
*/
/* \brief Set USART baud rate.
*
* Sets the USART's baud rate register.
*
* UBRR_Value : Value written to UBRR
* ScaleFactor : Time Base Generator Scale Factor
*
* Equation for calculation of BSEL value in asynchronous normal speed mode:
* If ScaleFactor >= 0
* BSEL = ((I/O clock frequency)/(2^(ScaleFactor)*16*Baudrate))-1
* If ScaleFactor < 0
* BSEL = (1/(2^(ScaleFactor)*16))*(((I/O clock frequency)/Baudrate)-1)
*
* \note See XMEGA manual for equations for calculation of BSEL value in other
* modes.
*
* \param _usart Pointer to the USART module.
* \param _bselValue Value to write to BSEL part of Baud control register.
* Use uint16_t type.
* \param _bScaleFactor USART baud rate scale factor.
* Use uint8_t type
*/
#define USART_SET_BAUDRATE(_usart, _bselValue, _bScaleFactor) \
(_usart)->BAUDCTRLA =(uint8_t)_bselValue; \
(_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
/* \brief Enable USART receiver.
*
* \param _usart Pointer to the USART module
*/
#define USART_RX_ENABLE(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
/* \brief Disable USART receiver.
*
* \param _usart Pointer to the USART module.
*/
#define USART_RX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_RXEN_bm)
/* \brief Enable USART transmitter.
*
* \param _usart Pointer to the USART module.
*/
#define USART_TX_ENABLE(_usart) ((_usart)->CTRLB |= USART_TXEN_bm)
/* \brief Disable USART transmitter.
*
* \param _usart Pointer to the USART module.
*/
#define USART_TX_DISABLE(_usart) ((_usart)->CTRLB &= ~USART_TXEN_bm)
/* \brief Set USART RXD interrupt level.
*
* Sets the interrupt level on RX Complete interrupt.
*
* \param _usart Pointer to the USART module.
* \param _rxdIntLevel Interrupt level of the RXD interrupt.
* Use USART_RXCINTLVL_t type.
*/
#define USART_SET_RX_INTERRUPT_LEVEL(_usart, _rxdIntLevel) \
((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)
/* \brief Set USART TXD interrupt level.
*
* Sets the interrupt level on TX Complete interrupt.
*
* \param _usart Pointer to the USART module.
* \param _txdIntLevel Interrupt level of the TXD interrupt.
* Use USART_TXCINTLVL_t type.
*/
#define USART_SET_TX_INTERRUPT_LEVEL(_usart, _txdIntLevel) \
(_usart)->CTRLA = ((_usart)->CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
/* \brief Set USART DRE interrupt level.
*
* Sets the interrupt level on Data Register interrupt.
*
* \param _usart Pointer to the USART module.
* \param _dreIntLevel Interrupt level of the DRE interrupt.
* Use USART_DREINTLVL_t type.
*/
#define USART_SET_DRE_INTERRUPT_LEVEL(_usart, _dreIntLevel) \
(_usart)->CTRLA = ((_usart)->CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
/* \brief Set the mode the USART run in.
*
* Set the mode the USART run in. The default mode is asynchronous mode.
*
* \param _usart Pointer to the USART module register section.
* \param _usartMode Selects the USART mode. Use USART_CMODE_t type.
*
* USART modes:
* - 0x0 : Asynchronous mode.
* - 0x1 : Synchronous mode.
* - 0x2 : IrDA mode.
* - 0x3 : Master SPI mode.
*/
#define USART_SET_MODE(_usart, _usartMode) \
((_usart)->CTRLC = ((_usart)->CTRLC & (~USART_CMODE_gm)) | _usartMode)
/* \brief Check if data register empty flag is set.
*
* \param _usart The USART module.
*/
#define USART_IS_TX_DATA_REGISTER_EMPTY(_usart) (((_usart)->STATUS & USART_DREIF_bm) != 0)
/* \brief Put data (5-8 bit character).
*
* Use the macro USART_IsTXDataRegisterEmpty before using this function to
* put data to the TX register.
*
* \param _usart The USART module.
* \param _data The data to send.
*/
#define USART_PUT_CHAR(_usart, _data) ((_usart)->DATA = _data)
/* \brief Checks if the RX complete interrupt flag is set.
*
* Checks if the RX complete interrupt flag is set.
*
* \param _usart The USART module.
*/
#define USART_IS_RX_COMPLETE(_usart) (((_usart)->STATUS & USART_RXCIF_bm) != 0)
/* \brief Get received data (5-8 bit character).
*
* This macro reads out the RX register.
* Use the macro USART_RX_Complete to check if anything is received.
*
* \param _usart The USART module.
*
* \retval Received data.
*/
#define USART_GET_CHAR(_usart) ((_usart)->DATA)
/* configurable macros */
#if !CONFIG_SER_HWHANDSHAKE
/**
* \name Hardware handshake (RTS/CTS).
* \{
*/
#define RTS_ON do {} while (0)
#define RTS_OFF do {} while (0)
#define IS_CTS_ON true
#define EIMSKF_CTS 0 /**< Dummy value, must be overridden */
/*\}*/
#endif
/*
* \name Overridable serial bus hooks
*
* These can be redefined in hw.h to implement
* special bus policies such as half-duplex, 485, etc.
*
*
* \code
* TXBEGIN TXCHAR TXEND TXOFF
* | __________|__________ | |
* | | | | | | | | |
* v v v v v v v v v
* ______ __ __ __ __ __ __ ________________
* \/ \/ \/ \/ \/ \/ \/
* ______/\__/\__/\__/\__/\__/\__/
*
* \endcode
*
* \{
*/
#ifndef SER_UART_BUS_TXINIT
/*
* Default TXINIT macro - invoked in uart_init()
*
* - Enable both the receiver and the transmitter
* - Enable only the RX complete interrupt
*/
#define SER_UART_BUS_TXINIT(_usart) do { \
USART_RX_ENABLE(_usart); \
USART_TX_ENABLE(_usart); \
USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
} while (0)
#endif
#ifndef SER_UART_BUS_TXBEGIN
/*
* Invoked before starting a transmission
*
* - Enable both the receiver and the transmitter
* - Enable both the RX complete and UDR empty interrupts
*/
#define SER_UART_BUS_TXBEGIN(_usart) do { \
USART_SET_RX_INTERRUPT_LEVEL(_usart, USART_RXCINTLVL_MED_gc); \
USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_MED_gc);\
} while (0)
#endif
#ifndef SER_UART_BUS_TXCHAR
/*
* Invoked to send one character.
*/
#define SER_UART_BUS_TXCHAR(_usart, c) do { \
USART_PUT_CHAR(_usart, c); \
} while (0)
#endif
#ifndef SER_UART_BUS_TXEND
/*
* Invoked as soon as the txfifo becomes empty
*
* - Keep both the receiver and the transmitter enabled
* - Keep the RX complete interrupt enabled
* - Disable the UDR empty interrupt
*/
#define SER_UART_BUS_TXEND(_usart) do { \
USART_SET_DRE_INTERRUPT_LEVEL(_usart, USART_DREINTLVL_OFF_gc); \
} while (0)
#endif
#ifndef SER_UART_BUS_TXOFF
/*
* \def SER_UART_BUS_TXOFF
*
* Invoked after the last character has been transmitted
*
* The default is no action.
*/
#ifdef __doxygen__
#define SER_UART_BUS_TXOFF(_usart)
#endif
#endif
/*\}*/
/* From the high-level serial driver */
extern struct Serial *ser_handles[SER_CNT];
/* TX and RX buffers */
static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
#ifdef CPU_AVR_XMEGA_A
static unsigned char uart2_txbuffer[CONFIG_UART2_TXBUFSIZE];
static unsigned char uart2_rxbuffer[CONFIG_UART2_RXBUFSIZE];
static unsigned char uart3_txbuffer[CONFIG_UART3_TXBUFSIZE];
static unsigned char uart3_rxbuffer[CONFIG_UART3_RXBUFSIZE];
static unsigned char uart4_txbuffer[CONFIG_UART4_TXBUFSIZE];
static unsigned char uart4_rxbuffer[CONFIG_UART4_RXBUFSIZE];
#endif
/*
* Internal hardware state structure
*
* The \a sending variable is true while the transmission
* interrupt is retriggering itself.
*
* the \a usart variable will point to the USART_t structure
* that should be used.
*
* the \a port variable will point to the PORT_t structure
* that should be modified to set the tx pin as an output and the
* rx pin as an input
*
* the \a txpin variable will hold the pinnumber of the pin to use
* as the tx output
*
* the \a rxpin variable will hold the pinnumber of the pin to use
* as the rx input
*
* For the USARTs the \a sending flag is useful for taking specific
* actions before sending a burst of data, at the start of a trasmission
* but not before every char sent.
*
* For the SPI, this flag is necessary because the SPI sends and receives
* bytes at the same time and the SPI IRQ is unique for send/receive.
* The only way to start transmission is to write data in SPDR (this
* is done by spi_starttx()). We do this *only* if a transfer is
* not already started.
*/
struct AvrxmegaSerial
{
struct SerialHardware hw;
volatile bool sending;
volatile USART_t* usart;
volatile PORT_t* port;
uint8_t txpin;
uint8_t rxpin;
};
/*
* Callbacks
* The same callbacks are used for all USARTS.
* By casting the SerialHardware structure to the AvrxmegaSerial
* structure a pointer to the USART_t structure can be obtained,
* to perform the callback for the specific USART.
* This methode might cost some more cpu time, but saves on
* code duplication and code size.
*/
/*
* \brief Initializes the uart
*
* The TX pin of the uart will be set as an outputpin
* The RX pin of the uart will be set as an inputpin
* The usart will be initialized
* \see SER_UART_BUS_TXINIT
*
* \param _hw struct AvrxmegaSerial
* \param ser Unused
*/
static void uart_init(struct SerialHardware * _hw, UNUSED_ARG(struct Serial *, ser))
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
//set transmit pin as output
hw->port->DIRSET = BV(hw->txpin);
hw->port->OUTCLR = BV(hw->txpin);
//set receive pin as input
hw->port->DIRCLR = BV(hw->rxpin);
//initialize the USART
SER_UART_BUS_TXINIT(hw->usart);
RTS_ON;
SER_STROBE_INIT;
}
/*
* \brief Cleans up / Disables the uart
*
* \param _hw struct AvrxmegaSerial
*/
static void uart_cleanup(struct SerialHardware * _hw)
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
hw->usart->CTRLA = 0;
hw->usart->CTRLB = 0;
}
/*
* \brief Enableds the TX interrupt
*
* \param _hw struct AvrxmegaSerial
*/
static void uart_enabletxirq(struct SerialHardware *_hw)
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
/*
* WARNING: racy code here! The tx interrupt sets hw->sending to false
* when it runs with an empty fifo. The order of statements in the
* if-block matters.
*/
if (!hw->sending)
{
hw->sending = true;
SER_UART_BUS_TXBEGIN(hw->usart);
}
}
/*
* \brief sets the uart to the provided baudrate
*
* For setting the baudrate an scale factor (bscale) and a period
* setting (BSEL) is required.
*
* The scale factor should be privided by defining USART_SCALE_FACTOR
*
* Atmel specifies BSEL for normal speed mode and bscale >= 0 as:
* BSEL = (cpu_freq / ((2^bscale) * 16 * rate)) - 1
* To allow BSEL to be calculated with an power function this can be
* rewriten to:
* BSEL = BSEL = (cpu_freq / ((1 << bscale) * 16 * rate)) - 1
*
* Atmel specifies BSEL for normal speed mode and bscale < 0 as:
* BSEL = (1 / (2^bscale)) * ( (cpu_freq / (16 * rate)) - 1)
* To calculte this float atheritmic is required as the second product will be smaller
* than zero in a lot of cases.
* To allow BSEL to be calculated with interger devision and no power function
* this can be rewriten by folowing simple math rules to:
* BSEL = ((1 << -bscale) * (cpu_freq - (16 * rate)) / (16 * rate)
*
* \param _hw struct AvrxmegaSerial
* \param _rate the required baudrate
*
*/
static void uart_setbaudrate(struct SerialHardware * _hw, unsigned long _rate)
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
/* Compute baud-rate period, this requires a valid USART_SCALE_FACTOR */
#if USART_SCALE_FACTOR < 0
uint16_t bsel = DIV_ROUND((1 << (-(USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * _rate)), 16 * _rate);
#else
uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (USART_SCALE_FACTOR)) * 16 * _rate) - 1;
#endif
USART_SET_BAUDRATE(hw->usart, bsel, USART_SCALE_FACTOR);
}
/*
* \brief Sets the parity of the uart
*
* \param _hw struct AvrxmegaSerial
* \param _parity the parity to set
*/
static void uart_setparity(struct SerialHardware * _hw, int _parity)
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
USART_SET_MODE(hw->usart, _parity);
}
/*
* \brief Returns true if Transmitter is sending
*
* \param _hw struct AvrxmegaSerial
* \return true if transmitter is sending
*/
static bool tx_sending(struct SerialHardware* _hw)
{
struct AvrxmegaSerial *hw = (struct AvrxmegaSerial *)_hw;
return hw->sending;
}
// FIXME: move into compiler.h? Ditch?
#if COMPILER_C99
#define C99INIT(name,val) .name = val
#elif defined(__GNUC__)
#define C99INIT(name,val) name: val
#else
#warning No designated initializers, double check your code
#define C99INIT(name,val) (val)
#endif
/*
* High-level interface data structures
*/
static const struct SerialHardwareVT UART_VT =
{
C99INIT(init, uart_init),
C99INIT(cleanup, uart_cleanup),
C99INIT(setBaudrate, uart_setbaudrate),
C99INIT(setParity, uart_setparity),
C99INIT(txStart, uart_enabletxirq),
C99INIT(txSending, tx_sending)
};
static struct AvrxmegaSerial UARTDescs[SER_CNT] =
{
{
C99INIT(hw, /**/) {
C99INIT(table, &UART_VT),
C99INIT(txbuffer, uart0_txbuffer),
C99INIT(rxbuffer, uart0_rxbuffer),
C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
},
C99INIT(sending, false),
C99INIT(usart, &USARTC0),
C99INIT(port, &PORTC),
C99INIT(txpin, PIN3_bp),
C99INIT(rxpin, PIN2_bp),
},
{
C99INIT(hw, /**/) {
C99INIT(table, &UART_VT),
C99INIT(txbuffer, uart1_txbuffer),
C99INIT(rxbuffer, uart1_rxbuffer),
C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
},
C99INIT(sending, false),
C99INIT(usart, &USARTD0),
C99INIT(port, &PORTD),
C99INIT(txpin, PIN3_bp),
C99INIT(rxpin, PIN2_bp),
},
#ifdef CPU_AVR_XMEGA_A
{
C99INIT(hw, /**/) {
C99INIT(table, &UART_VT),
C99INIT(txbuffer, uart2_txbuffer),
C99INIT(rxbuffer, uart2_rxbuffer),
C99INIT(txbuffer_size, sizeof(uart2_txbuffer)),
C99INIT(rxbuffer_size, sizeof(uart2_rxbuffer)),
},
C99INIT(sending, false),
C99INIT(usart, &USARTC1),
C99INIT(port, &PORTC),
C99INIT(txpin, PIN7_bp),
C99INIT(rxpin, PIN6_bp),
},
{
C99INIT(hw, /**/) {
C99INIT(table, &UART_VT),
C99INIT(txbuffer, uart3_txbuffer),
C99INIT(rxbuffer, uart3_rxbuffer),
C99INIT(txbuffer_size, sizeof(uart3_txbuffer)),
C99INIT(rxbuffer_size, sizeof(uart3_rxbuffer)),
},
C99INIT(sending, false),
C99INIT(usart, &USARTD1),
C99INIT(port, &PORTD),
C99INIT(txpin, PIN7_bp),
C99INIT(rxpin, PIN6_bp),
},
{
C99INIT(hw, /**/) {
C99INIT(table, &UART_VT),
C99INIT(txbuffer, uart4_txbuffer),
C99INIT(rxbuffer, uart4_rxbuffer),
C99INIT(txbuffer_size, sizeof(uart4_txbuffer)),
C99INIT(rxbuffer_size, sizeof(uart4_rxbuffer)),
},
C99INIT(sending, false),
C99INIT(usart, &USARTE0),
C99INIT(port, &PORTE),
C99INIT(txpin, PIN3_bp),
C99INIT(rxpin, PIN2_bp),
},
#endif //CPU_AVR_XMEGA_A
};
struct SerialHardware *ser_hw_getdesc(int unit)
{
ASSERT(unit < SER_CNT);
return &UARTDescs[unit].hw;
}
/*
* Interrupt handlers
*/
static inline void usart_handleDreInterrupt(uint8_t usartNumber)
{
SER_STROBE_ON;
struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
if (fifo_isempty(txfifo))
{
SER_UART_BUS_TXEND(UARTDescs[usartNumber].usart);
#ifndef SER_UART_BUS_TXOFF
UARTDescs[usartNumber].sending = false;
#endif
}
else
{
char c = fifo_pop(txfifo);
SER_UART_BUS_TXCHAR(UARTDescs[usartNumber].usart, c);
}
SER_STROBE_OFF;
}
#define USART_DRE_INTERRUPT_VECTOR(_vector, _usart) \
DECLARE_ISR(_vector) \
{ \
usart_handleDreInterrupt( _usart ); \
}
USART_DRE_INTERRUPT_VECTOR(USARTC0_DRE_vect, SER_UART0)
USART_DRE_INTERRUPT_VECTOR(USARTD0_DRE_vect, SER_UART1)
#ifdef CPU_AVR_XMEGA_A
USART_DRE_INTERRUPT_VECTOR(USARTC1_DRE_vect, SER_UART2)
USART_DRE_INTERRUPT_VECTOR(USARTD1_DRE_VECT, SER_UART3)
USART_DRE_INTERRUPT_VECTOR(USARTE0_DRE_vect, SER_UART4)
#endif
#ifdef SER_UART_BUS_TXOFF
static inline void USART_handleTXCInterrupt(uint8_t usartNumber)
{
SER_STROBE_ON;
struct FIFOBuffer * const txfifo = &ser_handles[usartNumber]->txfifo;
if (fifo_isempty(txfifo))
{
SER_UART_BUS_TXOFF(UARTDescs[usartNumber].usart);
UARTDescs[usartNumber].sending = false;
}
else
{
SER_UART_BUS_TXBEGIN(UARTDescs[usartNumber].usart);
}
SER_STROBE_OFF;
}
/*
* Serial port 0 TX complete interrupt handler.
*
* This IRQ is usually disabled. The UDR-empty interrupt
* enables it when there's no more data to transmit.
* We need to wait until the last character has been
* transmitted before switching the 485 transceiver to
* receive mode.
*
* The txfifo might have been refilled by putchar() while
* we were waiting for the transmission complete interrupt.
* In this case, we must restart the UDR empty interrupt,
* otherwise we'd stop the serial port with some data
* still pending in the buffer.
*/
#define USART_TXC_INTERRUPT_VECTOR(_vector, _usart) \
DECLARE_ISR(_vector) \
{ \
USART_handleTXCInterrupt( _usart ); \
}
USART_TXC_INTERRUPT_VECTOR(USARTC0_TXC_vect, SER_UART0)
USART_TXC_INTERRUPT_VECTOR(USARTD0_TXC_vect, SER_UART1)
#ifdef CPU_AVR_XMEGA_A
USART_TXC_INTERRUPT_VECTOR(USARTC1_TXC_vect, SER_UART2)
USART_TXC_INTERRUPT_VECTOR(USARTD1_TXC_vect, SER_UART3)
USART_TXC_INTERRUPT_VECTOR(USARTE0_TXC_vect, SER_UART4)
#endif /* CPU_AVR_XMEGA_A */
#endif /* SER_UART_BUS_TXOFF */
/*
* Serial RX complete interrupt handler.
*
* This handler is interruptible.
* Interrupt are reenabled as soon as recv complete interrupt is
* disabled. Using INTERRUPT() is troublesome when the serial
* is heavily loaded, because an interrupt could be retriggered
* when executing the handler prologue before RXCIE is disabled.
*/
static inline void USART_handleRXCInterrupt(uint8_t usartNumber)
{
SER_STROBE_ON;
/* read status */
ser_handles[usartNumber]->status |= (UARTDescs[usartNumber].usart)->STATUS & (SERRF_RXSROVERRUN | SERRF_FRAMEERROR);
/* To clear the RXC flag we must _always_ read the UDR even when we're
* not going to accept the incoming data, otherwise a new interrupt
* will occur once the handler terminates.
*/
char c = (UARTDescs[usartNumber].usart)->DATA;
struct FIFOBuffer * const rxfifo = &ser_handles[usartNumber]->rxfifo;
if (fifo_isfull(rxfifo))
{
ser_handles[usartNumber]->status |= SERRF_RXFIFOOVERRUN;
}
else
{
fifo_push(rxfifo, c);
#if CONFIG_SER_HWHANDSHAKE
if (fifo_isfull(rxfifo))
{
RTS_OFF(UARTDescs[usartNumber].usart);
}
#endif
}
SER_STROBE_OFF;
}
#define USART_RXC_INTERRUPT_VECTOR(_vector, _usart) \
DECLARE_ISR(_vector) \
{ \
USART_handleRXCInterrupt( _usart ); \
}
USART_RXC_INTERRUPT_VECTOR(USARTC0_RXC_vect, SER_UART0)
USART_RXC_INTERRUPT_VECTOR(USARTD0_RXC_vect, SER_UART1)
#ifdef CPU_AVR_XMEGA_A
USART_RXC_INTERRUPT_VECTOR(USARTC1_RXC_vect, SER_UART2)
USART_RXC_INTERRUPT_VECTOR(USARTD1_RXC_vect, SER_UART3)
USART_RXC_INTERRUPT_VECTOR(USARTE0_RXC_vect, SER_UART4)
#endif

View file

@ -0,0 +1,85 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2007, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2011 Onno <developer@gorgoz.org>
* -->
*
*
* \brief Low-level serial module for AVR XMEGA (interface).
*
* This file is heavily inspired by the AVR implementation for BeRTOS,
* but uses a different approach for implementing the different debug
* ports, by using the USART_t structs.
*
* \author Onno <developer@gorgoz.org>
*
*/
#ifndef DRV_SER_XMEGA_H
#define DRV_SER_XMEGA_H
#include <cfg/macros.h> /* BV() */
#include <cfg/compiler.h> /* uint8_t */
typedef uint8_t serstatus_t;
/* Software errors */
#define SERRF_RXFIFOOVERRUN BV(0) /**< Rx FIFO buffer overrun */
#define SERRF_RXTIMEOUT BV(5) /**< Receive timeout */
#define SERRF_TXTIMEOUT BV(6) /**< Transmit timeout */
/*
* Hardware errors.
* These flags map directly to the AVR XMEGA UART Status Register.
*/
#define SERRF_RXSROVERRUN BV(3) /**< Rx shift register overrun */
#define SERRF_FRAMEERROR BV(4) /**< Stop bit missing */
#define SERRF_PARITYERROR BV(2) /**< Parity error */
#define SERRF_NOISEERROR 0 /**< Unsupported */
/*
* \name Serial hw numbers
*
* \{
*/
enum
{
SER_UART0,
SER_UART1,
#ifdef CPU_AVR_XMEGA_A
//the XMEGA A Family have 5 USART ports
SER_UART2,
SER_UART3,
SER_UART4,
#endif
SER_CNT /**< Number of serial ports */
};
/*\}*/
#endif /* DRV_SER_XMEGA_H */

View file

@ -0,0 +1,87 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2008 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Low-level stepper timer module for AVR (inplementation).
*
*
* \author Daniele Basile <asterix@develer.com>
*
*/
#include "stepper_avr.h"
#include "cfg/cfg_stepper.h"
#include <cfg/macros.h>
#include <cfg/debug.h>
#include <cpu/types.h>
#include <cpu/irq.h>
#warning TODO:This is an example, you must implement it!
///< Static array of timer counter struct for stepper.
/*
static struct TimerCounter stepper_timers[CONFIG_TC_STEPPER_MAX_NUM] =
{
{ //Timer Counter settings for TIO0 output pin
// fill with stepper timer channel settings
}
// Add here other stepper timer channel settings
};
*/
/**
* Timer couter setup.
*
* This function apply to select timer couter all needed settings.
* Every settings are stored in stepper_timers[].
*/
void stepper_tc_setup(int index, stepper_isr_t callback, struct Stepper *motor)
{
/* Put here the code to setup the stepper timer drive */
//Only for test remove when implement this function
(void)index;
(void)callback;
(void)motor;
}
/**
* Timer counter init.
*/
void stepper_tc_init(void)
{
/* Put here the code to init the stepper timer drive */
}

View file

@ -0,0 +1,140 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2008 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Low-level stepper timer module for AVR (inplementation).
*
*
* \author Daniele Basile <asterix@develer.com>
*
*/
#ifndef DRV_STEPPER_AVR_H
#define DRV_STEPPER_AVR_H
#include <cfg/compiler.h>
#include <cfg/macros.h>
#include <drv/stepper.h>
#warning TODO:This is an example, you must implement it!
/**
* IRQ callback function type definition.
*/
typedef void (*irq_t)(void);
/**
* Timer contex structure.
*/
typedef struct TimerCounter
{
int timer_id; ///< Timer counter ID
irq_t isr; ///< IRQ handler
stepper_isr_t callback; ///< Interrupt callback pointer
struct Stepper *motor; ///< Stepper context structure
} TimerCounter;
/**
* Enable interrupt for timer counter compare event.
*/
INLINE void stepper_tc_irq_enable(struct TimerCounter *timer)
{
/* put here code to enable timer irq */
//Only for test remove when implement this function
(void)timer;
}
/**
* Disable interrupt for timer counter compare event.
*/
INLINE void stepper_tc_irq_disable(struct TimerCounter *timer)
{
/* put here code to disable timer irq */
//Only for test remove when implement this function
(void)timer;
}
/**
* Set delay for next interrupt compare event.
*/
INLINE void stepper_tc_setDelay(struct TimerCounter *timer, stepper_time_t delay)
{
/* put here code to set the delay for next irq */
//Only for test remove when implement this function
(void)timer;
(void)delay;
}
/**
* Set delay for next interrupt compare event.
*/
INLINE void stepper_tc_resetTimer(struct TimerCounter *timer)
{
/* put here code to reset the timer */
//Only for test remove when implement this function
(void)timer;
}
/**
* Programm timer counter to generate a pulse on select TIO output.
*/
INLINE void FAST_FUNC stepper_tc_doPulse(struct TimerCounter *timer)
{
/* put here code to generate a pulse */
//Only for test remove when implement this function
(void)timer;
}
/**
* Programm timer counter to not generate a pulse on select TIO output.
*/
INLINE void FAST_FUNC stepper_tc_skipPulse(struct TimerCounter *timer)
{
/* put here code to skip a pulse */
//Only for test remove when implement this function
(void)timer;
}
void stepper_tc_setup(int index, stepper_isr_t callback, struct Stepper *motor);
void stepper_tc_init(void);
#endif /*DRV_STEPPER_AVR_H */

View file

@ -0,0 +1,57 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2005, 2010 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \author Onno <developer@gorgoz.org>
*
* \brief Low-level timer module for AVR (implementation).
*
* This module is automatically included so no need to include
* in test list.
* notest: avr
*/
#ifndef WIZ_AUTOGEN
#warning This file is deprecated, you should probably use timer_mega.c
#include <cpu/detect.h>
#if CPU_AVR_MEGA
#include "timer_mega.c"
#elif CPU_AVR_XMEGA
#include "timer_xmega.c"
/*#elif Add other AVR families here */
#else
#error Unknown CPU
#endif
#endif /* WIZ_AUTOGEN */

View file

@ -0,0 +1,55 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
*
* -->
*
* \brief Low-level timer module for AVR (interface).
*
* \author Onno <developer@gorgoz.org>
*
*/
#ifndef TIMER_AVR_H_
#define TIMER_AVR_H_
#include <cpu/detect.h>
#if CPU_AVR_MEGA
#include "timer_mega.h"
#elif CPU_AVR_XMEGA
#include "timer_xmega.h"
/*#elif Add other AVR families here */
#else
#error Unknown CPU
#endif
#endif /* TIMER_AVR_H_ */

View file

@ -0,0 +1,257 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2005, 2010 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \author Bernie Innocenti <bernie@codewiz.org>
* \author Francesco Sacchi <batt@develer.com>
* \author Luca Ottaviano <lottaviano@develer.com>
*
* \brief Low-level timer module for AVR MEGA (implementation).
*
* This module is automatically included so no need to include
* in test list.
* notest: avr
*/
#include <drv/timer_mega.h>
#include <cfg/macros.h> // BV()
#include <cpu/types.h>
#include <cpu/irq.h>
#include <avr/io.h>
#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA2560
#define REG_TIFR0 TIFR0
#define REG_TIFR1 TIFR1
#define REG_TIFR2 TIFR2
#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
#define REG_TIFR3 TIFR3
#endif
#define REG_TIMSK0 TIMSK0
#define REG_TIMSK1 TIMSK1
#define REG_TIMSK2 TIMSK2
#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
#define REG_TIMSK3 TIMSK3
#endif
#define REG_TCCR0A TCCR0A
#define REG_TCCR0B TCCR0B
#define REG_TCCR2A TCCR2A
#define REG_TCCR2B TCCR2B
#define REG_OCR0A OCR0A
#define REG_OCR2A OCR2A
#define BIT_OCF0A OCF0A
#define BIT_OCF2A OCF2A
#define BIT_OCIE0A OCIE0A
#define BIT_OCIE2A OCIE2A
#else
#define REG_TIFR0 TIFR
#define REG_TIFR1 TIFR
#define REG_TIFR2 TIFR
#define REG_TIFR3 TIFR
#define REG_TIMSK0 TIMSK
#define REG_TIMSK1 TIMSK
#define REG_TIMSK2 TIMSK
#define REG_TIMSK3 ETIMSK
#define REG_TCCR0A TCCR0
#define REG_TCCR0B TCCR0
#define REG_TCCR2A TCCR2
#define REG_TCCR2B TCCR2
#define REG_OCR0A OCR0
#define REG_OCR2A OCR2
#define BIT_OCF0A OCF0
#define BIT_OCF2A OCF2
#define BIT_OCIE0A OCIE0
#define BIT_OCIE2A OCIE2
#endif
#if CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA103
/* These ATMega have different prescaler options. */
#define TIMER0_PRESCALER_64 BV(CS02)
#define TIMER2_PRESCALER_64 (BV(CS21) | BV(CS20))
#else
#define TIMER0_PRESCALER_64 (BV(CS01) | BV(CS00))
#define TIMER2_PRESCALER_64 BV(CS22)
#endif
/** HW dependent timer initialization */
#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0)
void timer_hw_init(void)
{
cpu_flags_t flags;
IRQ_SAVE_DISABLE(flags);
/* Reset Timer flags */
REG_TIFR0 = BV(BIT_OCF0A) | BV(TOV0);
/* Setup Timer/Counter interrupt */
REG_TCCR0A = 0; // TCCR2 reg could be separate or a unique register with both A & B values, this is needed to
REG_TCCR0B = 0;
REG_TCCR0A = BV(WGM01); /* Clear on Compare match */
#if TIMER_PRESCALER == 64
REG_TCCR0B |= TIMER0_PRESCALER_64;
#else
#error Unsupported value of TIMER_PRESCALER
#endif
TCNT0 = 0x00; /* Initialization of Timer/Counter */
REG_OCR0A = OCR_DIVISOR; /* Timer/Counter Output Compare Register */
/* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */
REG_TIMSK0 &= ~BV(TOIE0);
REG_TIMSK0 |= BV(BIT_OCIE0A);
IRQ_RESTORE(flags);
}
#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1)
void timer_hw_init(void)
{
cpu_flags_t flags;
IRQ_SAVE_DISABLE(flags);
/* Reset Timer overflow flag */
REG_TIFR1 |= BV(TOV1);
/* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */
#if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9)
TCCR1A |= BV(WGM11);
TCCR1A &= ~BV(WGM10);
TCCR1B |= BV(WGM12) | BV(CS10);
TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12));
/* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */
#elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8)
TCCR1A |= BV(WGM10);
TCCR1A &= ~BV(WGM11);
TCCR1B |= BV(WGM12) | BV(CS10);
TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12));
#else
#error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS
#endif
TCNT1 = 0x00; /* initialization of Timer/Counter */
/* Enable timer interrupt: Timer/Counter1 Overflow */
REG_TIMSK1 |= BV(TOIE1);
IRQ_RESTORE(flags);
}
#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2)
void timer_hw_init(void)
{
cpu_flags_t flags;
IRQ_SAVE_DISABLE(flags);
/* Reset Timer flags */
REG_TIFR2 = BV(BIT_OCF2A) | BV(TOV2);
/* Setup Timer/Counter interrupt */
REG_TCCR2A = 0; // TCCR2 reg could be separate or a unique register with both A & B values, this is needed to
REG_TCCR2B = 0; // ensure correct initialization.
REG_TCCR2A = BV(WGM21);
#if TIMER_PRESCALER == 64
REG_TCCR2B |= TIMER2_PRESCALER_64;
#else
#error Unsupported value of TIMER_PRESCALER
#endif
/* Clear on Compare match & prescaler = 64, internal sys clock.
When changing prescaler change TIMER_HW_HPTICKS_PER_SEC too */
TCNT2 = 0x00; /* initialization of Timer/Counter */
REG_OCR2A = (uint8_t)OCR_DIVISOR; /* Timer/Counter Output Compare Register */
/* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */
REG_TIMSK2 &= ~BV(TOIE2);
REG_TIMSK2 |= BV(BIT_OCIE2A);
IRQ_RESTORE(flags);
}
#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3)
#if CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA32
#error For select target there is not TIMER_ON_OVERFLOW3, please select an other one.
#endif
void timer_hw_init(void)
{
cpu_flags_t flags;
IRQ_SAVE_DISABLE(flags);
/* Reset Timer overflow flag */
REG_TIFR3 |= BV(TOV3);
/* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */
#if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9)
TCCR3A |= BV(WGM31);
TCCR3A &= ~BV(WGM30);
TCCR3B |= BV(WGM32) | BV(CS30);
TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32));
/* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */
#elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8)
TCCR3A |= BV(WGM30);
TCCR3A &= ~BV(WGM31);
TCCR3B |= BV(WGM32) | BV(CS30);
TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32));
#else
#error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS
#endif
/* initialization of Timer/Counter */
TCNT3 = 0x00;
/* Enable timer interrupt: Timer/Counter3 Overflow */
REG_TIMSK3 |= BV(TOIE3);
IRQ_RESTORE(flags);
}
#else
#error Unimplemented value for CONFIG_TIMER
#endif /* CONFIG_TIMER */

View file

@ -0,0 +1,173 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
*
* -->
*
* \brief Low-level timer module for AVR MEGA (interface).
*
* \author Bernie Innocenti <bernie@codewiz.org>
* \author Francesco Sacchi <batt@develer.com>
* \author Luca Ottaviano <lottaviano@develer.com>
*
*/
#ifndef DRV_TIMER_MEGA_H
#define DRV_TIMER_MEGA_H
#include <hw/hw_cpufreq.h> /* CPU_FREQ */
#include "cfg/cfg_timer.h" /* CONFIG_TIMER */
#include <cfg/compiler.h> /* uint8_t */
#include <cfg/macros.h> /* DIV_ROUND */
#include <avr/io.h>
#include <avr/interrupt.h>
/**
* \name Values for CONFIG_TIMER.
*
* Select which hardware timer interrupt to use for system clock and softtimers.
* \note The timer 1 overflow mode set the timer as a 24 kHz PWM.
* $WIZ$ timer_select = "TIMER_ON_OUTPUT_COMPARE0", "TIMER_ON_OVERFLOW1", "TIMER_ON_OUTPUT_COMPARE2", "TIMER_ON_OVERFLOW3", "TIMER_DEFAULT"
*/
#define TIMER_ON_OUTPUT_COMPARE0 1
#define TIMER_ON_OVERFLOW1 2
#define TIMER_ON_OUTPUT_COMPARE2 3
#define TIMER_ON_OVERFLOW3 4
#define TIMER_DEFAULT TIMER_ON_OUTPUT_COMPARE0 ///< Default system timer
/*
* Hardware dependent timer initialization.
*/
#if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0)
#define TIMER_PRESCALER 64
#define TIMER_HW_BITS 8
#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA2560
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER0_COMPA_vect)
#else
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER0_COMP_vect)
#endif
#define TIMER_TICKS_PER_SEC 1000
#define TIMER_HW_CNT OCR_DIVISOR
/// Type of time expressed in ticks of the hardware high-precision timer
typedef uint8_t hptime_t;
#define SIZEOF_HPTIME_T 1
INLINE hptime_t timer_hw_hpread(void)
{
return TCNT0;
}
#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1)
#define TIMER_PRESCALER 1
#define TIMER_HW_BITS 8
/** This value is the maximum in overflow based timers. */
#define TIMER_HW_CNT (1 << TIMER_HW_BITS)
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER1_OVF_vect)
#define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT)
/// Type of time expressed in ticks of the hardware high precision timer
typedef uint16_t hptime_t;
#define SIZEOF_HPTIME_T 2
INLINE hptime_t timer_hw_hpread(void)
{
return TCNT1;
}
#elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2)
#define TIMER_PRESCALER 64
#define TIMER_HW_BITS 8
#if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA2560
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER2_COMPA_vect)
#else
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER2_COMP_vect)
#endif
#define TIMER_TICKS_PER_SEC 1000
/** Value for OCR register in output-compare based timers. */
#define TIMER_HW_CNT OCR_DIVISOR
/// Type of time expressed in ticks of the hardware high precision timer
typedef uint8_t hptime_t;
#define SIZEOF_HPTIME_T 1
INLINE hptime_t timer_hw_hpread(void)
{
return TCNT2;
}
#elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3)
#define TIMER_PRESCALER 1
#define TIMER_HW_BITS 8
/** This value is the maximum in overflow based timers. */
#define TIMER_HW_CNT (1 << TIMER_HW_BITS)
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER3_OVF_vect)
#define TIMER_TICKS_PER_SEC DIV_ROUND(TIMER_HW_HPTICKS_PER_SEC, TIMER_HW_CNT)
/// Type of time expressed in ticks of the hardware high precision timer
typedef uint16_t hptime_t;
#define SIZEOF_HPTIME_T 2
INLINE hptime_t timer_hw_hpread(void)
{
return TCNT3;
}
#else
#error Unimplemented value for CONFIG_TIMER
#endif /* CONFIG_TIMER */
/** Frequency of the hardware high precision timer. */
#define TIMER_HW_HPTICKS_PER_SEC DIV_ROUND(CPU_FREQ, TIMER_PRESCALER)
/**
* System timer: additional division after the prescaler
* 12288000 / 64 / 192 (0..191) = 1 ms
*/
#define OCR_DIVISOR (DIV_ROUND(DIV_ROUND(CPU_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC) - 1)
/** Not needed, IRQ timer flag cleared automatically */
#define timer_hw_irq() do {} while (0)
/** Not needed, timer IRQ handler called only for timer source */
#define timer_hw_triggered() (true)
void timer_hw_init(void);
#endif /* DRV_TIMER_MEGA_H */

View file

@ -0,0 +1,78 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
* All Rights Reserved.
* -->
*
* \brief Some simple delay routines.
*
* Simple serial driver
* \author Francesco Sacchi <batt@develer.com>
*/
#warning FIXME:This module is obsolete, yuo must refactor it.
#if 0
#include <hw/hw_cpufreq.h>
#include "timer_simple_avr.h"
#include <drv/wdt.h>
#include <cfg/compiler.h>
#include <cfg/macros.h> /* BV() */
#include <avr/io.h>
#define MS_PER_SEC 1000UL
#define TIMER_PRESCALER 64UL
#define TIMER_DELAY_1MS (255 - CPU_FREQ / TIMER_PRESCALER / MS_PER_SEC)
/**
* Wait \a time ms using timer 0.
*
*/
void timer_delay(mtime_t time)
{
/* Set timer clock to clock_freq/64 */
TCCR0 = BV(CS02);
while (time--)
{
/* Initialize timer counter register */
TCNT0 = TIMER_DELAY_1MS;
/* Clear overflow bit. */
TIFR |= BV(TOV0);
/* Wait overflow. */
while (!(TIFR & BV(TOV0)));
#if CONFIG_WATCHDOG
wdt_reset();
#endif
}
}
#endif

View file

@ -0,0 +1,49 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
* -->
*
* \brief Simple delay routine
*
* \author Francesco Sacchi <batt@develer.com>
*/
#ifndef DRV_TIMER_SIMPLE_AVR_H
#define DRV_TIMER_SIMPLE_AVR_H
#warning FIXME:This module is obsolete, yuo must refactor it.
#if 0
#include <compiler.h>
extern void timer_delay(mtime_t time);
#endif /* TIMER_SIMPLE_H */
#endif

View file

@ -0,0 +1,126 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2005, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2011 Onno <developer@gorgoz.org>
*
* -->
*
* \author Onno <developer@gorgoz.org>
*
* \brief Low-level timer module for AVR XMEGA (implementation).
*
* This file is heavily inspired by the AVR implementation for BeRTOS,
* but uses a different approach for implementing the different debug
* ports, by using the timer structs.
*
* This module is automatically included so no need to include
* in test list.
* notest: all
*/
#include <drv/timer_xmega.h>
#include <cfg/macros.h> // BV()
#include <cpu/types.h>
#include <cpu/irq.h>
#include <avr/io.h>
/* Helper MACROS taken from the Atmel examples and altered
*
* The AVR XMEGA has different structures for TC0 and TC1,
* however these only differ in the amount of compare/capture
* channels, so for this purpose they can be used exactly the same
*/
//check if the bitvalues of the TC0 and TC1 Timer/Counters are really the same
#if TC0_CLKSEL_gm != TC1_CLKSEL_gm || TC0_WGMODE_gm != TC1_WGMODE_gm || TC0_OVFINTLVL_gm != TC1_OVFINTLVL_gm
#error TC0 and TC1 Timer/Counters cannot be configured with the same bitvalues
#endif
#define TIMER_CONFIG_CLOCK_SOURCE(_clkSel)\
((TIMERCOUNTER).CTRLA = ((TIMERCOUNTER).CTRLA & ~TC0_CLKSEL_gm) | _clkSel)
#define TIMER_CLEAR_FLAGS() ((TIMERCOUNTER).INTFLAGS = 0xFF)
#define TIMER_SET_PERIOD( _period ) ( (TIMERCOUNTER).PER = (_period) )
#define TIMER_SET_OVERFLOW_INTERRUPT_LEVEL( _interruptLevel )\
((TIMERCOUNTER).INTCTRLA = ( (TIMERCOUNTER).INTCTRLA & ~TC0_OVFINTLVL_gm ) | _interruptLevel)
#define TIMER_CONFIG_WGM(_wgm)\
((TIMERCOUNTER).CTRLB = ( (TIMERCOUNTER).CTRLB & ~TC0_WGMODE_gm ) | _wgm)
#define TIMER_RESET() ( (TIMERCOUNTER).CTRLFSET = TC_CMD_RESET_gc )
//Define TIMER_PRESCALE_REG_VALUE bases on the provided
//TIMER_PRESCALER value
#if TIMER_PRESCALER == 0
#define TIMER_CLKSEL_gc TC_CLKSEL_OFF_gc
#elif TIMER_PRESCALER == 1
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV1_gc
#elif TIMER_PRESCALER == 2
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV2_gc
#elif TIMER_PRESCALER == 4
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV4_gc
#elif TIMER_PRESCALER == 16
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV16_gc
#elif TIMER_PRESCALER == 64
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV64_gc
#elif TIMER_PRESCALER == 256
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV256_gc
#elif TIMER_PRESCALER == 1024
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV1024_gc
#else
#error Invalid value for TIMER_PRESCALER has been defined! Using default of 1
#define TIMER_CLKSEL_gc TC_CLKSEL_DIV1_gc
#endif
void timer_hw_init(void)
{
//Save and disable IRQ
cpu_flags_t flags;
IRQ_SAVE_DISABLE(flags);
//disable the timer
TIMER_CONFIG_CLOCK_SOURCE(TC_CLKSEL_OFF_gc);
//clear all flags
TIMER_CLEAR_FLAGS();
//setup the Periode register value
//CNT register will be reset to 0 when CNT == PER
TIMER_SET_PERIOD(TIMER_PERIOD_VALUE);
//set the Waveform Generation Mode to Normal
TIMER_CONFIG_WGM(TC_WGMODE_NORMAL_gc);
//enable the overflow interrupt
//use the highest priority
TIMER_SET_OVERFLOW_INTERRUPT_LEVEL(TC_OVFINTLVL_HI_gc);
//enable timer by setting the correct prescaler/clock
TIMER_CONFIG_CLOCK_SOURCE(TIMER_CLKSEL_gc);
//Restore IRQ
IRQ_RESTORE(flags);
}

View file

@ -0,0 +1,134 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2003, 2004, 2005, 2010 Develer S.r.l. (http://www.develer.com/)
* Copyright 2000 Bernie Innocenti <bernie@codewiz.org>
* Copyright 2011 Onno <developer@gorgoz.org>
*
* -->
*
* \brief Low-level timer module for AVR XMEGA (interface).
*
* This file is heavily inspired by the AVR implementation for BeRTOS,
* but uses a different approach for implementing the different debug
* ports, by using the timer structs.
*
* \author Onno <developer@gorgoz.org>
*
*/
#ifndef DRV_TIMER_XMEGA_H
#define DRV_TIMER_XMEGA_H
#include <hw/hw_cpufreq.h> /* CPU_FREQ */
#include "cfg/cfg_timer.h" /* CONFIG_TIMER */
#include <cfg/compiler.h> /* uint8_t */
#include <cfg/macros.h> /* DIV_ROUND */
#include <avr/io.h>
#include <avr/interrupt.h>
/*
* \name Values for CONFIG_TIMER.
*
* Select which hardware timer interrupt to use for system clock and softtimers.
* $WIZ$ timer_select = "TIMER_USE_TCC0", "TIMER_USE_TCC1", "TIMER_USE_TCD0", "TIMER_USE_TCE0", "TIMER_USE_TCD1", "TIMER_DEFAULT"
*/
#define TIMER_USE_TCC0 1
#define TIMER_USE_TCC1 2
#define TIMER_USE_TCD0 3
#define TIMER_USE_TCE0 4
// The XMEGA A Family has one extra timer
#ifdef CPU_AVR_XMEGA_A
#define TIMER_USE_TCD1 5
#endif
#define TIMER_DEFAULT TIMER_USE_TCC1 ///< Default system timer
/*
* Hardware dependent timer initialization.
*/
#if (CONFIG_TIMER == TIMER_USE_TCC0)
#define TIMER_OVF_VECT TCC0_OVF_vect
#define TIMERCOUNTER TCC0
#elif (CONFIG_TIMER == TIMER_USE_TCC1)
#define TIMER_OVF_VECT TCC1_OVF_vect
#define TIMERCOUNTER TCC1
#elif (CONFIG_TIMER == TIMER_USE_TCD0)
#define TIMER_OVF_VECT TCD0_OVF_vect
#define TIMERCOUNTER TCD0
#elif (CONFIG_TIMER == TIMER_USE_TCE0)
#define TIMER_OVF_VECT TCE0_OVF_vect
#define TIMERCOUNTER TCE0
#elif (CONFIG_TIMER == TIMER_USE_TCD1)
#define TIMER_OVF_VECT TCD1_OVF_vect
#define TIMERCOUNTER TCD1
#else
#error Unimplemented value for CONFIG_TIMER
#endif /* CONFIG_TIMER */
//define the Interrupt Service Routine for this Timer Mode
#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER_OVF_VECT)
//define the Ticks per second we want
#define TIMER_TICKS_PER_SEC 1000
//define the Prescaler to use, which is dependend on the amount
//of ticks per second, the maximum value for the TOP value of the
//timer (0xFFFF) and the clock frequency.
//The maximum clock frequency is 32Mhz, so as long as the TIMER_TICKS_PER_SEC
//is larger then (about) 500 no prescaler is required.
#define TIMER_PRESCALER 1
//define the TOP/PERIOD value
#define TIMER_PERIOD_VALUE DIV_ROUND(DIV_ROUND(CPU_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC)
//check if the TIMER_PRESCALER is large enough to accomate for the TIMER_TICKS_PER_SEC
#if TIMER_PERIOD_VALUE > 0xFFFF
#error Timer cannot generate the required Ticks per second, please adjust TIMER_PRESCALER
#endif
//define TIMER_HW_CNT it is used by the timer.c module to determine the 'edge' of the hardware counter
#define TIMER_HW_CNT TIMER_PERIOD_VALUE
/** Frequency of the hardware high precision timer. */
#define TIMER_HW_HPTICKS_PER_SEC DIV_ROUND(CPU_FREQ, TIMER_PRESCALER)
// Type of time expressed in ticks of the hardware high-precision timer
typedef uint16_t hptime_t;
#define SIZEOF_HPTIME_T 2
INLINE hptime_t timer_hw_hpread(void)
{
return (TIMERCOUNTER).CNT;
}
/* Not needed, IRQ timer flag cleared automatically */
#define timer_hw_irq() do {} while (0)
/* Not needed, timer IRQ handler called only for timer source */
#define timer_hw_triggered() (true)
void timer_hw_init(void);
#endif /* DRV_TIMER_XMEGA_H */

View file

@ -0,0 +1,96 @@
/**
* \file
* <!--
* This file is part of BeRTOS.
*
* Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*
* Copyright 2004 Develer S.r.l. (http://www.develer.com/)
*
* -->
*
* \brief Watchdog interface for AVR architecture.
*
* \note The avr-libc already provide an api to manage the watchdog on AVR architecture.
* In avr-libc are also available several constants used to set the timeout value
* (see documentation for more detail).
*
*
* \author Daniele Basile <asterix@develer.com>
*
*/
#ifndef DRV_WDT_AVR_H
#define DRV_WDT_AVR_H
#include "cfg/cfg_wdt.h"
#include <cfg/compiler.h> // INLINE
#include <avr/io.h>
#include <avr/wdt.h>
/**
* Reset the watchdog timer.
*
* This functions is already defind in avr-libc.
*/
// void wdt_reset(void)
/**
* Start the watchdog timer that fire at the select
* timeout.
*
* \param _timeout you can use the macro that are defineded in
* avr/wdt.h.
*
* (from avr libc documentation)
* WDTO_15MS
* WDTO_30MS
* WDTO_60MS
* WDTO_120MS
* WDTO_250MS
* WDTO_500MS
* WDTO_1S
* WDTO_2S
* WDTO_4S
* WDTO_8S
*/
INLINE void wdt_start(uint32_t _timeout)
{
uint8_t timeout = _timeout;
wdt_enable(timeout);
}
/**
* Stop watchdog timer.
*/
INLINE void wdt_stop(void)
{
wdt_disable();
}
#endif /* DRV_WDT_AVR_H */