Add AVR32 port and demo files.

This commit is contained in:
Richard Barry 2007-04-01 19:37:01 +00:00
parent b727359f1b
commit bf2b676eaa
52 changed files with 12194 additions and 0 deletions

View file

@ -0,0 +1,283 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Flash Controller driver.
*
* This file defines a useful set of functions for the flash controller
* on AVR32A devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32A devices.
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "flashc.h"
/*! Flash command key*/
#define X_KEY 0xA5000000
/*! Get locke error.
* \warning: Flash status register (FCR) is read, and Programmming error status may be automatically
* cleared when reading FCR.
*/
#define Flashc_get_lockerror() ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_LOCKE_MASK)>>AVR32_FLASHC_FSR_LOCKE_OFFSET)
/*! Get programming error.
* \warning: Flash status register (FCR) is read, and locke error status may be automatically
* cleared when reading FCR.
*/
#define Flashc_get_programming_error() ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_PROGE_MASK)>>AVR32_FLASHC_FSR_PROGE_OFFSET)
/*! Check if page is erased (used with the quick page read command result)
* \warning: Flash status register (FCR) is read, and error status may be automatically
* cleared when reading FCR.
*/
#define Flashc_is_page_erased() ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK)>>AVR32_FLASHC_FSR_QPRR_OFFSET)
/*! Set: No erase is performed before programming. */
#define Flashc_set_no_erase_before_programming() (AVR32_FLASHC.fcr |= AVR32_FLASHC_FCR_NEBP_MASK)
/*! Set: Page erase is performed before programming. */
#define Flashc_set_erase_before_programming() (AVR32_FLASHC.fcr &= ~AVR32_FLASHC_FCR_NEBP_MASK)
/*!
* Memcopy function
* \param *s1 destination
* \param *s2 source
* \param n word numbers to copy
*/
U32 *flashc_memcpy(U32 *s1, const U32 *s2, const U32 n) {
register U32 *u32pdst;
register U32 i;
u32pdst = s1;
for (i = n; i > 0; i--) *u32pdst++ = *s2++;
return s1;
}
/*!
* Set number of wait state for flash controller.
*/
int flashc_set_wait_state(U16 ws)
{
if (ws > 1 ) return FLASHC_INVALID_INPUT;
if (ws == 0) AVR32_FLASHC.fcr &= ~AVR32_FLASHC_FWS_MASK; // update flash control register FCR
if (ws == 1) AVR32_FLASHC.fcr |= AVR32_FLASHC_FWS_MASK;
return FLASHC_SUCCESS;
}
/*!
* Page write n
* \param n page number
* \warning Assuming the page address is already loaded
*/
void flashc_page_write_n(U16 page_n) {
register U32 u32Command;
u32Command = X_KEY | AVR32_FLASHC_FCMD_CMD_WP; // key and command
u32Command |= ((page_n<<AVR32_FLASHC_FCMD_PAGEN_OFFSET) & AVR32_FLASHC_FCMD_PAGEN_MASK); // update page field
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32Command;
}
/* Page write
* Assuming the page address is already loaded
*/
void flashc_page_write(U16 page_n) {
register U32 u32Command;
u32Command = X_KEY | AVR32_FLASHC_FCMD_CMD_WP; // key and command
u32Command |= ((page_n<<AVR32_FLASHC_FCMD_PAGEN_OFFSET) & AVR32_FLASHC_FCMD_PAGEN_MASK); // update page field
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32Command;
}
/* Clear page buffer */
void flashc_clear_page_buffer(void){
register U32 u32Command;
u32Command = X_KEY | AVR32_FLASHC_FCMD_CMD_CPB; // key and command clear page buffer
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32Command;
}
/* Page erase
* Assuming the page address is already loaded
*/
void flashc_erase_page(U16 page_n){
register U32 u32Command;
u32Command = X_KEY | AVR32_FLASHC_FCMD_CMD_EP; // key and command,
u32Command |= ((page_n<<AVR32_FLASHC_FCMD_PAGEN_OFFSET) & AVR32_FLASHC_FCMD_PAGEN_MASK); // update page field
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32Command;
}
/* Erase all Pages */
void flashc_erase_all(void){
register U32 u32Command;
u32Command = X_KEY | AVR32_FLASHC_FCMD_CMD_EA; // key and command,
//u32Command |= ((page_n<<AVR32_FLASHC_FCMD_PAGEN_OFFSET) & AVR32_FLASHC_FCMD_PAGEN_MASK); // update page field
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32Command;
flashc_busy_wait();
}
/* Erase a page and check if OK with the quick page read command */
int flashc_erase_page_and_check(U16 page_n)
{
flashc_erase_page(page_n); // erase page page_n first
flashc_busy_wait();
AVR32_FLASHC.fcmd = X_KEY | ((page_n<<AVR32_FLASHC_PAGEN_OFFSET)&AVR32_FLASHC_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_QPR; // qpr on current page number
while(!((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK)>>AVR32_FLASHC_FSR_FRDY_OFFSET));
if (Flashc_is_page_erased() == 0) // check QPRR bit in FCR to have the result of the quick page read
return FLASHC_FAILURE;
return FLASHC_SUCCESS;
}
/*!
* Page load and write
* \warning Dest is a FLASH address at a page size boundary
* (assuming the page is already erased)
*/
void flashc_page_copy_write(U32 *u32dest, const U32 *src) {
register U32 u32command,pagen;
flashc_memcpy(u32dest, src, AVR32_FLASHC_PAGE_SIZE / 4); // copy Src to Dest (Dest is a FLASH address at a page boundary)
pagen = (U32)(((U32)u32dest-AVR32_FLASH_ADDRESS)/AVR32_FLASHC_PAGE_SIZE); // memory page addr
u32command = X_KEY | ((pagen<<AVR32_FLASHC_PAGEN_OFFSET)&AVR32_FLASHC_PAGEN_MASK) |AVR32_FLASHC_FCMD_CMD_WP; // key and command
flashc_busy_wait();
AVR32_FLASHC.fcmd = u32command;
}
/* Copy data into page buffer */
#if __GNUC__
__attribute__((__always_inline__))
#endif
static __inline__ void flash_fill_temp_buffer(U32 u32Data, U32 u32Address)
{
*((U32*)u32Address) = u32Data;
}
/* Read word from flash
* addr should be 32-bit aligned.
*/
#if __GNUC__
__attribute__((__always_inline__))
#endif
static __inline__ U32 flash_rd_word(U32 const* addr)
{
return *addr;
}
/**
* This function allows to write up to 65535 bytes in the flash memory.
* This function manages alignement issue (byte and page alignements).
*/
int flash_wr_block(U32 * src, U32 dst, U32 n)
{
U32 u32NbWord=0;
U32 u32Temp=0;
U32 u32SavePageAddr=0;
U32 u32Address = dst-(dst%AVR32_FLASHC_PAGE_SIZE); // Compute the start of the page to be modified
while(n) // While there is data to load from src buffer
{
// u32Address = dst-((dst&0xFFFFffff)%AVR32_FLASHC_PAGE_SIZE); // Compute the start of the page to be modified
u32SavePageAddr = (u32Address-AVR32_FLASH_ADDRESS)/AVR32_FLASHC_PAGE_SIZE; //memorize page addr
// For each word in this page
for(u32NbWord=0 ; u32NbWord<AVR32_FLASHC_PAGE_SIZE/4 ; u32NbWord++)
{
if(n) //Still some data to load from src
{
if(u32Address >= dst) //current address is inside the target range adr
{
u32Temp = * ((U32*)src); // load word from buffer src
src++;
n--;
}
else //current word addr out of dst target
{
u32Temp = flash_rd_word((U32 const*)u32Address); // load word from existing flash
}
}
else //complete page with words from existing flash
{
u32Temp = flash_rd_word((U32 const*)u32Address);
}
flash_fill_temp_buffer(u32Temp, u32Address); // fill page buffer
u32Address+=4; // one more word for u32Address
}
// u32Address = u32SavePageAddr*AVR32_FLASHC_PAGE_SIZE+AVR32_FLASH_ADDRESS;
/*
// Done with QPR
for(u32NbWord=0 ; u32NbWord<AVR32_FLASHC_PAGE_SIZE/4 ; u32NbWord++)
{
if(flash_rd_word((U32 farcode*)u32Address)!=0xFFFFffff) // check if the page is erased
{
Flash_page_erase(u32SavePageAddr);
break;
}
u32Address+=4;
}
*/
// Check if page is erased
AVR32_FLASHC.fcmd = X_KEY | ((u32SavePageAddr<<AVR32_FLASHC_PAGEN_OFFSET)&AVR32_FLASHC_PAGEN_MASK) | AVR32_FLASHC_CMD_QPR; // qpr on current page number
while(!((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK)>>AVR32_FLASHC_FSR_FRDY_OFFSET));
if ( (AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK)>> AVR32_FLASHC_FSR_QPRR_OFFSET == 0 ) // test QPR bit in FSR
{ // erase page
AVR32_FLASHC.fcmd = X_KEY | ((u32SavePageAddr<<AVR32_FLASHC_PAGEN_OFFSET)&AVR32_FLASHC_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_EP; //page n erase cmd
while(!((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK)>>AVR32_FLASHC_FSR_FRDY_OFFSET));
}
flashc_page_write_n(u32SavePageAddr); // write the corresponding page number
flashc_clear_page_buffer();
} // end while (n)
return FLASHC_SUCCESS;
}
/* Erase all flash with pages access */
void flash_erase(void)
{
U32 u32NbPage = flashc_get_page_count();
while (u32NbPage) flashc_erase_page(--u32NbPage);
}

View file

@ -0,0 +1,193 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Flash Controller driver .h file.
*
* This file defines a useful set of functions for the flash controller
* on AVR32A devices.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32A devices.
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FLASHC_H_
#define _FLASHC_H_
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
# include <avr32/uc3a0512.h>
#else
# error Unknown compiler
#endif
#include "compiler.h"
/*! Value returned by function when it completed successfully */
#define FLASHC_SUCCESS 0
/*! Value returned by function when it was unable to complete successfully
for some unspecified reason */
#define FLASHC_FAILURE -1
/*! Value returned by function when the input paramters are out of range */
#define FLASHC_INVALID_INPUT 1
/*! Get Flash size */
#if __GNUC__
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned int flashc_get_flash_size(void)
{
static const unsigned int FLASHC_SIZE[1 << AVR32_FLASHC_FSR_FSZ_SIZE] =
{
32 << 10,
64 << 10,
128 << 10,
256 << 10,
384 << 10,
512 << 10,
768 << 10,
1024 << 10
};
return FLASHC_SIZE[Rd_bitfield(AVR32_FLASHC.fsr, AVR32_FLASHC_FSR_FSZ_MASK)];
}
/*! Get Flash page count */
#if __GNUC__
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned int flashc_get_page_count(void)
{
return flashc_get_flash_size() / AVR32_FLASHC_PAGE_SIZE;
}
/*! Get Flash page count per region */
#if __GNUC__
__attribute__((__always_inline__))
#endif
extern __inline__ unsigned int flashc_get_page_count_per_region(void)
{
return flashc_get_page_count() / 16;
}
/*! Wait flash ready status, the application must wait before running a new command.
* Warning: Flash status register (FCR) is read, and error status may be automatically
* cleared when reading FCR.
*/
#if __GNUC__
__attribute__((__always_inline__))
#endif
extern __inline__ void flashc_busy_wait(void)
{
while (!Tst_bits(AVR32_FLASHC.fsr, AVR32_FLASHC_FSR_FRDY_MASK));
}
/*! Check if security bit is active.
* \warning: Flash status register (FCR) is read, and error status may be automatically
* cleared when reading FCR.
*/
#if __GNUC__
__attribute__((__always_inline__))
#endif
extern __inline__ Bool flashc_is_security_active(void)
{
return Tst_bits(AVR32_FLASHC.fsr, AVR32_FLASHC_FSR_SECURITY_MASK);
}
/*! \brief Memcopy function
* \param *s1 destination
* \param *s2 source
* \param n number of words to copy
*/
extern U32 *flashc_memcpy(U32 *s1, const U32 *s2, const U32 n);
/*! \brief Set number of wait state
* \param ws 0 if for no-wait state, for 1 wait-state
* \return FLASHC_SUCCESS, FLASHC_INVALID_INPUT or FLASHC_FAILURE
*/
extern int flashc_set_wait_state(U16 ws);
/*! \brief Page write number n. Assuming page bubuffer is already loaded.
* \param n Page number
*/
extern void flashc_page_write_n(U16 n);
/*! \brief Page write
* Assuming the page address is already loaded
*/
extern void flashc_page_write(U16 page_n);
/*! \brief Clear page buffer
*/
extern void flashc_clear_page_buffer(void);
/*! \brief Page erase
* Assuming the page address is already loaded
*/
extern void flashc_erase_page(U16 page_n);
/*! \brief Erase all Pages
*/
extern void flashc_erase_all(void);
/*! \brief Erase a page and check if erase is OK
*/
extern int flashc_erase_page_and_check(U16 page_n);
/*! \brief Page load and write
* \warning Dest is a FLASH address at a page boundary
* (assuming the page is already erased)
*/
extern void flashc_page_copy_write(U32 *Dest, const U32 *Src) ;
/*! \brief This function allows to write up to 65535 bytes in the flash memory.
* This function manages alignement issue (byte and page alignements).
*
* \param *src Address of data to write.
* \param dst Start address in flash memory where write data
* \param n Number of word to write
* \return FLASHC_SUCCESS or FLASHC_FAILURE
*/
extern int flash_wr_block(U32 * src, U32 dst, U32 n);
#endif /* #ifndef _FLASHC_H_*/

View file

@ -0,0 +1,216 @@
/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief GPIO driver for AVR32 UC3.
*
* This file defines a useful set of functions for the GPIO.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a PWM module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gpio.h"
//! GPIO module instance.
#define GPIO AVR32_GPIO
int gpio_enable_module(avr32_gpiomap_t gpiomap, int size)
{
int i,status=GPIO_SUCCESS;
for(i=0; i<size; i++) {
status |= gpio_enable_module_pin(**gpiomap, *(*gpiomap+1) );
gpiomap++;
}
return status;
}
int gpio_enable_module_pin(int pin, int function)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
// Enable the correct function
switch(function)
{
case 0: // A function
gpio_port->pmr0c = (1<<(pin%32));
gpio_port->pmr1c = (1<<(pin%32));
break;
case 1: // B function
gpio_port->pmr0s = (1<<(pin%32));
gpio_port->pmr1c = (1<<(pin%32));
break;
case 2: // C function
gpio_port->pmr0c = (1<<(pin%32));
gpio_port->pmr1s = (1<<(pin%32));
break;
default:
return GPIO_INVALID_ARGUMENT;
}
// Disable gpio control
gpio_port->gperc = (1<<(pin%32));
return GPIO_SUCCESS;
}
void gpio_enable_gpio(avr32_gpiomap_t gpiomap, int size)
{
int i;
for(i=0; i<size; i++){
gpio_enable_gpio_pin(**gpiomap);
gpiomap++;
}
}
void gpio_enable_gpio_pin(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
gpio_port->gpers = 1<<(pin%32);
}
void gpio_enable_gpio_glitch_filter(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
gpio_port->gfers = 1<<(pin%32);
}
void gpio_disable_gpio_glitch_filter(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
gpio_port->gferc = 1<<(pin%32);
}
void gpio_disable_module(avr32_gpiomap_t gpiomap, int size)
{
int i;
for(i=0; i<size; i++){
gpio_disable_gpio_pin(**gpiomap);
gpiomap++;
}
}
void gpio_disable_gpio_pin(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
gpio_port->gperc = 1<<(pin%32);
}
int gpio_pin_value(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
return (gpio_port->pvr >>(pin%32))&1;
}
void gpio_set_gpio_pin(int pin)
{
// The port holding that pin.
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32];
gpio_port->ovrs = (1<<(pin%32)); // Value to be driven on the I/O line: 1
gpio_port->oders = (1<<(pin%32)); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = (1<<(pin%32)); // The GPIO module controls that pin.
}
void gpio_clr_gpio_pin(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32]; // The port holding that pin.
gpio_port->ovrc = (1<<(pin%32)); // Value to be driven on the I/O line: 0
gpio_port->oders = (1<<(pin%32)); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = (1<<(pin%32)); // The GPIO module controls that pin.
}
void gpio_tgl_gpio_pin(int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32]; // The port holding that pin.
gpio_port->ovrt = (1<<(pin%32)); // Toggle the I/O line.
gpio_port->oders = (1<<(pin%32)); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = (1<<(pin%32)); // The GPIO module controls that pin.
}
void gpio_cfg_int_gpio_pin(int pin, int level)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin/32]; // The port holding that pin.
gpio_port->gpers = 1<<(pin%32); // GPIO controller enable
gpio_port->gfers = 1<<(pin%32); // GPIO glitch filter enable
switch (level)
{
case GPIO_RISING_EDGE:
{
// mode rising edge
gpio_port->imr0s = 1<<(pin%32);
gpio_port->imr1c = 1<<(pin%32);
break;
}
case GPIO_FALLING_EDGE:
{
// mode falling edge
gpio_port->imr0c = 1<<(pin%32);
gpio_port->imr1s = 1<<(pin%32);
break;
}
default :
{
// mode pin change
gpio_port->imr0c = 1<<(pin%32);
gpio_port->imr1c = 1<<(pin%32);
break;
}
}
gpio_port->iers = 1<<(pin%32); // GPIO interrupt enable
}

View file

@ -0,0 +1,195 @@
/* This header file is part of the ATMEL FREERTOS-0.9.0 Release */
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief GPIO header for AVR32 UC3.
*
* This file contains basic GPIO driver functions.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a GPIO module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
#else
# error Unknown compiler
#endif
/*! \name General GPIO API defines
* These values are returned by the GPIO API:
*/
//! @{
#define GPIO_SUCCESS 0 //!< Function successfully completed
#define GPIO_FAILURE -1 //!< Function did not successfully complete for some unspecified reason
#define GPIO_INVALID_ARGUMENT 1 //!< Input paramters are out of range
//! @}
/*! \name Interrupt configuration defines
* Configure the method used to trigger the interrupt:
*/
//! @{
#define GPIO_RISING_EDGE 1 //!< configure IT upon Rising Edge
#define GPIO_FALLING_EDGE 2 //!< configure IT upon Falling Edge
#define GPIO_INPUT_CHANGE 3 //!< configure IT upon Pin Change
//! @}
/*!
* A type definitions of pins and module connectivity.
* First column is the pin number, the second is gpio connectivity.
*/
typedef char avr32_gpiomap_t[][2];
/*!
* \brief Enable a module pin for a given set of pins and respective modules.
*
* \param gpiomap A list of pins and pio connectivity
* \param size The number of pins in \a gpiomap
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT
*/
extern int gpio_enable_module(avr32_gpiomap_t gpiomap, int size);
/*!
* \brief Enable a special module (function) for a pin (pin number).
*
* \param pin The pin number
* \param function The pin function
* \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT
*/
extern int gpio_enable_module_pin(int pin, int function);
/*!
* \brief Enable pins of a module according gpiomap.
*
* \param gpiomap The pin map
* \param size The number of pins in \a gpiomap
*/
extern void gpio_enable_gpio(avr32_gpiomap_t gpiomap, int size);
/*!
* \brief Enable the GPIO module to control the pin.
*
* \param pin The pin number
*/
extern void gpio_enable_gpio_pin(int pin);
/*!
* \brief Enable the GPIO glitch filter.
*
* When the glitch filter is enabled, a
* glitch with duration of less than 1 clock cycle is automatically rejected, while a pulse with duration
* of 2 clock cycles or more is accepted. For pulse durations between 1 clock cycle and 2 clock
* cycles, the pulse may or may not be taken into account, depending on the precise timing of its
* occurrence. Thus for a pulse to be guaranteed visible it must exceed 2 clock cycles, whereas for
* a glitch to be reliably filtered out, its duration must not exceed 1 clock cycle. The filter introduces
* 2 clock cycles latency.
*
* \param pin The pin number
* \return \ref GPIO_SUCCESS
*/
extern void gpio_enable_gpio_glitch_filter(int pin);
/*!
* \brief Disable the GPIO glitch filter.
*
* \param pin The pin number
*/
extern void gpio_disable_gpio_glitch_filter(int pin);
/*!
* \brief Return the pin value
*
* \param pin The pin number
* \return pin value
*/
extern int gpio_pin_value(int pin);
/*!
* \brief Disable the GPIO module to control a set of pins according to gpiomap.
*
* \param gpiomap The pin map
* \param size The number of pins in \a gpiomap
*/
extern void gpio_disable_module(avr32_gpiomap_t gpiomap, int size);
/*!
* \brief Disable the GPIO module to control the pin.
*
* \param pin The pin number
*/
extern void gpio_disable_gpio_pin(int pin);
/*!
* \brief Configure a pin to generate IT
*
* \param pin GPIO pin number to configure.
* \param level level to configure (\ref GPIO_RISING_EDGE, \ref GPIO_FALLING_EDGE, \ref GPIO_INPUT_CHANGE).
*/
extern void gpio_cfg_int_gpio_pin(int pin, int level);
/*!
* \brief Drive a gpio pin value to 1.
*
* \param pin The pin number
*/
extern void gpio_set_gpio_pin(int pin);
/*!
* \brief Drive a gpio pin value to 0.
*
* \param pin The pin number
*/
extern void gpio_clr_gpio_pin(int pin);
/*!
* \brief This function toggle a gpio pin value.
*
* \param pin The pin number
*/
extern void gpio_tgl_gpio_pin(int pin);
#endif // _GPIO_H_

View file

@ -0,0 +1,201 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief INTC driver for AVR32 UC3.
*
* AVR32 Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
#else
# error Unknown compiler
#endif
#include "compiler.h"
#include "preprocessor.h"
#include "intc.h"
//! Values to store in the interrupt priority registers for the various interrupt priority levels.
extern const unsigned int ipr_val[AVR32_INTC_NUM_INT_LEVELS];
//! Creates a table of interrupt line handlers per interrupt group in order to optimize RAM space.
//! Each line handler table contains a set of pointers to interrupt handlers.
#define DECL_INT_LINE_HANDLER_TABLE(GRP, unused) \
static volatile __int_handler _int_line_handler_table_##GRP[AVR32_INTC_NUM_IRQS_PER_GRP##GRP];
MREPEAT(AVR32_INTC_NUM_INT_GRPS, DECL_INT_LINE_HANDLER_TABLE, ~);
#undef DECL_INT_LINE_HANDLER_TABLE
//! Table containing for each interrupt group the number of interrupt request
//! lines and a pointer to the table of interrupt line handlers.
static const struct
{
unsigned int num_irqs;
volatile __int_handler *_int_line_handler_table;
} _int_handler_table[AVR32_INTC_NUM_INT_GRPS] =
{
#define INSERT_INT_LINE_HANDLER_TABLE(GRP, unused) \
{AVR32_INTC_NUM_IRQS_PER_GRP##GRP, _int_line_handler_table_##GRP},
MREPEAT(AVR32_INTC_NUM_INT_GRPS, INSERT_INT_LINE_HANDLER_TABLE, ~)
#undef INSERT_INT_LINE_HANDLER_TABLE
};
/*! \brief Default interrupt handler.
*
* \note Taken and adapted from Newlib.
*/
#if __GNUC__
__attribute__((__interrupt__))
#elif __ICCAVR32__
__interrupt
#endif
static void _unhandled_interrupt(void)
{
// Catch unregistered interrupts.
while (TRUE);
}
/*! \brief Gets the interrupt handler of the current event at the \a int_lev
* interrupt priority level (called from exception.S).
*
* \param int_lev Interrupt priority level to handle.
*
* \return Interrupt handler to execute.
*
* \note Taken and adapted from Newlib.
*/
__int_handler _get_interrupt_handler(unsigned int int_lev)
{
// ICR3 is mapped first, ICR0 last.
// Code in exception.S puts int_lev in R12 which is used by AVR32-GCC to pass
// a single argument to a function.
unsigned int int_grp = (&AVR32_INTC.icr3)[INT3 - int_lev];
unsigned int int_req = AVR32_INTC.irr[int_grp];
// As an interrupt may disappear while it is being fetched by the CPU
// (spurious interrupt caused by a delayed response from an MCU peripheral to
// an interrupt flag clear or interrupt disable instruction), check if there
// are remaining interrupt lines to process.
// If a spurious interrupt occurs, the status register (SR) contains an
// execution mode and interrupt level masks corresponding to a level 0
// interrupt, whatever the interrupt priority level causing the spurious
// event. This behavior has been chosen because a spurious interrupt has not
// to be a priority one and because it may not cause any trouble to other
// interrupts.
// However, these spurious interrupts place the hardware in an unstable state
// and could give problems in other/future versions of the CPU, so the
// software has to be written so that they never occur. The only safe way of
// achieving this is to always clear or disable peripheral interrupts with the
// following sequence:
// 1: Mask the interrupt in the CPU by setting GM (or IxM) in SR.
// 2: Perform the bus access to the peripheral register that clears or
// disables the interrupt.
// 3: Wait until the interrupt has actually been cleared or disabled by the
// peripheral. This is usually performed by reading from a register in the
// same peripheral (it DOES NOT have to be the same register that was
// accessed in step 2, but it MUST be in the same peripheral), what takes
// bus system latencies into account, but peripheral internal latencies
// (generally 0 cycle) also have to be considered.
// 4: Unmask the interrupt in the CPU by clearing GM (or IxM) in SR.
// Note that steps 1 and 4 are useless inside interrupt handlers as the
// corresponding interrupt level is automatically masked by IxM (unless IxM is
// explicitly cleared by the software).
//
// Get the right IRQ handler.
//
// If several interrupt lines are active in the group, the interrupt line with
// the highest number is selected. This is to be coherent with the
// prioritization of interrupt groups performed by the hardware interrupt
// controller.
//
// If no handler has been registered for the pending interrupt,
// _unhandled_interrupt will be selected thanks to the initialization of
// _int_line_handler_table_x by INTC_init_interrupts.
//
// exception.S will provide the interrupt handler with a clean interrupt stack
// frame, with nothing more pushed onto the stack. The interrupt handler must
// manage the `rete' instruction, what can be done thanks to pure assembly,
// inline assembly or the `__attribute__((__interrupt__))' C function
// attribute.
return (int_req) ? _int_handler_table[int_grp]._int_line_handler_table[32 - clz(int_req) - 1] : NULL;
}
void INTC_init_interrupts(void)
{
unsigned int int_grp, int_req;
// For all interrupt groups,
for (int_grp = 0; int_grp < AVR32_INTC_NUM_INT_GRPS; int_grp++)
{
// For all interrupt request lines of each group,
for (int_req = 0; int_req < _int_handler_table[int_grp].num_irqs; int_req++)
{
// Assign _unhandled_interrupt as default interrupt handler.
_int_handler_table[int_grp]._int_line_handler_table[int_req] = &_unhandled_interrupt;
}
// Set the interrupt group priority register to its default value.
// By default, all interrupt groups are linked to the interrupt priority
// level 0 and to the interrupt vector _int0.
AVR32_INTC.ipr[int_grp] = ipr_val[INT0];
}
}
void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_lev)
{
unsigned int int_grp = irq / AVR32_INTC_MAX_NUM_IRQS_PER_GRP;
// Store in _int_line_handler_table_x the pointer to the interrupt handler, so
// that _get_interrupt_handler can retrieve it when the interrupt is vectored.
_int_handler_table[int_grp]._int_line_handler_table[irq % AVR32_INTC_MAX_NUM_IRQS_PER_GRP] = handler;
// Program the corresponding IPRX register to set the interrupt priority level
// and the interrupt vector offset that will be fetched by the core interrupt
// system.
// NOTE: The _intx functions are intermediate assembly functions between the
// core interrupt system and the user interrupt handler.
AVR32_INTC.ipr[int_grp] = ipr_val[int_lev & (AVR32_INTC_IPR0_INTLEV_MASK >> AVR32_INTC_IPR0_INTLEV_OFFSET)];
}

View file

@ -0,0 +1,104 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief INTC driver for AVR32 UC3.
*
* AVR32 Interrupt Controller driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _INTC_H_
#define _INTC_H_
#include "compiler.h"
//! Maximal number of interrupt request lines per group.
#define AVR32_INTC_MAX_NUM_IRQS_PER_GRP 32
//! Number of interrupt priority levels.
#define AVR32_INTC_NUM_INT_LEVELS (1 << AVR32_INTC_IPR0_INTLEV_SIZE)
/*! \name Interrupt Priority Levels
*/
//! @{
#define INT0 0 //!< Lowest interrupt priority level.
#define INT1 1
#define INT2 2
#define INT3 3 //!< Highest interrupt priority level.
//! @}
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
//! Pointer to interrupt handler.
#if __GNUC__
typedef void (*__int_handler)(void);
#elif __ICCAVR32__
typedef void (__interrupt *__int_handler)(void);
#endif
/*! \brief Initializes the hardware interrupt controller driver.
*
* \note Taken and adapted from Newlib.
*/
extern void INTC_init_interrupts(void);
/*! \brief Registers an interrupt handler.
*
* \param handler Interrupt handler to register.
* \param irq IRQ of the interrupt handler to register.
* \param int_lev Interrupt priority level to assign to the group of this IRQ.
*
* \warning The interrupt handler must manage the `rete' instruction, what can
* be done thanks to pure assembly, inline assembly or the
* `__attribute__((__interrupt__))' C function attribute.
*
* \warning If several interrupt handlers of a same group are registered with
* different priority levels, only the latest priority level set will
* be effective.
*
* \note Taken and adapted from Newlib.
*/
extern void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_lev);
#endif // __AVR32_ABI_COMPILER__
#endif // _INTC_H_

View file

@ -0,0 +1,608 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Power Manager driver.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "pm.h"
void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)
{
union {
unsigned long oscctrl0;
avr32_pm_oscctrl0_t OSCCTRL0;
} oscctrl0 ;
// Read
oscctrl0.oscctrl0 = pm->oscctrl0;
// Modify
oscctrl0.OSCCTRL0.mode = AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK;
// Write
pm->oscctrl0 = oscctrl0.oscctrl0;
}
void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)
{
union {
unsigned long oscctrl0;
avr32_pm_oscctrl0_t OSCCTRL0;
} oscctrl0 ;
// Read
oscctrl0.oscctrl0 = pm->oscctrl0;
// Modify
oscctrl0.OSCCTRL0.mode = (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :
AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3;
// Write
pm->oscctrl0 = oscctrl0.oscctrl0;
}
void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
union {
unsigned long oscctrl0;
avr32_pm_oscctrl0_t OSCCTRL0;
} oscctrl0 ;
// Read register
mcctrl.mcctrl = pm->mcctrl;
oscctrl0.oscctrl0 = pm->oscctrl0;
// Modify
mcctrl.MCCTRL.osc0en = 1;
oscctrl0.OSCCTRL0.startup = startup;
// Write back
pm->oscctrl0 = oscctrl0.oscctrl0;
pm->mcctrl = mcctrl.mcctrl;
while(!pm->ISR.osc0rdy); //For osc output valid
}
void pm_disable_clk0(volatile avr32_pm_t *pm)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
// Read register
mcctrl.mcctrl = pm->mcctrl;
// Modify
mcctrl.MCCTRL.osc0en = 0;
// Write back
pm->mcctrl = mcctrl.mcctrl;
}
void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
union {
unsigned long oscctrl0;
avr32_pm_oscctrl0_t OSCCTRL0;
} oscctrl0 ;
// Read register
mcctrl.mcctrl = pm->mcctrl;
oscctrl0.oscctrl0 = pm->oscctrl0;
// Modify
mcctrl.MCCTRL.osc0en = 1;
oscctrl0.OSCCTRL0.startup=startup;
// Write back
pm->mcctrl = mcctrl.mcctrl;
pm->oscctrl0 = oscctrl0.oscctrl0;
}
void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)
{
while(!pm->ISR.osc0rdy);
}
void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)
{
union {
unsigned long oscctrl1;
avr32_pm_oscctrl1_t OSCCTRL1;
} oscctrl1 ;
// Read
oscctrl1.oscctrl1= pm->oscctrl1;
// Modify
oscctrl1.OSCCTRL1.mode = AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK;
// Write
pm->oscctrl1 = oscctrl1.oscctrl1;
}
void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)
{
union {
unsigned long oscctrl1;
avr32_pm_oscctrl1_t OSCCTRL1;
} oscctrl1 ;
// Read
oscctrl1.oscctrl1= pm->oscctrl1;
// Modify
oscctrl1.OSCCTRL1.mode = (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :
AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3;
// Write
pm->oscctrl1 = oscctrl1.oscctrl1;
}
void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
union {
unsigned long oscctrl1;
avr32_pm_oscctrl1_t OSCCTRL1;
} oscctrl1 ;
// Read register
mcctrl.mcctrl = pm->mcctrl;
oscctrl1.oscctrl1 = pm->oscctrl1;
mcctrl.MCCTRL.osc1en = 1;
oscctrl1.OSCCTRL1.startup=startup;
// Write back
pm->oscctrl1 = oscctrl1.oscctrl1;
pm->mcctrl = mcctrl.mcctrl;
while(!pm->ISR.osc1rdy);
}
void pm_disable_clk1(volatile avr32_pm_t *pm)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
// Read register
mcctrl.mcctrl = pm->mcctrl;
// Modify
mcctrl.MCCTRL.osc1en = 0;
// Write back
pm->mcctrl = mcctrl.mcctrl;
}
void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
union {
unsigned long oscctrl1;
avr32_pm_oscctrl1_t OSCCTRL1;
} oscctrl1 ;
// Read register
mcctrl.mcctrl = pm->mcctrl;
oscctrl1.oscctrl1 = pm->oscctrl1;
mcctrl.MCCTRL.osc1en = 1;
oscctrl1.OSCCTRL1.startup=startup;
// Write back
pm->oscctrl1 = oscctrl1.oscctrl1;
pm->mcctrl = mcctrl.mcctrl;
}
void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)
{
while(!pm->ISR.osc1rdy);
}
void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)
{
union {
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} u_ctrl;
u_ctrl.oscctrl32 = pm->oscctrl32;
u_ctrl.OSCCTRL32.mode = AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK;
pm->oscctrl32 = u_ctrl.oscctrl32;
}
void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)
{
union {
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} u_ctrl;
u_ctrl.oscctrl32 = pm->oscctrl32;
u_ctrl.OSCCTRL32.mode = AVR32_PM_OSCCTRL32_MODE_CRYSTAL;
pm->oscctrl32 = u_ctrl.oscctrl32;
}
void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} oscctrl32 ;
// Read register
oscctrl32.oscctrl32 = pm->oscctrl32;
// Modify
oscctrl32.OSCCTRL32.osc32en = 1;
oscctrl32.OSCCTRL32.startup=startup;
// Write back
pm->oscctrl32 = oscctrl32.oscctrl32;
while(!pm->ISR.osc32rdy);
}
void pm_disable_clk32(volatile avr32_pm_t *pm)
{
// To get rid of a GCC bug
// This makes C code longer, but not ASM
union {
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} oscctrl32 ;
// Read register
oscctrl32.oscctrl32 = pm->oscctrl32;
// Modify
oscctrl32.OSCCTRL32.osc32en = 0;
// Write back
pm->oscctrl32 = oscctrl32.oscctrl32;
}
void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
{
union {
unsigned long oscctrl32;
avr32_pm_oscctrl32_t OSCCTRL32;
} oscctrl32 ;
// Read register
oscctrl32.oscctrl32 = pm->oscctrl32;
// Modify
oscctrl32.OSCCTRL32.osc32en = 1;
oscctrl32.OSCCTRL32.startup=startup;
// Write back
pm->oscctrl32 = oscctrl32.oscctrl32;
}
void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)
{
// To get rid of a GCC bug
// This makes C code longer, but not ASM
while(!pm->ISR.osc32rdy);
}
void pm_cksel(volatile avr32_pm_t *pm,
unsigned int pbadiv,
unsigned int pbasel,
unsigned int pbbdiv,
unsigned int pbbsel,
unsigned int hsbdiv,
unsigned int hsbsel)
{
// Force the compiler to generate only one 32 bits access
union {
avr32_pm_cksel_t selval ;
unsigned long uword32;
} cksel;
cksel.uword32 = 0;
cksel.selval.cpudiv = hsbdiv;
cksel.selval.cpusel = hsbsel;
cksel.selval.hsbdiv = hsbdiv;
cksel.selval.hsbsel = hsbsel;
cksel.selval.pbbdiv = pbbdiv;
cksel.selval.pbbsel = pbbsel;
cksel.selval.pbadiv = pbadiv;
cksel.selval.pbasel = pbasel;
pm->cksel = cksel.uword32;
// Wait for ckrdy bit and then clear it
while(!(pm->ISR.ckrdy));
return;
}
void pm_gc_setup(volatile avr32_pm_t *pm,
unsigned int gc,
unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)
unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1
unsigned int diven,
unsigned int div) {
union {
unsigned long gcctrl;
avr32_pm_gcctrl_t GCCTRL;
} u_gc;
u_gc.GCCTRL.oscsel = pll_osc;
u_gc.GCCTRL.pllsel = osc_or_pll;
u_gc.GCCTRL.diven = diven;
u_gc.GCCTRL.div = div;
u_gc.GCCTRL.cen = 0; // Disable GC first
pm->gcctrl[gc] = u_gc.gcctrl;
}
void pm_gc_enable(volatile avr32_pm_t *pm,
unsigned int gc) {
union {
unsigned long gcctrl;
avr32_pm_gcctrl_t GCCTRL;
} u_gc;
u_gc.gcctrl = pm->gcctrl[gc];
u_gc.GCCTRL.cen = 1;
pm->gcctrl[gc] = u_gc.gcctrl;
}
void pm_gc_disable(volatile avr32_pm_t *pm,
unsigned int gc) {
union {
unsigned long gcctrl;
avr32_pm_gcctrl_t GCCTRL;
} u_gc;
u_gc.gcctrl = pm->gcctrl[gc];
u_gc.GCCTRL.cen = 0;
pm->gcctrl[gc] = u_gc.gcctrl;
}
void pm_pll_setup(volatile avr32_pm_t *pm,
unsigned int pll,
unsigned int mul,
unsigned int div,
unsigned int osc,
unsigned int lockcount) {
union {
unsigned long pll ;
avr32_pm_pll_t PLL ;
} u_pll;
u_pll.pll=0;
u_pll.PLL.pllmul = mul;
u_pll.PLL.plldiv = div;
u_pll.PLL.pllosc = osc;
u_pll.PLL.pllcount = lockcount;
u_pll.PLL.pllopt = 0;
u_pll.PLL.plltest = 0;
(pm->pll)[pll] = u_pll.pll;
}
void pm_pll_set_option(volatile avr32_pm_t *pm,
unsigned int pll,
unsigned int pll_freq,
unsigned int pll_div2,
unsigned int pll_wbwdisable) {
union {
unsigned long pll ;
avr32_pm_pll_t PLL ;
} u_pll;
u_pll.pll = (pm->pll)[pll];
u_pll.PLL.pllopt = pll_freq | (pll_div2<<1) | (pll_wbwdisable<<2);
(pm->pll)[pll] = u_pll.pll;
}
unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,
unsigned int pll) {
return (pm->PLL)[pll].pllopt;
}
void pm_pll_enable(volatile avr32_pm_t *pm,
unsigned int pll) {
union {
unsigned long pll ;
avr32_pm_pll_t PLL ;
} u_pll;
u_pll.pll = (pm->pll)[pll];
u_pll.PLL.pllen = 1;
(pm->pll)[pll] = u_pll.pll;
}
void pm_pll_disable(volatile avr32_pm_t *pm,
unsigned int pll) {
union {
unsigned long pll ;
avr32_pm_pll_t PLL ;
} u_pll;
u_pll.pll = (pm->pll)[pll];
u_pll.PLL.pllen = 0;
(pm->pll)[pll] = u_pll.pll;
}
void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)
{
while(!pm->ISR.lock0);
// Bypass the lock signal of the PLL
pm->pll[0] |= AVR32_PM_PLL0_PLLBPL_MASK;
}
void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)
{
while(!pm->ISR.lock1);
// Bypass the lock signal of the PLL
pm->pll[1] |= AVR32_PM_PLL1_PLLBPL_MASK;
}
void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)
{
union {
avr32_pm_mcctrl_t MCCTRL;
unsigned long mcctrl;
} mcctrl;
// Read
mcctrl.mcctrl = pm->mcctrl;
// Modify
mcctrl.MCCTRL.mcsel = clock;
// Write Back
pm->MCCTRL.mcsel = mcctrl.mcctrl;
}
void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)
{
pm_enable_osc0_crystal(pm, fosc0); // Enable the Osc0 in crystal mode
pm_enable_clk0(pm, startup); // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal
pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0); // Then switch main clock to Osc0
}
void pm_bod_enable_irq(volatile struct avr32_pm_t *pm) {
union {
unsigned long ier ;
avr32_pm_ier_t IER ;
} u_ier;
u_ier.ier = 0;
u_ier.IER.boddet = 1;
pm->ier = u_ier.ier;
}
void pm_bod_disable_irq(volatile struct avr32_pm_t *pm) {
union {
unsigned long idr ;
avr32_pm_idr_t IDR ;
} u_idr;
u_idr.idr = 0;
u_idr.IDR.boddet = 1;
pm->idr = u_idr.idr;
}
void pm_bod_clear_irq(volatile struct avr32_pm_t *pm) {
union {
unsigned long icr ;
avr32_pm_idr_t ICR ;
} u_icr;
u_icr.icr = 0;
u_icr.ICR.boddet = 1;
pm->icr = u_icr.icr;
}
unsigned long pm_bod_get_irq_status(volatile struct avr32_pm_t *pm) {
return pm->ISR.boddet;
}
unsigned long pm_bod_get_irq_enable_bit(volatile struct avr32_pm_t *pm) {
return pm->IMR.boddet;
}
unsigned long pm_bod_get_level(volatile avr32_pm_t *pm) {
union {
unsigned long bod ;
avr32_pm_bod_t BOD ;
} u_bod;
u_bod.bod = pm->bod;
return (unsigned long) u_bod.BOD.level;
}
void pm_write_gplp(volatile avr32_pm_t *pm,unsigned long gplp, unsigned long value) {
(pm->gplp)[gplp] = value;
}
unsigned long pm_read_gplp(volatile avr32_pm_t *pm,unsigned long gplp) {
return (pm->gplp)[gplp];
}

View file

@ -0,0 +1,331 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Power Manager driver.
*
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
*****************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PM_H_
#define _PM_H_
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
# include <avr32/uc3a0512.h>
#else
# error Unknown compiler
#endif
#include "compiler.h"
#include "preprocessor.h"
/*! \brief Sets the MCU in the specified sleep mode.
*
* \param mode Sleep mode:
* \arg \c AVR32_PM_SMODE_IDLE: Idle;
* \arg \c AVR32_PM_SMODE_FROZEN: Frozen;
* \arg \c AVR32_PM_SMODE_STANDBY: Standby;
* \arg \c AVR32_PM_SMODE_STOP: Stop;
* \arg \c AVR32_PM_SMODE_SHUTDOWN: Shutdown (DeepStop);
* \arg \c AVR32_PM_SMODE_STATIC: Static.
*/
#define SLEEP(mode) {__asm__ __volatile__ ("sleep "STRINGZ(mode));}
/*!
* \brief This function will enable the external clock mode of the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc0 Oscillator 0 crystal frequency (Hz)
*/
extern void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0);
/*!
* \brief This function will enable the oscillator 0 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 0 startup time. Time is expressed in term of RCOsc periods (3-bit value)
*/
extern void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 0.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk0(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 0 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 0 startup time. Time is expressed in term of RCOsc periods (3-bit value) but not checked.
*/
extern void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the Osc0 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the external clock mode of the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc1 Oscillator 1 crystal frequency (Hz)
*/
extern void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1);
/*!
* \brief This function will enable the oscillator 1 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 1 startup time. Time is expressed in term of RCOsc periods (3-bit value)
*/
extern void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 1.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk1(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 1 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 1 startup time. Time is expressed in term of RCOsc periods (3-bit value) but not checked.
*/
extern void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the Osc1 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the external clock mode of the 32-kHz oscillator.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the crystal mode of the 32-kHz oscillator.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_enable_osc32_crystal(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 32 to be used with a startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 32 kHz startup time. Time is expressed in term of RCOsc periods (3-bit value)
*/
extern void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will disable the oscillator 32.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_disable_clk32(volatile avr32_pm_t *pm);
/*!
* \brief This function will enable the oscillator 32 to be used with no startup time.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param startup Clock 32 kHz startup time. Time is expressed in term of RCOsc periods (3-bit value) but not checked.
*/
extern void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup);
/*!
* \brief This function will wait until the osc32 clock is ready.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm);
//FIXME update this header -SM
/*!
* \brief This function will select all the power manager clocks.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pbadiv Peripheral Bus A clock divisor enable
* \param pbasel Peripheral Bus A select
* \param pbbdiv Peripheral Bus B clock divisor enable
* \param pbbsel Peripheral Bus B select
* \param hsbdiv High Speed Bus clock divisor enable (CPU clock = HSB clock)
* \param hsbsel High Speed Bus select (CPU clock = HSB clock )
*/
extern void pm_cksel(volatile avr32_pm_t *pm, unsigned int pbadiv, unsigned int pbasel, unsigned int pbbdiv, unsigned int pbbsel, unsigned int hsbdiv, unsigned int hsbsel);
/*!
* \brief This function will setup a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
* \param osc_or_pll Use OSC (=0) or PLL (=1)
* \param pll_osc Select Osc0/PLL0 or Osc1/PLL1
* \param diven Generic clock divisor enable
* \param div Generic clock divisor
*/
extern void pm_gc_setup(volatile avr32_pm_t *pm, unsigned int gc, unsigned int osc_or_pll, unsigned int pll_osc, unsigned int diven, unsigned int div);
/*!
* \brief This function will enable a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
*/
extern void pm_gc_enable(volatile avr32_pm_t *pm, unsigned int gc);
/*!
* \brief This function will disable a generic clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param gc generic clock number (0 for gc0...)
*/
extern void pm_gc_disable(volatile avr32_pm_t *pm, unsigned int gc);
//FIXME update this header -SM
/*!
* \brief This function will setup a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \param mul
* \param div
* \param osc
* \param lockcount
*/
extern void pm_pll_setup(volatile avr32_pm_t *pm, unsigned int pll, unsigned int mul, unsigned int div, unsigned int osc, unsigned int lockcount);
//FIXME update this header -SM
/*!
* \brief This function will set a PLL option.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \param pll_freq Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz.
* \param pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value)
* \param pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode.
*/
extern void pm_pll_set_option(volatile avr32_pm_t *pm, unsigned int pll, unsigned int pll_freq, unsigned int pll_div2, unsigned int pll_wbwdisable);
//FIXME update this header -SM
/*!
* \brief This function will get a PLL option.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
* \return Option
*/
extern unsigned int pm_pll_get_option(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will enable a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
*/
extern void pm_pll_enable(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will disable a PLL.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param pll PLL number(0 for PLL0, 1 for PLL1)
*/
extern void pm_pll_disable(volatile avr32_pm_t *pm, unsigned int pll);
/*!
* \brief This function will wait for PLL0 locked
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm);
/*!
* \brief This function will wait for PLL1 locked
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
*/
extern void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm);
/*!
* \brief This function will switch the power manager main clock.
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param clock Clock to be switched on. AVR32_PM_MCSEL_SLOW for RCOsc, AVR32_PM_MCSEL_OSC0 for Osc0, AVR32_PM_MCSEL_PLL0 for PLL0.
*/
extern void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock);
/*!
* \brief Switch main clock to clock Osc0 (crystal mode)
* \param pm Base address of the Power Manager (i.e. &AVR32_PM)
* \param fosc0 Oscillator 0 crystal frequency (Hz)
* \param startup Crystal 0 startup time. Time is expressed in term of RCOsc periods (3-bit value)
*/
extern void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup);
#endif // _PM_H_

View file

@ -0,0 +1,299 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief TC driver for AVR32 UC3.
*
* AVR32 Timer/Counter driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a TC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
#else
# error Unknown compiler
#endif
#include "compiler.h"
#include "tc.h"
int tc_get_interrupt_settings(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return tc->channel[channel].imr;
}
int tc_configure_interrupts(volatile avr32_tc_t *tc, unsigned int channel, const tc_interrupt_t *bitfield)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Enable the appropriate interrupts.
tc->channel[channel].ier = bitfield->etrgs << AVR32_TC_ETRGS_OFFSET |
bitfield->ldrbs << AVR32_TC_LDRBS_OFFSET |
bitfield->ldras << AVR32_TC_LDRAS_OFFSET |
bitfield->cpcs << AVR32_TC_CPCS_OFFSET |
bitfield->cpbs << AVR32_TC_CPBS_OFFSET |
bitfield->cpas << AVR32_TC_CPAS_OFFSET |
bitfield->lovrs << AVR32_TC_LOVRS_OFFSET |
bitfield->covfs << AVR32_TC_COVFS_OFFSET;
// Disable the appropriate interrupts.
tc->channel[channel].idr = (~bitfield->etrgs & 1) << AVR32_TC_ETRGS_OFFSET |
(~bitfield->ldrbs & 1) << AVR32_TC_LDRBS_OFFSET |
(~bitfield->ldras & 1) << AVR32_TC_LDRAS_OFFSET |
(~bitfield->cpcs & 1) << AVR32_TC_CPCS_OFFSET |
(~bitfield->cpbs & 1) << AVR32_TC_CPBS_OFFSET |
(~bitfield->cpas & 1) << AVR32_TC_CPAS_OFFSET |
(~bitfield->lovrs & 1) << AVR32_TC_LOVRS_OFFSET |
(~bitfield->covfs & 1) << AVR32_TC_COVFS_OFFSET;
return 0;
}
int tc_select_external_clock(volatile avr32_tc_t *tc, unsigned int channel, unsigned int ext_clk_sig_src)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS || ext_clk_sig_src >= 1 << AVR32_TC_BMR_TC0XC0S_SIZE)
return TC_INVALID_ARGUMENT;
// Clear bit-field and set the correct behavior.
tc->bmr = (tc->bmr & ~(AVR32_TC_BMR_TC0XC0S_MASK << (channel * AVR32_TC_BMR_TC0XC0S_SIZE))) |
(ext_clk_sig_src << (channel * AVR32_TC_BMR_TC0XC0S_SIZE));
return 0;
}
int tc_init_capture(volatile avr32_tc_t *tc, const tc_capture_opt_t *opt)
{
// Check for valid input.
if (opt->channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// MEASURE SIGNALS: Capture operating mode.
tc->channel[opt->channel].cmr = opt->ldrb << AVR32_TC_LDRB_OFFSET |
opt->ldra << AVR32_TC_LDRA_OFFSET |
0 << AVR32_TC_WAVE_OFFSET |
opt->cpctrg << AVR32_TC_CPCTRG_OFFSET |
opt->abetrg << AVR32_TC_ABETRG_OFFSET |
opt->etrgedg << AVR32_TC_ETRGEDG_OFFSET|
opt->ldbdis << AVR32_TC_LDBDIS_OFFSET |
opt->ldbstop << AVR32_TC_LDBSTOP_OFFSET |
opt->burst << AVR32_TC_BURST_OFFSET |
opt->clki << AVR32_TC_CLKI_OFFSET |
opt->tcclks << AVR32_TC_TCCLKS_OFFSET;
return 0;
}
int tc_init_waveform(volatile avr32_tc_t *tc, const tc_waveform_opt_t *opt)
{
// Check for valid input.
if (opt->channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// GENERATE SIGNALS: Waveform operating mode.
tc->channel[opt->channel].cmr = opt->bswtrg << AVR32_TC_BSWTRG_OFFSET |
opt->beevt << AVR32_TC_BEEVT_OFFSET |
opt->bcpc << AVR32_TC_BCPC_OFFSET |
opt->bcpb << AVR32_TC_BCPB_OFFSET |
opt->aswtrg << AVR32_TC_ASWTRG_OFFSET |
opt->aeevt << AVR32_TC_AEEVT_OFFSET |
opt->acpc << AVR32_TC_ACPC_OFFSET |
opt->acpa << AVR32_TC_ACPA_OFFSET |
1 << AVR32_TC_WAVE_OFFSET |
opt->wavsel << AVR32_TC_WAVSEL_OFFSET |
opt->enetrg << AVR32_TC_ENETRG_OFFSET |
opt->eevt << AVR32_TC_EEVT_OFFSET |
opt->eevtedg << AVR32_TC_EEVTEDG_OFFSET |
opt->cpcdis << AVR32_TC_CPCDIS_OFFSET |
opt->cpcstop << AVR32_TC_CPCSTOP_OFFSET |
opt->burst << AVR32_TC_BURST_OFFSET |
opt->clki << AVR32_TC_CLKI_OFFSET |
opt->tcclks << AVR32_TC_TCCLKS_OFFSET;
return 0;
}
int tc_start(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Enable, reset and start the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK | AVR32_TC_CLKEN_MASK;
return 0;
}
int tc_stop(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Disable the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_CLKDIS_MASK;
return 0;
}
int tc_software_trigger(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// Reset the selected timer/counter channel.
tc->channel[channel].ccr = AVR32_TC_SWTRG_MASK;
return 0;
}
void tc_sync_trigger(volatile avr32_tc_t *tc)
{
// Reset all channels of the selected timer/counter.
tc->bcr = AVR32_TC_BCR_SYNC_MASK;
}
int tc_read_sr(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return tc->channel[channel].sr;
}
int tc_read_tc(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].cv, AVR32_TC_CV_MASK);
}
int tc_read_ra(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK);
}
int tc_read_rb(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK);
}
int tc_read_rc(volatile avr32_tc_t *tc, unsigned int channel)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
return Rd_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK);
}
int tc_write_ra(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].ra, AVR32_TC_RA_MASK, value);
return value;
}
int tc_write_rb(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].rb, AVR32_TC_RB_MASK, value);
return value;
}
int tc_write_rc(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value)
{
// Check for valid input.
if (channel >= TC_NUMBER_OF_CHANNELS)
return TC_INVALID_ARGUMENT;
// This function is only available in WAVEFORM mode.
if (Tst_bits(tc->channel[channel].cmr, AVR32_TC_WAVE_MASK))
Wr_bitfield(tc->channel[channel].rc, AVR32_TC_RC_MASK, value);
return value;
}

View file

@ -0,0 +1,586 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Timer/Counter driver for AVR32 UC3.
*
* AVR32 Timer/Counter driver module.
*
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32
* - Supported devices: All AVR32 devices with a TC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support email: avr32@atmel.com
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TC_H_
#define _TC_H_
#if __GNUC__
# include <avr32/io.h>
#elif __ICCAVR32__
# include <avr32/iouc3a0512.h>
#else
# error Unknown compiler
#endif
//! TC driver functions return value in case of invalid argument(s).
#define TC_INVALID_ARGUMENT -1
//! Number of timer/counter channels.
#define TC_NUMBER_OF_CHANNELS (sizeof(((avr32_tc_t *)0)->channel) / sizeof(avr32_tc_channel_t))
/*! \name External Clock Signal 0 Selection
*/
//! @{
#define TC_CH0_EXT_CLK0_SRC_TCLK0 AVR32_TC_TC0XC0S_TCLK0
#define TC_CH0_EXT_CLK0_SRC_NO_CLK AVR32_TC_TC0XC0S_NO_CLK
#define TC_CH0_EXT_CLK0_SRC_TIOA1 AVR32_TC_TC0XC0S_TIOA1
#define TC_CH0_EXT_CLK0_SRC_TIOA2 AVR32_TC_TC0XC0S_TIOA2
//! @}
/*! \name External Clock Signal 1 Selection
*/
//! @{
#define TC_CH1_EXT_CLK1_SRC_TCLK1 AVR32_TC_TC1XC1S_TCLK1
#define TC_CH1_EXT_CLK1_SRC_NO_CLK AVR32_TC_TC1XC1S_NO_CLK
#define TC_CH1_EXT_CLK1_SRC_TIOA0 AVR32_TC_TC1XC1S_TIOA0
#define TC_CH1_EXT_CLK1_SRC_TIOA2 AVR32_TC_TC1XC1S_TIOA2
//! @}
/*! \name External Clock Signal 2 Selection
*/
//! @{
#define TC_CH2_EXT_CLK2_SRC_TCLK2 AVR32_TC_TC2XC2S_TCLK2
#define TC_CH2_EXT_CLK2_SRC_NO_CLK AVR32_TC_TC2XC2S_NO_CLK
#define TC_CH2_EXT_CLK2_SRC_TIOA0 AVR32_TC_TC2XC2S_TIOA0
#define TC_CH2_EXT_CLK2_SRC_TIOA1 AVR32_TC_TC2XC2S_TIOA1
//! @}
/*! \name Event/Trigger Actions on Output
*/
//! @{
#define TC_EVT_EFFECT_NOOP AVR32_TC_NONE
#define TC_EVT_EFFECT_SET AVR32_TC_SET
#define TC_EVT_EFFECT_CLEAR AVR32_TC_CLEAR
#define TC_EVT_EFFECT_TOGGLE AVR32_TC_TOGGLE
//! @}
/*! \name RC Compare Trigger Enable
*/
//! @{
#define TC_NO_TRIGGER_COMPARE_RC 0
#define TC_TRIGGER_COMPARE_RC 1
//! @}
/*! \name Waveform Selection
*/
//! @{
#define TC_WAVEFORM_SEL_UP_MODE AVR32_TC_WAVSEL_UP_NO_AUTO
#define TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER AVR32_TC_WAVSEL_UP_AUTO
#define TC_WAVEFORM_SEL_UPDOWN_MODE AVR32_TC_WAVSEL_UPDOWN_NO_AUTO
#define TC_WAVEFORM_SEL_UPDOWN_MODE_RC_TRIGGER AVR32_TC_WAVSEL_UPDOWN_AUTO
//! @}
/*! \name TIOA or TIOB External Trigger Selection
*/
//! @{
#define TC_EXT_TRIG_SEL_TIOA 1
#define TC_EXT_TRIG_SEL_TIOB 0
//! @}
/*! \name External Event Selection
*/
//! @{
#define TC_EXT_EVENT_SEL_TIOB_INPUT AVR32_TC_EEVT_TIOB_INPUT
#define TC_EXT_EVENT_SEL_XC0_OUTPUT AVR32_TC_EEVT_XC0_OUTPUT
#define TC_EXT_EVENT_SEL_XC1_OUTPUT AVR32_TC_EEVT_XC1_OUTPUT
#define TC_EXT_EVENT_SEL_XC2_OUTPUT AVR32_TC_EEVT_XC2_OUTPUT
//! @}
/*! \name Edge Selection
*/
//! @{
#define TC_SEL_NO_EDGE AVR32_TC_EEVTEDG_NO_EDGE
#define TC_SEL_RISING_EDGE AVR32_TC_EEVTEDG_POS_EDGE
#define TC_SEL_FALLING_EDGE AVR32_TC_EEVTEDG_NEG_EDGE
#define TC_SEL_EACH_EDGE AVR32_TC_EEVTEDG_BOTH_EDGES
//! @}
/*! \name Burst Signal Selection
*/
//! @{
#define TC_BURST_NOT_GATED AVR32_TC_BURST_NOT_GATED
#define TC_BURST_CLK_AND_XC0 AVR32_TC_BURST_CLK_AND_XC0
#define TC_BURST_CLK_AND_XC1 AVR32_TC_BURST_CLK_AND_XC1
#define TC_BURST_CLK_AND_XC2 AVR32_TC_BURST_CLK_AND_XC2
//! @}
/*! \name Clock Invert
*/
//! @{
#define TC_CLOCK_RISING_EDGE 0
#define TC_CLOCK_FALLING_EDGE 1
//! @}
/*! \name Clock Selection
*/
//! @{
#define TC_CLOCK_SOURCE_TC1 AVR32_TC_TCCLKS_TIMER_DIV1_CLOCK
#define TC_CLOCK_SOURCE_TC2 AVR32_TC_TCCLKS_TIMER_DIV2_CLOCK
#define TC_CLOCK_SOURCE_TC3 AVR32_TC_TCCLKS_TIMER_DIV3_CLOCK
#define TC_CLOCK_SOURCE_TC4 AVR32_TC_TCCLKS_TIMER_DIV4_CLOCK
#define TC_CLOCK_SOURCE_TC5 AVR32_TC_TCCLKS_TIMER_DIV5_CLOCK
#define TC_CLOCK_SOURCE_XC0 AVR32_TC_TCCLKS_XC0
#define TC_CLOCK_SOURCE_XC1 AVR32_TC_TCCLKS_XC1
#define TC_CLOCK_SOURCE_XC2 AVR32_TC_TCCLKS_XC2
//! @}
//! Timer/counter interrupts.
typedef struct
{
unsigned int :24;
//! External trigger interrupt.
unsigned int etrgs : 1;
//! RB load interrupt.
unsigned int ldrbs : 1;
//! RA load interrupt.
unsigned int ldras : 1;
//! RC compare interrupt.
unsigned int cpcs : 1;
//! RB compare interrupt.
unsigned int cpbs : 1;
//! RA compare interrupt.
unsigned int cpas : 1;
//! Load overrun interrupt.
unsigned int lovrs : 1;
//! Counter overflow interrupt.
unsigned int covfs : 1;
} tc_interrupt_t;
//! Parameters when initializing a timer/counter in capture mode.
typedef struct
{
//! Channel to initialize.
unsigned int channel ;
unsigned int :12;
//! RB loading selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int ldrb : 2;
//! RA loading selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int ldra : 2;
unsigned int : 1;
//! RC compare trigger enable:\n
//! - \ref TC_NO_TRIGGER_COMPARE_RC;\n
//! - \ref TC_TRIGGER_COMPARE_RC.
unsigned int cpctrg : 1;
unsigned int : 3;
//! TIOA or TIOB external trigger selection:\n
//! - \ref TC_EXT_TRIG_SEL_TIOA;\n
//! - \ref TC_EXT_TRIG_SEL_TIOB.
unsigned int abetrg : 1;
//! External trigger edge selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int etrgedg : 2;
//! Counter clock disable with RB loading:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int ldbdis : 1;
//! Counter clock stopped with RB loading:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int ldbstop : 1;
//! Burst signal selection:\n
//! - \ref TC_BURST_NOT_GATED;\n
//! - \ref TC_BURST_CLK_AND_XC0;\n
//! - \ref TC_BURST_CLK_AND_XC1;\n
//! - \ref TC_BURST_CLK_AND_XC2.
unsigned int burst : 2;
//! Clock invert:\n
//! - \ref TC_CLOCK_RISING_EDGE;\n
//! - \ref TC_CLOCK_FALLING_EDGE.
unsigned int clki : 1;
//! Clock selection:\n
//! - \ref TC_CLOCK_SOURCE_TC1;\n
//! - \ref TC_CLOCK_SOURCE_TC2;\n
//! - \ref TC_CLOCK_SOURCE_TC3;\n
//! - \ref TC_CLOCK_SOURCE_TC4;\n
//! - \ref TC_CLOCK_SOURCE_TC5;\n
//! - \ref TC_CLOCK_SOURCE_XC0;\n
//! - \ref TC_CLOCK_SOURCE_XC1;\n
//! - \ref TC_CLOCK_SOURCE_XC2.
unsigned int tcclks : 3;
} tc_capture_opt_t;
//! Parameters when initializing a timer/counter in waveform mode.
typedef struct
{
//! Channel to initialize.
unsigned int channel ;
//! Software trigger effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bswtrg : 2;
//! External event effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int beevt : 2;
//! RC compare effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bcpc : 2;
//! RB compare effect on TIOB:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int bcpb : 2;
//! Software trigger effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int aswtrg : 2;
//! External event effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int aeevt : 2;
//! RC compare effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int acpc : 2;
//! RA compare effect on TIOA:\n
//! - \ref TC_EVT_EFFECT_NOOP;\n
//! - \ref TC_EVT_EFFECT_SET;\n
//! - \ref TC_EVT_EFFECT_CLEAR;\n
//! - \ref TC_EVT_EFFECT_TOGGLE.
unsigned int acpa : 2;
unsigned int : 1;
//! Waveform selection:\n
//! - \ref TC_WAVEFORM_SEL_UP_MODE;\n
//! - \ref TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER;\n
//! - \ref TC_WAVEFORM_SEL_UPDOWN_MODE;\n
//! - \ref TC_WAVEFORM_SEL_UPDOWN_MODE_RC_TRIGGER.
unsigned int wavsel : 2;
//! External event trigger enable:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int enetrg : 1;
//! External event selection:\n
//! - \ref TC_EXT_EVENT_SEL_TIOB_INPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC0_OUTPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC1_OUTPUT;\n
//! - \ref TC_EXT_EVENT_SEL_XC2_OUTPUT.
unsigned int eevt : 2;
//! External event edge selection:\n
//! - \ref TC_SEL_NO_EDGE;\n
//! - \ref TC_SEL_RISING_EDGE;\n
//! - \ref TC_SEL_FALLING_EDGE;\n
//! - \ref TC_SEL_EACH_EDGE.
unsigned int eevtedg : 2;
//! Counter clock disable with RC compare:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int cpcdis : 1;
//! Counter clock stopped with RC compare:\n
//! - \c FALSE;\n
//! - \c TRUE.
unsigned int cpcstop : 1;
//! Burst signal selection:\n
//! - \ref TC_BURST_NOT_GATED;\n
//! - \ref TC_BURST_CLK_AND_XC0;\n
//! - \ref TC_BURST_CLK_AND_XC1;\n
//! - \ref TC_BURST_CLK_AND_XC2.
unsigned int burst : 2;
//! Clock invert:\n
//! - \ref TC_CLOCK_RISING_EDGE;\n
//! - \ref TC_CLOCK_FALLING_EDGE.
unsigned int clki : 1;
//! Clock selection:\n
//! - \ref TC_CLOCK_SOURCE_TC1;\n
//! - \ref TC_CLOCK_SOURCE_TC2;\n
//! - \ref TC_CLOCK_SOURCE_TC3;\n
//! - \ref TC_CLOCK_SOURCE_TC4;\n
//! - \ref TC_CLOCK_SOURCE_TC5;\n
//! - \ref TC_CLOCK_SOURCE_XC0;\n
//! - \ref TC_CLOCK_SOURCE_XC1;\n
//! - \ref TC_CLOCK_SOURCE_XC2.
unsigned int tcclks : 3;
} tc_waveform_opt_t;
/*! \brief Reads timer/counter interrupt settings.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 The interrupt enable configuration organized according to \ref tc_interrupt_t.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_get_interrupt_settings(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Enables various timer/counter interrupts.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param bitfield The interrupt enable configuration.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_configure_interrupts(volatile avr32_tc_t *tc, unsigned int channel, const tc_interrupt_t *bitfield);
/*! \brief Selects which external clock to use and how to configure it.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param ext_clk_sig_src External clock signal selection:
* \arg \c TC_CH0_EXT_CLK0_SRC_TCLK0;
* \arg \c TC_CH0_EXT_CLK0_SRC_NO_CLK;
* \arg \c TC_CH0_EXT_CLK0_SRC_TIOA1;
* \arg \c TC_CH0_EXT_CLK0_SRC_TIOA2;
* \arg \c TC_CH1_EXT_CLK1_SRC_TCLK1;
* \arg \c TC_CH1_EXT_CLK1_SRC_NO_CLK;
* \arg \c TC_CH1_EXT_CLK1_SRC_TIOA0;
* \arg \c TC_CH1_EXT_CLK1_SRC_TIOA2;
* \arg \c TC_CH2_EXT_CLK2_SRC_TCLK2;
* \arg \c TC_CH2_EXT_CLK2_SRC_NO_CLK;
* \arg \c TC_CH2_EXT_CLK2_SRC_TIOA0;
* \arg \c TC_CH2_EXT_CLK2_SRC_TIOA1.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_select_external_clock(volatile avr32_tc_t *tc, unsigned int channel, unsigned int ext_clk_sig_src);
/*! \brief Sets options for timer/counter capture initialization.
*
* \param tc Pointer to the TC instance to access.
* \param opt Options for capture mode.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_init_capture(volatile avr32_tc_t *tc, const tc_capture_opt_t *opt);
/*! \brief Sets options for timer/counter waveform initialization.
*
* \param tc Pointer to the TC instance to access.
* \param opt Options for waveform generation.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_init_waveform(volatile avr32_tc_t *tc, const tc_waveform_opt_t *opt);
/*! \brief Starts a timer/counter.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_start(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Stops a timer/counter.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_stop(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Performs a software trigger: the counter is reset and the clock is started.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval 0 Success.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_software_trigger(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Asserts a SYNC signal to generate a software trigger and reset all channels.
*
* \param tc Pointer to the TC instance to access.
*/
extern void tc_sync_trigger(volatile avr32_tc_t *tc);
/*! \brief Reads the status register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 Status register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_sr(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's TC counter and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 TC counter value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_tc(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RA register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RA register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_ra(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RB register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RB register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_rb(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Reads the channel's RC register and returns the value.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
*
* \retval >=0 RC register value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_read_rc(volatile avr32_tc_t *tc, unsigned int channel);
/*! \brief Writes a value to the channel's RA register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RA register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_ra(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
/*! \brief Writes a value to the channel's RB register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RB register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_rb(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
/*! \brief Writes a value to the channel's RC register.
*
* \param tc Pointer to the TC instance to access.
* \param channel The TC instance channel to access.
* \param value Value to write to the RC register.
*
* \retval >=0 Written value.
* \retval TC_INVALID_ARGUMENT Invalid argument(s).
*/
extern int tc_write_rc(volatile avr32_tc_t *tc, unsigned int channel, unsigned short value);
#endif // _TC_H_