add atmel SAM D21 bsp support

This commit is contained in:
xieyangrun 2017-08-30 12:18:28 +08:00
parent f3f523d22f
commit 189c999f8e
1412 changed files with 599447 additions and 1 deletions

3
bsp/samd21/README.txt Normal file
View File

@ -0,0 +1,3 @@
使用SAMD21-Xplained-Pro开发板
scons:只支持scons --target=mdk5,其他命令没有支持
demo代码演示了串口、外部中断、RTC低功耗唤醒

14
bsp/samd21/SConscript Normal file
View File

@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

34
bsp/samd21/SConstruct Normal file
View File

@ -0,0 +1,34 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'SAM_D2X_RTT.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM == 'iar':
env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map'])
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)

View File

@ -0,0 +1,14 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd, str(Dir('#'))]
#remove other no use files
#SrcRemove(src, '*.c')
group = DefineGroup('Application', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,141 @@
#include <rtthread.h>
#include <rthw.h>
#include "board.h"
#include "port.h"
#include "extint.h"
#include "sleep_timer.h"
void LED_Init(void)
{
struct port_config config_port_pin;
port_get_config_defaults(&config_port_pin);
config_port_pin.direction = PORT_PIN_DIR_INPUT;
config_port_pin.input_pull = PORT_PIN_PULL_UP;
port_pin_set_config(PIN_PA15, &config_port_pin);
config_port_pin.direction = PORT_PIN_DIR_OUTPUT;
port_pin_set_config(PIN_PB30, &config_port_pin);
}
void LED_ON(void)
{
port_pin_set_output_level(PIN_PB30, false);
}
void LED_OFF(void)
{
port_pin_set_output_level(PIN_PB30, true);
}
void extint_detection_callback(void);
void configure_extint_channel(void)
{
//! [setup_1]
struct extint_chan_conf config_extint_chan;
//! [setup_1]
//! [setup_2]
extint_chan_get_config_defaults(&config_extint_chan);
//! [setup_2]
//! [setup_3]
config_extint_chan.gpio_pin = PIN_PA15A_EIC_EXTINT15;
config_extint_chan.gpio_pin_mux = MUX_PA15A_EIC_EXTINT15;
config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP;
config_extint_chan.detection_criteria = EXTINT_DETECT_BOTH;
//! [setup_3]
//! [setup_4]
extint_chan_set_config(15, &config_extint_chan);
//! [setup_4]
}
void configure_extint_callbacks(void)
{
//! [setup_5]
extint_register_callback(extint_detection_callback, 15, EXTINT_CALLBACK_TYPE_DETECT);
//! [setup_5]
//! [setup_6]
extint_chan_enable_callback(15, EXTINT_CALLBACK_TYPE_DETECT);
//! [setup_6]
}
//! [setup_7]
void extint_detection_callback(void)
{
bool pin_state = port_pin_get_input_level(PIN_PA15);
port_pin_set_output_level(PIN_PB30, pin_state);
}
static struct rt_semaphore _rx_sem;
static rt_err_t _rx_ind(rt_device_t dev, rt_size_t size)
{
return rt_sem_release(&_rx_sem);
}
void rt_init_thread_entry(void* parameter)
{
rt_thread_t thread;
rt_device_t dev;
rt_kprintf("SYSTEM running at %uhz\n", SystemCoreClock);
sleep_timer_init();
// sleep_timer_start(1500);
LED_Init();
configure_extint_channel();
configure_extint_callbacks();
while (1)
{
rt_kprintf("init thread running tick:%u\n", rt_tick_get());
rt_thread_delay(2*RT_TICK_PER_SECOND);
}
#if 0
dev = rt_device_find("uart3");
if (dev != RT_NULL)
{
rt_sem_init(&_rx_sem, "rxsem", 0, RT_IPC_FLAG_FIFO);
rt_device_set_rx_indicate(dev, _rx_ind);
rt_device_open(dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
}
while (1)
{
rt_size_t r_size;
rt_uint8_t r_buf[1];
// rt_kprintf("SAMD2xJ18A hello thread\n");
// rt_thread_delay(RT_TICK_PER_SECOND);
rt_sem_take(&_rx_sem, RT_WAITING_FOREVER);
while ((r_size = rt_device_read(dev, 0, r_buf, 1)) > 0)
{
rt_device_write(dev, 0, r_buf, r_size);
if (r_buf[0] == '\r')
{
r_buf[0] = '\n';
rt_device_write(dev, 0, r_buf, r_size);
}
}
}
#endif
}
int rt_application_init(void)
{
rt_thread_t tid;
tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL,
512, RT_THREAD_PRIORITY_MAX / 3, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
return 0;
}

View File

@ -0,0 +1,127 @@
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-08-31 Bernard first implementation
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
/**
* @addtogroup STM32
*/
/*@{*/
extern int rt_application_init(void);
#ifdef RT_USING_FINSH
extern void finsh_system_init(void);
extern void finsh_set_device(const char* device);
#endif
#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
#elif __ICCARM__
#pragma section="HEAP"
#else
extern int __bss_end;
#endif
#ifdef DEBUG
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert error has occurred.
* Input : - file: pointer to the source file name
* - line: assert error line source number
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(uint8_t* file, uint32_t line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
}
#endif
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
/* init board */
rt_board_init();
/* show version */
rt_show_version();
/* init tick */
rt_system_tick_init();
/* init kernel object */
rt_system_object_init();
/* init timer system */
rt_system_timer_init();
#ifdef RT_USING_HEAP
#ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)CHIP_SRAM_END);
#elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)CHIP_SRAM_END);
#else
/* init memory system */
rt_system_heap_init((void*)&__bss_end, (void*)CHIP_SRAM_END);
#endif
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* init application */
rt_application_init();
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
finsh_set_device("uart1");
#endif
/* init timer thread */
rt_system_timer_thread_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* startup RT-Thread RTOS */
rtthread_startup();
return 0;
}
/*@}*/

View File

@ -0,0 +1,170 @@
/**
* \file
*
* \brief SAM D20 Clock configuration
*
* Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <clock.h>
#ifndef CONF_CLOCKS_H_INCLUDED
# define CONF_CLOCKS_H_INCLUDED
/* System clock bus configuration */
# define CONF_CLOCK_FLASH_WAIT_STATES 0
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBC_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
# define CONF_CLOCK_OSC8M_ON_DEMAND true
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
# define CONF_CLOCK_XOSC_ENABLE false
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
# define CONF_CLOCK_XOSC_ON_DEMAND true
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
# define CONF_CLOCK_XOSC32K_ENABLE false
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_XOSC32K_ON_DEMAND true
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
# define CONF_CLOCK_OSC32K_ENABLE false
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ON_DEMAND true
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
# define CONF_CLOCK_DFLL_ENABLE false
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN
# define CONF_CLOCK_DFLL_ON_DEMAND false
/* DFLL open loop mode configuration */
# define CONF_CLOCK_DFLL_FINE_VALUE (512)
/* DFLL closed loop mode configuration */
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR 1465 /* (48000000 / 32768) */
# define CONF_CLOCK_DFLL_QUICK_LOCK true
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4)
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4)
/* Set this to true to configure the GCLK when running clocks_init. If set to
* false, none of the GCLK generators will be configured in clocks_init(). */
# define CONF_CLOCK_CONFIGURE_GCLK true
/* Configure GCLK generator 0 (Main Clock) */
# define CONF_CLOCK_GCLK_0_ENABLE true
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_0_PRESCALER 1
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
/* Configure GCLK generator 1 */
# define CONF_CLOCK_GCLK_1_ENABLE false
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_XOSC32K
# define CONF_CLOCK_GCLK_1_PRESCALER 1
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false
/* Configure GCLK generator 2 (RTC) */
# define CONF_CLOCK_GCLK_2_ENABLE false
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K
# define CONF_CLOCK_GCLK_2_PRESCALER 32
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
/* Configure GCLK generator 3 */
# define CONF_CLOCK_GCLK_3_ENABLE false
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_3_PRESCALER 1
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
/* Configure GCLK generator 4 */
# define CONF_CLOCK_GCLK_4_ENABLE false
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_4_PRESCALER 1
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
/* Configure GCLK generator 5 */
# define CONF_CLOCK_GCLK_5_ENABLE false
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_5_PRESCALER 1
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
/* Configure GCLK generator 6 */
# define CONF_CLOCK_GCLK_6_ENABLE false
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_6_PRESCALER 1
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
/* Configure GCLK generator 7 */
# define CONF_CLOCK_GCLK_7_ENABLE false
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_7_PRESCALER 1
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
#endif /* CONF_CLOCKS_H_INCLUDED */

View File

@ -0,0 +1,198 @@
/**
* \file
*
* \brief SAM D21/R21/DA/HA Clock configuration
*
* Copyright (C) 2013-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <clock.h>
#ifndef CONF_CLOCKS_H_INCLUDED
# define CONF_CLOCKS_H_INCLUDED
/* System clock bus configuration */
# define CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT false
# define CONF_CLOCK_FLASH_WAIT_STATES 1
# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
# define CONF_CLOCK_APBC_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1
/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */
# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1
# define CONF_CLOCK_OSC8M_ON_DEMAND true
# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */
# define CONF_CLOCK_XOSC_ENABLE false
# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL
# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768
# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true
# define CONF_CLOCK_XOSC_ON_DEMAND true
# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */
# define CONF_CLOCK_XOSC32K_ENABLE true
# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL
# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_2048
# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL true
# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false
# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_XOSC32K_ON_DEMAND false
# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY true
/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */
# define CONF_CLOCK_OSC32K_ENABLE false
# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130
# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true
# define CONF_CLOCK_OSC32K_ON_DEMAND true
# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false
/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */
# define CONF_CLOCK_DFLL_ENABLE true
# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN
# define CONF_CLOCK_DFLL_ON_DEMAND true
/* DFLL open loop mode configuration */
# define CONF_CLOCK_DFLL_FINE_VALUE ((*((uint32_t*)(0x806020 + 8))) & 0x3FF)/*(512)*/
/* DFLL closed loop mode configuration */
# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_2
# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR (48000000 / 32768)
# define CONF_CLOCK_DFLL_QUICK_LOCK true
# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true
# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true
# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true
# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE ((*((uint8_t*)(0x806020 + 7))) >> 2)/*(0x1f / 4)*/
# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE ((*((uint32_t*)(0x806020 + 8))) & 0x3FF)/*(0xff / 4)*/
/* SYSTEM_CLOCK_SOURCE_DPLL configuration - Digital Phase-Locked Loop */
# define CONF_CLOCK_DPLL_ENABLE false
# define CONF_CLOCK_DPLL_ON_DEMAND true
# define CONF_CLOCK_DPLL_RUN_IN_STANDBY false
# define CONF_CLOCK_DPLL_LOCK_BYPASS false
# define CONF_CLOCK_DPLL_WAKE_UP_FAST false
# define CONF_CLOCK_DPLL_LOW_POWER_ENABLE false
# define CONF_CLOCK_DPLL_LOCK_TIME SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT
# define CONF_CLOCK_DPLL_REFERENCE_CLOCK SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC32K
# define CONF_CLOCK_DPLL_FILTER SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT
# define CONF_CLOCK_DPLL_REFERENCE_FREQUENCY 32768
# define CONF_CLOCK_DPLL_REFERENCE_DIVIDER 1
# define CONF_CLOCK_DPLL_OUTPUT_FREQUENCY 48000000
/* DPLL GCLK reference configuration */
# define CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR GCLK_GENERATOR_1
/* DPLL GCLK lock timer configuration */
# define CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR GCLK_GENERATOR_1
/* Set this to true to configure the GCLK when running clocks_init. If set to
* false, none of the GCLK generators will be configured in clocks_init(). */
# define CONF_CLOCK_CONFIGURE_GCLK true
/* Configure GCLK generator 0 (Main Clock) */
# define CONF_CLOCK_GCLK_0_ENABLE true
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL
# define CONF_CLOCK_GCLK_0_PRESCALER 1
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false
/* Configure GCLK generator 1 */
# define CONF_CLOCK_GCLK_1_ENABLE false
# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY true
# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_XOSC32K
# define CONF_CLOCK_GCLK_1_PRESCALER 1
# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false
/* Configure GCLK generator 2 (RTC) */
# define CONF_CLOCK_GCLK_2_ENABLE true
# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY true
# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_XOSC32K
# define CONF_CLOCK_GCLK_2_PRESCALER 1
# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false
/* Configure GCLK generator 3 */
# define CONF_CLOCK_GCLK_3_ENABLE false
# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_3_PRESCALER 1
# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false
/* Configure GCLK generator 4 */
# define CONF_CLOCK_GCLK_4_ENABLE false
# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_4_PRESCALER 1
# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false
/* Configure GCLK generator 5 */
# define CONF_CLOCK_GCLK_5_ENABLE false
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_5_PRESCALER 1
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false
/* Configure GCLK generator 6 */
# define CONF_CLOCK_GCLK_6_ENABLE false
# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_6_PRESCALER 1
# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false
/* Configure GCLK generator 7 */
# define CONF_CLOCK_GCLK_7_ENABLE false
# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_7_PRESCALER 1
# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false
/* Configure GCLK generator 8 */
# define CONF_CLOCK_GCLK_8_ENABLE false
# define CONF_CLOCK_GCLK_8_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_8_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M
# define CONF_CLOCK_GCLK_8_PRESCALER 1
# define CONF_CLOCK_GCLK_8_OUTPUT_ENABLE false
#endif /* CONF_CLOCKS_H_INCLUDED */

View File

@ -0,0 +1,51 @@
/**
* \file
*
* \brief SAM D21 External Interrupt Driver Configuration Header
*
* Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_EXTINT_H_INCLUDED
#define CONF_EXTINT_H_INCLUDED
# define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_2
#endif

View File

@ -0,0 +1,20 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
path = [cwd]
#remove other no use files
#SrcRemove(src, 'i2c_iomaster.c')
#SrcRemove(src, 'delay.c')
if rtconfig.DEVICE_SERIES == 'SAMD20':
path += [cwd + '/../asflib_config', cwd + '/../asflib_config/clock_samd20']
elif rtconfig.DEVICE_SERIES == 'SAMD21':
path += [cwd + '/../asflib_config', cwd + '/../asflib_config/clock_samd21_r21_da_ha1']
group = DefineGroup('Board', src, depend = [''], CPPPATH = path)
Return('group')

102
bsp/samd21/board/board.c Normal file
View File

@ -0,0 +1,102 @@
#include "board.h"
#include <clock.h>
#include <gclk.h>
#include <system.h>
#include <rtthread.h>
/**
* This is the timer interrupt service routine.
*
*/
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
void configure_extosc32k(void);
void configure_dfll_open_loop(void);
//! [setup]
//! [config_extosc32k]
void configure_extosc32k(void)
{
//! [config_extosc32k_config]
struct system_clock_source_xosc32k_config config_ext32k;
//! [config_extosc32k_config]
//! [config_extosc32k_get_defaults]
system_clock_source_xosc32k_get_config_defaults(&config_ext32k);
//! [config_extosc32k_get_defaults]
//! [config_extosc32k_change_defaults]
config_ext32k.startup_time = SYSTEM_XOSC32K_STARTUP_4096;
config_ext32k.on_demand = false;
//! [config_extosc32k_change_defaults]
//! [config_extosc32k_set_config]
system_clock_source_xosc32k_set_config(&config_ext32k);
//! [config_extosc32k_set_config]
system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC32K));
}
//! [config_extosc32k]
#if (!SAMC21)
//! [config_dfll]
void configure_dfll_open_loop(void)
{
//! [config_dfll_config]
struct system_clock_source_dfll_config config_dfll;
//! [config_dfll_config]
//! [config_dfll_get_defaults]
system_clock_source_dfll_get_config_defaults(&config_dfll);
//! [config_dfll_get_defaults]
config_dfll.coarse_value = (*((uint8_t*)(0x806020 + 7))) >> 2;// 0x1f / 4; /* Midpoint */
config_dfll.fine_value = (*((uint32_t*)(0x806020 + 8))) & 0x3FF;//0xff / 4; /* Midpoint */
//! [config_dfll_set_config]
system_clock_source_dfll_set_config(&config_dfll);
//! [config_dfll_set_config]
//! [enable_dfll_main]
system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);
// while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL));
//! [enable_dfll_main]
/* Configure flash wait states before switching to high frequency clock */
//! [set_sys_wait_states]
system_flash_set_waitstates(2);
//! [set_sys_wait_states]
/* Change system clock to DFLL */
//! [set_sys_clk_src]
struct system_gclk_gen_config config_gclock_gen;
system_gclk_gen_get_config_defaults(&config_gclock_gen);
config_gclock_gen.source_clock = SYSTEM_CLOCK_SOURCE_DFLL;
config_gclock_gen.division_factor = 1;
system_gclk_gen_set_config(GCLK_GENERATOR_0, &config_gclock_gen);
//! [set_sys_clk_src]
}
//! [config_dfll]
#endif
void rt_board_init(void)
{
extern void uart_init(void);
// configure_extosc32k();
// configure_dfll_open_loop();
system_init();
/* initialize systick */
SystemCoreClock = system_gclk_gen_get_hz(0);
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
uart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
}

36
bsp/samd21/board/board.h Normal file
View File

@ -0,0 +1,36 @@
/* This is a template file for board configuration created by MCUXpresso Project Generator. Enjoy! */
#ifndef _BOARD_H_
#define _BOARD_H_
/*******************************************************************************
* Definitions
******************************************************************************/
#include <stdint.h>
#include "samd21.h"
#include "system_samd21.h"
#include "core_cm0plus.h" /* Core Peripheral Access Layer */
/* The board name */
#define BOARD_NAME "###-not-specified-###"
#define CHIP_SRAM_END (0x20000000 + 32*1024)
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @brief initialize debug console to enable printf for this demo/example
*/
void rt_board_init(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* _BOARD_H_ */

View File

@ -0,0 +1,126 @@
// From module: RTC - Real Time Counter in Count Mode (Polled APIs)
#include <rtc_count.h>
#include <rtc_count_interrupt.h>
// #include <rtc_tamper.h>
#include <power.h>
#include <port.h>
#include <rtthread.h>
/* RTC module instance */
static struct rtc_module rtc_instance;
static void _rtc_timer_int_cb(void)
{
port_pin_toggle_output_level(PIN_PB30);
}
/* Init RTC as ADC sample timer */
static void _rtc_timer_init(void)
{
struct rtc_count_config conf;
rtc_count_get_config_defaults(&conf);
conf.prescaler = RTC_COUNT_PRESCALER_DIV_1;
conf.mode = RTC_COUNT_MODE_32BIT;
conf.clear_on_match = false;
conf.compare_values[0] = 0;
// struct rtc_count_events evconfig;
// evconfig.generate_event_on_compare[0] = true;
rtc_count_init(&rtc_instance, RTC, &conf);
// rtc_count_enable_events(&rtc_instance, &evconfig);
// rtc_count_enable(&rtc_instance);
rtc_count_set_count(&rtc_instance, 0);
rtc_count_register_callback(&rtc_instance, _rtc_timer_int_cb, RTC_COUNT_CALLBACK_COMPARE_0);
// rtc_count_enable_callback(&rtc_instance, RTC_COUNT_CALLBACK_COMPARE_0);
}
static void _rtc_timer_start(uint32_t ms)
{
uint32_t compare = 0;
compare = (uint32_t)(32.768 * ms);
// rtc_count_register_callback(&rtc_instance, _rtc_timer_int_cb, RTC_COUNT_CALLBACK_COMPARE_0);
rtc_count_enable_callback(&rtc_instance, RTC_COUNT_CALLBACK_COMPARE_0);
rtc_count_set_count(&rtc_instance, 0);
rtc_count_set_compare(&rtc_instance, compare, RTC_COUNT_COMPARE_0);
rtc_count_enable(&rtc_instance);
}
static void sleep_tick_adjust(uint32_t ms)
{
uint32_t diff;
diff = rt_tick_from_millisecond(ms);
rt_tick_set(rt_tick_get() + diff);
{
struct rt_thread *thread;
/* check time slice */
thread = rt_thread_self();
if (thread->remaining_tick <= diff)
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;
/* yield */
rt_thread_yield();
}
else
{
thread->remaining_tick -= diff;
}
/* check timer */
rt_timer_check();
}
}
static void _sleep_entry(void)
{
rt_tick_t timeout;
rt_uint32_t ms;
rt_uint32_t count;
system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
timeout = rt_timer_next_timeout_tick() - rt_tick_get();
ms = timeout * (1000 / RT_TICK_PER_SECOND);
rt_kprintf("os tick:%u entry sleep:%u tick\r\n", rt_tick_get(), timeout);
_rtc_timer_start(ms);
system_sleep();
rt_enter_critical();
count = rtc_count_get_count(&rtc_instance);
ms = (count + 32) / 32.768;
rtc_count_disable(&rtc_instance);
sleep_tick_adjust(ms);
timeout = rt_tick_get();
rt_exit_critical();
rt_kprintf("sleep exited, os tick:%u\n", timeout);
}
void sleep_timer_init(void)
{
_rtc_timer_init();
rt_thread_idle_sethook(_sleep_entry);
}
void sleep_timer_start(uint32_t ms)
{
_rtc_timer_start(ms);
}
void sleep_timer_stop(void)
{
rtc_count_disable(&rtc_instance);
}

View File

@ -0,0 +1,8 @@
#ifndef _SLEEP_TIMER_H_
#define _SLEEP_TIMER_H_
void sleep_timer_init(void);
void sleep_timer_start(uint32_t ms);
#endif

321
bsp/samd21/board/uart.c Normal file
View File

@ -0,0 +1,321 @@
// From module: SERCOM Callback API
#include <samd21.h>
#include <sercom.h>
// #include <sercom_interrupt.h>
// From module: SERCOM USART - Serial Communications (Callback APIs)
#include <usart.h>
// #include <usart_interrupt.h>
#include <rtdevice.h>
typedef struct _samd2x_uart_t
{
struct rt_serial_device *serial;
struct usart_module *instance;
Sercom *com;
enum usart_signal_mux_settings mux_setting;
uint32_t pinmux_pad0;
uint32_t pinmux_pad1;
uint32_t pinmux_pad2;
uint32_t pinmux_pad3;
enum system_interrupt_vector vector;
} SAMD2x_UART_T;
static struct rt_serial_device _serial3;
static struct usart_module _uart3_instance;
static SAMD2x_UART_T _uart3 = {
&_serial3,
&_uart3_instance,
SERCOM3,
USART_RX_1_TX_0_XCK_1,
PINMUX_PA22C_SERCOM3_PAD0,
PINMUX_PA23C_SERCOM3_PAD1,
PINMUX_UNUSED,
PINMUX_UNUSED,
SYSTEM_INTERRUPT_MODULE_SERCOM3
};
// static struct rt_serial_device _serial2;
// static struct rt_serial_device _serial3;
// static struct rt_serial_device _serial4;
static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg)
{
SAMD2x_UART_T *uart;
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(cfg != RT_NULL);
uart = (SAMD2x_UART_T *)serial->parent.user_data;
//! [setup_config]
struct usart_config config_usart;
//! [setup_config]
//! [setup_config_defaults]
usart_get_config_defaults(&config_usart);
//! [setup_config_defaults]
config_usart.baudrate = cfg->baud_rate;
switch (cfg->data_bits )
{
case DATA_BITS_8:
config_usart.character_size = USART_CHARACTER_SIZE_8BIT;
break;
case DATA_BITS_5:
config_usart.character_size = USART_CHARACTER_SIZE_5BIT;
break;
case DATA_BITS_6:
config_usart.character_size = USART_CHARACTER_SIZE_6BIT;
break;
case DATA_BITS_7:
config_usart.character_size = USART_CHARACTER_SIZE_7BIT;
break;
case DATA_BITS_9:
config_usart.character_size = USART_CHARACTER_SIZE_9BIT;
break;
default:
config_usart.character_size = USART_CHARACTER_SIZE_8BIT;
break;
}
switch (cfg->parity)
{
case PARITY_NONE:
config_usart.parity = USART_PARITY_NONE;
break;
case PARITY_EVEN:
config_usart.parity = USART_PARITY_EVEN;
break;
case PARITY_ODD:
config_usart.parity = USART_PARITY_ODD;
break;
default:
config_usart.parity = USART_PARITY_NONE;
break;
}
config_usart.stopbits = USART_STOPBITS_1;
if (cfg->stop_bits != USART_STOPBITS_1)
{
config_usart.stopbits = USART_STOPBITS_2;
}
config_usart.data_order = USART_DATAORDER_LSB;
if (cfg->bit_order != BIT_ORDER_LSB)
{
config_usart.data_order = USART_DATAORDER_MSB;
}
config_usart.mux_setting = uart->mux_setting;
config_usart.pinmux_pad0 = uart->pinmux_pad0;
config_usart.pinmux_pad1 = uart->pinmux_pad1;
config_usart.pinmux_pad2 = uart->pinmux_pad2;
config_usart.pinmux_pad3 = uart->pinmux_pad3;
config_usart.receiver_enable = false;
config_usart.transmitter_enable = true;
while (usart_init(uart->instance, uart->com, &config_usart) != STATUS_OK) {
}
usart_enable(uart->instance);
/* Wait for the synchronization to complete */
_usart_wait_for_sync(uart->instance);
return RT_EOK;
}
static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg)
{
SAMD2x_UART_T *uart;
RT_ASSERT(serial != RT_NULL);
uart = (SAMD2x_UART_T *)(serial->parent.user_data);
switch (cmd)
{
/* disable interrupt */
case RT_DEVICE_CTRL_CLR_INT:
uart->com->USART.INTENCLR.reg = SERCOM_USART_INTFLAG_RXC;
usart_disable_transceiver(uart->instance, USART_TRANSCEIVER_RX);
system_interrupt_disable(uart->vector);
/* Wait for the synchronization to complete */
_usart_wait_for_sync(uart->instance);
break;
/* enable interrupt */
case RT_DEVICE_CTRL_SET_INT:
/* Enable RX interrupt. */
/* Enable the RX Complete Interrupt */
uart->com->USART.INTENSET.reg = SERCOM_USART_INTFLAG_RXC;
usart_enable_transceiver(uart->instance, USART_TRANSCEIVER_RX);
system_interrupt_enable(uart->vector);
/* Wait for the synchronization to complete */
_usart_wait_for_sync(uart->instance);
break;
default:
return RT_ERROR;
}
return RT_EOK;
}
static int _uart_putc(struct rt_serial_device *serial, char c)
{
SAMD2x_UART_T *uart;
RT_ASSERT(serial != RT_NULL);
// while (!(uart->com->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) {
// }
uart = (SAMD2x_UART_T *)(serial->parent.user_data);
/* Write data to USART module */
uart->com->USART.DATA.reg = c;
while (!(uart->com->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)) {
/* Wait until data is sent */
}
return 1;
}
static int _uart_getc(struct rt_serial_device *serial)
{
int ch;
SAMD2x_UART_T *uart;
RT_ASSERT(serial != RT_NULL);
uart = (SAMD2x_UART_T *)(serial->parent.user_data);
/* Check if USART has new data */
if (!(uart->com->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) {
/* Return error code */
return -1;
}
ch = uart->com->USART.DATA.reg & 0x1FF;
return ch;
}
static struct rt_uart_ops _uart_ops = {
_uart_cfg,
_uart_ctrl,
_uart_putc,
_uart_getc
};
static void uart_int_cb(SAMD2x_UART_T *uart_handle)
{
/* Temporary variables */
uint16_t interrupt_status;
uint8_t error_code;
struct usart_module *module = uart_handle->instance;
/* Pointer to the hardware module instance */
SercomUsart *const usart_hw = &(module->hw->USART);
/* Read and mask interrupt flag register */
interrupt_status = usart_hw->INTFLAG.reg;
interrupt_status &= usart_hw->INTENSET.reg;
/* Check if the Receive Complete interrupt has occurred, and that
* there's more data to receive */
if (interrupt_status & SERCOM_USART_INTFLAG_RXC) {
/* Read out the status code and mask away all but the 4 LSBs*/
error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK);
#if !SAMD20
/* CTS status should not be considered as an error */
if(error_code & SERCOM_USART_STATUS_CTS) {
error_code &= ~SERCOM_USART_STATUS_CTS;
}
#endif
#ifdef FEATURE_USART_LIN_MASTER
/* TXE status should not be considered as an error */
if(error_code & SERCOM_USART_STATUS_TXE) {
error_code &= ~SERCOM_USART_STATUS_TXE;
}
#endif
/* Check if an error has occurred during the receiving */
if (error_code) {
/* Check which error occurred */
if (error_code & SERCOM_USART_STATUS_FERR) {
/* clear flag by writing 1 to it */
usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR;
} else if (error_code & SERCOM_USART_STATUS_BUFOVF) {
/* clear flag by writing 1 to it */
usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF;
} else if (error_code & SERCOM_USART_STATUS_PERR) {
/* clear flag by writing 1 to it */
usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR;
}
#ifdef FEATURE_USART_LIN_SLAVE
else if (error_code & SERCOM_USART_STATUS_ISF) {
/* clear flag by writing 1 to it */
usart_hw->STATUS.reg = SERCOM_USART_STATUS_ISF;
}
#endif
#ifdef FEATURE_USART_COLLISION_DECTION
else if (error_code & SERCOM_USART_STATUS_COLL) {
/* clear flag by writing 1 to it */
usart_hw->STATUS.reg = SERCOM_USART_STATUS_COLL;
}
#endif
} else {
rt_hw_serial_isr(uart_handle->serial, RT_SERIAL_EVENT_RX_IND);
}
}
#ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL
if (interrupt_status & SERCOM_USART_INTFLAG_CTSIC) {
/* Disable interrupts */
usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_CTSIC;
/* Clear interrupt flag */
usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_CTSIC;
}
#endif
#ifdef FEATURE_USART_LIN_SLAVE
if (interrupt_status & SERCOM_USART_INTFLAG_RXBRK) {
/* Disable interrupts */
usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXBRK;
/* Clear interrupt flag */
usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXBRK;
}
#endif
#ifdef FEATURE_USART_START_FRAME_DECTION
if (interrupt_status & SERCOM_USART_INTFLAG_RXS) {
/* Disable interrupts */
usart_hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXS;
/* Clear interrupt flag */
usart_hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXS;
}
#endif
}
void SERCOM3_Handler(void)
{
uart_int_cb(&_uart3);
}
void uart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.bufsz = 512;
_serial3.config = config;
_serial3.ops = &_uart_ops;
rt_hw_serial_register(&_serial3, "uart3", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &_uart3);
}

634
bsp/samd21/project.uvprojx Normal file
View File

@ -0,0 +1,634 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>RT-Thread</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed>
<TargetOption>
<TargetCommonOption>
<Device>ATSAMD21J18A</Device>
<Vendor>Atmel</Vendor>
<PackID>Keil.SAMD21_DFP.1.2.0</PackID>
<PackURL>http://www.keil.com/pack/</PackURL>
<Cpu>IRAM(0x20000000,0x00008000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0ATSAMD21_256 -FS00 -FL040000 -FP0($$Device:ATSAMD21J18A$Flash\ATSAMD21_256.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId>
<RegisterFile>$$Device:ATSAMD21J18A$Device\SAMD21\Include\samd21.h</RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:ATSAMD21J18A$SVD\SAMD21\ATSAMD21J18A.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath></RegisterFilePath>
<DBRegisterFilePath></DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\Objects\</OutputDirectory>
<OutputName>RT-Thread</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>0</CreateHexFile>
<DebugInformation>1</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath>.\Listings\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>1</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments> </SimDllArguments>
<SimDlgDll>DARMCM1.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM0+</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments> </TargetDllArguments>
<TargetDlgDll>TARMCM1.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM0+</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4096</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3>"" ()</Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M0+"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>0</RvdsVP>
<hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>1</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x8000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x40000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x40000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x20000000</StartAddress>
<Size>0x8000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>1</Optim>
<oTime>0</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>2</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>1</uC99>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>__SAMD21J18A__, DEBUG, EXTINT_CALLBACK_MODE=true, RTC_COUNT_ASYNC=true, USART_CALLBACK_MODE=false</Define>
<Undefine></Undefine>
<IncludePath>applications;.;board;asflib_config;asflib_config\clock_samd21_r21_da_ha1;sam_d2x_asflib\CMSIS\Include;sam_d2x_asflib\common\utils;sam_d2x_asflib\common\utils\interrupt;sam_d2x_asflib\common\boards;sam_d2x_asflib\common2\services\delay;sam_d2x_asflib\common2\services\delay\sam0;sam_d2x_asflib\sam0;sam_d2x_asflib\sam0\utils;sam_d2x_asflib\sam0\utils\preprocessor;sam_d2x_asflib\sam0\utils\header_files;sam_d2x_asflib\sam0\utils\cmsis\samd21\include;sam_d2x_asflib\sam0\utils\cmsis\samd21\source;sam_d2x_asflib\sam0\drivers\system;sam_d2x_asflib\sam0\drivers\system\pinmux;sam_d2x_asflib\sam0\drivers\system\power\power_sam_d_r_h;sam_d2x_asflib\sam0\drivers\system\reset\reset_sam_d_r_h;sam_d2x_asflib\sam0\drivers\system\clock;sam_d2x_asflib\sam0\drivers\system\interrupt;sam_d2x_asflib\sam0\drivers\system\interrupt\system_interrupt_samd21;sam_d2x_asflib\sam0\drivers\system\clock\clock_samd21_r21_da_ha1;sam_d2x_asflib\sam0\drivers\sercom;sam_d2x_asflib\sam0\drivers\sercom\usart;sam_d2x_asflib\sam0\drivers\port;sam_d2x_asflib\sam0\drivers\rtc;sam_d2x_asflib\sam0\drivers\extint;sam_d2x_asflib\sam0\drivers\extint\extint_sam_d_r_h;..\..\include;..\..\libcpu\arm\cortex-m0;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include</IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<uClangAs>0</uClangAs>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>1</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x00000000</TextAddressRange>
<DataAddressRange>0x20000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile></ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc></Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>Application</GroupName>
<Files>
<File>
<FileName>application.c</FileName>
<FileType>1</FileType>
<FilePath>applications\application.c</FilePath>
</File>
<File>
<FileName>startup.c</FileName>
<FileType>1</FileType>
<FilePath>applications\startup.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Board</GroupName>
<Files>
<File>
<FileName>board.c</FileName>
<FileType>1</FileType>
<FilePath>board\board.c</FilePath>
</File>
<File>
<FileName>sleep_timer.c</FileName>
<FileType>1</FileType>
<FilePath>board\sleep_timer.c</FilePath>
</File>
<File>
<FileName>uart.c</FileName>
<FileType>1</FileType>
<FilePath>board\uart.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Drivers</GroupName>
<Files>
<File>
<FileName>interrupt_sam_nvic.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\common\utils\interrupt\interrupt_sam_nvic.c</FilePath>
</File>
<File>
<FileName>system_samd21.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\utils\cmsis\samd21\source\system_samd21.c</FilePath>
</File>
<File>
<FileName>startup_SAMD21.s</FileName>
<FileType>2</FileType>
<FilePath>sam_d2x_asflib\sam0\utils\cmsis\samd21\source\arm\startup_SAMD21.s</FilePath>
</File>
<File>
<FileName>system.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\system\system.c</FilePath>
</File>
<File>
<FileName>pinmux.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\system\pinmux\pinmux.c</FilePath>
</File>
<File>
<FileName>system_interrupt.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\system\interrupt\system_interrupt.c</FilePath>
</File>
<File>
<FileName>clock.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\system\clock\clock_samd21_r21_da_ha1\clock.c</FilePath>
</File>
<File>
<FileName>gclk.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\system\clock\clock_samd21_r21_da_ha1\gclk.c</FilePath>
</File>
<File>
<FileName>sercom.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\sercom\sercom.c</FilePath>
</File>
<File>
<FileName>usart.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\sercom\usart\usart.c</FilePath>
</File>
<File>
<FileName>port.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\port\port.c</FilePath>
</File>
<File>
<FileName>rtc_count.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\rtc\rtc_sam_d_r_h\rtc_count.c</FilePath>
</File>
<File>
<FileName>rtc_count_interrupt.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\rtc\rtc_sam_d_r_h\rtc_count_interrupt.c</FilePath>
</File>
<File>
<FileName>extint_callback.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\extint\extint_callback.c</FilePath>
</File>
<File>
<FileName>extint.c</FileName>
<FileType>1</FileType>
<FilePath>sam_d2x_asflib\sam0\drivers\extint\extint_sam_d_r_h\extint.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>Kernel</GroupName>
<Files>
<File>
<FileName>src_clock.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\clock.c</FilePath>
</File>
<File>
<FileName>device.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\device.c</FilePath>
</File>
<File>
<FileName>idle.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\idle.c</FilePath>
</File>
<File>
<FileName>ipc.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\ipc.c</FilePath>
</File>
<File>
<FileName>irq.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\irq.c</FilePath>
</File>
<File>
<FileName>kservice.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\kservice.c</FilePath>
</File>
<File>
<FileName>mem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\mem.c</FilePath>
</File>
<File>
<FileName>object.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\object.c</FilePath>
</File>
<File>
<FileName>scheduler.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\scheduler.c</FilePath>
</File>
<File>
<FileName>thread.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\thread.c</FilePath>
</File>
<File>
<FileName>timer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\src\timer.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>CORTEX-M0</GroupName>
<Files>
<File>
<FileName>cpuport.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\cortex-m0\cpuport.c</FilePath>
</File>
<File>
<FileName>context_rvds.S</FileName>
<FileType>2</FileType>
<FilePath>..\..\libcpu\arm\cortex-m0\context_rvds.S</FilePath>
</File>
<File>
<FileName>backtrace.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\backtrace.c</FilePath>
</File>
<File>
<FileName>div0.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\div0.c</FilePath>
</File>
<File>
<FileName>showmem.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\libcpu\arm\common\showmem.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>DeviceDrivers</GroupName>
<Files>
<File>
<FileName>serial.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\serial\serial.c</FilePath>
</File>
<File>
<FileName>completion.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\completion.c</FilePath>
</File>
<File>
<FileName>dataqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\dataqueue.c</FilePath>
</File>
<File>
<FileName>pipe.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\pipe.c</FilePath>
</File>
<File>
<FileName>portal.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\portal.c</FilePath>
</File>
<File>
<FileName>ringbuffer.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\ringbuffer.c</FilePath>
</File>
<File>
<FileName>workqueue.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\components\drivers\src\workqueue.c</FilePath>
</File>
</Files>
</Group>
</Groups>
</Target>
</Targets>
<RTE>
<apis/>
<components/>
<files/>
</RTE>
</Project>

94
bsp/samd21/rtconfig.h Normal file
View File

@ -0,0 +1,94 @@
/* RT-Thread config file */
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__
/* RT_NAME_MAX*/
#define RT_NAME_MAX 6
/* RT_ALIGN_SIZE*/
#define RT_ALIGN_SIZE 4
/* PRIORITY_MAX */
#define RT_THREAD_PRIORITY_MAX 8
/* Tick per Second */
#define RT_TICK_PER_SECOND 200
/* SECTION: RT_DEBUG */
/* Thread Debug */
#define RT_DEBUG
//#define RT_DEBUG_INIT 1
#define RT_USING_OVERFLOW_CHECK
/* Using Hook */
#define RT_USING_HOOK
#define IDLE_THREAD_STACK_SIZE 512
/* Using Software Timer */
/* #define RT_USING_TIMER_SOFT */
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 512
#define RT_TIMER_TICK_PER_SECOND 100
/* SECTION: IPC */
/* Using Semaphore*/
#define RT_USING_SEMAPHORE
/* Using Mutex */
#define RT_USING_MUTEX
/* Using Event */
#define RT_USING_EVENT
/* Using MailBox */
/* #define RT_USING_MAILBOX */
/* Using Message Queue */
/* #define RT_USING_MESSAGEQUEUE */
/* SECTION: Memory Management */
/* Using Memory Pool Management*/
/* #define RT_USING_MEMPOOL */
/* Using Dynamic Heap Management */
#define RT_USING_HEAP
/* Using Small MM */
#define RT_USING_SMALL_MEM
#define RT_USING_TINY_SIZE
// <bool name="RT_USING_COMPONENTS_INIT" description="Using RT-Thread components initialization" default="true" />
//#define RT_USING_COMPONENTS_INIT
/* SECTION: Device System */
/* Using Device System */
#define RT_USING_DEVICE
// <bool name="RT_USING_DEVICE_IPC" description="Using device communication" default="true" />
#define RT_USING_DEVICE_IPC
// <bool name="RT_USING_SERIAL" description="Using Serial" default="true" />
#define RT_USING_SERIAL
/* SECTION: Console options */
#define RT_USING_CONSOLE
/* the buffer size of console*/
#define RT_CONSOLEBUF_SIZE 128
// <string name="RT_CONSOLE_DEVICE_NAME" description="The device name for console" default="uart1" />
#define RT_CONSOLE_DEVICE_NAME "uart3"
// #define RT_USING_SPI
/* SECTION: finsh, a C-Express shell */
// #define RT_USING_FINSH
/* configure finsh parameters */
#define FINSH_THREAD_PRIORITY 6
#define FINSH_THREAD_STACK_SIZE 512
#define FINSH_HISTORY_LINES 1
/* Using symbol table */
// #define FINSH_USING_SYMTAB
// #define FINSH_USING_DESCRIPTION
// #define FINSH_USING_MSH
// #define FINSH_USING_MSH_ONLY
#endif

87
bsp/samd21/rtconfig.py Normal file
View File

@ -0,0 +1,87 @@
import os
# toolchains options
ARCH='arm'
CPU='cortex-m0'
CROSS_TOOL='keil'
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
#DEVICE_SERIES = 'SAMD20'
DEVICE_SERIES = 'SAMD21'
#DEVICE_TYPE = '__SAMD20G18A__'
DEVICE_TYPE = '__SAMD21J18A__'
# cross_tool provides the cross compiler
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin'
elif CROSS_TOOL == 'keil':
PLATFORM = 'armcc'
EXEC_PATH = 'C:/Keil'
elif CROSS_TOOL == 'iar':
print '================ERROR============================'
print 'Not support iar yet!'
print '================================================='
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'arm-none-eabi-'
CC = PREFIX + 'gcc'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'axf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=cortex-m0+ -mthumb -ffunction-sections -fdata-sections'
CFLAGS = DEVICE
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-MKL15Z128.map,-cref,-u,Reset_Handler -T MKL15Z128_FLASH.ld'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
else:
CFLAGS += ' -O2'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
elif PLATFORM == 'armcc':
# toolchains
CC = 'armcc'
AS = 'armasm'
AR = 'armar'
LINK = 'armlink'
TARGET_EXT = 'axf'
DEVICE = ' --device DARMSTM'
CFLAGS = DEVICE + ' --apcs=interwork'
AFLAGS = DEVICE
LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-SAM_D2x.map --strict --scatter SAM_D2X_RTT.scf'
CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC'
LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB'
EXEC_PATH += '/arm/bin40/'
if BUILD == 'debug':
CFLAGS += ' -g -O0'
AFLAGS += ' -g'
else:
CFLAGS += ' -O2'
POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'

View File

@ -0,0 +1,136 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 31. July 2014
* $Revision: V1.4.4
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - Neither the name of ARM LIMITED nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* -------------------------------------------------------------------- */
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
//extern const q31_t realCoefAQ31[1024];
//extern const q31_t realCoefBQ31[1024];
extern const float32_t twiddleCoef_16[32];
extern const float32_t twiddleCoef_32[64];
extern const float32_t twiddleCoef_64[128];
extern const float32_t twiddleCoef_128[256];
extern const float32_t twiddleCoef_256[512];
extern const float32_t twiddleCoef_512[1024];
extern const float32_t twiddleCoef_1024[2048];
extern const float32_t twiddleCoef_2048[4096];
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
extern const q31_t twiddleCoef_16_q31[24];
extern const q31_t twiddleCoef_32_q31[48];
extern const q31_t twiddleCoef_64_q31[96];
extern const q31_t twiddleCoef_128_q31[192];
extern const q31_t twiddleCoef_256_q31[384];
extern const q31_t twiddleCoef_512_q31[768];
extern const q31_t twiddleCoef_1024_q31[1536];
extern const q31_t twiddleCoef_2048_q31[3072];
extern const q31_t twiddleCoef_4096_q31[6144];
extern const q15_t twiddleCoef_16_q15[24];
extern const q15_t twiddleCoef_32_q15[48];
extern const q15_t twiddleCoef_64_q15[96];
extern const q15_t twiddleCoef_128_q15[192];
extern const q15_t twiddleCoef_256_q15[384];
extern const q15_t twiddleCoef_512_q15[768];
extern const q15_t twiddleCoef_1024_q15[1536];
extern const q15_t twiddleCoef_2048_q15[3072];
extern const q15_t twiddleCoef_4096_q15[6144];
extern const float32_t twiddleCoef_rfft_32[32];
extern const float32_t twiddleCoef_rfft_64[64];
extern const float32_t twiddleCoef_rfft_128[128];
extern const float32_t twiddleCoef_rfft_256[256];
extern const float32_t twiddleCoef_rfft_512[512];
extern const float32_t twiddleCoef_rfft_1024[1024];
extern const float32_t twiddleCoef_rfft_2048[2048];
extern const float32_t twiddleCoef_rfft_4096[4096];
/* floating-point bit reversal tables */
#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
/* fixed-point bit reversal tables */
#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
/* Tables for Fast Math Sine and Cosine */
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* ARM_COMMON_TABLES_H */

View File

@ -0,0 +1,79 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 31. July 2014
* $Revision: V1.4.4
*
* Project: CMSIS DSP Library
* Title: arm_const_structs.h
*
* Description: This file has constant structs that are initialized for
* user convenience. For example, some can be given as
* arguments to the arm_cfft_f32() function.
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - 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.
* - Neither the name of ARM LIMITED nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* -------------------------------------------------------------------- */
#ifndef _ARM_CONST_STRUCTS_H
#define _ARM_CONST_STRUCTS_H
#include "arm_math.h"
#include "arm_common_tables.h"
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,711 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
#ifdef __cplusplus
extern "C" {
#endif
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI__VFP_SUPPORT____
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ ) /* Cosmic */
#if ( __CSMC__ & 0x400) // FPU present for parser
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

View File

@ -0,0 +1,822 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
#ifdef __cplusplus
extern "C" {
#endif
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI__VFP_SUPPORT____
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ ) /* Cosmic */
#if ( __CSMC__ & 0x400) // FPU present for parser
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,637 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.00
* @date 28. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,880 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.00
* @date 28. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03) || ((defined(__CORTEX_SC)) && (__CORTEX_SC >= 300))
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint32_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,697 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32) ) >> 32))
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/* not yet supported */
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */

View File

@ -0,0 +1,842 @@
/**************************************************************************//**
* @file core_sc000.h
* @brief CMSIS SC000 Core Peripheral Access Layer Header File
* @version V4.00
* @date 22. August 2014
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 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.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_SC000_H_GENERIC
#define __CORE_SC000_H_GENERIC
#ifdef __cplusplus
extern "C" {
#endif
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup SC000
@{
*/
/* CMSIS SC000 definitions */
#define __SC000_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */
#define __SC000_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16) | \
__SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_SC (000) /*!< Cortex secure core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI__VFP_SUPPORT____
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ ) /* Cosmic */
#if ( __CSMC__ & 0x400) // FPU present for parser
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_SC000_H_DEPENDANT
#define __CORE_SC000_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __SC000_REV
#define __SC000_REV 0x0000
#warning "__SC000_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group SC000 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED0[1];
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
uint32_t RESERVED1[154];
__IO uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/* SCB Security Features Register Definitions */
#define SCB_SFCR_UNIBRTIMING_Pos 0 /*!< SCB SFCR: UNIBRTIMING Position */
#define SCB_SFCR_UNIBRTIMING_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: UNIBRTIMING Mask */
#define SCB_SFCR_SECKEY_Pos 16 /*!< SCB SFCR: SECKEY Position */
#define SCB_SFCR_SECKEY_Msk (0xFFFFUL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SFCR: SECKEY Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
\brief Type definitions for the System Control and ID Register not in the SCB
@{
*/
/** \brief Structure type to access the System Control and ID Register not in the SCB.
*/
typedef struct
{
uint32_t RESERVED0[2];
__IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
} SCnSCB_Type;
/* Auxiliary Control Register Definitions */
#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */
#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */
/*@} end of group CMSIS_SCnotSCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of SC000 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
# get current directory
cwd = GetCurrentDir()
#var defined
CPPDEFINES = []
src = []
path = []
#common lib define
CPPDEFINES += [rtconfig.DEVICE_TYPE, 'DEBUG']
#CMSIS/Include/ common/ common2/service/delay
path += [cwd + '/CMSIS/Include/']
path += [cwd + '/common/utils/', cwd + '/common/utils/interrupt/']
path += [cwd + '/common/boards/']
path += [cwd + '/common2/services/delay/', cwd + '/common2/services/delay/sam0/']
src += Glob('./common/utils/interrupt/interrupt_sam_nvic.c')
#sam0/ sam0/utils/
path += [cwd + '/sam0/', cwd + '/sam0/utils/']
path += [cwd + '/sam0/utils/preprocessor']
path += [cwd + '/sam0/utils/header_files']
#sam0/utils/cmsis/
if rtconfig.DEVICE_SERIES == 'SAMD20':
#D20
path += [cwd + '/sam0/', cwd + '/sam0/utils/cmsis/samd20/include/']
path += [cwd + '/sam0/utils/cmsis/samd20/source/']
src += Glob('./sam0/utils/cmsis/samd20/source/*.c')
src += Glob('./sam0/utils/cmsis/samd20/source/arm/*.s')
elif rtconfig.DEVICE_SERIES == 'SAMD21':
#D21
path += [cwd + '/sam0/utils/cmsis/samd21/include/']
path += [cwd + '/sam0/utils/cmsis/samd21/source/']
src += Glob('./sam0/utils/cmsis/samd21/source/*.c')
src += Glob('./sam0/utils/cmsis/samd21/source/arm/*.s')
#sam0/drivers/system
path += [cwd + '/sam0/drivers/system/']
src += Glob('./sam0/drivers/system/system.c')
path += [cwd + '/sam0/drivers/system/pinmux']
src += Glob('./sam0/drivers/system/pinmux/*.c')
path += [cwd + '/sam0/drivers/system/power/power_sam_d_r_h']
path += [cwd + '/sam0/drivers/system/reset/reset_sam_d_r_h']
path += [cwd + '/sam0/drivers/system/clock']
path += [cwd + '/sam0/drivers/system/interrupt/']
src += Glob('./sam0/drivers/system/interrupt/*.c')
if rtconfig.DEVICE_SERIES == 'SAMD20':
path += [cwd + '/sam0/drivers/system/interrupt/system_interrupt_samd20/']
elif rtconfig.DEVICE_SERIES == 'SAMD21':
path += [cwd + '/sam0/drivers/system/interrupt/system_interrupt_samd21/']
#sam0/drivers/system/clock
if rtconfig.DEVICE_SERIES == 'SAMD20':
path += [cwd + '/sam0/drivers/system/clock/clock_samd20']
#path += [cwd + '/sam0/drivers/system/clock/clock_samd20/module_config']
src += Glob('./sam0/drivers/system/clock/clock_samd20/*.c')
elif rtconfig.DEVICE_SERIES == 'SAMD21':
#path += [cwd + '/sam0/drivers/system/clock/clock_samd21_r21_da_ha1/module_config']
path += [cwd + '/sam0/drivers/system/clock/clock_samd21_r21_da_ha1']
src += Glob('./sam0/drivers/system/clock/clock_samd21_r21_da_ha1/*.c')
#sam0/drivers/sercom
path += [cwd + '/sam0/drivers/sercom', cwd + '/sam0/drivers/sercom/usart']
src += Glob('./sam0/drivers/sercom/*.c')
src += Glob('./sam0/drivers/sercom/usart/*.c')
SrcRemove(src, 'sercom_interrupt.c')
SrcRemove(src, 'usart_interrupt.c')
CPPDEFINES += ['USART_CALLBACK_MODE=false']
#sam0/drivers/port
path += [cwd + '/sam0/drivers/port']
src += Glob('./sam0/drivers/port/port.c')
#sam0/drivers/rtc
path += [cwd + '/sam0/drivers/rtc']
src += Glob('./sam0/drivers/rtc/rtc_sam_d_r_h/rtc_count*.c')
CPPDEFINES += ['RTC_COUNT_ASYNC=true']
#sam0/drivers/extint
path += [cwd + '/sam0/drivers/extint', cwd + '/sam0/drivers/extint/extint_sam_d_r_h']
src += Glob('./sam0/drivers/extint/extint_callback.c')
src += Glob('./sam0/drivers/extint/extint_sam_d_r_h/extint.c')
CPPDEFINES += ['EXTINT_CALLBACK_MODE=true']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)
Return('group')

View File

@ -0,0 +1,448 @@
/**
* \file
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board (parameter BOARD).
*
* Copyright (c) 2009-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/**
* \defgroup group_common_boards Generic board support
*
* The generic board support module includes board-specific definitions
* and function prototypes, such as the board initialization function.
*
* \{
*/
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/*! \name Base Boards
*/
//! @{
#define EVK1100 1 //!< AT32UC3A EVK1100 board.
#define EVK1101 2 //!< AT32UC3B EVK1101 board.
#define UC3C_EK 3 //!< AT32UC3C UC3C-EK board.
#define EVK1104 4 //!< AT32UC3A3 EVK1104 board.
#define EVK1105 5 //!< AT32UC3A EVK1105 board.
#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board.
#define UC3L_EK 7 //!< AT32UC3L-EK board.
#define XPLAIN 8 //!< ATxmega128A1 Xplain board.
#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board.
#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board.
#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board.
#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board.
#define STK600_RCUC3D 16 //!< STK600 RCUC3D board.
#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board.
#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board.
#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board.
#define XMEGA_A1U_XPLAINED_PRO 20 //!< ATxmega128A1U XMEGA-A1U Xplained Pro board.
#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board.
#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board.
#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board.
#define STK600_RC044X 24 //!< STK600 with RC044X routing card board.
#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board.
#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board.
#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board.
#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board.
#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board.
#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards.
#define RZ600 31 //!< AT32UC3A RZ600 MCU board.
#define SAM3S_EK 32 //!< SAM3S-EK board.
#define SAM3U_EK 33 //!< SAM3U-EK board.
#define SAM3X_EK 34 //!< SAM3X-EK board.
#define SAM3N_EK 35 //!< SAM3N-EK board.
#define SAM3S_EK2 36 //!< SAM3S-EK2 board.
#define SAM4S_EK 37 //!< SAM4S-EK board.
#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board.
#define STK600_MEGA 39 //!< STK600 MEGA board.
#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board.
#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board.
#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board.
#define ARDUINO_DUE_X 43 //!< Arduino Due/X board.
#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board.
#define SAM4L_EK 45 //!< SAM4L-EK board.
#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board.
#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board.
#define STK600_RC032X 48 //!< STK600 with RC032X routing card board.
#define SAM4S_EK2 49 //!< SAM4S-EK2 board.
#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board.
#define SAM4E_EK 51 //!< SAM4E-EK board.
#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board.
#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board.
#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board.
#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit.
#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 Zigbit.
#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B Zigbit.
#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board.
#define SAMD20_XPLAINED_PRO 59 //!< SAM D20 Xplained Pro board.
#define SAM4L8_XPLAINED_PRO 60 //!< SAM4L8 Xplained Pro board.
#define SAM4N_XPLAINED_PRO 61 //!< SAM4N Xplained Pro board.
#define XMEGA_A3_REB_CBB 62 //!< XMEGA REB Controller Base board.
#define ATMEGARFX_RCB 63 //!< RFR2 & RFA1 RCB.
#define SAM4C_EK 64 //!< SAM4C-EK board.
#define RCB256RFR2_XPRO 65 //!< RFR2 RCB Xplained Pro board.
#define SAMG53_XPLAINED_PRO 66 //!< SAMG53 Xplained Pro board.
#define SAM4CP16BMB 67 //!< SAM4CP16BMB board.
#define SAM4E_XPLAINED_PRO 68 //!< SAM4E Xplained Pro board.
#define SAMD21_XPLAINED_PRO 69 //!< SAM D21 Xplained Pro board.
#define SAMR21_XPLAINED_PRO 70 //!< SAM R21 Xplained Pro board.
#define SAM4CMP_DB 71 //!< SAM4CMP demo board.
#define SAM4CMS_DB 72 //!< SAM4CMS demo board.
#define ATPL230AMB 73 //!< ATPL230AMB board.
#define SAMD11_XPLAINED_PRO 74 //!< SAM D11 Xplained Pro board.
#define SAMG55_XPLAINED_PRO 75 //!< SAMG55 Xplained Pro board.
#define SAML21_XPLAINED_PRO 76 //!< SAM L21 Xplained Pro board.
#define SAMD10_XPLAINED_MINI 77 //!< SAM D10 Xplained Mini board.
#define SAMDA1_XPLAINED_PRO 78 //!< SAM DA1 Xplained Pro board.
#define SAMW25_XPLAINED_PRO 79 //!< SAMW25 Xplained Pro board.
#define SAMC21_XPLAINED_PRO 80 //!< SAM C21 Xplained Pro board.
#define SAMV71_XPLAINED_ULTRA 81 //!< SAMV71 Xplained Ultra board.
#define ATMEGA328P_XPLAINED_MINI 82 //!< ATMEGA328P Xplained MINI board.
#define ATMEGA328PB_XPLAINED_MINI 83 //!< ATMEGA328PB Xplained MINI board.
#define SAMB11_XPLAINED_PRO 84 //!< SAM B11 Xplained Pro board.
#define SAME70_XPLAINED 85 //!< SAME70 Xplained board.
#define SAML22_XPLAINED_PRO 86 //!< SAM L22 Xplained Pro board.
#define SAML22_XPLAINED_PRO_B 87 //!< SAM L22 Xplained Pro board.
#define SAMR21ZLL_EK 88 //!< SAMR21ZLL-EK board.
#define ATMEGA168PB_XPLAINED_MINI 89 //!< ATMEGA168PB Xplained MINI board.
#define ATMEGA324PB_XPLAINED_PRO 90 //!< ATMEGA324PB Xplained Pro board.
#define SAMB11CSP_XPLAINED_PRO 91 //!< SAM B11 CSP Xplained Pro board.
#define SAMB11ZR_XPLAINED_PRO 92 //!< SAM B11 ZR Xplained Pro board.
#define SAMR30_XPLAINED_PRO 93 //!< SAM R30 Xplained Pro board.
#define SAMHA1G16A_XPLAINED_PRO 94 //!< SAM HA1G16A Xplained Pro board.
#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices.
#define AVR_SIMULATOR_UC3 98 //!< Simulator for the AVR UC3 device family.
#define USER_BOARD 99 //!< User-reserved board (if any).
#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader).
//! @}
/*! \name Extension Boards
*/
//! @{
#define EXT1102 1 //!< AT32UC3B EXT1102 board
#define MC300 2 //!< AT32UC3 MC300 board
#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1
#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2
#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board
#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board
#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A"
#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600
#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600
#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600
#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard
#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board
#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any).
//! @}
#if BOARD == EVK1100
# include "evk1100/evk1100.h"
#elif BOARD == EVK1101
# include "evk1101/evk1101.h"
#elif BOARD == UC3C_EK
# include "uc3c_ek/uc3c_ek.h"
#elif BOARD == EVK1104
# include "evk1104/evk1104.h"
#elif BOARD == EVK1105
# include "evk1105/evk1105.h"
#elif BOARD == STK600_RCUC3L0
# include "stk600/rcuc3l0/stk600_rcuc3l0.h"
#elif BOARD == UC3L_EK
# include "uc3l_ek/uc3l_ek.h"
#elif BOARD == STK600_RCUC3L4
# include "stk600/rcuc3l4/stk600_rcuc3l4.h"
#elif BOARD == XPLAIN
# include "xplain/xplain.h"
#elif BOARD == STK600_MEGA
/*No header-file to include*/
#elif BOARD == STK600_MEGA_RF
# include "stk600.h"
#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO
# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h"
#elif BOARD == ATMEGA256RFR2_ZIGBIT
# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h"
#elif BOARD == STK600_RC032X
# include "stk600/rc032x/stk600_rc032x.h"
#elif BOARD == STK600_RC044X
# include "stk600/rc044x/stk600_rc044x.h"
#elif BOARD == STK600_RC064X
# include "stk600/rc064x/stk600_rc064x.h"
#elif BOARD == STK600_RC100X
# include "stk600/rc100x/stk600_rc100x.h"
#elif BOARD == UC3_A3_XPLAINED
# include "uc3_a3_xplained/uc3_a3_xplained.h"
#elif BOARD == UC3_L0_XPLAINED
# include "uc3_l0_xplained/uc3_l0_xplained.h"
#elif BOARD == STK600_RCUC3B0
# include "stk600/rcuc3b0/stk600_rcuc3b0.h"
#elif BOARD == STK600_RCUC3D
# include "stk600/rcuc3d/stk600_rcuc3d.h"
#elif BOARD == STK600_RCUC3C0
# include "stk600/rcuc3c0/stk600_rcuc3c0.h"
#elif BOARD == SAMG53_XPLAINED_PRO
# include "samg53_xplained_pro/samg53_xplained_pro.h"
#elif BOARD == SAMG55_XPLAINED_PRO
# include "samg55_xplained_pro/samg55_xplained_pro.h"
#elif BOARD == XMEGA_B1_XPLAINED
# include "xmega_b1_xplained/xmega_b1_xplained.h"
#elif BOARD == STK600_RC064X_LCDX
# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h"
#elif BOARD == STK600_RC100X_LCDX
# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h"
#elif BOARD == XMEGA_A1_XPLAINED
# include "xmega_a1_xplained/xmega_a1_xplained.h"
#elif BOARD == XMEGA_A1U_XPLAINED_PRO
# include "xmega_a1u_xplained_pro/xmega_a1u_xplained_pro.h"
#elif BOARD == UC3_L0_XPLAINED_BC
# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h"
#elif BOARD == SAM3S_EK
# include "sam3s_ek/sam3s_ek.h"
# include "system_sam3s.h"
#elif BOARD == SAM3S_EK2
# include "sam3s_ek2/sam3s_ek2.h"
# include "system_sam3sd8.h"
#elif BOARD == SAM3U_EK
# include "sam3u_ek/sam3u_ek.h"
# include "system_sam3u.h"
#elif BOARD == SAM3X_EK
# include "sam3x_ek/sam3x_ek.h"
# include "system_sam3x.h"
#elif BOARD == SAM3N_EK
# include "sam3n_ek/sam3n_ek.h"
# include "system_sam3n.h"
#elif BOARD == SAM4S_EK
# include "sam4s_ek/sam4s_ek.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_WPIR_RD
# include "sam4s_wpir_rd/sam4s_wpir_rd.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_XPLAINED
# include "sam4s_xplained/sam4s_xplained.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_EK2
# include "sam4s_ek2/sam4s_ek2.h"
# include "system_sam4s.h"
#elif BOARD == MEGA_1284P_XPLAINED
/*No header-file to include*/
#elif BOARD == ARDUINO_DUE_X
# include "arduino_due_x/arduino_due_x.h"
# include "system_sam3x.h"
#elif BOARD == SAM4L_EK
# include "sam4l_ek/sam4l_ek.h"
#elif BOARD == SAM4E_EK
# include "sam4e_ek/sam4e_ek.h"
#elif BOARD == SAMD20_XPLAINED_PRO
# include "samd20_xplained_pro/samd20_xplained_pro.h"
#elif BOARD == SAMD21_XPLAINED_PRO
# include "samd21_xplained_pro/samd21_xplained_pro.h"
#elif BOARD == SAMR21_XPLAINED_PRO
# include "samr21_xplained_pro/samr21_xplained_pro.h"
#elif BOARD == SAMR30_XPLAINED_PRO
# include "samr30_xplained_pro/samr30_xplained_pro.h"
#elif BOARD == SAMR21ZLL_EK
# include "samr21zll_ek/samr21zll_ek.h"
#elif BOARD == SAMD11_XPLAINED_PRO
# include "samd11_xplained_pro/samd11_xplained_pro.h"
#elif BOARD == SAML21_XPLAINED_PRO && defined(__SAML21J18A__)
# include "saml21_xplained_pro/saml21_xplained_pro.h"
#elif BOARD == SAML22_XPLAINED_PRO
# include "saml22_xplained_pro/saml22_xplained_pro.h"
#elif BOARD == SAML22_XPLAINED_PRO_B
# include "saml22_xplained_pro_b/saml22_xplained_pro_b.h"
#elif BOARD == SAML21_XPLAINED_PRO && defined(__SAML21J18B__)
# include "saml21_xplained_pro_b/saml21_xplained_pro.h"
#elif BOARD == SAMD10_XPLAINED_MINI
# include "samd10_xplained_mini/samd10_xplained_mini.h"
#elif BOARD == SAMDA1_XPLAINED_PRO
# include "samda1_xplained_pro/samda1_xplained_pro.h"
#elif BOARD == SAMHA1G16A_XPLAINED_PRO
# include "samha1g16a_xplained_pro/samha1g16a_xplained_pro.h"
#elif BOARD == SAMC21_XPLAINED_PRO
# include "samc21_xplained_pro/samc21_xplained_pro.h"
#elif BOARD == SAM4N_XPLAINED_PRO
# include "sam4n_xplained_pro/sam4n_xplained_pro.h"
#elif BOARD == SAMW25_XPLAINED_PRO
# include "samw25_xplained_pro/samw25_xplained_pro.h"
#elif BOARD == SAMV71_XPLAINED_ULTRA
# include "samv71_xplained_ultra/samv71_xplained_ultra.h"
#elif BOARD == MEGA1284P_XPLAINED_BC
# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h"
#elif BOARD == UC3_L0_QT600
# include "uc3_l0_qt600/uc3_l0_qt600.h"
#elif BOARD == XMEGA_A3BU_XPLAINED
# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h"
#elif BOARD == XMEGA_E5_XPLAINED
# include "xmega_e5_xplained/xmega_e5_xplained.h"
#elif BOARD == UC3B_BOARD_CONTROLLER
# include "uc3b_board_controller/uc3b_board_controller.h"
#elif BOARD == RZ600
# include "rz600/rz600.h"
#elif BOARD == STK600_RCUC3A0
# include "stk600/rcuc3a0/stk600_rcuc3a0.h"
#elif BOARD == ATXMEGA128A1_QT600
# include "atxmega128a1_qt600/atxmega128a1_qt600.h"
#elif BOARD == STK600_RCUC3L3
# include "stk600/rcuc3l3/stk600_rcuc3l3.h"
#elif BOARD == SAM4S_XPLAINED_PRO
# include "sam4s_xplained_pro/sam4s_xplained_pro.h"
#elif BOARD == SAM4L_XPLAINED_PRO
# include "sam4l_xplained_pro/sam4l_xplained_pro.h"
#elif BOARD == SAM4L8_XPLAINED_PRO
# include "sam4l8_xplained_pro/sam4l8_xplained_pro.h"
#elif BOARD == SAM4C_EK
# include "sam4c_ek/sam4c_ek.h"
#elif BOARD == SAM4CMP_DB
# include "sam4cmp_db/sam4cmp_db.h"
#elif BOARD == SAM4CMS_DB
# include "sam4cms_db/sam4cms_db.h"
#elif BOARD == SAM4CP16BMB
# include "sam4cp16bmb/sam4cp16bmb.h"
#elif BOARD == ATPL230AMB
# include "atpl230amb/atpl230amb.h"
#elif BOARD == XMEGA_C3_XPLAINED
# include "xmega_c3_xplained/xmega_c3_xplained.h"
#elif BOARD == XMEGA_RF233_ZIGBIT
# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h"
#elif BOARD == XMEGA_A3_REB_CBB
# include "xmega_a3_reb_cbb/xmega_a3_reb_cbb.h"
#elif BOARD == ATMEGARFX_RCB
# include "atmegarfx_rcb/atmegarfx_rcb.h"
#elif BOARD == RCB256RFR2_XPRO
# include "atmega256rfr2_rcb_xpro/atmega256rfr2_rcb_xpro.h"
#elif BOARD == XMEGA_RF212B_ZIGBIT
# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h"
#elif BOARD == SAM4E_XPLAINED_PRO
# include "sam4e_xplained_pro/sam4e_xplained_pro.h"
#elif BOARD == ATMEGA328P_XPLAINED_MINI
# include "atmega328p_xplained_mini/atmega328p_xplained_mini.h"
#elif BOARD == ATMEGA328PB_XPLAINED_MINI
# include "atmega328pb_xplained_mini/atmega328pb_xplained_mini.h"
#elif BOARD == SAMB11_XPLAINED_PRO
# include "samb11_xplained_pro/samb11_xplained_pro.h"
#elif BOARD == SAME70_XPLAINED
# include "same70_xplained/same70_xplained.h"
#elif BOARD == ATMEGA168PB_XPLAINED_MINI
# include "atmega168pb_xplained_mini/atmega168pb_xplained_mini.h"
#elif BOARD == ATMEGA324PB_XPLAINED_PRO
# include "atmega324pb_xplained_pro/atmega324pb_xplained_pro.h"
#elif BOARD == SAMB11CSP_XPLAINED_PRO
# include "samb11csp_xplained_pro/samb11csp_xplained_pro.h"
#elif BOARD == SAMB11ZR_XPLAINED_PRO
# include "samb11zr_xplained_pro/samb11zr_xplained_pro.h"
#elif BOARD == SIMULATOR_XMEGA_A1
# include "simulator/xmega_a1/simulator_xmega_a1.h"
#elif BOARD == AVR_SIMULATOR_UC3
# include "avr_simulator_uc3/avr_simulator_uc3.h"
#elif BOARD == USER_BOARD
// User-reserved area: #include the header file of your board here (if any).
# include "user_board.h"
#elif BOARD == DUMMY_BOARD
# include "dummy/dummy_board.h"
#else
# error No known Atmel board defined
#endif
#if (defined EXT_BOARD)
# if EXT_BOARD == MC300
# include "mc300/mc300.h"
# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \
(EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \
(EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \
(EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# include "sensors_xplained/sensors_xplained.h"
# elif EXT_BOARD == RZ600_AT86RF231
# include "at86rf231/at86rf231.h"
# elif EXT_BOARD == RZ600_AT86RF230B
# include "at86rf230b/at86rf230b.h"
# elif EXT_BOARD == RZ600_AT86RF212
# include "at86rf212/at86rf212.h"
# elif EXT_BOARD == SECURITY_XPLAINED
# include "security_xplained.h"
# elif EXT_BOARD == USER_EXT_BOARD
// User-reserved area: #include the header file of your extension board here
// (if any).
# endif
#endif
#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__))
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init(void);
#endif // #ifdef __AVR32_ABI_COMPILER__
#else
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init(void);
#endif
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif // _BOARD_H_

View File

@ -0,0 +1,76 @@
/**
* \file
*
* \brief SECURITY_XPLAINED extension board adaptation.
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "security_xplained.h"
#include "sha204_physical.h"
#include "conf_atsha204.h"
//! TWI address used at SHA204 library startup
#define SHA204_I2C_DEFAULT_ADDRESS (0xCA)
/** \brief This function initializes peripherals needed to communicate with
* the I2C security devices (ATSHA204 and ATAES132).
*/
void security_board_init(void)
{
sha204p_init();
}
/** \brief This function returns the I2C address of a chosen SHA204 device.
* \param[in] index the selected device on the Security Xplained board
* \return I2C address of chosen device
*/
uint8_t sha204_i2c_address(uint8_t index)
{
static uint8_t i2c_addresses[SHA204_DEVICE_COUNT] = {SHA204_I2C_DEFAULT_ADDRESS, 0xCC, 0xCE, 0xF8};
return i2c_addresses[index % SHA204_DEVICE_COUNT];
}

View File

@ -0,0 +1,63 @@
/**
* \file
*
* \brief SECURITY_XPLAINED_BOARD board header file.
*
* This file contains definitions and services related to the features of the
* SECURITY_XPLAINED Xplained board.
*
* To use the board, define EXT_BOARD=SECURITY_XPLAINED.
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SECURITY_XPLAINED_H_
# define SECURITY_XPLAINED_H_
#include <compiler.h>
//! number of ATSHA204 I2C devices on Security Xplained extension board
#define SHA204_DEVICE_COUNT (4)
void security_board_init(void);
uint8_t sha204_i2c_address(uint8_t index);
#endif /* SECURITY_XPLAINED_H_ */

View File

@ -0,0 +1,435 @@
/**
* \file
*
* \brief SENSORS_XPLAINED_BOARD extension board adaptation.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "sensors_xplained.h"
#include <sysclk.h>
#if UC3
# include <eic.h>
#endif
#if UC3
# define PIN_OUTPUT_FLAGS (GPIO_DIR_OUTPUT | GPIO_INIT_HIGH)
# define PIN_INPUT_FLAGS (GPIO_DIR_INPUT)
#elif XMEGA
# define PIN_OUTPUT_FLAGS (IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH)
# define PIN_INPUT_FLAGS (IOPORT_DIR_INPUT)
#endif
#if defined(__AVR32__) || defined(__ICCAVR32__)
# if !defined(AVR32_GPIO_IRQ_GROUP)
# define AVR32_GPIO_IRQ_GROUP (AVR32_GPIO_IRQ_0 / 32)
# endif
# if defined(CONFIG_GPIO_INT_LVL)
# define GPIO_INT_LVL CONFIG_GPIO_INT_LVL
# else
# define GPIO_INT_LVL 0
# endif
# if !defined(AVR32_EIC_IRQ_GROUP)
# if UC3L
# define AVR32_EIC_IRQ_GROUP (AVR32_EIC_IRQ_1 / 32)
# else
# define AVR32_EIC_IRQ_GROUP (AVR32_EIC_IRQ_0 / 32)
# endif
# endif
# if defined(CONFIG_EIC_INT_LVL)
# define EIC_INT_LVL CONFIG_EIC_INT_LVL
# else
# define EIC_INT_LVL 0
# endif
#endif /* (__AVR32__) || (__ICCAVR32__) */
/* Don't include interrupt definitions without a valid board configuration. */
#if defined(SENSORS_XPLAINED_BOARD) && defined(COMMON_SENSOR_PLATFORM)
/*! \internal
* \name Sensor Board GPIO interrupt handler callback pointers
* @{
*/
static SENSOR_IRQ_HANDLER sensor_pin3_handler;
static volatile void *sensor_pin3_arg;
static SENSOR_IRQ_HANDLER sensor_pin4_handler;
static volatile void *sensor_pin4_arg;
static SENSOR_IRQ_HANDLER sensor_pin5_handler;
static volatile void *sensor_pin5_arg;
/*! @} */
#if UC3
/*! \internal Sensor Board GPIO interrupt handler
*
* This is the default ISR for the Xplained Sensor board GPIO pins. If
* an external interrupt interface is available, the corresponding
* eic_pinX_handler will be used instead.
*
* \return Nothing.
*/
ISR(gpio_irq_handler, AVR32_GPIO_IRQ_GROUP, GPIO_INT_LVL)
{
if (gpio_get_pin_interrupt_flag(SENSOR_BOARD_PIN3)) {
sensor_pin3_handler(sensor_pin3_arg);
gpio_clear_pin_interrupt_flag(SENSOR_BOARD_PIN3);
} else if (gpio_get_pin_interrupt_flag(SENSOR_BOARD_PIN4)) {
sensor_pin4_handler(sensor_pin4_arg);
gpio_clear_pin_interrupt_flag(SENSOR_BOARD_PIN4);
} else if (gpio_get_pin_interrupt_flag(SENSOR_BOARD_PIN5)) {
sensor_pin5_handler(sensor_pin5_arg);
gpio_clear_pin_interrupt_flag(SENSOR_BOARD_PIN5);
}
}
#elif XMEGA
/*! \internal Sensor Board GPIO interrupt handler
*
* This is the default ISR for the Xplained Sensor board GPIO pins. The
* installed handler routine for the particular pin will be called with
* the argument specified when the handler was installed..
*
* \return Nothing.
*/
ISR(SENSOR_BOARD_PORT_vect)
{
PORT_t *const port = &(SENSOR_BOARD_PORT);
/* Call the interrupt handler (if any). */
if (sensor_pin3_handler && (port->IN & PIN2_bm)) {
/* Note: header pin 3 = io port pin 2 */
sensor_pin3_handler(sensor_pin3_arg);
} else if (sensor_pin4_handler && (port->IN & PIN3_bm)) {
/* Note: header pin 4 = io port pin 3 */
sensor_pin4_handler(sensor_pin4_arg);
} else if (sensor_pin5_handler && (port->IN & PIN4_bm)) {
/* Note: header pin 5 = io port pin 4 */
sensor_pin5_handler(sensor_pin5_arg);
}
/* Clear the port interrupt flag */
port->INTFLAGS = PORT_INT0IF_bm;
}
#endif
#if defined(SENSOR_PIN3_EIC_LINE)
/*! \internal Sensor Board external interrupt handler - PIN3
*
* This is the ISR for the Xplained Sensor board GPIO PIN3 for configurations
* in which it can generate an external interrupt.
*
* \return Nothing.
*/
ISR(eic_pin3_handler, AVR32_EIC_IRQ_GROUP, EIC_INT_LVL)
{
sensor_pin3_handler(sensor_pin3_arg); /* call handler in driver */
eic_clear_interrupt_line(&AVR32_EIC, SENSOR_PIN3_EIC_LINE);
}
#endif
#if defined(SENSOR_PIN4_EIC_LINE)
/*! \internal Sensor Board external interrupt handler - PIN4
*
* This is the ISR for the Xplained Sensor board GPIO PIN4 for configurations
* in which it can generate an external interrupt.
*
* \return Nothing.
*/
ISR(eic_pin4_handler, AVR32_EIC_IRQ_GROUP, EIC_INT_LVL)
{
sensor_pin4_handler(sensor_pin4_arg); /* call handler in driver */
eic_clear_interrupt_line(&AVR32_EIC, SENSOR_PIN4_EIC_LINE);
}
#endif
#if defined(SENSOR_PIN5_EIC_LINE)
/*! \internal Sensor Board external interrupt handler - PIN5
*
* This is the ISR for the Xplained Sensor board GPIO PIN5 for configurations
* in which it can generate an external interrupt.
*
* \return Nothing.
*/
ISR(eic_pin5_handler, AVR32_EIC_IRQ_GROUP, EIC_INT_LVL)
{
sensor_pin5_handler(sensor_pin5_arg); /* call handler in driver */
eic_clear_interrupt_line(&AVR32_EIC, SENSOR_PIN5_EIC_LINE);
}
#endif
#if UC3
/*! \internal Enable a general purpose I/O pin interrupt.
*
* This routine enables interrupts on a specified general purpose I/O pin.
*
* \param gpio_pin GPIO pin interface to the MCU
* \param gpio_irq IRQ of the interrupt handler
*/
static void gpio_irq_connect(uint32_t gpio_pin, uint32_t gpio_irq)
{
irq_register_handler(gpio_irq_handler, gpio_irq, GPIO_INT_LVL);
gpio_enable_pin_interrupt(gpio_pin, GPIO_RISING_EDGE);
}
#endif
#if defined(SYSCLK_EIC)
/*! \brief Enable an EIC interrupt line.
*
* This routine maps a GPIO pin and peripheral function to a specified EIC line.
*
* \param eic_line Line number to enable
* \param eic_pin GPIO module pin
* \param eic_func GPIO module function
* \param eic_irq IRQ of the interrupt handler
* \param eic_handler Interrupt handler to register
*/
static void eic_irq_connect(uint32_t eic_line, uint32_t eic_pin,
uint32_t eic_func, uint32_t eic_irq, __int_handler eic_handler)
{
eic_options_t const eic_options = {
.eic_line = eic_line,
.eic_mode = EIC_MODE_EDGE_TRIGGERED,
.eic_edge = EIC_EDGE_RISING_EDGE,
.eic_level = EIC_LEVEL_HIGH_LEVEL,
.eic_filter = EIC_FILTER_ENABLED,
.eic_async = EIC_ASYNCH_MODE
};
sysclk_enable_pba_module(SYSCLK_EIC);
gpio_enable_module_pin(eic_pin, eic_func);
irq_register_handler(eic_handler, eic_irq, 0);
eic_init(&AVR32_EIC, &eic_options, 1);
eic_enable_line(&AVR32_EIC, eic_line);
eic_enable_interrupt_line(&AVR32_EIC, eic_line);
}
#endif
/*! \brief Install a sensor interrupt handler
*
* The Sensors Xplained add-on boards route sensor device I/O pins to GPIO
* pins for the MCU installed on an Xplained platform board. Some sensor
* devices can be configured to generate interrupts on these pins to indicate
* the availability of new sensor data or the occurrence of configurable
* events related to sensor data thresholds, for example.
*
* This routine will enable interrupts on the GPIO pin specified by the
* \c gpio_pin parameter and call a user-defined callback \c handler when an
* interrupt is detected. The \c arg parameter is used to pass the address
* of user-defined input and output storage for the callback handler. Calling
* the routine with the \c handler parameter set to 0 (the NULL pointer) will
* fail with \c false returned to the caller.
*
* \param gpio_pin Board-specific GPIO pin interface to the MCU.
* \param handler The address of a driver-defined interrupt handler.
* \param arg An optional address passed to the interrupt handler.
*
* \return bool true if the call succeeds, else false.
*/
bool sensor_board_irq_connect(uint32_t gpio_pin,
SENSOR_IRQ_HANDLER handler, void *arg)
{
bool status = false;
#if XMEGA
PORT_t *sensor_port;
#endif
/* Ensure that the caller has specified a function address. */
if (handler == NULL) {
return status;
}
/* Save the interrupt flag state and disable MCU interrupts. */
irqflags_t const irq_flags = cpu_irq_save();
cpu_irq_disable();
/* Initialize an interrupt for a specified I/O pin. */
if (SENSOR_BOARD_PIN3 == gpio_pin) {
sensor_pin3_handler = handler;
sensor_pin3_arg = arg;
#if UC3
# if defined(SENSOR_PIN3_EIC_LINE)
eic_irq_connect(SENSOR_PIN3_EIC_LINE, SENSOR_PIN3_EIC_PIN,
SENSOR_PIN3_EIC_FUNC, SENSOR_PIN3_EIC_IRQ,
eic_pin3_handler);
# else
gpio_irq_connect(gpio_pin, SENSOR_PIN3_IRQ);
# endif
#elif XMEGA
sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN3);
sensor_port->INTCTRL = PORT_INT0LVL_LO_gc;
sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN3);
/* Some Xplained kits have limited asynchronous sensing on most
* pins, which requires them to be sensing on both edges.
*/
ioport_set_pin_sense_mode(SENSOR_BOARD_PIN3,
IOPORT_SENSE_BOTHEDGES);
#endif
status = true;
} else if (SENSOR_BOARD_PIN4 == gpio_pin) {
sensor_pin4_handler = handler;
sensor_pin4_arg = arg;
#if UC3
# if defined(SENSOR_PIN4_EIC_LINE)
eic_irq_connect(SENSOR_PIN4_EIC_LINE, SENSOR_PIN4_EIC_PIN,
SENSOR_PIN4_EIC_FUNC, SENSOR_PIN4_EIC_IRQ,
eic_pin4_handler);
# else
gpio_irq_connect(gpio_pin, SENSOR_PIN4_IRQ);
# endif
#elif XMEGA
sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN4);
sensor_port->INTCTRL = PORT_INT0LVL_LO_gc;
sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN4);
/* Some Xplained kits have limited asynchronous sensing on most
* pins, which requires them to be sensing on both edges.
*/
ioport_set_pin_sense_mode(SENSOR_BOARD_PIN4,
IOPORT_SENSE_BOTHEDGES);
#endif
status = true;
} else if (SENSOR_BOARD_PIN5 == gpio_pin) {
sensor_pin5_handler = handler;
sensor_pin5_arg = arg;
#if UC3
# if defined(SENSOR_PIN5_EIC_LINE)
eic_irq_connect(SENSOR_PIN5_EIC_LINE, SENSOR_PIN5_EIC_PIN,
SENSOR_PIN5_EIC_FUNC, SENSOR_PIN5_EIC_IRQ,
eic_pin5_handler);
# else
gpio_irq_connect(gpio_pin, SENSOR_PIN5_IRQ);
# endif
#elif XMEGA
sensor_port = ioport_pin_to_port(SENSOR_BOARD_PIN5);
sensor_port->INTCTRL = PORT_INT0LVL_LO_gc;
sensor_port->INT0MASK |= ioport_pin_to_mask(SENSOR_BOARD_PIN5);
/* Some Xplained kits have limited asynchronous sensing on most
* pins, which requires them to be sensing on both edges.
*/
ioport_set_pin_sense_mode(SENSOR_BOARD_PIN5,
IOPORT_SENSE_BOTHEDGES);
#endif
status = true;
}
/* Restore the MCU interrupt flag state. */
cpu_irq_restore(irq_flags);
return status;
}
#endif /* defined(SENSORS_XPLAINED_BOARD) && defined(COMMON_SENSOR_PLATFORM) */
/*! \brief Initialize sensor board target resources
*
* This function should be called to ensure proper initialization
* of sensor hardware connected to an Atmel AVR32 or XMEGA platform.
*
* \return Nothing.
*/
void sensor_board_init(void)
{
/* Configure all defined Xplained Sensor board I/O pins.
*
* \todo
* Determine whether the interrupt event flag (rising edge, falling
* edge, toggle, etc.) should be a statically configurable parameter
* for devices requiring more flexibility in how events are detected.
*/
#if (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1)
gpio_configure_pin(SENSOR_BOARD_PIN3, PIN_INPUT_FLAGS);
gpio_configure_pin(SENSOR_BOARD_PIN4, PIN_INPUT_FLAGS);
gpio_configure_pin(SENSOR_BOARD_PIN5, PIN_INPUT_FLAGS);
#elif (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1)
gpio_configure_pin(SENSOR_BOARD_PIN3, PIN_OUTPUT_FLAGS);
gpio_configure_pin(SENSOR_BOARD_PIN4, PIN_INPUT_FLAGS);
#elif (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1)
gpio_configure_pin(SENSOR_BOARD_PIN3, PIN_INPUT_FLAGS);
#elif (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
gpio_configure_pin(SENSOR_BOARD_PIN4, PIN_INPUT_FLAGS);
#endif
/* Global Interrupt Disable */
cpu_irq_disable();
/* Initialize interrupt vector table support. */
irq_initialize_vectors();
/* Global Interrupt Enable */
cpu_irq_enable();
}

View File

@ -0,0 +1,468 @@
/**
* \file
*
* \brief SENSORS_XPLAINED_BOARD board header file.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _sensors_xplained_h_
#define _sensors_xplained_h_
/**
* \defgroup group_common_boards_sensors_xplained Sensors Xplained Extension Boards
*
* This file contains definitions and services related to the features of the
* SENSORS_XPLAINED_XXX Xplained boards.
*
* To use these boards, define EXT_BOARD=SENSORS_XPLAINED_XXX, where \c 'XXX'
* is a place holder for the specific sensor extension board as defined in
* the board.h file. For example, \ref SENSORS_XPLAINED_INERTIAL_1 selects a
* configuration supporting the Atmel Inertial Sensor Board #1.
*
* When this header file is included in a platform build, the
* \ref SENSORS_XPLAINED_BOARD configuration constant will be defined so
* that conditionally built pieces of platform functionality can be invoked
* to make the sensor board usable to the system. For example, the
* platform board_init() routine can conditionally compile calls to
* sensor_board_init().
*
* \{
*/
#include "xplained_headers.h"
#include "conf_board.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup atavrsb_config Sensors Xplained Extension Board Configuration
* @brief
* The extension board configuration defines constants identifying the sensors,
* bus interface, I/O pin mappings, and sensor device signals from an Atmel
* Sensor board (\p ATAVRSBPR1, \p ATAVARSBIN1, \p ATAVARSBIN2, and so on)
* to the development platform.
*
* @sa atavrpb_config
* @{
*/
/**
* \name Common Sensor Service Configuration Constants
*
* \brief
* This module defines \ref mems_sensor_api configuration constants based
* upon a user-specified \b EXT_BOARD value. The Sensor Service determines
* which drivers and bus interface modules to use based upon these definitions.
* When \b EXT_BOARD defines a valid Sensors Xplained board constant, a
* catch-all constant named SENSORS_XPLAINED_BOARD is defined so that platform,
* service, and other code can be conditionally configured without testing for
* every particular Sensors Xplained board constant.
*
* All of the following boards are compatible with the Atmel Xplained MCU
* boards provided the required I/O peripheral pin mapping has been added
* and a call to the sensor_board_init() routine has been included in the
* board_init() routine.
*
* \par ATAVRSBIN1 Inertial Sensor Board No. 1
*
* This sensor board includes an InvenSense 3-axis gyro (ITG-3200), Bosch
* 3-axis accelerometer (BMA150), and AKM 3-axis magnetometer (AK8975).
* These sensors are interfaced via a TWI master bus mapped to pins on the
* J1 I/O expansion header on an Xplained development platform. When the
* EXT_BOARD value is set to \ref SENSORS_XPLAINED_INERTIAL_1, the following
* are defined:
*
* - \c CONF_SENSOR_BUS_TWI
* - \c INCLUDE_AK8975
* - \c INCLUDE_BMA150
* - \c INCLUDE_ITG3200
*
* \par ATAVRSBIN2 Inertial Sensor Board No. 2
*
* This sensor board includes an InvenSense 3-axis gyro (IMU-3000), Kionix
* 3-axis accelerometer (KXTF9), and Honeywell 3-axis magnetometer (HMC5883).
* These sensors are interfaced via a TWI master bus mapped to pins on the
* J1 I/O expansion header on an Xplained development platform. When the
* EXT_BOARD value is set to \ref SENSORS_XPLAINED_INERTIAL_2, the following
* are defined:
*
* - \c CONF_SENSOR_BUS_TWI
* - \c INCLUDE_HMC5883L
* - \c INCLUDE_IMU3000
* - \c INCLUDE_KXTF9
*
* \par ATAVRSBPR1 Barometric Pressure Sensor Board No. 1
*
* This sensor board includes a Bosch barometric pressure sensor (BMP085).
* This sensor is interfaced via a TWI master bus mapped to pins on the
* J1 I/O expansion header on an Xplained development platform. When the
* EXT_BOARD value is set to \ref SENSORS_XPLAINED_PRESSURE_1, the following
* are defined:
*
* - \c CONF_SENSOR_BUS_TWI
* - \c INCLUDE_BMP085
*
* \par ATAVRSBLP1 Ambient Light & IR Proximity Sensor Board No. 1
*
* This sensor board includes an Osram IR light/proximity sensor (SFH7770).
* This sensor is interfaced via a TWI master bus mapped to pins on the
* J1 I/O expansion header on an Xplained development platform. When the
* EXT_BOARD value is set to \ref SENSORS_XPLAINED_LIGHTPROX_1, the following
* are defined:
*
* - \c CONF_SENSOR_BUS_TWI
* - \c INCLUDE_SFH7770
*
* The following list summarizes available sensor service configuration
* constants that are specified by board configurations defined in this
* module.
* @{
*/
#define SENSORS_XPLAINED_BOARD
#if (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_AK8975
# define INCLUDE_BMA150
# define INCLUDE_ITG3200
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_HMC5883L
# define INCLUDE_IMU3000
# define INCLUDE_KXTF9
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_AK8975
# define INCLUDE_IMU3000
# define INCLUDE_KXTF9
#elif (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_BMP085
#elif (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_SFH7770
#elif (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# define CONF_SENSOR_BUS_TWI
# define INCLUDE_BMA222
#else
# undef SENSORS_XPLAINED_BOARD
# warning "The EXT_BOARD constant does not define a Sensors Xplained board."
#endif
// @}
/*! \name Xplained Board J1 Connector Pin Mapping
*
* \internal
* These constants map AVR & AVR32 ports to pins on the Xplained board J1
* connector where pins on the 10-pin header correspond to the following
* functions:
*
* \code
10-pin Header Function
-------------------------------------------
Pin 1 SDA
Pin 2 SCL
Pin 3 RXD
Pin 4 TXD
Pin 5 SS
Pin 6 MOSI
Pin 7 MISO
Pin 8 SCK
\endcode
* @{
*/
#define SENSOR_BOARD_PIN1 XPLD_HEADER_J1_PIN1
#define SENSOR_BOARD_PIN2 XPLD_HEADER_J1_PIN2
#define SENSOR_BOARD_PIN3 XPLD_HEADER_J1_PIN3
#define SENSOR_BOARD_PIN4 XPLD_HEADER_J1_PIN4
#define SENSOR_BOARD_PIN5 XPLD_HEADER_J1_PIN5
#define SENSOR_BOARD_PIN6 XPLD_HEADER_J1_PIN6
#define SENSOR_BOARD_PIN7 XPLD_HEADER_J1_PIN7
#define SENSOR_BOARD_PIN8 XPLD_HEADER_J1_PIN8
#if XMEGA
# define SENSOR_BOARD_PORT XPLD_HEADER_J1_PORT
# define SENSOR_BOARD_PORT_vect XPLD_HEADER_J1_INT0_vect
#endif
// @}
/*! \name Sensor Device Interrupt Routing
*
* \internal
* The following constants map I/O expansion header pins that are used as
* sensor event signal inputs to the MCU interrupt controller lines and IRQ
* numbers.
*
* These definitions are provided as a board-level description for the
* sensor drivers and are not used directly in sensor service client
* applications.
* @{
*/
#define INVALID_IRQ_NUMBER ((unsigned int) -1)
#if UC3
# define SENSOR_PIN1_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN1 / 8))
# define SENSOR_PIN2_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN2 / 8))
# define SENSOR_PIN3_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN3 / 8))
# define SENSOR_PIN4_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN4 / 8))
# define SENSOR_PIN5_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN5 / 8))
# define SENSOR_PIN6_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN6 / 8))
# define SENSOR_PIN7_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN7 / 8))
# define SENSOR_PIN8_IRQ (AVR32_GPIO_IRQ_0 + (SENSOR_BOARD_PIN8 / 8))
#else
# define SENSOR_PIN1_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN2_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN3_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN4_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN5_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN6_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN7_IRQ (INVALID_IRQ_NUMBER)
# define SENSOR_PIN8_IRQ (INVALID_IRQ_NUMBER)
#endif
#ifdef XPLD_HEADER_J1_PIN1_EIC_LINE
# define SENSOR_PIN1_EIC_LINE XPLD_HEADER_J1_PIN1_EIC_LINE
# define SENSOR_PIN1_EIC_IRQ XPLD_HEADER_J1_PIN1_EIC_IRQ
# define SENSOR_PIN1_EIC_PIN XPLD_HEADER_J1_PIN1_EIC_PIN
# define SENSOR_PIN1_EIC_FUNC XPLD_HEADER_J1_PIN1_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN2_EIC_LINE
# define SENSOR_PIN2_EIC_LINE XPLD_HEADER_J1_PIN2_EIC_LINE
# define SENSOR_PIN2_EIC_IRQ XPLD_HEADER_J1_PIN2_EIC_IRQ
# define SENSOR_PIN2_EIC_PIN XPLD_HEADER_J1_PIN2_EIC_PIN
# define SENSOR_PIN2_EIC_FUNC XPLD_HEADER_J1_PIN2_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN3_EIC_LINE
# define SENSOR_PIN3_EIC_LINE XPLD_HEADER_J1_PIN3_EIC_LINE
# define SENSOR_PIN3_EIC_IRQ XPLD_HEADER_J1_PIN3_EIC_IRQ
# define SENSOR_PIN3_EIC_PIN XPLD_HEADER_J1_PIN3_EIC_PIN
# define SENSOR_PIN3_EIC_FUNC XPLD_HEADER_J1_PIN3_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN4_EIC_LINE
# define SENSOR_PIN4_EIC_LINE XPLD_HEADER_J1_PIN4_EIC_LINE
# define SENSOR_PIN4_EIC_IRQ XPLD_HEADER_J1_PIN4_EIC_IRQ
# define SENSOR_PIN4_EIC_PIN XPLD_HEADER_J1_PIN4_EIC_PIN
# define SENSOR_PIN4_EIC_FUNC XPLD_HEADER_J1_PIN4_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN5_EIC_LINE
# define SENSOR_PIN5_EIC_LINE XPLD_HEADER_J1_PIN5_EIC_LINE
# define SENSOR_PIN5_EIC_IRQ XPLD_HEADER_J1_PIN5_EIC_IRQ
# define SENSOR_PIN5_EIC_PIN XPLD_HEADER_J1_PIN5_EIC_PIN
# define SENSOR_PIN5_EIC_FUNC XPLD_HEADER_J1_PIN5_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN6_EIC_LINE
# define SENSOR_PIN6_EIC_LINE XPLD_HEADER_J1_PIN6_EIC_LINE
# define SENSOR_PIN6_EIC_IRQ XPLD_HEADER_J1_PIN6_EIC_IRQ
# define SENSOR_PIN6_EIC_PIN XPLD_HEADER_J1_PIN6_EIC_PIN
# define SENSOR_PIN6_EIC_FUNC XPLD_HEADER_J1_PIN6_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN7_EIC_LINE
# define SENSOR_PIN7_EIC_LINE XPLD_HEADER_J1_PIN7_EIC_LINE
# define SENSOR_PIN7_EIC_IRQ XPLD_HEADER_J1_PIN7_EIC_IRQ
# define SENSOR_PIN7_EIC_PIN XPLD_HEADER_J1_PIN7_EIC_PIN
# define SENSOR_PIN7_EIC_FUNC XPLD_HEADER_J1_PIN7_EIC_FUNC
#endif
#ifdef XPLD_HEADER_J1_PIN8_EIC_LINE
# define SENSOR_PIN8_EIC_LINE XPLD_HEADER_J1_PIN8_EIC_LINE
# define SENSOR_PIN8_EIC_IRQ XPLD_HEADER_J1_PIN8_EIC_IRQ
# define SENSOR_PIN8_EIC_PIN XPLD_HEADER_J1_PIN8_EIC_PIN
# define SENSOR_PIN8_EIC_FUNC XPLD_HEADER_J1_PIN8_EIC_FUNC
#endif
// @}
/*! \name Sensor Device I/O Pins
*
* \internal
* The following constants specify I/O expansion header pins that are used as
* sensor event signal inputs to the MCU and, in some cases, control signal
* outputs from the MCU to the sensor device. For example, the \c BMP085
* pressure sensor on the \c ATAVRSBPR1 board provides a pressure sample
* End-of-Conversion (EOC) input signal to the MCU and a device "master clear"
* and reset signal (XCLR) output from the MCU to the sensor.
*
* These definitions are provided as a board-level description for the
* sensor drivers and are not used directly in sensor service client
* applications.
* @{
*/
#if (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1)
# define ak8975_sigint (SENSOR_BOARD_PIN3)
# define bma150_sigint (SENSOR_BOARD_PIN4)
# define itg3200_sigint (SENSOR_BOARD_PIN5)
# define ak8975_sigout (INVALID_PIN_NUMBER)
# define bma150_sigout (INVALID_PIN_NUMBER)
# define itg3200_sigout (INVALID_PIN_NUMBER)
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2)
# define hmc5883l_sigint (SENSOR_BOARD_PIN3)
# define kxtf9_sigint (SENSOR_BOARD_PIN4)
# define imu3000_sigint (SENSOR_BOARD_PIN5)
# define hmc5883l_sigout (INVALID_PIN_NUMBER)
# define kxtf9_sigout (INVALID_PIN_NUMBER)
# define imu3000_sigout (INVALID_PIN_NUMBER)
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1)
# define ak8975_sigint (SENSOR_BOARD_PIN3)
# define kxtf9_sigint (SENSOR_BOARD_PIN4)
# define imu3000_sigint (SENSOR_BOARD_PIN5)
# define ak8975_sigout (INVALID_PIN_NUMBER)
# define kxtf9_sigout (INVALID_PIN_NUMBER)
# define imu3000_sigout (INVALID_PIN_NUMBER)
#elif (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1)
# define bmp085_sigint (SENSOR_BOARD_PIN4)
# define bmp085_sigout (SENSOR_BOARD_PIN3)
#elif (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1)
# define sfh7770_sigint (SENSOR_BOARD_PIN3)
# define sfh7770_sigout (INVALID_PIN_NUMBER)
#elif (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# define bma222_sigint (SENSOR_BOARD_PIN4)
# define bma222_sigout (INVALID_PIN_NUMBER)
#endif
// @}
/*! \name Sensor Physical Orientation
*
* \internal
* The following constants describe the physical orientation of multi-axis
* sensor devices, relative to the standardized axes of the sensors API.
* This allows for devices to be mounted in different configurations but
* provide consistent output to applications in terms of each axis.
* For each sensor device, the orientation description consists of a set
* of three values in X, Y, Z order, which specify which sensor axis and sign
* corresponds to the standard axis positive direction.
*
* These definitions are provided as a board-level description for the
* sensor drivers and are not used directly in sensor service client
* applications.
* @{
*/
#define NON_DIRECTIONAL_DEV {AXIS_NONE, AXIS_NONE, AXIS_NONE}
#if (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1)
# define ak8975_orientation {AXIS_X_NEG, AXIS_Y_POS, AXIS_Z_NEG}
# define bma150_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
# define itg3200_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2)
# define hmc5883l_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
# define kxtf9_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
# define imu3000_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
#elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1)
# define ak8975_orientation {AXIS_X_NEG, AXIS_Y_POS, AXIS_Z_NEG}
# define kxtf9_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
# define imu3000_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
#elif (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1)
# define bmp085_orientation NON_DIRECTIONAL_DEV
#elif (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1)
# define sfh7770_orientation NON_DIRECTIONAL_DEV
#elif (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# define bma222_orientation {AXIS_X_POS, AXIS_Y_POS, AXIS_Z_POS}
#endif
// @}
/** @} */ // atavrsb_config group
//! \brief Sensor Pin Interrupt Handler Callback Type
typedef void (*SENSOR_IRQ_HANDLER)(volatile void *);
/*! \brief Initialize sensor board target resources
*
* This function is called to ensure proper initialization
* of sensor hardware connected to an Atmel AVR32 or XMEGA platform.
*
* \return Nothing.
*/
extern void sensor_board_init(void);
/*! \brief Install a sensor interrupt handler
*
* The Sensors Xplained add-on boards route sensor device I/O pins to GPIO
* pins for the MCU installed on an Xplained platform board. Some sensor
* devices can be configured to generate interrupts on these pins to indicate
* the availability of new sensor data or the occurrence of configurable
* events related to sensor data thresholds, for example.
*
* This routine will enable interrupts on the GPIO pin specified by the
* \c gpio_pin parameter and call a user-defined callback \c handler when an
* interrupt is detected. The \c arg parameter is used to pass the address
* of user-defined input and output storage for the callback handler. Calling
* the routine with the \c handler parameter set to 0 (the NULL pointer) will
* fail with \c false returned to the caller.
*
* \param gpio_pin Board-specific GPIO pin interface to the MCU.
* \param handler The address of a driver-defined interrupt handler.
* \param arg An optional address passed to the interrupt handler.
*
* \return bool true if the call succeeds, else false.
*/
extern bool sensor_board_irq_connect
(uint32_t gpio_pin, SENSOR_IRQ_HANDLER handler, void *arg);
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif /* _sensors_xplained_h_ */

View File

@ -0,0 +1,439 @@
/**
* \file
*
* \brief Xplained I/O Expansion Header Pin Mapping
*
* The Atmel Xplained evaluation boards have four 10-pin, 100mil headers that
* are used to access spare analog and digital pins on the board
* microcontroller. This file provides a common set of definitions mapping
* the Xplained expansion header \c J1, \c J2, \c J3, and \c J4 pins to spare
* pins on the board microcontroller. Software can then use these common
* definitions to configure I/O for peripherals and expansion boards connected
* to the Xplained header blocks.
*
* For each board type, the pin definitions are specified for the pins in
* each of the four headers. For UC3 based boards, if a pin can be used as
* an external interrupt source, the interrupt and GPIO pin mapping settings
* that are needed for initializing the external interrupt controller (EIC)
* are also provided.
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _xplained_headers_h_
#define _xplained_headers_h_
#include <board.h>
#include <gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define INVALID_PIN_NUMBER ((unsigned int) -1)
//! \name Xplained I/O Expansion Header Pin Mapping
// @{
#if (BOARD == UC3_A3_XPLAINED)
# define XPLD_HEADER_J1_PIN1 (AVR32_PIN_PA25)
# define XPLD_HEADER_J1_PIN2 (AVR32_PIN_PA26)
# define XPLD_HEADER_J1_PIN3 (AVR32_PIN_PX57)
# define XPLD_HEADER_J1_PIN4 (AVR32_PIN_PX58)
# define XPLD_HEADER_J1_PIN5 (AVR32_PIN_PB09)
# define XPLD_HEADER_J1_PIN6 (AVR32_PIN_PB10)
# define XPLD_HEADER_J1_PIN7 (AVR32_PIN_PB08)
# define XPLD_HEADER_J1_PIN8 (AVR32_PIN_PB07)
# define XPLD_HEADER_J2_PIN1 (AVR32_PIN_PA21)
# define XPLD_HEADER_J2_PIN2 (AVR32_PIN_PA22)
# define XPLD_HEADER_J2_PIN3 (AVR32_PIN_PA23)
# define XPLD_HEADER_J2_PIN4 (AVR32_PIN_PA24)
# define XPLD_HEADER_J2_PIN5 (AVR32_PIN_PA20)
# define XPLD_HEADER_J2_PIN6 (AVR32_PIN_PA19)
# define XPLD_HEADER_J2_PIN7 (AVR32_PIN_PA18)
# define XPLD_HEADER_J2_PIN8 (AVR32_PIN_PA17)
# define XPLD_HEADER_J3_PIN1 (AVR32_PIN_PA31)
# define XPLD_HEADER_J3_PIN2 (AVR32_PIN_PA30)
# define XPLD_HEADER_J3_PIN3 (AVR32_PIN_PA29)
# define XPLD_HEADER_J3_PIN4 (AVR32_PIN_PA28)
# define XPLD_HEADER_J3_PIN5 (AVR32_PIN_PA27)
# define XPLD_HEADER_J3_PIN6 (AVR32_PIN_PB00)
# define XPLD_HEADER_J3_PIN7 (AVR32_PIN_PB04)
# define XPLD_HEADER_J3_PIN8 (AVR32_PIN_PX19)
# define XPLD_HEADER_J4_PIN1 (AVR32_PIN_PA15)
# define XPLD_HEADER_J4_PIN2 (AVR32_PIN_PA14)
# define XPLD_HEADER_J4_PIN3 (AVR32_PIN_PA05)
# define XPLD_HEADER_J4_PIN4 (AVR32_PIN_PA06)
# define XPLD_HEADER_J4_PIN5 (AVR32_PIN_PA07)
# define XPLD_HEADER_J4_PIN6 (AVR32_PIN_PA10)
# define XPLD_HEADER_J4_PIN7 (AVR32_PIN_PA11)
# define XPLD_HEADER_J4_PIN8 (AVR32_PIN_PA08)
#elif (BOARD == UC3_L0_XPLAINED)
# define XPLD_HEADER_J1_PIN1 (AVR32_PIN_PA21)
# define XPLD_HEADER_J1_PIN2 (AVR32_PIN_PB05)
# define XPLD_HEADER_J1_PIN3 (AVR32_PIN_PB11)
# define XPLD_HEADER_J1_PIN4 (AVR32_PIN_PB10)
# define XPLD_HEADER_J1_PIN5 (AVR32_PIN_PA08)
# define XPLD_HEADER_J1_PIN6 (AVR32_PIN_PB03)
# define XPLD_HEADER_J1_PIN7 (AVR32_PIN_PB02)
# define XPLD_HEADER_J1_PIN8 (AVR32_PIN_PB01)
# define XPLD_HEADER_J2_PIN1 (AVR32_PIN_PA14)
# define XPLD_HEADER_J2_PIN2 (AVR32_PIN_PA15)
# define XPLD_HEADER_J2_PIN3 (AVR32_PIN_PA16)
# define XPLD_HEADER_J2_PIN4 (AVR32_PIN_PA18)
# define XPLD_HEADER_J2_PIN5 (AVR32_PIN_PB07)
# define XPLD_HEADER_J2_PIN6 (AVR32_PIN_PB08)
# define XPLD_HEADER_J2_PIN7 (AVR32_PIN_PB06)
# define XPLD_HEADER_J2_PIN8 (AVR32_PIN_PA19)
# define XPLD_HEADER_J3_PIN1 (AVR32_PIN_PA13)
# define XPLD_HEADER_J3_PIN2 (AVR32_PIN_PA17)
# define XPLD_HEADER_J3_PIN3 (AVR32_PIN_PA20)
# define XPLD_HEADER_J3_PIN4 (AVR32_PIN_PA22)
# define XPLD_HEADER_J3_PIN5 (AVR32_PIN_PB12)
# define XPLD_HEADER_J3_PIN6 (AVR32_PIN_PB09)
# define XPLD_HEADER_J3_PIN7 (AVR32_PIN_PB04)
# define XPLD_HEADER_J3_PIN8 (AVR32_PIN_PA11)
# define XPLD_HEADER_J4_PIN1 (AVR32_PIN_PA21)
# define XPLD_HEADER_J4_PIN2 (AVR32_PIN_PB05)
# define XPLD_HEADER_J4_PIN3 (AVR32_PIN_PB11)
# define XPLD_HEADER_J4_PIN4 (AVR32_PIN_PB10)
# define XPLD_HEADER_J4_PIN5 (AVR32_PIN_PB00)
# define XPLD_HEADER_J4_PIN6 (AVR32_PIN_PB03)
# define XPLD_HEADER_J4_PIN7 (AVR32_PIN_PB02)
# define XPLD_HEADER_J4_PIN8 (AVR32_PIN_PB01)
#elif (BOARD == XMEGA_A1_XPLAINED)
# define XPLD_HEADER_J1_PIN1 IOPORT_CREATE_PIN(PORTF,0)
# define XPLD_HEADER_J1_PIN2 IOPORT_CREATE_PIN(PORTF,1)
# define XPLD_HEADER_J1_PIN3 IOPORT_CREATE_PIN(PORTF,2)
# define XPLD_HEADER_J1_PIN4 IOPORT_CREATE_PIN(PORTF,3)
# define XPLD_HEADER_J1_PIN5 IOPORT_CREATE_PIN(PORTF,4)
# define XPLD_HEADER_J1_PIN6 IOPORT_CREATE_PIN(PORTF,5)
# define XPLD_HEADER_J1_PIN7 IOPORT_CREATE_PIN(PORTF,6)
# define XPLD_HEADER_J1_PIN8 IOPORT_CREATE_PIN(PORTF,7)
# define XPLD_HEADER_J2_PIN1 IOPORT_CREATE_PIN(PORTA,0)
# define XPLD_HEADER_J2_PIN2 IOPORT_CREATE_PIN(PORTA,1)
# define XPLD_HEADER_J2_PIN3 IOPORT_CREATE_PIN(PORTA,2)
# define XPLD_HEADER_J2_PIN4 IOPORT_CREATE_PIN(PORTA,3)
# define XPLD_HEADER_J2_PIN5 IOPORT_CREATE_PIN(PORTA,4)
# define XPLD_HEADER_J2_PIN6 IOPORT_CREATE_PIN(PORTA,5)
# define XPLD_HEADER_J2_PIN7 IOPORT_CREATE_PIN(PORTA,6)
# define XPLD_HEADER_J2_PIN8 IOPORT_CREATE_PIN(PORTA,7)
# define XPLD_HEADER_J3_PIN1 IOPORT_CREATE_PIN(PORTD,0)
# define XPLD_HEADER_J3_PIN2 IOPORT_CREATE_PIN(PORTD,1)
# define XPLD_HEADER_J3_PIN3 IOPORT_CREATE_PIN(PORTD,2)
# define XPLD_HEADER_J3_PIN4 IOPORT_CREATE_PIN(PORTD,3)
# define XPLD_HEADER_J3_PIN5 IOPORT_CREATE_PIN(PORTD,4)
# define XPLD_HEADER_J3_PIN6 IOPORT_CREATE_PIN(PORTD,5)
# define XPLD_HEADER_J3_PIN7 IOPORT_CREATE_PIN(PORTR,0)
# define XPLD_HEADER_J3_PIN8 IOPORT_CREATE_PIN(PORTR,1)
# define XPLD_HEADER_J4_PIN1 IOPORT_CREATE_PIN(PORTC,0)
# define XPLD_HEADER_J4_PIN2 IOPORT_CREATE_PIN(PORTC,1)
# define XPLD_HEADER_J4_PIN3 IOPORT_CREATE_PIN(PORTC,2)
# define XPLD_HEADER_J4_PIN4 IOPORT_CREATE_PIN(PORTC,3)
# define XPLD_HEADER_J4_PIN5 IOPORT_CREATE_PIN(PORTC,4)
# define XPLD_HEADER_J4_PIN6 IOPORT_CREATE_PIN(PORTC,5)
# define XPLD_HEADER_J4_PIN7 IOPORT_CREATE_PIN(PORTC,6)
# define XPLD_HEADER_J4_PIN8 IOPORT_CREATE_PIN(PORTC,7)
#elif (BOARD == XMEGA_B1_XPLAINED)
# define XPLD_HEADER_J1_PIN1 IOPORT_CREATE_PIN(PORTC,0)
# define XPLD_HEADER_J1_PIN2 IOPORT_CREATE_PIN(PORTC,1)
# define XPLD_HEADER_J1_PIN3 IOPORT_CREATE_PIN(PORTC,2)
# define XPLD_HEADER_J1_PIN4 IOPORT_CREATE_PIN(PORTC,3)
# define XPLD_HEADER_J1_PIN5 IOPORT_CREATE_PIN(PORTC,4)
# define XPLD_HEADER_J1_PIN6 IOPORT_CREATE_PIN(PORTC,5)
# define XPLD_HEADER_J1_PIN7 IOPORT_CREATE_PIN(PORTC,6)
# define XPLD_HEADER_J1_PIN8 IOPORT_CREATE_PIN(PORTC,7)
# define XPLD_HEADER_J2_PIN1 IOPORT_CREATE_PIN(PORTA,0)
# define XPLD_HEADER_J2_PIN2 IOPORT_CREATE_PIN(PORTA,1)
# define XPLD_HEADER_J2_PIN3 IOPORT_CREATE_PIN(PORTA,2)
# define XPLD_HEADER_J2_PIN4 IOPORT_CREATE_PIN(PORTA,3)
# define XPLD_HEADER_J2_PIN5 IOPORT_CREATE_PIN(PORTA,4)
# define XPLD_HEADER_J2_PIN6 IOPORT_CREATE_PIN(PORTA,5)
# define XPLD_HEADER_J2_PIN7 IOPORT_CREATE_PIN(PORTA,6)
# define XPLD_HEADER_J2_PIN8 IOPORT_CREATE_PIN(PORTA,7)
# define XPLD_HEADER_J3_PIN1 IOPORT_CREATE_PIN(PORTB,0)
# define XPLD_HEADER_J3_PIN2 IOPORT_CREATE_PIN(PORTB,1)
# define XPLD_HEADER_J3_PIN3 IOPORT_CREATE_PIN(PORTB,2)
# define XPLD_HEADER_J3_PIN4 IOPORT_CREATE_PIN(PORTB,3)
# define XPLD_HEADER_J3_PIN5 IOPORT_CREATE_PIN(PORTB,4)
# define XPLD_HEADER_J3_PIN6 IOPORT_CREATE_PIN(PORTB,5)
# define XPLD_HEADER_J3_PIN7 IOPORT_CREATE_PIN(PORTB,6)
# define XPLD_HEADER_J3_PIN8 IOPORT_CREATE_PIN(PORTB,7)
# define XPLD_HEADER_J4_PIN1 IOPORT_CREATE_PIN(PORTE,0)
# define XPLD_HEADER_J4_PIN2 IOPORT_CREATE_PIN(PORTE,1)
# define XPLD_HEADER_J4_PIN3 IOPORT_CREATE_PIN(PORTE,2)
# define XPLD_HEADER_J4_PIN4 IOPORT_CREATE_PIN(PORTE,3)
# define XPLD_HEADER_J4_PIN5 IOPORT_CREATE_PIN(PORTE,4)
# define XPLD_HEADER_J4_PIN6 IOPORT_CREATE_PIN(PORTE,5)
# define XPLD_HEADER_J4_PIN7 IOPORT_CREATE_PIN(PORTE,6)
# define XPLD_HEADER_J4_PIN8 IOPORT_CREATE_PIN(PORTE,7)
#elif (BOARD == XMEGA_A3BU_XPLAINED)
# define XPLD_HEADER_J1_PIN1 IOPORT_CREATE_PIN(PORTC,0)
# define XPLD_HEADER_J1_PIN2 IOPORT_CREATE_PIN(PORTC,1)
# define XPLD_HEADER_J1_PIN3 IOPORT_CREATE_PIN(PORTC,2)
# define XPLD_HEADER_J1_PIN4 IOPORT_CREATE_PIN(PORTC,3)
# define XPLD_HEADER_J1_PIN5 IOPORT_CREATE_PIN(PORTC,4)
# define XPLD_HEADER_J1_PIN6 IOPORT_CREATE_PIN(PORTC,5)
# define XPLD_HEADER_J1_PIN7 IOPORT_CREATE_PIN(PORTC,6)
# define XPLD_HEADER_J1_PIN8 IOPORT_CREATE_PIN(PORTC,7)
# define XPLD_HEADER_J2_PIN1 IOPORT_CREATE_PIN(PORTB,0)
# define XPLD_HEADER_J2_PIN2 IOPORT_CREATE_PIN(PORTB,1)
# define XPLD_HEADER_J2_PIN3 IOPORT_CREATE_PIN(PORTB,2)
# define XPLD_HEADER_J2_PIN4 IOPORT_CREATE_PIN(PORTB,3)
# define XPLD_HEADER_J2_PIN5 IOPORT_CREATE_PIN(PORTA,4)
# define XPLD_HEADER_J2_PIN6 IOPORT_CREATE_PIN(PORTA,5)
# define XPLD_HEADER_J2_PIN7 IOPORT_CREATE_PIN(PORTA,6)
# define XPLD_HEADER_J2_PIN8 IOPORT_CREATE_PIN(PORTA,7)
# define XPLD_HEADER_J3_PIN1 IOPORT_CREATE_PIN(PORTA,0)
# define XPLD_HEADER_J3_PIN2 IOPORT_CREATE_PIN(PORTA,1)
# define XPLD_HEADER_J3_PIN3 IOPORT_CREATE_PIN(PORTA,2)
# define XPLD_HEADER_J3_PIN4 IOPORT_CREATE_PIN(PORTA,3)
# define XPLD_HEADER_J3_PIN5 IOPORT_CREATE_PIN(PORTB,4)
# define XPLD_HEADER_J3_PIN6 IOPORT_CREATE_PIN(PORTB,5)
# define XPLD_HEADER_J3_PIN7 IOPORT_CREATE_PIN(PORTB,6)
# define XPLD_HEADER_J3_PIN8 IOPORT_CREATE_PIN(PORTB,7)
# define XPLD_HEADER_J4_PIN1 IOPORT_CREATE_PIN(PORTE,0)
# define XPLD_HEADER_J4_PIN2 IOPORT_CREATE_PIN(PORTE,1)
# define XPLD_HEADER_J4_PIN3 IOPORT_CREATE_PIN(PORTE,2)
# define XPLD_HEADER_J4_PIN4 IOPORT_CREATE_PIN(PORTE,3)
# define XPLD_HEADER_J4_PIN5 IOPORT_CREATE_PIN(PORTD,0)
# define XPLD_HEADER_J4_PIN6 IOPORT_CREATE_PIN(PORTD,3)
# define XPLD_HEADER_J4_PIN7 IOPORT_CREATE_PIN(PORTD,2)
# define XPLD_HEADER_J4_PIN8 IOPORT_CREATE_PIN(PORTD,1)
#else
# warning "The BOARD constant does not define a supported Xplained board."
# define XPLD_HEADER_J1_PIN1 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN2 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN3 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN4 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN5 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN6 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN7 INVALID_PIN_NUMBER
# define XPLD_HEADER_J1_PIN8 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN1 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN2 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN3 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN4 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN5 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN6 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN7 INVALID_PIN_NUMBER
# define XPLD_HEADER_J2_PIN8 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN1 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN2 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN3 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN4 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN5 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN6 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN7 INVALID_PIN_NUMBER
# define XPLD_HEADER_J3_PIN8 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN1 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN2 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN3 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN4 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN5 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN6 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN7 INVALID_PIN_NUMBER
# define XPLD_HEADER_J4_PIN8 INVALID_PIN_NUMBER
#endif
// @}
//! \name Xplained Expansion Header External Interrupt Controller Pin Mapping
// @{
#if (BOARD == UC3_A3_XPLAINED)
# define XPLD_HEADER_J2_PIN1_EIC_LINE (AVR32_EIC_INT0)
# define XPLD_HEADER_J2_PIN1_EIC_IRQ (AVR32_EIC_IRQ_0)
# define XPLD_HEADER_J2_PIN1_EIC_PIN (AVR32_EIC_EXTINT_0_PIN)
# define XPLD_HEADER_J2_PIN1_EIC_FUNC (AVR32_EIC_EXTINT_0_FUNCTION)
# define XPLD_HEADER_J2_PIN2_EIC_LINE (AVR32_EIC_INT1)
# define XPLD_HEADER_J2_PIN2_EIC_IRQ (AVR32_EIC_IRQ_1)
# define XPLD_HEADER_J2_PIN2_EIC_PIN (AVR32_EIC_EXTINT_1_PIN)
# define XPLD_HEADER_J2_PIN2_EIC_FUNC (AVR32_EIC_EXTINT_1_FUNCTION)
# define XPLD_HEADER_J2_PIN3_EIC_LINE (AVR32_EIC_INT2)
# define XPLD_HEADER_J2_PIN3_EIC_IRQ (AVR32_EIC_IRQ_2)
# define XPLD_HEADER_J2_PIN3_EIC_PIN (AVR32_EIC_EXTINT_2_PIN)
# define XPLD_HEADER_J2_PIN3_EIC_FUNC (AVR32_EIC_EXTINT_2_FUNCTION)
# define XPLD_HEADER_J2_PIN4_EIC_LINE (AVR32_EIC_INT3)
# define XPLD_HEADER_J2_PIN4_EIC_IRQ (AVR32_EIC_IRQ_3)
# define XPLD_HEADER_J2_PIN4_EIC_PIN (AVR32_EIC_EXTINT_3_PIN)
# define XPLD_HEADER_J2_PIN4_EIC_FUNC (AVR32_EIC_EXTINT_3_FUNCTION)
# define XPLD_HEADER_J2_PIN5_EIC_LINE (8) // NMI
# define XPLD_HEADER_J2_PIN5_EIC_IRQ (0) // NMI - special handler required
# define XPLD_HEADER_J2_PIN5_EIC_PIN (AVR32_EIC_EXTINT_8_PIN)
# define XPLD_HEADER_J2_PIN5_EIC_FUNC (AVR32_EIC_EXTINT_8_FUNCTION)
#elif (BOARD == UC3_L0_XPLAINED)
# define XPLD_HEADER_J1_PIN3_EIC_LINE (AVR32_EIC_INT5)
# define XPLD_HEADER_J1_PIN3_EIC_IRQ (AVR32_EIC_IRQ_5)
# define XPLD_HEADER_J1_PIN3_EIC_PIN (AVR32_EIC_EXTINT_5_1_PIN)
# define XPLD_HEADER_J1_PIN3_EIC_FUNC (AVR32_EIC_EXTINT_5_1_FUNCTION)
# define XPLD_HEADER_J1_PIN4_EIC_LINE (AVR32_EIC_INT4)
# define XPLD_HEADER_J1_PIN4_EIC_IRQ (AVR32_EIC_IRQ_4)
# define XPLD_HEADER_J1_PIN4_EIC_PIN (AVR32_EIC_EXTINT_4_1_PIN)
# define XPLD_HEADER_J1_PIN4_EIC_FUNC (AVR32_EIC_EXTINT_4_1_FUNCTION)
# define XPLD_HEADER_J2_PIN2_EIC_LINE (AVR32_EIC_INT3)
# define XPLD_HEADER_J2_PIN2_EIC_IRQ (AVR32_EIC_IRQ_3)
# define XPLD_HEADER_J2_PIN2_EIC_PIN (AVR32_EIC_EXTINT_3_0_PIN)
# define XPLD_HEADER_J2_PIN2_EIC_FUNC (AVR32_EIC_EXTINT_3_0_FUNCTION)
# define XPLD_HEADER_J2_PIN3_EIC_LINE (AVR32_EIC_INT4)
# define XPLD_HEADER_J2_PIN3_EIC_IRQ (AVR32_EIC_IRQ_4)
# define XPLD_HEADER_J2_PIN3_EIC_PIN (AVR32_EIC_EXTINT_4_0_PIN)
# define XPLD_HEADER_J2_PIN3_EIC_FUNC (AVR32_EIC_EXTINT_4_0_FUNCTION)
# define XPLD_HEADER_J2_PIN4_EIC_LINE (AVR32_EIC_INT5)
# define XPLD_HEADER_J2_PIN4_EIC_IRQ (AVR32_EIC_IRQ_5)
# define XPLD_HEADER_J2_PIN4_EIC_PIN (AVR32_EIC_EXTINT_5_0_PIN)
# define XPLD_HEADER_J2_PIN4_EIC_FUNC (AVR32_EIC_EXTINT_5_0_FUNCTION)
# define XPLD_HEADER_J2_PIN5_EIC_LINE (AVR32_EIC_INT1)
# define XPLD_HEADER_J2_PIN5_EIC_IRQ (AVR32_EIC_IRQ_1)
# define XPLD_HEADER_J2_PIN5_EIC_PIN (AVR32_EIC_EXTINT_1_1_PIN)
# define XPLD_HEADER_J2_PIN5_EIC_FUNC (AVR32_EIC_EXTINT_1_1_FUNCTION)
# define XPLD_HEADER_J2_PIN6_EIC_LINE (AVR32_EIC_INT2)
# define XPLD_HEADER_J2_PIN6_EIC_IRQ (AVR32_EIC_IRQ_2)
# define XPLD_HEADER_J2_PIN6_EIC_PIN (AVR32_EIC_EXTINT_2_1_PIN)
# define XPLD_HEADER_J2_PIN6_EIC_FUNC (AVR32_EIC_EXTINT_2_1_FUNCTION)
# define XPLD_HEADER_J2_PIN7_EIC_LINE (AVR32_EIC_INT0)
# define XPLD_HEADER_J2_PIN7_EIC_IRQ (AVR32_EIC_IRQ_0)
# define XPLD_HEADER_J2_PIN7_EIC_PIN (AVR32_EIC_EXTINT_0_1_PIN)
# define XPLD_HEADER_J2_PIN7_EIC_FUNC (AVR32_EIC_EXTINT_0_1_FUNCTION)
# define XPLD_HEADER_J3_PIN1_EIC_LINE (AVR32_EIC_INT2)
# define XPLD_HEADER_J3_PIN1_EIC_IRQ (AVR32_EIC_IRQ_2)
# define XPLD_HEADER_J3_PIN1_EIC_PIN (AVR32_EIC_EXTINT_2_0_PIN)
# define XPLD_HEADER_J3_PIN1_EIC_FUNC (AVR32_EIC_EXTINT_2_0_FUNCTION)
# define XPLD_HEADER_J3_PIN6_EIC_LINE (AVR32_EIC_INT3)
# define XPLD_HEADER_J3_PIN6_EIC_IRQ (AVR32_EIC_IRQ_3)
# define XPLD_HEADER_J3_PIN6_EIC_PIN (AVR32_EIC_EXTINT_3_1_PIN)
# define XPLD_HEADER_J3_PIN6_EIC_FUNC (AVR32_EIC_EXTINT_3_1_FUNCTION)
# define XPLD_HEADER_J4_PIN3_EIC_LINE (AVR32_EIC_INT5)
# define XPLD_HEADER_J4_PIN3_EIC_IRQ (AVR32_EIC_IRQ_5)
# define XPLD_HEADER_J4_PIN3_EIC_PIN (AVR32_EIC_EXTINT_5_1_PIN)
# define XPLD_HEADER_J4_PIN3_EIC_FUNC (AVR32_EIC_EXTINT_5_1_FUNCTION)
# define XPLD_HEADER_J4_PIN4_EIC_LINE (AVR32_EIC_INT4)
# define XPLD_HEADER_J4_PIN4_EIC_IRQ (AVR32_EIC_IRQ_4)
# define XPLD_HEADER_J4_PIN4_EIC_PIN (AVR32_EIC_EXTINT_4_1_PIN)
# define XPLD_HEADER_J4_PIN4_EIC_FUNC (AVR32_EIC_EXTINT_4_1_FUNCTION)
#elif (BOARD == XMEGA_A1_XPLAINED)
# define XPLD_HEADER_J1_PORT (PORTF)
# define XPLD_HEADER_J1_INT0_vect (PORTF_INT0_vect)
# define XPLD_HEADER_J1_INT1_vect (PORTF_INT1_vect)
# define XPLD_HEADER_J2_PORT (PORTA)
# define XPLD_HEADER_J2_INT0_vect (PORTA_INT0_vect)
# define XPLD_HEADER_J2_INT1_vect (PORTA_INT1_vect)
# define XPLD_HEADER_J3_PORT (PORTD)
# define XPLD_HEADER_J3_INT0_vect (PORTD_INT0_vect)
# define XPLD_HEADER_J3_INT1_vect (PORTD_INT1_vect)
# define XPLD_HEADER_J4_PORT (PORTC)
# define XPLD_HEADER_J4_INT0_vect (PORTC_INT0_vect)
# define XPLD_HEADER_J4_INT1_vect (PORTC_INT1_vect)
#elif (BOARD == XMEGA_B1_XPLAINED)
# define XPLD_HEADER_J1_PORT (PORTC)
# define XPLD_HEADER_J1_INT0_vect (PORTC_INT0_vect)
# define XPLD_HEADER_J1_INT1_vect (PORTC_INT1_vect)
# define XPLD_HEADER_J2_PORT (PORTA)
# define XPLD_HEADER_J2_INT0_vect (PORTA_INT0_vect)
# define XPLD_HEADER_J2_INT1_vect (PORTA_INT1_vect)
# define XPLD_HEADER_J3_PORT (PORTB)
# define XPLD_HEADER_J3_INT0_vect (PORTB_INT0_vect)
# define XPLD_HEADER_J3_INT1_vect (PORTB_INT1_vect)
# define XPLD_HEADER_J4_PORT (PORTE)
# define XPLD_HEADER_J4_INT0_vect (PORTE_INT0_vect)
# define XPLD_HEADER_J4_INT1_vect (PORTE_INT1_vect)
#elif (BOARD == XMEGA_A3BU_XPLAINED)
# define XPLD_HEADER_J1_PORT (PORTC)
# define XPLD_HEADER_J1_INT0_vect (PORTC_INT0_vect)
# define XPLD_HEADER_J1_INT1_vect (PORTC_INT1_vect)
#endif
// @}
#ifdef __cplusplus
}
#endif
#endif /* _xplained_headers_h_ */

View File

@ -0,0 +1,14 @@
/**
* \file
*
* \brief User board configuration template
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_BOARD_H
#define CONF_BOARD_H
#endif // CONF_BOARD_H

View File

@ -0,0 +1 @@
# This file needs to be customized to your MCU and is intentionally left blank

View File

@ -0,0 +1,3 @@
// This file needs to be customized to your MCU and is intentionally left blank /**
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/

View File

@ -0,0 +1 @@
# This file needs to be customized to your MCU and is intentionally left blank

View File

@ -0,0 +1,3 @@
// This file needs to be customized to your MCU and is intentionally left blank /**
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/

View File

@ -0,0 +1,21 @@
/**
* \file
*
* \brief User board initialization template
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <asf.h>
#include <board.h>
#include <conf_board.h>
void board_init(void)
{
/* This function is meant to contain board-specific initialization code
* for, e.g., the I/O pins. The initialization can rely on application-
* specific board configuration, found in conf_board.h.
*/
}

View File

@ -0,0 +1,40 @@
/**
* \file
*
* \brief User board definition template
*
*/
/* This file is intended to contain definitions and configuration details for
* features and devices that are available on the board, e.g., frequency and
* startup time for an external crystal, external memory devices, LED and USART
* pins.
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef USER_BOARD_H
#define USER_BOARD_H
#include <conf_board.h>
// External oscillator settings.
// Uncomment and set correct values if external oscillator is used.
// External oscillator frequency
//#define BOARD_XOSC_HZ 8000000
// External oscillator type.
//!< External clock signal
//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL
//!< 32.768 kHz resonator on TOSC
//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ
//!< 0.4 to 16 MHz resonator on XTALS
//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL
// External oscillator startup time
//#define BOARD_XOSC_STARTUP_US 500000
#endif // USER_BOARD_H

View File

@ -0,0 +1,68 @@
/**
* \file
*
* \brief ATSHA204 CryptoAuth driver configuration file
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_ATSHA204_H_INCLUDED
#define CONF_ATSHA204_H_INCLUDED
#include <board.h>
#if BOARD == XMEGA_A1_XPLAINED
// Interface configuration for XMEGA-A1 Xplained
# define ATSHA204_TWI_PORT (&TWIC)
#else
// Interface configuration for other boards
# warning ATSHA204 TWI port is not set for your board. Please see conf_atsha204.h.
# define ATSHA204_TWI_PORT (&TWIC)
#endif // BOARD
// Xplain board independent configuration
#define ATSHA204_TWI_SPEED (400000)
//! TWI address used at SHA204 library startup
#define SHA204_I2C_DEFAULT_ADDRESS (0xCA)
#endif /* CONF_ATSHA204_H_INCLUDED */

View File

@ -0,0 +1,312 @@
/*
* \file
*
* \brief ATSHA204 file that implements the communication layer for the device
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "sha204_comm.h" //!< definitions and declarations for the Communication module
#include "sha204_timer.h" //!< definitions for timer functions
#include "sha204_lib_return_codes.h" //!< declarations of function return codes
uint8_t sha204c_check_crc(uint8_t *response);
uint8_t sha204c_resync(uint8_t size, uint8_t *response);
/** \brief This function calculates CRC.
*
* \param[in] length number of bytes in buffer
* \param[in] data pointer to data for which CRC should be calculated
* \param[out] crc pointer to 16-bit CRC
*/
void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) {
uint8_t counter;
uint16_t crc_register = 0;
uint16_t polynom = 0x8005;
uint8_t shift_register;
uint8_t data_bit, crc_bit;
for (counter = 0; counter < length; counter++) {
for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
data_bit = (data[counter] & shift_register) ? 1 : 0;
crc_bit = crc_register >> 15;
// Shift CRC to the left by 1.
crc_register <<= 1;
if ((data_bit ^ crc_bit) != 0)
crc_register ^= polynom;
}
}
crc[0] = (uint8_t) (crc_register & 0x00FF);
crc[1] = (uint8_t) (crc_register >> 8);
}
/** \brief This function checks the consistency of a response.
* \param[in] response pointer to response
* \return status of the consistency check
*/
uint8_t sha204c_check_crc(uint8_t *response)
{
uint8_t crc[SHA204_CRC_SIZE];
uint8_t count = response[SHA204_BUFFER_POS_COUNT];
count -= SHA204_CRC_SIZE;
sha204c_calculate_crc(count, response, crc);
return (crc[0] == response[count] && crc[1] == response[count + 1])
? SHA204_SUCCESS : SHA204_BAD_CRC;
}
/** \brief This function wakes up a SHA204 device
* and receives a response.
* \param[out] response pointer to four-byte response
* \return status of the operation
*/
uint8_t sha204c_wakeup(uint8_t *response)
{
uint8_t ret_code = sha204p_wakeup();
if (ret_code != SHA204_SUCCESS)
return ret_code;
ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
if (ret_code != SHA204_SUCCESS)
return ret_code;
// Verify status response.
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN)
ret_code = SHA204_INVALID_SIZE;
else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP)
ret_code = SHA204_COMM_FAIL;
else {
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43))
ret_code = SHA204_BAD_CRC;
}
if (ret_code != SHA204_SUCCESS)
sha204h_delay_ms(SHA204_COMMAND_EXEC_MAX);
return ret_code;
}
/** \brief This function re-synchronizes communication.
*
Be aware that succeeding only after waking up the
device could mean that it had gone to sleep and lost
its TempKey in the process.\n
Re-synchronizing communication is done in a maximum of
three steps:
<ol>
<li>
Try to re-synchronize without sending a Wake token.
This step is implemented in the Physical layer.
</li>
<li>
If the first step did not succeed send a Wake token.
</li>
<li>
Try to read the Wake response.
</li>
</ol>
*
* \param[in] size size of response buffer
* \param[out] response pointer to Wake-up response buffer
* \return status of the operation
*/
uint8_t sha204c_resync(uint8_t size, uint8_t *response)
{
// Try to re-synchronize without sending a Wake token
// (step 1 of the re-synchronization process).
uint8_t ret_code = sha204p_resync(size, response);
if (ret_code == SHA204_SUCCESS)
return ret_code;
// We lost communication. Send a Wake pulse and try
// to receive a response (steps 2 and 3 of the
// re-synchronization process).
(void) sha204p_sleep();
ret_code = sha204c_wakeup(response);
// Translate a return value of success into one
// that indicates that the device had to be woken up
// and might have lost its TempKey.
return (ret_code == SHA204_SUCCESS ? SHA204_RESYNC_WITH_WAKEUP : ret_code);
}
/** \brief This function runs a communication sequence:
* Append CRC to tx buffer, send command, delay, and verify response after receiving it.
*
* The first byte in tx buffer must be the byte count of the packet.
* If CRC or count of the response is incorrect, or a command byte got "nacked" (TWI),
* this function requests re-sending the response.
* If the response contains an error status, this function resends the command.
*
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204c_send_and_receive(struct sha204_send_and_receive_parameters *args)
{
uint8_t ret_code = SHA204_FUNC_FAIL;
uint8_t ret_code_resync;
uint8_t n_retries_send;
uint8_t n_retries_receive;
uint8_t i;
uint8_t status_byte;
uint8_t count = args->tx_buffer[SHA204_BUFFER_POS_COUNT];
uint8_t count_minus_crc = count - SHA204_CRC_SIZE;
// Append CRC.
sha204c_calculate_crc(count_minus_crc, args->tx_buffer, args->tx_buffer + count_minus_crc);
// Retry loop for sending a command and receiving a response.
n_retries_send = SHA204_RETRY_COUNT + 1;
while ((n_retries_send-- > 0) && (ret_code != SHA204_SUCCESS)) {
// Send command.
ret_code = sha204p_send_command(count, args->tx_buffer);
if (ret_code != SHA204_SUCCESS) {
if (sha204c_resync(args->rx_size, args->rx_buffer) == SHA204_RX_NO_RESPONSE)
// The device seems to be dead in the water.
return ret_code;
else
continue;
}
// Wait typical command execution time and then start polling for a response.
sha204h_delay_ms(args->poll_delay);
// Retry loop for receiving a response.
n_retries_receive = SHA204_RETRY_COUNT + 1;
while (n_retries_receive-- > 0) {
// Reset response buffer.
for (i = 0; i < args->rx_size; i++)
args->rx_buffer[i] = 0;
sha204h_start_timeout_timer_ms(args->poll_timeout);
do {
ret_code = sha204p_receive_response(args->rx_size, args->rx_buffer);
} while (!sha204_timer_expired && (ret_code == SHA204_RX_NO_RESPONSE));
if (ret_code == SHA204_RX_NO_RESPONSE) {
// We did not receive a response. Re-synchronize and send command again.
if (sha204c_resync(args->rx_size, args->rx_buffer) == SHA204_RX_NO_RESPONSE)
// The device seems to be dead in the water.
return ret_code;
else
break;
}
// Check whether we received a valid response.
if (ret_code == SHA204_INVALID_SIZE) {
// We see 0xFF for the count when communication got out of sync.
ret_code_resync = sha204c_resync(args->rx_size, args->rx_buffer);
if (ret_code_resync == SHA204_SUCCESS)
// We did not have to wake up the device. Try receiving response again.
continue;
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP)
// We could re-synchronize, but only after waking up the device.
// Re-send command.
break;
else
// We failed to re-synchronize.
return ret_code;
}
// We received a response of valid size.
// Check the consistency of the response.
ret_code = sha204c_check_crc(args->rx_buffer);
if (ret_code == SHA204_SUCCESS) {
// Received valid response.
if (args->rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN)
// Received non-status response. We are done.
return ret_code;
// Received status response.
status_byte = args->rx_buffer[SHA204_BUFFER_POS_STATUS];
// Translate the three possible device status error codes
// into library return codes.
if (status_byte == SHA204_STATUS_BYTE_PARSE)
return SHA204_PARSE_ERROR;
if (status_byte == SHA204_STATUS_BYTE_EXEC)
return SHA204_CMD_FAIL;
if (status_byte == SHA204_STATUS_BYTE_COMM) {
// In case of the device status byte indicating a communication
// error this function exits the retry loop for receiving a response
// and enters the overall retry loop
// (send command / receive response).
ret_code = SHA204_STATUS_CRC;
break;
}
// Received status response from CheckMAC, DeriveKey, GenDig,
// Lock, Nonce, Pause, UpdateExtra, or Write command.
return ret_code;
}
else {
// Received response with incorrect CRC.
ret_code_resync = sha204c_resync(args->rx_size, args->rx_buffer);
if (ret_code_resync == SHA204_SUCCESS)
// We did not have to wake up the device. Try receiving response again.
continue;
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP)
// We could re-synchronize, but only after waking up the device.
// Re-send command.
break;
else
// We failed to re-synchronize.
return ret_code;
} // block end of check response consistency
} // block end of receive retry loop
} // block end of send and receive retry loop
return ret_code;
}

View File

@ -0,0 +1,105 @@
/*
* \file
*
* \brief ATSHA204 header file for the communication layer for the device
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SHA204_COMM_H
# define SHA204_COMM_H
#include <compiler.h> //!< compiler dependent definitions
#include "sha204_physical.h" //!< declarations that are common to all interface implementations
//! maximum command delay
#define SHA204_COMMAND_EXEC_MAX (69)
//! minimum number of bytes in command (from count byte to second CRC byte)
#define SHA204_CMD_SIZE_MIN ((uint8_t) 7)
//! maximum size of command packet (CheckMac)
#define SHA204_CMD_SIZE_MAX ((uint8_t) 84)
//! number of CRC bytes
#define SHA204_CRC_SIZE ((uint8_t) 2)
//! buffer index of status byte in status response
#define SHA204_BUFFER_POS_STATUS (1)
//! buffer index of first data byte in data response
#define SHA204_BUFFER_POS_DATA (1)
//! status byte after wake-up
#define SHA204_STATUS_BYTE_WAKEUP ((uint8_t) 0x11)
//! command parse error
#define SHA204_STATUS_BYTE_PARSE ((uint8_t) 0x03)
//! command execution error
#define SHA204_STATUS_BYTE_EXEC ((uint8_t) 0x0F)
//! communication error
#define SHA204_STATUS_BYTE_COMM ((uint8_t) 0xFF)
/**
* \brief This structure contains the parameters for the \ref sha204c_send_and_receive function.
*/
struct sha204_send_and_receive_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t rx_size; //!< size of receive buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t poll_delay; //!< how long to wait before polling for response-ready
uint8_t poll_timeout; //!< how long to poll before timing out
};
/**
* \defgroup sha204_communication_group SHA204 Service - hardware independent communication functions
* @{
*/
void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc);
uint8_t sha204c_wakeup(uint8_t *response);
uint8_t sha204c_send_and_receive(struct sha204_send_and_receive_parameters *args);
//! @}
#endif

View File

@ -0,0 +1,755 @@
/*
* \file
*
* \brief ATSHA204 file that implements the command marshaling layer for the device
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <string.h> // needed for memcpy()
#include "sha204_lib_return_codes.h" // declarations of function return codes
#include "sha204_command_marshaling.h" // definitions and declarations for the Command module
/** \brief This function checks the parameters for sha204m_execute().
*
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
static uint8_t sha204m_check_parameters(struct sha204_command_parameters *args)
{
#ifdef SHA204_CHECK_PARAMETERS
uint8_t len = args->data_len_1 + args->data_len_2 + args->data_len_3 + SHA204_CMD_SIZE_MIN;
if (!args->tx_buffer || args->tx_size < len || args->rx_size < SHA204_RSP_SIZE_MIN || !args->rx_buffer)
return SHA204_BAD_PARAM;
if ((args->data_len_1 > 0 && !args->data_1) || (args->data_len_2 > 0 && !args->data_2) || (args->data_len_3 > 0 && !args->data_3))
return SHA204_BAD_PARAM;
// Check parameters depending on op-code.
switch (args->op_code) {
case SHA204_CHECKMAC:
if (
// no null pointers allowed
!args->data_1 || !args->data_2
// No reserved bits should be set.
|| (args->param_1 | CHECKMAC_MODE_MASK) != CHECKMAC_MODE_MASK
// key_id > 15 not allowed
|| args->param_2 > SHA204_KEY_ID_MAX
)
return SHA204_BAD_PARAM;
break;
case SHA204_DERIVE_KEY:
if (((args->param_1 & ~DERIVE_KEY_RANDOM_FLAG) != 0)
|| (args->param_2 > SHA204_KEY_ID_MAX))
return SHA204_BAD_PARAM;
break;
case SHA204_DEVREV:
break;
case SHA204_GENDIG:
if ((args->param_1 != GENDIG_ZONE_OTP) && (args->param_1 != GENDIG_ZONE_DATA))
return SHA204_BAD_PARAM;
break;
case SHA204_HMAC:
if ((args->param_1 & ~HMAC_MODE_MASK) != 0)
return SHA204_BAD_PARAM;
break;
case SHA204_LOCK:
if (((args->param_1 & ~LOCK_ZONE_MASK) != 0)
|| ((args->param_1 & LOCK_ZONE_NO_CRC) && (args->param_2 != 0)))
return SHA204_BAD_PARAM;
break;
case SHA204_MAC:
if (((args->param_1 & ~MAC_MODE_MASK) != 0)
|| (((args->param_1 & MAC_MODE_BLOCK2_TEMPKEY) == 0) && !args->data_1))
return SHA204_BAD_PARAM;
break;
case SHA204_NONCE:
if (!args->data_1
|| (args->param_1 > NONCE_MODE_PASSTHROUGH)
|| (args->param_1 == NONCE_MODE_INVALID)
)
return SHA204_BAD_PARAM;
break;
case SHA204_PAUSE:
break;
case SHA204_RANDOM:
if (args->param_1 > RANDOM_NO_SEED_UPDATE)
return SHA204_BAD_PARAM;
break;
case SHA204_READ:
if (((args->param_1 & ~READ_ZONE_MASK) != 0)
|| ((args->param_1 & READ_ZONE_MODE_32_BYTES) && (args->param_1 == SHA204_ZONE_OTP)))
return SHA204_BAD_PARAM;
break;
case SHA204_UPDATE_EXTRA:
if (args->param_1 > UPDATE_CONFIG_BYTE_86)
return SHA204_BAD_PARAM;
break;
case SHA204_WRITE:
if (!args->data_1 || ((args->param_1 & ~WRITE_ZONE_MASK) != 0))
return SHA204_BAD_PARAM;
break;
default:
// unknown op-code
return SHA204_BAD_PARAM;
}
return SHA204_SUCCESS;
#else
return SHA204_SUCCESS;
#endif
}
/** \brief This function creates a command packet, sends it, and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_execute(struct sha204_command_parameters *args)
{
uint8_t *p_buffer;
uint8_t len;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer
};
uint8_t ret_code = sha204m_check_parameters(args);
if (ret_code != SHA204_SUCCESS)
return ret_code;
// Supply delays and response size.
switch (args->op_code) {
case SHA204_CHECKMAC:
comm_parameters.poll_delay = CHECKMAC_DELAY;
comm_parameters.poll_timeout = CHECKMAC_EXEC_MAX - CHECKMAC_DELAY;
comm_parameters.rx_size = CHECKMAC_RSP_SIZE;
break;
case SHA204_DERIVE_KEY:
comm_parameters.poll_delay = DERIVE_KEY_DELAY;
comm_parameters.poll_timeout = DERIVE_KEY_EXEC_MAX - DERIVE_KEY_DELAY;
comm_parameters.rx_size = DERIVE_KEY_RSP_SIZE;
break;
case SHA204_DEVREV:
comm_parameters.poll_delay = DEVREV_DELAY;
comm_parameters.poll_timeout = DEVREV_EXEC_MAX - DEVREV_DELAY;
comm_parameters.rx_size = DEVREV_RSP_SIZE;
break;
case SHA204_GENDIG:
comm_parameters.poll_delay = GENDIG_DELAY;
comm_parameters.poll_timeout = GENDIG_EXEC_MAX - GENDIG_DELAY;
comm_parameters.rx_size = GENDIG_RSP_SIZE;
break;
case SHA204_HMAC:
comm_parameters.poll_delay = HMAC_DELAY;
comm_parameters.poll_timeout = HMAC_EXEC_MAX - HMAC_DELAY;
comm_parameters.rx_size = HMAC_RSP_SIZE;
break;
case SHA204_LOCK:
comm_parameters.poll_delay = LOCK_DELAY;
comm_parameters.poll_timeout = LOCK_EXEC_MAX - LOCK_DELAY;
comm_parameters.rx_size = LOCK_RSP_SIZE;
break;
case SHA204_MAC:
comm_parameters.poll_delay = MAC_DELAY;
comm_parameters.poll_timeout = MAC_EXEC_MAX - MAC_DELAY;
comm_parameters.rx_size = MAC_RSP_SIZE;
break;
case SHA204_NONCE:
comm_parameters.poll_delay = NONCE_DELAY;
comm_parameters.poll_timeout = NONCE_EXEC_MAX - NONCE_DELAY;
comm_parameters.rx_size = args->param_1 == NONCE_MODE_PASSTHROUGH
? NONCE_RSP_SIZE_SHORT : NONCE_RSP_SIZE_LONG;
break;
case SHA204_PAUSE:
comm_parameters.poll_delay = PAUSE_DELAY;
comm_parameters.poll_timeout = PAUSE_EXEC_MAX - PAUSE_DELAY;
comm_parameters.rx_size = PAUSE_RSP_SIZE;
break;
case SHA204_RANDOM:
comm_parameters.poll_delay = RANDOM_DELAY;
comm_parameters.poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY;
comm_parameters.rx_size = RANDOM_RSP_SIZE;
break;
case SHA204_READ:
comm_parameters.poll_delay = READ_DELAY;
comm_parameters.poll_timeout = READ_EXEC_MAX - READ_DELAY;
comm_parameters.rx_size = (args->param_1 & SHA204_ZONE_COUNT_FLAG)
? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
break;
case SHA204_UPDATE_EXTRA:
comm_parameters.poll_delay = UPDATE_DELAY;
comm_parameters.poll_timeout = UPDATE_EXEC_MAX - UPDATE_DELAY;
comm_parameters.rx_size = UPDATE_RSP_SIZE;
break;
case SHA204_WRITE:
comm_parameters.poll_delay = WRITE_DELAY;
comm_parameters.poll_timeout = WRITE_EXEC_MAX - WRITE_DELAY;
comm_parameters.rx_size = WRITE_RSP_SIZE;
break;
default:
comm_parameters.poll_delay = 0;
comm_parameters.poll_timeout = SHA204_COMMAND_EXEC_MAX;
comm_parameters.rx_size = args->rx_size;
}
// Assemble command.
len = args->data_len_1 + args->data_len_2 + args->data_len_3 + SHA204_CMD_SIZE_MIN;
p_buffer = args->tx_buffer;
*p_buffer++ = len;
*p_buffer++ = args->op_code;
*p_buffer++ = args->param_1;
*p_buffer++ = args->param_2 & 0xFF;
*p_buffer++ = args->param_2 >> 8;
if (args->data_len_1 > 0) {
memcpy(p_buffer, args->data_1, args->data_len_1);
p_buffer += args->data_len_1;
}
if (args->data_len_2 > 0) {
memcpy(p_buffer, args->data_2, args->data_len_2);
p_buffer += args->data_len_2;
}
if (args->data_len_3 > 0) {
memcpy(p_buffer, args->data_3, args->data_len_3);
p_buffer += args->data_len_3;
}
sha204c_calculate_crc(len - SHA204_CRC_SIZE, args->tx_buffer, p_buffer);
// Send command and receive response.
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a CheckMAC command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_check_mac(struct sha204_check_mac_parameters *args)
{
if ( // no null pointers allowed
!args->tx_buffer || !args->rx_buffer || !args->client_response || !args->other_data
// No reserved bits should be set.
|| (args->mode | CHECKMAC_MODE_MASK) != CHECKMAC_MODE_MASK
// key_id > 15 not allowed
|| args->key_id > SHA204_KEY_ID_MAX)
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = CHECKMAC_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_CHECKMAC;
args->tx_buffer[CHECKMAC_MODE_IDX] = args->mode & CHECKMAC_MODE_MASK;
args->tx_buffer[CHECKMAC_KEYID_IDX]= args->key_id;
args->tx_buffer[CHECKMAC_KEYID_IDX + 1] = 0;
if (args->client_challenge == NULL)
memset(&args->tx_buffer[CHECKMAC_CLIENT_CHALLENGE_IDX], 0, CHECKMAC_CLIENT_CHALLENGE_SIZE);
else
memcpy(&args->tx_buffer[CHECKMAC_CLIENT_CHALLENGE_IDX], args->client_challenge, CHECKMAC_CLIENT_CHALLENGE_SIZE);
memcpy(&args->tx_buffer[CHECKMAC_CLIENT_RESPONSE_IDX], args->client_response, CHECKMAC_CLIENT_RESPONSE_SIZE);
memcpy(&args->tx_buffer[CHECKMAC_DATA_IDX], args->other_data, CHECKMAC_OTHER_DATA_SIZE);
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = CHECKMAC_RSP_SIZE,
.poll_delay = CHECKMAC_DELAY,
.poll_timeout = CHECKMAC_EXEC_MAX - CHECKMAC_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a DeriveKey command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_derive_key(struct sha204_derive_key_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || ((args->use_random & ~DERIVE_KEY_RANDOM_FLAG) != 0)
|| (args->target_key > SHA204_KEY_ID_MAX))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_DERIVE_KEY;
args->tx_buffer[DERIVE_KEY_RANDOM_IDX] = args->use_random;
args->tx_buffer[DERIVE_KEY_TARGETKEY_IDX] = args->target_key;
args->tx_buffer[DERIVE_KEY_TARGETKEY_IDX + 1] = 0;
if (args->mac != NULL)
{
memcpy(&args->tx_buffer[DERIVE_KEY_MAC_IDX], args->mac, DERIVE_KEY_MAC_SIZE);
args->tx_buffer[SHA204_COUNT_IDX] = DERIVE_KEY_COUNT_LARGE;
}
else
args->tx_buffer[SHA204_COUNT_IDX] = DERIVE_KEY_COUNT_SMALL;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = DERIVE_KEY_RSP_SIZE,
.poll_delay = DERIVE_KEY_DELAY,
.poll_timeout = DERIVE_KEY_EXEC_MAX - DERIVE_KEY_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a DevRev command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_dev_rev(struct sha204_dev_rev_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer)
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = DEVREV_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_DEVREV;
// Parameters are 0.
args->tx_buffer[DEVREV_PARAM1_IDX] =
args->tx_buffer[DEVREV_PARAM2_IDX] =
args->tx_buffer[DEVREV_PARAM2_IDX + 1] = 0;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = DEVREV_RSP_SIZE,
.poll_delay = DEVREV_DELAY,
.poll_timeout = DEVREV_EXEC_MAX - DEVREV_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a GenDig command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_gen_dig(struct sha204_gen_dig_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer
|| ((args->zone != GENDIG_ZONE_OTP) && (args->zone != GENDIG_ZONE_DATA)))
return SHA204_BAD_PARAM;
if (((args->zone == GENDIG_ZONE_OTP) && (args->key_id > SHA204_OTP_BLOCK_MAX))
|| ((args->zone == GENDIG_ZONE_DATA) && (args->key_id > SHA204_KEY_ID_MAX)))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_GENDIG;
args->tx_buffer[GENDIG_ZONE_IDX] = args->zone;
args->tx_buffer[GENDIG_KEYID_IDX] = args->key_id;
args->tx_buffer[GENDIG_KEYID_IDX + 1] = 0;
if (args->other_data != NULL)
{
memcpy(&args->tx_buffer[GENDIG_DATA_IDX], args->other_data, GENDIG_OTHER_DATA_SIZE);
args->tx_buffer[SHA204_COUNT_IDX] = GENDIG_COUNT_DATA;
}
else
args->tx_buffer[SHA204_COUNT_IDX] = GENDIG_COUNT;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = GENDIG_RSP_SIZE,
.poll_delay = GENDIG_DELAY,
.poll_timeout = GENDIG_EXEC_MAX - GENDIG_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends an HMAC command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_hmac(struct sha204_hmac_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || ((args->mode & ~HMAC_MODE_MASK) != 0))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = HMAC_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_HMAC;
args->tx_buffer[HMAC_MODE_IDX] = args->mode;
// Although valid key identifiers are only
// from 0 to 15, all 16 bits are used in the HMAC message.
args->tx_buffer[HMAC_KEYID_IDX] = args->key_id & 0xFF;
args->tx_buffer[HMAC_KEYID_IDX + 1] = args->key_id >> 8;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = HMAC_RSP_SIZE,
.poll_delay = HMAC_DELAY,
.poll_timeout = HMAC_EXEC_MAX - HMAC_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a Lock command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_lock(struct sha204_lock_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || ((args->zone & ~LOCK_ZONE_MASK) != 0)
|| ((args->zone & LOCK_ZONE_NO_CRC) && (args->summary != 0)))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = LOCK_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_LOCK;
args->tx_buffer[LOCK_ZONE_IDX] = args->zone & LOCK_ZONE_MASK;
args->tx_buffer[LOCK_SUMMARY_IDX]= args->summary & 0xFF;
args->tx_buffer[LOCK_SUMMARY_IDX + 1]= args->summary >> 8;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = LOCK_RSP_SIZE,
.poll_delay = LOCK_DELAY,
.poll_timeout = LOCK_EXEC_MAX - LOCK_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a MAC command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_mac(struct sha204_mac_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || ((args->mode & ~MAC_MODE_MASK) != 0)
|| (((args->mode & MAC_MODE_BLOCK2_TEMPKEY) == 0) && !args->challenge))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = MAC_COUNT_SHORT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_MAC;
args->tx_buffer[MAC_MODE_IDX] = args->mode;
args->tx_buffer[MAC_KEYID_IDX] = args->key_id & 0xFF;
args->tx_buffer[MAC_KEYID_IDX + 1] = args->key_id >> 8;
if ((args->mode & MAC_MODE_BLOCK2_TEMPKEY) == 0)
{
memcpy(&args->tx_buffer[MAC_CHALLENGE_IDX], args->challenge, MAC_CHALLENGE_SIZE);
args->tx_buffer[SHA204_COUNT_IDX] = MAC_COUNT_LONG;
}
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = MAC_RSP_SIZE,
.poll_delay = MAC_DELAY,
.poll_timeout = MAC_EXEC_MAX - MAC_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a Nonce command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_nonce(struct sha204_nonce_parameters *args)
{
uint8_t rx_size;
if (!args->tx_buffer || !args->rx_buffer || !args->num_in
|| (args->mode > NONCE_MODE_PASSTHROUGH) || (args->mode == NONCE_MODE_INVALID))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_NONCE;
args->tx_buffer[NONCE_MODE_IDX] = args->mode;
// 2. parameter is 0.
args->tx_buffer[NONCE_PARAM2_IDX] =
args->tx_buffer[NONCE_PARAM2_IDX + 1] = 0;
if (args->mode != NONCE_MODE_PASSTHROUGH)
{
memcpy(&args->tx_buffer[NONCE_INPUT_IDX], args->num_in, NONCE_NUMIN_SIZE);
args->tx_buffer[SHA204_COUNT_IDX] = NONCE_COUNT_SHORT;
rx_size = NONCE_RSP_SIZE_LONG;
}
else
{
memcpy(&args->tx_buffer[NONCE_INPUT_IDX], args->num_in, NONCE_NUMIN_SIZE_PASSTHROUGH);
args->tx_buffer[SHA204_COUNT_IDX] = NONCE_COUNT_LONG;
rx_size = NONCE_RSP_SIZE_SHORT;
}
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = rx_size,
.poll_delay = NONCE_DELAY,
.poll_timeout = NONCE_EXEC_MAX - NONCE_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a Pause command to SWI devices and receives a response from the selected device.
* All others pause.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_pause(struct sha204_pause_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer)
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = PAUSE_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_PAUSE;
args->tx_buffer[PAUSE_SELECT_IDX] = args->selector;
// 2. parameter is 0.
args->tx_buffer[PAUSE_PARAM2_IDX] =
args->tx_buffer[PAUSE_PARAM2_IDX + 1] = 0;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = PAUSE_RSP_SIZE,
.poll_delay = PAUSE_DELAY,
.poll_timeout = PAUSE_EXEC_MAX - PAUSE_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a Random command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_random(struct sha204_random_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || (args->mode > RANDOM_NO_SEED_UPDATE))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = RANDOM_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_RANDOM;
args->tx_buffer[RANDOM_MODE_IDX] = args->mode & RANDOM_SEED_UPDATE;
// 2. parameter is 0.
args->tx_buffer[RANDOM_PARAM2_IDX] =
args->tx_buffer[RANDOM_PARAM2_IDX + 1] = 0;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = RANDOM_RSP_SIZE,
.poll_delay = RANDOM_DELAY,
.poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends a Read command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_read(struct sha204_read_parameters *args)
{
uint8_t rx_size;
uint16_t address;
if (!args->tx_buffer || !args->rx_buffer || ((args->zone & ~READ_ZONE_MASK) != 0)
|| ((args->zone & READ_ZONE_MODE_32_BYTES) && (args->zone == SHA204_ZONE_OTP)))
return SHA204_BAD_PARAM;
// If we would just mask address bits, we would
// read from an address that was not intended.
address = args->address >> 2;
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_CONFIG) {
if (address > SHA204_ADDRESS_MASK_CONFIG)
return SHA204_BAD_PARAM;
}
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_OTP) {
if (address > SHA204_ADDRESS_MASK_OTP)
// If we would just mask this bit, we would
// read from an address that was not intended.
return SHA204_BAD_PARAM;
}
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_DATA) {
if (address > SHA204_ADDRESS_MASK)
// If we would just mask this bit, we would
// read from an address that was not intended.
return SHA204_BAD_PARAM;
}
args->tx_buffer[SHA204_COUNT_IDX] = READ_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_READ;
args->tx_buffer[READ_ZONE_IDX] = args->zone;
args->tx_buffer[READ_ADDR_IDX] = (uint8_t) address;
args->tx_buffer[READ_ADDR_IDX + 1] = 0;
rx_size = (args->zone & SHA204_ZONE_COUNT_FLAG) ? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = rx_size,
.poll_delay = READ_DELAY,
.poll_timeout = READ_EXEC_MAX - READ_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/** \brief This function sends an UpdateExtra command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_update_extra(struct sha204_update_extra_parameters *args)
{
if (!args->tx_buffer || !args->rx_buffer || (args->mode > UPDATE_CONFIG_BYTE_86))
return SHA204_BAD_PARAM;
args->tx_buffer[SHA204_COUNT_IDX] = UPDATE_COUNT;
args->tx_buffer[SHA204_OPCODE_IDX] = SHA204_UPDATE_EXTRA;
args->tx_buffer[UPDATE_MODE_IDX] = args->mode;
args->tx_buffer[UPDATE_VALUE_IDX] = args->new_value;
args->tx_buffer[UPDATE_VALUE_IDX + 1] = 0;
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = UPDATE_RSP_SIZE,
.poll_delay = UPDATE_DELAY,
.poll_timeout = UPDATE_EXEC_MAX - UPDATE_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}
/**\brief This function sends a Write command to the device and receives its response.
* \param[in, out] args pointer to parameter structure
* \return status of the operation
*/
uint8_t sha204m_write(struct sha204_write_parameters *args)
{
uint8_t *p_command;
uint8_t count;
uint16_t address;
if (!args->tx_buffer || !args->rx_buffer || !args->new_value || ((args->zone & ~WRITE_ZONE_MASK) != 0))
return SHA204_BAD_PARAM;
// If we would just mask address bits, we would
// read from an address that was not intended.
address = args->address >> 2;
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_CONFIG) {
if (address > SHA204_ADDRESS_MASK_CONFIG)
return SHA204_BAD_PARAM;
}
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_OTP) {
if (address > SHA204_ADDRESS_MASK_OTP)
// If we would just mask this bit, we would
// read from an address that was not intended.
return SHA204_BAD_PARAM;
}
if ((args->zone & SHA204_ZONE_MASK) == SHA204_ZONE_DATA) {
if (address > SHA204_ADDRESS_MASK)
// If we would just mask this bit, we would
// read from an address that was not intended.
return SHA204_BAD_PARAM;
}
p_command = &args->tx_buffer[SHA204_OPCODE_IDX];
*p_command++ = SHA204_WRITE;
*p_command++ = args->zone;
*p_command++ = (uint8_t) address;
*p_command++ = 0;
count = (args->zone & SHA204_ZONE_COUNT_FLAG) ? SHA204_ZONE_ACCESS_32 : SHA204_ZONE_ACCESS_4;
memcpy(p_command, args->new_value, count);
p_command += count;
if (args->mac != NULL)
{
memcpy(p_command, args->mac, WRITE_MAC_SIZE);
p_command += WRITE_MAC_SIZE;
}
// Supply count.
args->tx_buffer[SHA204_COUNT_IDX] = (uint8_t) (p_command - &args->tx_buffer[0] + SHA204_CRC_SIZE);
struct sha204_send_and_receive_parameters comm_parameters = {
.tx_buffer = args->tx_buffer,
.rx_buffer = args->rx_buffer,
.rx_size = WRITE_RSP_SIZE,
.poll_delay = WRITE_DELAY,
.poll_timeout = WRITE_EXEC_MAX - WRITE_DELAY
};
return sha204c_send_and_receive(&comm_parameters);
}

View File

@ -0,0 +1,539 @@
/*
* \file
*
* \brief ATSHA204 header file for the command marshaling layer for the device
*
<table>
<caption>Command Packet Structure</caption>
<tr>
<th width=25%>Byte #</th> <th width=25%>Name</th> <th>Meaning</th>
</tr>
<tr>
<td>0</td>
<td>Count</td>
<td>Number of bytes in the packet, includes the count byte, body and the checksum</td>
</tr>
<tr>
<td>1</td>
<td>Ordinal</td>
<td>Command Opcode (Ordinal)</td>
</tr>
<tr>
<td>2 to n</td>
<td>Parameters</td>
<td>Parameters for specific command</td>
</tr>
<tr>
<td>n+1 to n+2</td>
<td>Checksum</td>
<td>Checksum of the command packet</td>
</tr>
</table>
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SHA204_COMMAND_MARSHALING_H
# define SHA204_COMMAND_MARSHALING_H
#include "sha204_comm.h"
/** \todo Create doxygen groups. */
//////////////////////////////////////////////////////////////////////
// command op-code definitions
#define SHA204_CHECKMAC ((uint8_t) 0x28) //!< CheckMac command op-code
#define SHA204_DERIVE_KEY ((uint8_t) 0x1C) //!< DeriveKey command op-code
#define SHA204_DEVREV ((uint8_t) 0x30) //!< DevRev command op-code
#define SHA204_GENDIG ((uint8_t) 0x15) //!< GenDig command op-code
#define SHA204_HMAC ((uint8_t) 0x11) //!< HMAC command op-code
#define SHA204_LOCK ((uint8_t) 0x17) //!< Lock command op-code
#define SHA204_MAC ((uint8_t) 0x08) //!< MAC command op-code
#define SHA204_NONCE ((uint8_t) 0x16) //!< Nonce command op-code
#define SHA204_PAUSE ((uint8_t) 0x01) //!< Pause command op-code
#define SHA204_RANDOM ((uint8_t) 0x1B) //!< Random command op-code
#define SHA204_READ ((uint8_t) 0x02) //!< Read command op-code
#define SHA204_UPDATE_EXTRA ((uint8_t) 0x20) //!< UpdateExtra command op-code
#define SHA204_WRITE ((uint8_t) 0x12) //!< Write command op-code
//////////////////////////////////////////////////////////////////////
// packet size definitions
#define SHA204_RSP_SIZE_VAL ((uint8_t) 7) //!< size of response packet containing four bytes of data
//////////////////////////////////////////////////////////////////////
// parameter range definitions
#define SHA204_KEY_ID_MAX ((uint8_t) 15) //!< maximum value for key id
#define SHA204_OTP_BLOCK_MAX ((uint8_t) 1) //!< maximum value for OTP block
//////////////////////////////////////////////////////////////////////
// definitions for command packet indexes common to all commands
#define SHA204_COUNT_IDX ( 0) //!< command packet index for count
#define SHA204_OPCODE_IDX ( 1) //!< command packet index for op-code
#define SHA204_PARAM1_IDX ( 2) //!< command packet index for first parameter
#define SHA204_PARAM2_IDX ( 3) //!< command packet index for second parameter
#define SHA204_DATA_IDX ( 5) //!< command packet index for second parameter
//////////////////////////////////////////////////////////////////////
// zone definitions
#define SHA204_ZONE_CONFIG ((uint8_t) 0x00) //!< Configuration zone
#define SHA204_ZONE_OTP ((uint8_t) 0x01) //!< OTP (One Time Programming) zone
#define SHA204_ZONE_DATA ((uint8_t) 0x02) //!< Data zone
#define SHA204_ZONE_MASK ((uint8_t) 0x03) //!< Zone mask
#define SHA204_ZONE_COUNT_FLAG ((uint8_t) 0x80) //!< Zone bit 7 set: Access 32 bytes, otherwise 4 bytes.
#define SHA204_ZONE_ACCESS_4 ((uint8_t) 4) //!< Read or write 4 bytes.
#define SHA204_ZONE_ACCESS_32 ((uint8_t) 32) //!< Read or write 32 bytes.
#define SHA204_ADDRESS_MASK_CONFIG ( 0x001F) //!< Address bits 5 to 7 are 0 for Configuration zone.
#define SHA204_ADDRESS_MASK_OTP ( 0x000F) //!< Address bits 4 to 7 are 0 for OTP zone.
#define SHA204_ADDRESS_MASK ( 0x007F) //!< Address bit 7 to 15 are always 0.
//////////////////////////////////////////////////////////////////////
// CheckMAC command definitions
#define CHECKMAC_MODE_IDX SHA204_PARAM1_IDX //!< CheckMAC command index for mode
#define CHECKMAC_KEYID_IDX SHA204_PARAM2_IDX //!< CheckMAC command index for key identifier
#define CHECKMAC_CLIENT_CHALLENGE_IDX SHA204_DATA_IDX //!< CheckMAC command index for client challenge
#define CHECKMAC_CLIENT_RESPONSE_IDX (37) //!< CheckMAC command index for client response
#define CHECKMAC_DATA_IDX (69) //!< CheckMAC command index for other data
#define CHECKMAC_COUNT (84) //!< CheckMAC command packet size
#define CHECKMAC_MODE_MASK ((uint8_t) 0x27) //!< CheckMAC mode bits 3, 4, 6, and 7 are 0.
#define CHECKMAC_CLIENT_CHALLENGE_SIZE (32) //!< CheckMAC size of client challenge
#define CHECKMAC_CLIENT_RESPONSE_SIZE (32) //!< CheckMAC size of client response
#define CHECKMAC_OTHER_DATA_SIZE (13) //!< CheckMAC size of "other data"
#define CHECKMAC_CLIENT_COMMAND_SIZE ( 4) //!< CheckMAC size of client command header size inside "other data"
//////////////////////////////////////////////////////////////////////
// DeriveKey command definitions
#define DERIVE_KEY_RANDOM_IDX SHA204_PARAM1_IDX //!< DeriveKey command index for random bit
#define DERIVE_KEY_TARGETKEY_IDX SHA204_PARAM2_IDX //!< DeriveKey command index for target slot
#define DERIVE_KEY_MAC_IDX SHA204_DATA_IDX //!< DeriveKey command index for optional MAC
#define DERIVE_KEY_COUNT_SMALL SHA204_CMD_SIZE_MIN //!< DeriveKey command packet size without MAC
#define DERIVE_KEY_COUNT_LARGE (39) //!< DeriveKey command packet size with MAC
#define DERIVE_KEY_RANDOM_FLAG ((uint8_t) 4) //!< DeriveKey 1. parameter
#define DERIVE_KEY_MAC_SIZE (32) //!< DeriveKey MAC size
//////////////////////////////////////////////////////////////////////
// DevRev command definitions
#define DEVREV_PARAM1_IDX SHA204_PARAM1_IDX //!< DevRev command index for 1. parameter (ignored)
#define DEVREV_PARAM2_IDX SHA204_PARAM2_IDX //!< DevRev command index for 2. parameter (ignored)
#define DEVREV_COUNT SHA204_CMD_SIZE_MIN //!< DevRev command packet size
//////////////////////////////////////////////////////////////////////
// GenDig command definitions
#define GENDIG_ZONE_IDX SHA204_PARAM1_IDX //!< GenDig command index for zone
#define GENDIG_KEYID_IDX SHA204_PARAM2_IDX //!< GenDig command index for key id
#define GENDIG_DATA_IDX SHA204_DATA_IDX //!< GenDig command index for optional data
#define GENDIG_COUNT SHA204_CMD_SIZE_MIN //!< GenDig command packet size without "other data"
#define GENDIG_COUNT_DATA (11) //!< GenDig command packet size with "other data"
#define GENDIG_OTHER_DATA_SIZE (4) //!< GenDig size of "other data"
#define GENDIG_ZONE_OTP ((uint8_t) 1) //!< GenDig zone id OTP
#define GENDIG_ZONE_DATA ((uint8_t) 2) //!< GenDig zone id data
//////////////////////////////////////////////////////////////////////
// HMAC command definitions
#define HMAC_MODE_IDX SHA204_PARAM1_IDX //!< HMAC command index for mode
#define HMAC_KEYID_IDX SHA204_PARAM2_IDX //!< HMAC command index for key id
#define HMAC_COUNT SHA204_CMD_SIZE_MIN //!< HMAC command packet size
#define HMAC_MODE_MASK ((uint8_t) 0x74) //!< HMAC mode bits 0, 1, 3, and 7 are 0.
//////////////////////////////////////////////////////////////////////
// Lock command definitions
#define LOCK_ZONE_IDX SHA204_PARAM1_IDX //!< Lock command index for zone
#define LOCK_SUMMARY_IDX SHA204_PARAM2_IDX //!< Lock command index for summary
#define LOCK_COUNT SHA204_CMD_SIZE_MIN //!< Lock command packet size
#define LOCK_ZONE_NO_CONFIG ((uint8_t) 0x01) //!< Lock zone is OTP or Data
#define LOCK_ZONE_NO_CRC ((uint8_t) 0x80) //!< Lock command: Ignore summary.
#define LOCK_ZONE_MASK (0x81) //!< Lock parameter 1 bits 2 to 6 are 0.
//////////////////////////////////////////////////////////////////////
// Mac command definitions
#define MAC_MODE_IDX SHA204_PARAM1_IDX //!< MAC command index for mode
#define MAC_KEYID_IDX SHA204_PARAM2_IDX //!< MAC command index for key id
#define MAC_CHALLENGE_IDX SHA204_DATA_IDX //!< MAC command index for optional challenge
#define MAC_COUNT_SHORT SHA204_CMD_SIZE_MIN //!< MAC command packet size without challenge
#define MAC_COUNT_LONG (39) //!< MAC command packet size with challenge
#define MAC_MODE_BLOCK2_TEMPKEY ((uint8_t) 0x01) //!< MAC mode bit 0: second SHA block from TempKey
#define MAC_MODE_BLOCK1_TEMPKEY ((uint8_t) 0x02) //!< MAC mode bit 1: first SHA block from TempKey
#define MAC_MODE_SOURCE_FLAG_MATCH ((uint8_t) 0x04) //!< MAC mode bit 2: match TempKey.SourceFlag
#define MAC_MODE_PASSTHROUGH ((uint8_t) 0x07) //!< MAC mode bit 0-2: pass-through mode
#define MAC_MODE_INCLUDE_OTP_88 ((uint8_t) 0x10) //!< MAC mode bit 4: include first 88 OTP bits
#define MAC_MODE_INCLUDE_OTP_64 ((uint8_t) 0x20) //!< MAC mode bit 5: include first 64 OTP bits
#define MAC_MODE_INCLUDE_SN ((uint8_t) 0x50) //!< MAC mode bit 6: include serial number
#define MAC_CHALLENGE_SIZE (32) //!< MAC size of challenge
#define MAC_MODE_MASK ((uint8_t) 0x77) //!< MAC mode bits 3 and 7 are 0.
//////////////////////////////////////////////////////////////////////
// Nonce command definitions
#define NONCE_MODE_IDX SHA204_PARAM1_IDX //!< Nonce command index for mode
#define NONCE_PARAM2_IDX SHA204_PARAM2_IDX //!< Nonce command index for 2. parameter
#define NONCE_INPUT_IDX SHA204_DATA_IDX //!< Nonce command index for input data
#define NONCE_COUNT_SHORT (27) //!< Nonce command packet size for 20 bytes of data
#define NONCE_COUNT_LONG (39) //!< Nonce command packet size for 32 bytes of data
#define NONCE_MODE_MASK ((uint8_t) 3) //!< Nonce mode bits 2 to 7 are 0.
#define NONCE_MODE_SEED_UPDATE ((uint8_t) 0x00) //!< Nonce mode: update seed
#define NONCE_MODE_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Nonce mode: do not update seed
#define NONCE_MODE_INVALID ((uint8_t) 0x02) //!< Nonce mode 2 is invalid.
#define NONCE_MODE_PASSTHROUGH ((uint8_t) 0x03) //!< Nonce mode: pass-through
#define NONCE_NUMIN_SIZE (20) //!< Nonce data length
#define NONCE_NUMIN_SIZE_PASSTHROUGH (32) //!< Nonce data length in pass-through mode (mode = 3)
//////////////////////////////////////////////////////////////////////
// Pause command definitions
#define PAUSE_SELECT_IDX SHA204_PARAM1_IDX //!< Pause command index for Selector
#define PAUSE_PARAM2_IDX SHA204_PARAM2_IDX //!< Pause command index for 2. parameter
#define PAUSE_COUNT SHA204_CMD_SIZE_MIN //!< Pause command packet size
//////////////////////////////////////////////////////////////////////
// Random command definitions
#define RANDOM_MODE_IDX SHA204_PARAM1_IDX //!< Random command index for mode
#define RANDOM_PARAM2_IDX SHA204_PARAM2_IDX //!< Random command index for 2. parameter
#define RANDOM_COUNT SHA204_CMD_SIZE_MIN //!< Random command packet size
#define RANDOM_SEED_UPDATE ((uint8_t) 0x00) //!< Random mode for automatic seed update
#define RANDOM_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Random mode for no seed update
//////////////////////////////////////////////////////////////////////
// Read command definitions
#define READ_ZONE_IDX SHA204_PARAM1_IDX //!< Read command index for zone
#define READ_ADDR_IDX SHA204_PARAM2_IDX //!< Read command index for address
#define READ_COUNT SHA204_CMD_SIZE_MIN //!< Read command packet size
#define READ_ZONE_MASK ((uint8_t) 0x83) //!< Read zone bits 2 to 6 are 0.
#define READ_ZONE_MODE_32_BYTES ((uint8_t) 0x80) //!< Read mode: 32 bytes
//////////////////////////////////////////////////////////////////////
// UpdateExtra command definitions
#define UPDATE_MODE_IDX SHA204_PARAM1_IDX //!< UpdateExtra command index for mode
#define UPDATE_VALUE_IDX SHA204_PARAM2_IDX //!< UpdateExtra command index for new value
#define UPDATE_COUNT SHA204_CMD_SIZE_MIN //!< UpdateExtra command packet size
#define UPDATE_CONFIG_BYTE_86 ((uint8_t) 0x01) //!< UpdateExtra mode: update Config byte 86
//////////////////////////////////////////////////////////////////////
// Write command definitions
#define WRITE_ZONE_IDX SHA204_PARAM1_IDX //!< Write command index for zone
#define WRITE_ADDR_IDX SHA204_PARAM2_IDX //!< Write command index for address
#define WRITE_VALUE_IDX SHA204_DATA_IDX //!< Write command index for data
#define WRITE_MAC_VS_IDX ( 9) //!< Write command index for MAC following short data
#define WRITE_MAC_VL_IDX (37) //!< Write command index for MAC following long data
#define WRITE_COUNT_SHORT (11) //!< Write command packet size with short data and no MAC
#define WRITE_COUNT_LONG (39) //!< Write command packet size with long data and no MAC
#define WRITE_COUNT_SHORT_MAC (43) //!< Write command packet size with short data and MAC
#define WRITE_COUNT_LONG_MAC (71) //!< Write command packet size with long data and MAC
#define WRITE_MAC_SIZE (32) //!< Write MAC size
#define WRITE_ZONE_MASK ((uint8_t) 0xC1) //!< Write zone bits 2 to 5 are 0.
#define WRITE_ZONE_WITH_MAC ((uint8_t) 0x40) //!< Write zone bit 6: write encrypted with MAC
//////////////////////////////////////////////////////////////////////
// Response size definitions
#define CHECKMAC_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
#define DERIVE_KEY_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
#define DEVREV_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of DevRev command returns 4 bytes
#define GENDIG_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of GenDig command
#define HMAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of HMAC command
#define LOCK_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Lock command
#define MAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of MAC command
#define NONCE_RSP_SIZE_SHORT SHA204_RSP_SIZE_MIN //!< response size of Nonce command with mode[0:1] = 3
#define NONCE_RSP_SIZE_LONG SHA204_RSP_SIZE_MAX //!< response size of Nonce command
#define PAUSE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Pause command
#define RANDOM_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Random command
#define READ_4_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of Read command when reading 4 bytes
#define READ_32_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Read command when reading 32 bytes
#define UPDATE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of UpdateExtra command
#define WRITE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Write command
//////////////////////////////////////////////////////////////////////
// command timing definitions for typical execution times (ms)
//! CheckMAC typical command delay
#define CHECKMAC_DELAY (12)
//! DeriveKey typical command delay
#define DERIVE_KEY_DELAY (14)
//! DevRev typical command delay
#define DEVREV_DELAY ( 1) // 0.4 rounded up
//! GenDig typical command delay
#define GENDIG_DELAY (11)
//! HMAC typical command delay
#define HMAC_DELAY (27)
//! Lock typical command delay
#define LOCK_DELAY ( 5)
//! MAC typical command delay
#define MAC_DELAY (12)
//! Nonce typical command delay
#define NONCE_DELAY (22)
//! Pause typical command delay
#define PAUSE_DELAY ( 1) // 0.4 rounded up
//! Random typical command delay
#define RANDOM_DELAY (11)
//! Read typical command delay
#define READ_DELAY ( 1) // 0.4 rounded up
//! UpdateExtra typical command delay
#define UPDATE_DELAY ( 8)
//! Write typical command delay
#define WRITE_DELAY ( 4)
//////////////////////////////////////////////////////////////////////
// command timing definitions for maximum execution times (ms)
//! CheckMAC maximum execution time
#define CHECKMAC_EXEC_MAX (38)
//! DeriveKey maximum execution time
#define DERIVE_KEY_EXEC_MAX (62)
//! DevRev maximum execution time
#define DEVREV_EXEC_MAX ( 2)
//! GenDig maximum execution time
#define GENDIG_EXEC_MAX (43)
//! HMAC maximum execution time
#define HMAC_EXEC_MAX (69)
//! Lock maximum execution time
#define LOCK_EXEC_MAX (24)
//! MAC maximum execution time
#define MAC_EXEC_MAX (35)
//! Nonce maximum execution time
#define NONCE_EXEC_MAX (60)
//! Pause maximum execution time
#define PAUSE_EXEC_MAX ( 2)
//! Random maximum execution time
#define RANDOM_EXEC_MAX (50)
//! Read maximum execution time
#define READ_EXEC_MAX ( 4)
//! UpdateExtra maximum execution time
#define UPDATE_EXEC_MAX (12)
//! Write maximum execution time
#define WRITE_EXEC_MAX (42)
//////////////////////////////////////////////////////////////////////
/**
* \brief This structure contains the parameters for the \ref sha204m_check_mac function.
*/
struct sha204_check_mac_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< what to include in the MAC calculation
uint8_t key_id; //!< what key to use for the MAC calculation
uint8_t *client_challenge; //!< pointer to challenge that host had sent to client
uint8_t *client_response; //!< pointer to challenge response received from client
uint8_t *other_data; //!< pointer to 13 bytes of data that were used by client to calculate MAC
};
/**
* \brief This structure contains the parameters for the \ref sha204m_derive_key function.
*/
struct sha204_derive_key_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t use_random; //!< true if source for TempKey was random number
uint8_t target_key; //!< slot where derived key should be stored
uint8_t *mac; //!< pointer to MAC for this command
};
/**
* \brief This structure contains the parameters for the \ref sha204m_dev_rev function.
*/
struct sha204_dev_rev_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
};
/**
* \brief This structure contains the parameters for the \ref sha204m_gen_dig function.
*/
struct sha204_gen_dig_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t zone; //!< what zone (config, OTP, or data) to use in the digest calculation
uint8_t key_id; //!< what key or OTP block to use for the digest calculation
uint8_t *other_data; //!< pointer to four bytes of data to use for the digest calculation, only needed when key is CheckMac only key
};
/**
* \brief This structure contains the parameters for the \ref sha204m_hmac function.
*/
struct sha204_hmac_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< what to include in the HMAC calculation
uint16_t key_id; //!< what key to use for the HMAC calculation
};
/**
* \brief This structure contains the parameters for the \ref sha204m_lock function.
*/
struct sha204_lock_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t zone; //!< what zone (config, OTP, or data) to lock
uint16_t summary; //!< CRC over the zone to be locked
};
/**
* \brief This structure contains the parameters for the \ref sha204m_mac function.
*/
struct sha204_mac_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< what to include in the MAC calculation
uint16_t key_id; //!< what key to use for the MAC calculation
uint8_t *challenge; //!< pointer to 32 bytes of challenge data to be sent to client
};
/**
* \brief This structure contains the parameters for the \ref sha204m_nonce function.
*/
struct sha204_nonce_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< what TempKey should be loaded with
uint8_t *num_in; //!< pointer to 20 bytes of input or 32 bytes of pass-through data
};
/**
* \brief This structure contains the parameters for the \ref sha204m_pause function.
*/
struct sha204_pause_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t selector; //!< which device not to set into Idle mode (single-wire interface only)
};
/**
* \brief This structure contains the parameters for the \ref sha204m_random function.
*/
struct sha204_random_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< true if existing EEPROM seed should be used
};
/**
* \brief This structure contains the parameters for the \ref sha204m_read function.
*/
struct sha204_read_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t zone; //!< what zone (config, OTP, or data) to read from and how many bytes (4 or 32)
uint16_t address; //!< what address to read from
};
/**
* \brief This structure contains the parameters for the \ref sha204m_update_extra function.
*/
struct sha204_update_extra_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t mode; //!< config byte address = 84 + mode (0 or 1)
uint8_t new_value; //!< value to write
};
/**
* \brief This structure contains the parameters for the \ref sha204m_write function.
*/
struct sha204_write_parameters {
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t zone; //!< what zone (config, OTP, or data) to write to, how many bytes (4 or 32), and whether data are encrypted
uint16_t address; //!< what address to write to
uint8_t *new_value; //!< pointer to 4 or 32 bytes of data to be written
uint8_t *mac; //!< pointer to MAC of this command (null if zone is unlocked)
};
/**
* \brief This structure contains the parameters for the \ref sha204m_execute function.
*/
struct sha204_command_parameters {
uint8_t op_code; //!< command code
uint8_t param_1; //!< parameter 1
uint16_t param_2; //!< parameter 2
uint8_t data_len_1; //!< length of data field 1
uint8_t data_len_2; //!< length of data field 2
uint8_t data_len_3; //!< length of data field 3
uint8_t *data_1; //!< pointer to data field 1
uint8_t *data_2; //!< pointer to data field 2
uint8_t *data_3; //!< pointer to data field 3
uint8_t *tx_buffer; //!< pointer to send buffer
uint8_t *rx_buffer; //!< pointer to receive buffer
uint8_t tx_size; //!< size of supplied send buffer
uint8_t rx_size; //!< size of supplied receive buffer
};
/**
* \defgroup sha204_command_marshaling_group SHA204 Service - command marshaling functions
*
* @{
*/
uint8_t sha204m_check_mac(struct sha204_check_mac_parameters *args);
uint8_t sha204m_derive_key(struct sha204_derive_key_parameters *args);
uint8_t sha204m_dev_rev(struct sha204_dev_rev_parameters *args);
uint8_t sha204m_gen_dig(struct sha204_gen_dig_parameters *args);
uint8_t sha204m_hmac(struct sha204_hmac_parameters *args);
uint8_t sha204m_lock(struct sha204_lock_parameters *args);
uint8_t sha204m_mac(struct sha204_mac_parameters *args);
uint8_t sha204m_nonce(struct sha204_nonce_parameters *args);
uint8_t sha204m_pause(struct sha204_pause_parameters *args);
uint8_t sha204m_random(struct sha204_random_parameters *args);
uint8_t sha204m_read(struct sha204_read_parameters *args);
uint8_t sha204m_update_extra(struct sha204_update_extra_parameters *args);
uint8_t sha204m_write(struct sha204_write_parameters *args);
uint8_t sha204m_execute(struct sha204_command_parameters *args);
//! @}
#endif

View File

@ -0,0 +1,63 @@
/*
* \file
*
* \brief Definitions for Configurable Values of the ATSHA204 Library
*
* This file contains configurations for the ATSHA204 modules.
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SHA204_CONFIG_H
# define SHA204_CONFIG_H
/** \brief number of command / response retries
*
* If communication is lost, re-synchronization includes waiting for the
* longest possible execution time of a command.
* This adds a #SHA204_COMMAND_EXEC_MAX delay to every retry.
* Every increment of the number of retries increases the time
* the library is spending in the retry loop by #SHA204_COMMAND_EXEC_MAX.
*/
#define SHA204_RETRY_COUNT (1)
#endif

View File

@ -0,0 +1,300 @@
/*
* \file
*
* \brief ATSHA204 file that implements the I2C layer for the device
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "conf_twim.h"
#include "conf_atsha204.h"
#include "twi_master.h"
#include "sha204_physical.h" // declarations that are common to all interface implementations
#include "sha204_lib_return_codes.h" // declarations of function return codes
#include "sha204_timer.h" // definitions for delay functions
/**
* \brief This enumeration lists all packet types sent to a SHA204 device.
*
* The following byte stream is sent to a SHA204 TWI device:
* {I2C start} {I2C address} {word address} [{data}] {I2C stop}.
* Data are only sent after a word address of value #SHA204_I2C_PACKET_FUNCTION_NORMAL.
*/
enum i2c_word_address {
SHA204_I2C_PACKET_FUNCTION_RESET, //!< Reset device.
SHA204_I2C_PACKET_FUNCTION_SLEEP, //!< Put device into Sleep mode.
SHA204_I2C_PACKET_FUNCTION_IDLE, //!< Put device into Idle mode.
SHA204_I2C_PACKET_FUNCTION_NORMAL //!< Write / evaluate data that follow this word address byte.
};
//! I2C address can be changed by calling #sha204p_set_device_id.
static uint8_t device_address = SHA204_I2C_DEFAULT_ADDRESS >> 1;
/** \brief This function initializes peripherals (timer and communication).
*/
void sha204p_init(void)
{
// Initialize timer.
sha204h_timer_init();
// Initialize interrupt vectors.
irq_initialize_vectors();
// Enable interrupts.
cpu_irq_enable();
}
/**
* \brief This I2C function sets the I2C address.
* Communication functions will use this address.
*
* \param[in] id I2C address
*/
void sha204p_set_device_id(uint8_t id)
{
device_address = id >> 1;
}
/**
* \brief This I2C function generates a Wake-up pulse and delays.
* \return status of the operation
*/
uint8_t sha204p_wakeup(void)
{
twi_package_t twi_package;
twi_options_t twi_options = {.speed = 133333};
// Set SDA low for 60 us. Speed is therefore: f = 1 / 0.00006 / 8 = 133,333.
// Generating the Stop condition adds 20 us for this particular implementation / target,
// but a longer wake pulse is okay.
twi_master_disable(ATSHA204_TWI_PORT);
int twi_master_setup_status = twi_master_setup(ATSHA204_TWI_PORT, &twi_options);
if (twi_master_setup_status != STATUS_OK)
return SHA204_COMM_FAIL;
twi_package.chip = 0;
twi_package.addr_length = 0;
twi_package.length = 0;
twi_package.buffer = NULL;
// This call will return a nack error.
(void) twi_master_write(ATSHA204_TWI_PORT, &twi_package);
sha204h_delay_ms(SHA204_WAKEUP_DELAY);
// Set I2C speed back to communication speed.
twi_master_enable(ATSHA204_TWI_PORT);
twi_options.speed = ATSHA204_TWI_SPEED;
return (uint8_t) twi_master_setup(ATSHA204_TWI_PORT, &twi_options);
}
/**
* \brief This function sends a I2C packet enclosed by a I2C start and stop to a SHA204 device.
*
* This function combines a I2C packet send sequence that is common to all packet types.
* Only if word_address is \ref SHA204_I2C_PACKET_FUNCTION_NORMAL, count and buffer parameters are
* expected to be non-zero.
* \param[in] word_address packet function code listed in #i2c_word_address
* \param[in] count number of bytes in data buffer
* \param[in] buffer pointer to data buffer
* \return status of the operation
*/
static uint8_t sha204p_send(uint8_t word_address, uint8_t count, uint8_t *buffer)
{
twi_package_t twi_package = {
.chip = device_address,
.addr_length = 1,
.length = count,
.buffer = (void *) buffer,
.addr[0] = word_address
};
return (twi_master_write(ATSHA204_TWI_PORT, &twi_package) ? SHA204_COMM_FAIL : SHA204_SUCCESS);
}
/**
* \brief This I2C function sends a command to the device.
* \param[in] count number of bytes to send
* \param[in] command pointer to command buffer
* \return status of the operation
*/
uint8_t sha204p_send_command(uint8_t count, uint8_t *command)
{
return sha204p_send(SHA204_I2C_PACKET_FUNCTION_NORMAL, count, command);
}
/**
* \brief This I2C function puts the SHA204 device into idle state.
* \return status of the operation
*/
uint8_t sha204p_idle(void)
{
return sha204p_send(SHA204_I2C_PACKET_FUNCTION_IDLE, 0, NULL);
}
/**
* \brief This I2C function puts the SHA204 device into low-power state.
* \return status of the operation
*/
uint8_t sha204p_sleep(void)
{
return sha204p_send(SHA204_I2C_PACKET_FUNCTION_SLEEP, 0, NULL);
}
/**
* \brief This I2C function resets the I/O buffer of the SHA204 device.
* \return status of the operation
*/
uint8_t sha204p_reset_io(void)
{
return sha204p_send(SHA204_I2C_PACKET_FUNCTION_RESET, 0, NULL);
}
/**
* \brief This I2C function receives a response from the SHA204 device.
*
* \param[in] size size of receive buffer
* \param[out] response pointer to receive buffer
* \return status of the operation
*/
uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
{
// Read count.
twi_package_t twi_package = {
.chip = device_address,
.addr_length = 0,
.length = 1,
.buffer = (void *) response
};
status_code_t i2c_status = twi_master_read(ATSHA204_TWI_PORT, &twi_package);
if (i2c_status != STATUS_OK)
return (i2c_status == ERR_TIMEOUT ? SHA204_TIMEOUT : SHA204_RX_NO_RESPONSE);
uint8_t count = response[SHA204_BUFFER_POS_COUNT];
if ((count < SHA204_RSP_SIZE_MIN) || (count > SHA204_RSP_SIZE_MAX))
return SHA204_INVALID_SIZE;
// Read packet remainder.
twi_package.length = (count > size) ? size : count;
twi_package.length--;
twi_package.buffer = response + 1;
return (twi_master_read(ATSHA204_TWI_PORT, &twi_package) ? SHA204_COMM_FAIL : SHA204_SUCCESS);
}
/**
* \brief This I2C function resynchronizes communication.
*
* Parameters are not used for I2C.\n
* Re-synchronizing communication is done in a maximum of three steps
* listed below. This function implements the first step. Since
* steps 2 and 3 (sending a Wake-up token and reading the response)
* are the same for I2C and SWI, they are
* implemented in the communication layer (\ref sha204c_resync).
* See the excerpt from the SHA204 data sheet below.
<ol>
<li>
To ensure an IO channel reset, the system should send
the standard I2C software reset sequence, as follows:
<ul>
<li>a Start condition</li>
<li>nine cycles of SCL, with SDA held high</li>
<li>another Start condition</li>
<li>a Stop condition</li>
</ul>
It should then be possible to send a read sequence and
if synchronization has completed properly the ATSHA204 will
acknowledge the device address. The chip may return data or
may leave the bus floating (which the system will interpret
as a data value of 0xFF) during the data periods.\n
If the chip does acknowledge the device address, the system
should reset the internal address counter to force the
ATSHA204 to ignore any partial input command that may have
been sent. This can be accomplished by sending a write
sequence to word address 0x00 (Reset), followed by a
Stop condition.
</li>
<li>
If the chip does NOT respond to the device address with an ACK,
then it may be asleep. In this case, the system should send a
complete Wake token and wait t_whi after the rising edge. The
system may then send another read sequence and if synchronization
has completed the chip will acknowledge the device address.
</li>
<li>
If the chip still does not respond to the device address with
an acknowledge, then it may be busy executing a command. The
system should wait the longest TEXEC and then send the
read sequence, which will be acknowledged by the chip.
</li>
</ol>
* \param[in] size size of response buffer
* \param[out] response pointer to response buffer
* \return status of the operation
*/
uint8_t sha204p_resync(uint8_t size, uint8_t *response)
{
// Generate Start, nine clocks, Stop.
// (Adding a Repeat Start before the Stop would additionally
// prevent erroneously writing a byte, but a Stop right after a
// Start is not "legal" for I2C and the SHA204 will not write
// anything without a successful CRC check.)
twi_package_t twi_package = {
.chip = (uint8_t) 0xFF,
.addr_length = 1,
.length = 0,
.buffer = (void *) response,
.addr[0] = 0
};
(void) twi_master_read(ATSHA204_TWI_PORT, &twi_package);
return sha204p_reset_io();
}

View File

@ -0,0 +1,68 @@
/*
* \file
*
* \brief ATSHA204 library return codes
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SHA204_LIB_RETURN_CODES_H
# define SHA204_LIB_RETURN_CODES_H
#include <compiler.h> //!< compiler dependent definitions
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
#define SHA204_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error
#define SHA204_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error
#define SHA204_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error
#define SHA204_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state.
#define SHA204_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.)
#define SHA204_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size.
#define SHA204_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received
#define SHA204_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0.
#define SHA204_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response.
#define SHA204_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< re-synchronization succeeded, but only after generating a Wake-up
#define SHA204_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules.
#define SHA204_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0.
#endif

View File

@ -0,0 +1,77 @@
/*
* \file
*
* \brief ATSHA204 header file for the I2C layer for the device
*
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SHA204_PHYSICAL_H
# define SHA204_PHYSICAL_H
#include "sha204_config.h" //!< configuration values
#define SHA204_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response
#define SHA204_RSP_SIZE_MAX ((uint8_t) 35) //!< maximum size of response packet
#define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response
#define SHA204_BUFFER_POS_DATA (1) //!< buffer index of data in response
//! delay between Wakeup pulse and communication in ms
#define SHA204_WAKEUP_DELAY (3)
/**
* \defgroup sha204_communication_physical_group SHA204 Service - hardware dependent communication functions
*
* @{
*/
void sha204p_init(void);
void sha204p_set_device_id(uint8_t id);
uint8_t sha204p_send_command(uint8_t count, uint8_t *command);
uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
uint8_t sha204p_wakeup(void);
uint8_t sha204p_idle(void);
uint8_t sha204p_sleep(void);
uint8_t sha204p_reset_io(void);
uint8_t sha204p_resync(uint8_t size, uint8_t *response);
//! @}
#endif

View File

@ -0,0 +1,332 @@
/**
* \file
*
* \brief Non volatile memories management
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef COMMON_NVM_H_INCLUDED
#define COMMON_NVM_H_INCLUDED
#include "compiler.h"
#include "conf_board.h"
#include "parts.h"
#include "status_codes.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
#include "at45dbx.h"
#endif
/* ! \name Non volatile memory types */
/* ! @{ */
typedef enum {
INT_FLASH /* !< Internal Flash */
#if (XMEGA || UC3 || SAM4S)
, INT_USERPAGE /* !< Userpage/User signature */
#endif
#if XMEGA
, INT_EEPROM /* !< Internal EEPROM */
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
, AT45DBX /* !< External AT45DBX dataflash */
#endif
} mem_type_t;
/* ! @} */
#if SAM
# ifndef IFLASH_PAGE_SIZE
# define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
# endif
# ifndef IFLASH_ADDR
# define IFLASH_ADDR IFLASH0_ADDR
# endif
#endif
/**
* \defgroup nvm_group NVM service
*
* See \ref common_nvm_quickstart.
*
* This is the common API for non volatile memories. Additional features are
* available
* in the documentation of the specific modules.
*
*/
/**
* \brief Initialize the non volatile memory specified.
*
* \param mem Type of non volatile memory to initialize
*/
status_code_t nvm_init(mem_type_t mem);
/**
* \brief Read single byte of data.
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param data Pointer to where to store the read data
*/
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data);
/**
* \brief Write single byte of data.
*
* \note For SAM4S internal flash, the page existed in the address must be erased first
* before written, and the minimum write unit is a page,thus when writing a single
* byte, a whole page that contains the data is writen.
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param data Data to be written
*/
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data);
/**
* \brief Read \a len number of bytes from address \a address in non volatile
* memory \a mem and store it in the buffer \a buffer
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param buffer Pointer to destination buffer
* \param len Number of bytes to read
*/
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Write \a len number of bytes at address \a address in non volatile
* memory \a mem from the buffer \a buffer
*
* \note For SAM4S internal flash, the page existed in the address must be erased
* first before written.
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param buffer Pointer to source buffer
* \param len Number of bytes to write
*/
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Erase a page in the non volatile memory.
*
* The function is only available for internal flash and/or userpage signature.
*
* \note For SAM4S internal flash erase, the minimum erase unit is 8 pages.
*
* \param mem Type of non volatile memory to erase
* \param page_number Page number to erase
*/
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number);
/**
* \brief Get the size of whole non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the size of a page in the non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the page number from the byte address \a address.
*
* \param mem Type of non volatile memory
* \param address Byte address of the non volatile memory
* \param num Pointer to where to store the page number
*/
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num);
/**
* \brief Enable security bit which blocks external read and write access
* to the device.
*
*/
status_code_t nvm_set_security_bit(void);
/**
* \page common_nvm_quickstart Quick Start quide for common NVM driver
*
* This is the quick start quide for the \ref nvm_group "Common NVM driver",
* with step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section nvm_basic_use_case Basic use case
* In this basic use case, NVM driver is configured for Internal Flash
*
* \section nvm_basic_use_case_setup Setup steps
*
* \subsection nvm_basic_use_case_setup_code Example code
* Add to you application C-file:
* \code
if(nvm_init(INT_FLASH) == STATUS_OK)
do_something();
\endcode
*
* \subsection nvm_basic_use_case_setup_flow Workflow
* -# Ensure that board_init() has configured selected I/Os for TWI function
* when using external AT45DBX dataflash
* -# Ensure that \ref conf_nvm.h is present for the driver.
* - \note This file is only for the driver and should not be included by the
* user.
* -# Call nvm_init \code nvm_init(INT_FLASH); \endcode
* and optionally check its return code
*
* \section nvm_basic_use_case_usage Usage steps
* \subsection nvm_basic_use_case_usage_code_writing Example code: Writing to
* non volatile memory
* Use in the application C-file:
* \code
uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
if(nvm_write(INT_FLASH, test_address, (void *)buffer, sizeof(buffer)) ==
STATUS_OK)
do_something();
\endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare the data you want to send to the non volatile memory
* \code uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; \endcode
* -# Call nvm_write \code nvm_write(INT_FLASH, test_address, (void *)buffer,
sizeof(buffer)) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_reading Example code: Reading from
* non volatile memory
* Use in application C-file:
* \code
uint8_t data_read[8];
if(nvm_read(INT_FLASH, test_address, (void *)data_read, sizeof(data_read))
== STATUS_OK) {
//Check read content
if(data_read[0] == 0xAA)
do_something();
}
\endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a data buffer that will read data from non volatile memory
* \code uint8_t data_read[8]; \endcode
* -# Call nvm_read \code nvm_read(INT_FLASH, test_address, (void *)data_read,
sizeof(data_read)); \endcode
* and optionally check its return value for STATUS_OK.
* The data read from the non volatile memory are in data_read.
*
* \subsection nvm_basic_use_case_usage_code_erasing Example code: Erasing a
* page of non volatile memory
* Use in the application C-file:
* \code
if(nvm_page_erase(INT_FLASH, test_page) == STATUS_OK)
do_something();
\endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_page_erase \code nvm_page_erase(INT_FLASH, test_page) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_config Example code: Reading
*configuration of non volatile memory
* Use in application C-file:
* \code
uint8_t mem_size, page_size, page_num;
nvm_get_size(INT_FLASH, &mem_size);
nvm_get_page_size(INT_FLASH, &page_size);
nvm_get_pagenumber(INT_FLASH, test_address, &page_num);
\endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a buffer to store configuration of non volatile memory
* \code uint8_t mem_size, page_size, page_num; \endcode
* -# Call nvm_get_size \code nvm_get_size(INT_FLASH, &mem_size); \endcode
* and optionally check its return value for STATUS_OK.
* The memory size of the non volatile memory is in mem_size.
* -# Call nvm_get_page_size \code nvm_get_page_size(INT_FLASH, &page_size);
\endcode
* and optionally check its return value for STATUS_OK.
* The page size of the non volatile memory is in page_size.
* -# Call nvm_get_pagenumber \code nvm_get_page_number(INT_FLASH, test_address,
&page_num); \endcode
* and optionally check its return value for STATUS_OK.
* The page number of given address in the non volatile memory is in page_num.
*
* \subsection nvm_basic_use_case_usage_code_locking Example code: Enabling
* security bit
* Use in the application C-file:
* \code
if(nvm_set_security_bit() == STATUS_OK)
do_something();
\endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_set_security_bit \code nvm_set_security_bit() \endcode
* and optionally check its return value for STATUS_OK.
*/
#ifdef __cplusplus
}
#endif
#endif /* COMMON_NVM_H_INCLUDED */

View File

@ -0,0 +1,50 @@
/**
* \file
*
* \brief Non volatile memories management for SAM devices
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_NVM_H_INCLUDED
#define CONF_NVM_H_INCLUDED
#endif /* CONF_NVM_H_INCLUDED */

View File

@ -0,0 +1,394 @@
/**
* \file
*
* \brief Non volatile memories management for SAM devices
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "common_nvm.h"
#include "conf_board.h"
#include "flash_efc.h"
#include "string.h"
status_code_t nvm_init(mem_type_t mem)
{
switch (mem) {
case INT_FLASH:
#if SAM4S
case INT_USERPAGE:
#endif
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
/* Initialize dataflash */
at45dbx_init();
/* Perform memory check */
if (!at45dbx_mem_check()) {
return ERR_NO_MEMORY;
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data)
{
switch (mem) {
case INT_FLASH:
*data = *((uint8_t *)(address));
break;
#if SAM4S
case INT_USERPAGE:
{
/*! This function creates a buffer of IFLASH_PAGE_SIZE to
* read the data from starting of user signature */
uint32_t buffer[IFLASH_PAGE_SIZE];
uint32_t offset = address - IFLASH_ADDR;
if (offset < 0) {
return ERR_INVALID_ARG;
}
flash_read_user_signature(buffer, offset);
*data = buffer[offset];
break;
}
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_read_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
*data = at45dbx_read_byte();
at45dbx_read_close();
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data)
{
switch (mem) {
case INT_FLASH:
#if SAM4S
if (flash_write(address, (const void *)&data, 1,
false)) {
return ERR_INVALID_ARG;
}
#else
if (flash_write(address, (const void *)&data, 1, true)) {
return ERR_INVALID_ARG;
}
#endif
break;
#if SAM4S
case INT_USERPAGE:
if (flash_write_user_signature((const void *)&data, 1)) {
return ERR_INVALID_ARG;
}
break;
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_write_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_byte(data);
at45dbx_write_close();
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
memcpy(buffer, (const void *)address, len);
break;
#if SAM4S
case INT_USERPAGE:
{
/*! This function creates a buffer of IFLASH_PAGE_SIZE to
* read the data from starting of user signature */
uint32_t temp_buff[IFLASH_PAGE_SIZE], *buff = buffer;
/* Read from the starting of user signature */
if (flash_read_user_signature(temp_buff, len)) {
return ERR_INVALID_ARG;
}
/* Calculate offset and copy required number of bytes */
for (uint16_t i = 0; i < len; i++) {
*buff = temp_buff[address - IFLASH_ADDR + i];
buff++;
}
break;
}
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
if (len == AT45DBX_SECTOR_SIZE) {
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_read_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_read_sector_to_ram(buffer);
at45dbx_read_close();
} else {
if (!at45dbx_read_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
uint8_t *buf = (uint8_t *)buffer;
while (len--) {
*buf++ = at45dbx_read_byte();
}
at45dbx_read_close();
}
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
#if SAM4S
if (flash_write(address, (const void *)buffer, len, false)) {
return ERR_INVALID_ARG;
}
#else
if (flash_write(address, (const void *)buffer, len, true)) {
return ERR_INVALID_ARG;
}
#endif
break;
#if SAM4S
case INT_USERPAGE:
if (flash_write_user_signature((const void *)buffer, len)) {
return ERR_INVALID_ARG;
}
break;
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
if (len == AT45DBX_SECTOR_SIZE) {
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_write_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_sector_from_ram((const void *)buffer);
at45dbx_write_close();
} else {
if (!at45dbx_write_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
uint8_t *buf = (uint8_t *)buffer;
while (len--) {
at45dbx_write_byte(*buf++);
}
at45dbx_write_close();
}
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number)
{
switch (mem) {
case INT_FLASH:
{
#if SAM4S
/*! Page erase function erases minimum 8 pages in Flash */
if (flash_erase_page((uint32_t)(page_number * IFLASH_PAGE_SIZE),
IFLASH_ERASE_PAGES_8)) {
return ERR_INVALID_ARG;
}
#else
uint32_t buffer[IFLASH_PAGE_SIZE], byte_address;
for (uint16_t i = 0; i < IFLASH_PAGE_SIZE; i++) {
buffer[i] = 0xFFFFFFFF;
}
byte_address = page_number * IFLASH_PAGE_SIZE;
/* Erase and write FFs to a page as there is no function for
* erase */
if (!flash_write(byte_address, (const void *)buffer,
IFLASH_PAGE_SIZE, true)) {
return ERR_INVALID_ARG;
}
#endif
break;
}
#if SAM4S
case INT_USERPAGE:
flash_erase_user_signature();
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
*size = (uint32_t)IFLASH_SIZE;
break;
#if SAM4S
case INT_USERPAGE:
*size = (uint32_t)IFLASH_PAGE_SIZE;
break;
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
*size = (uint32_t)AT45DBX_MEM_SIZE;
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
#if SAM4S
case INT_USERPAGE:
#endif
*size = (uint32_t)IFLASH_PAGE_SIZE;
break;
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num)
{
switch (mem) {
case INT_FLASH:
*num = (uint32_t)(address / IFLASH_PAGE_SIZE);
break;
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_set_security_bit(void)
{
if (!flash_enable_security_bit()) {
return ERR_INVALID_ARG;
}
return STATUS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,943 @@
/**
* \file
*
* \brief ADP service implementation
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef ADP_H_INCLUDED
#define ADP_H_INCLUDED
#include <compiler.h>
/** Version of ADP implemented here */
#define ADP_VERSION 1
/** Start token for ADP data */
#define ADP_TOKEN 0xFF
/** Maximum number of streams from PC to target */
#define ADP_MAX_INCOMMING_STREAMS 5
/** Maximum number of streams from target to PC */
#define ADP_MAX_OUTGOING_STREAMS 5
/** Maximum number of bytes target can request from PC in one request */
#define ADP_MAX_BYTE_REQUEST 20
/** Length of ADP packet header: Token, Message ID, Data Length */
#define ADP_LENGTH_PACKET_HEADER 4
/** Maximum number of bytes in data part of ADP packet */
#define ADP_MAX_PACKET_DATA_SIZE 254
/** Maximum number of all bytes in ADP packet */
#define ADP_MAX_PACKET_LENGTH (ADP_LENGTH_PACKET_HEADER + ADP_MAX_PACKET_DATA_SIZE)
/** Key used to identify proper handshake message */
#define ADP_HANDSHAKE_KEY {0x58, 0x99, 0xAB, 0xC9, 0x0F, 0xE2, 0xF7, 0xAA}
/** ADP RGB color definitions. Other RGB values can be used as well */
#define ADP_COLOR_WHITE 0xFF, 0xFF, 0xFF
#define ADP_COLOR_BLACK 0x00, 0x00, 0x00
#define ADP_COLOR_SILVER 0xC0, 0xC0, 0xC0
#define ADP_COLOR_GRAY 0x80, 0x80, 0x80
#define ADP_COLOR_MAROON 0x80, 0x00, 0x00
#define ADP_COLOR_RED 0xFF, 0x00, 0x00
#define ADP_COLOR_PURPLE 0x80, 0x00, 0x80
#define ADP_COLOR_FUCHSIA 0xFF, 0x00, 0xFF
#define ADP_COLOR_GREEN 0x00, 0x80, 0x00
#define ADP_COLOR_LIME 0x00, 0xFF, 0x00
#define ADP_COLOR_OLIVE 0x80, 0x80, 0x00
#define ADP_COLOR_YELLOW 0xFF, 0xFF, 0x00
#define ADP_COLOR_NAVY 0x00, 0x00, 0x80
#define ADP_COLOR_BLUE 0x00, 0x00, 0xFF
#define ADP_COLOR_TEAL 0x00, 0x80, 0x80
#define ADP_COLOR_AQUA 0x00, 0xFF, 0xFF
#define ADP_COLOR_ORANGE 0xFF, 0xA5, 0x00
/** States in receive state machine */
enum rx_state_e {
/** We are idle, waiting for a new packet */
RX_STATE_IDLE,
/** Start symbol received, waiting for Message ID */
RX_STATE_WAIT_MSG_ID,
/** Message ID received, waiting for data length */
RX_STATE_WAIT_LENGTH_LSB,
/** Message ID received, waiting for data length */
RX_STATE_WAIT_LENGTH_MSB,
/** Length received; we are receiving packet data */
RX_STATE_GET_DATA,
/** Start symbol received */
RX_STATE_GOT_SYMBOL,
};
/** Max length of labels */
#define ADP_CONF_MAX_LABEL 20
static inline void adp_set_color(uint8_t* struct_member, uint8_t c_red, uint8_t c_green, uint8_t c_blue)
{
struct_member[0] = c_red;
struct_member[1] = c_green;
struct_member[2] = c_blue;
}
#define adp_set_string(struct_member, string) \
Assert(sizeof(struct_member)); \
strncpy(struct_member, string, sizeof(struct_member)); \
struct_member[sizeof(struct_member)-1] = '\0';
/* MESSAGE FORMAT */
SHORTENUM struct adp_msg_format {
/* Start token for ADP data */
uint8_t protocol_token;
/* Describes what data is sent */
uint8_t protocol_msg_id;
/* Length of data packet */
uint16_t data_length;
/* Data packet for the message */
uint8_t data[ADP_MAX_PACKET_DATA_SIZE];
};
/* MSG_REQ_HANDSHAKE */
#define MSG_REQ_HANDSHAKE 0x00
#define MSQ_REQ_HANDSHAKE_LEN 10
enum adp_handshake_options {
/* Use GPIO */
ADP_HANDSHAKE_OPTIONS_GPIO,
/* Lock configuration */
ADP_HANDSHAKE_OPTIONS_LOCK,
};
SHORTENUM struct adp_msg_request_handshake {
/* Version of protocol on target */
uint8_t protocol_version;
/* Is GPIO in use in this app?
* Can user change configuration on PC side?
*/
uint8_t options;
/* Token used to verify ADP protocol */
uint8_t key[8];
};
/* MSG_RES_HANDSHAKE */
#define MSG_RES_HANDSHAKE 0x10
enum adp_handshake_status {
/* Handshake accepted */
ADP_HANDSHAKE_ACCEPTED,
/* Handshake rejected. Invalid protocol version */
ADP_HANDSHAKE_REJECTED_PROTOCOL,
/* Handshake rejected. Other reason */
ADP_HANDSHAKE_REJECTED_OTHER,
};
SHORTENUM struct adp_msg_response_handshake {
enum adp_handshake_status status;
};
enum adp_handshake_status adp_wait_for_handshake(void);
/* MSG_REQ_STATUS */
#define MSG_REQ_STATUS 0x02
#define MSG_REQ_STATUS_LEN 0
/* This message has no data */
/* MSG_RES_STATUS */
#define MSG_RES_STATUS 0x12
enum adp_status_code {
/* Invalid packet received */
ADP_STATUS_INVALID_PACKET,
/* Invalid configuration data received */
ADP_STATUS_INVALID_CONFIGURATION,
/* Data ready to be transmitted to target */
ADP_STATUS_DATA_READY,
/* Invalid stream request (req_data) */
ADP_STATUS_INVALID_REQUEST,
/* No data available on stream (req_data) */
ADP_STATUS_NO_DATA,
/* Request target software reset */
ADP_STATUS_RESET,
};
SHORTENUM struct adp_msg_response_status {
enum adp_status_code status;
};
enum adp_status_code adp_request_status(void);
/* MSG_RES_DATA */
#define MSG_RES_DATA 0x14
#define MSG_RES_DATA_MAX_LEN (ADP_MAX_BYTE_REQUEST + 4)
SHORTENUM struct adp_msg_response_data {
/* ID of stream */
uint8_t stream_id;
/* Number of bytes in packet.
* If the target has requested data from an unknown stream, or if stream
* has no data to send, this field should be set to 0 and the appropriate
* status flag should be set.
*/
uint8_t bytes_sent;
/* The data */
uint8_t data[ADP_MAX_BYTE_REQUEST];
};
void adp_request_data(uint8_t stream_id, uint8_t bytes_to_send, struct adp_msg_response_data *response);
#define MSG_RES_PACKET_DATA_MAX_LEN (ADP_MAX_BYTE_REQUEST + 2)
SHORTENUM struct adp_msg_packet_data {
uint16_t stream_id;
uint8_t bytes_sent;
uint8_t data[ADP_MAX_BYTE_REQUEST];
};
bool adp_receive_packet_data(uint8_t *receive_buf);
/* MSG_CONF_STREAM */
enum adp_stream_type {
ADP_STREAM_EVENT,
ADP_STREAM_STRING,
ADP_STREAM_UINT_8,
ADP_STREAM_INT_8,
ADP_STREAM_UINT_16,
ADP_STREAM_INT_16,
ADP_STREAM_UINT_32,
ADP_STREAM_INT_32,
ADP_STREAM_XY_8,
ADP_STREAM_XY_16,
ADP_STREAM_XY_32,
ADP_STREAM_BOOL,
ADP_STREAM_FLOAT,
};
enum adp_stream_state {
ADP_STREAM_OFF,
ADP_STREAM_ON,
};
enum adp_stream_mode {
/* Incoming (normal) */
ADP_STREAM_IN,
/* Incoming (single value) */
ADP_STREAM_IN_SINGLE,
/* Outgoing */
ADP_STREAM_OUT,
};
#define MSG_CONF_ACK 0x30
#define ADP_ACK_NOT_OK 0
#define ADP_ACK_OK 1
#define MSG_CONF_INFO 0x28
#define MSG_CONF_INFO_LEN
bool adp_configure_info(const char* title, const char* description);
#define MSG_CONF_STREAM 0x20
#define MSG_CONF_STREAM_LEN 5
SHORTENUM struct adp_msg_configure_stream {
/* ID of stream */
uint16_t stream_id;
/* Stream type */
enum adp_stream_type type;
/* Stream mode/direction */
enum adp_stream_mode mode;
/* Stream state */
enum adp_stream_state state;
};
static inline void adp_configure_stream_get_defaults(struct adp_msg_configure_stream *const config)
{
Assert(config);
config->stream_id = 0;
config->type = ADP_STREAM_UINT_8;
config->mode = ADP_STREAM_OUT;
config->state = ADP_STREAM_ON;
}
bool adp_configure_stream(struct adp_msg_configure_stream *const config, const char* label);
/* MSG_CONF_TOGGLE_STREAM */
#define MSG_CONF_TOGGLE_STREAM 0x21
#define MSG_CONF_TOGGLE_STREAM_LEN 3
SHORTENUM struct adp_msg_toggle_stream {
uint16_t stream_id;
enum adp_stream_state state;
};
bool adp_toggle_stream(struct adp_msg_toggle_stream *const config);
/* MSG_CONF_GRAPH */
#define MSG_CONF_GRAPH 0x22
#define MSG_CONF_GRAPH_LEN 23
enum adp_graph_scale_mode {
ADP_GRAPH_SCALE_OFF,
ADP_GRAPH_SCALE_AUTO
};
enum adp_graph_scroll_mode {
/* No scrolling */
ADP_GRAPH_SCROLL_OFF,
/* Stepping */
ADP_GRAPH_SCROLL_STEP,
/* Scroll */
ADP_GRAPH_SCROLL_SCROLL,
/* Circular/sweep */
ADP_GRAPH_SCROLL_CIRCULAR
};
SHORTENUM struct adp_msg_configure_graph {
/* ID of new graph */
uint8_t graph_id;
/* Range Xmin value */
uint32_t x_min;
/* Range Xmax value */
uint32_t x_max;
/* Xscale numerator */
uint32_t x_scale_numerator;
/* X range scale value. Set to 0 to enable auto range */
uint32_t x_scale_denominator;
/* Vertical scaling */
enum adp_graph_scale_mode scale_mode;
/* RGB background color */
uint8_t background_color[3];
/* Horizontal scrolling */
enum adp_graph_scroll_mode scroll_mode;
};
static inline void adp_configure_graph_get_defaults(struct adp_msg_configure_graph *const config)
{
Assert(config);
config->graph_id = 0;
config->x_min = 0;
config->x_max = 0;
config->x_scale_numerator = 0;
config->x_scale_denominator = 0;
config->scale_mode = ADP_GRAPH_SCALE_OFF;
adp_set_color(config->background_color, ADP_COLOR_WHITE);
config->scroll_mode = ADP_GRAPH_SCROLL_SCROLL;
}
bool adp_configure_graph(struct adp_msg_configure_graph *const config, \
const char* graph_label, const char* x_label);
/* MSG_CONF_AXIS */
#define MSG_CONF_AXIS 0x29
#define MSG_CONF_AXIS_LEN 24
SHORTENUM struct adp_msg_conf_axis {
/* ID of new axis */
uint16_t axis_id;
/* ID of graph */
uint16_t graph_id;
/* Range Ymin value */
int32_t y_min;
/* Range Ymax value */
int32_t y_max;
/* X range scale value. Set to 0 to enable auto range */
uint32_t x_scale_numerator;
/* X range scale value. Set to 0 to enable auto range */
uint32_t x_scale_denominator;
/* Mode */
uint8_t mode; // TODO
/* RGB color */
uint8_t color[3];
};
static inline void adp_add_axis_to_graph_get_defaults(struct adp_msg_conf_axis *const config)
{
Assert(config);
config->axis_id = 0;
config->graph_id = 0;
config->y_min = 0;
config->y_max = 0;
config->x_scale_numerator = 0;
config->x_scale_denominator = 0;
config->mode = 0;
adp_set_color(config->color, ADP_COLOR_BLACK);
}
bool adp_add_axis_to_graph(struct adp_msg_conf_axis *const config, const char* label);
/* MSG_CONF_ADD_STREAM_TO_GRAPH */
#define MSG_CONF_ADD_STREAM_TO_AXIS 0x23
#define MSG_CONF_ADD_STREAM_TO_AXIS_LEN 32
#define ADP_AXIS_LINE_bm 0x01
#define ADP_AXIS_POINTS_bm 0x02
SHORTENUM struct adp_msg_add_stream_to_axis {
/* ID of graph */
uint16_t graph_id;
/* ID of new axis */
uint16_t axis_id;
/* ID of stream */
uint16_t stream_id;
/* Sample rate of stream, set to 0 if NA */
uint32_t sample_rate_numerator;
/* Sample rate of stream, set to 0 if NA */
uint32_t sample_rate_denominator;
/* Range Ymin value */
uint32_t y_scale_numerator;
/* Range Ymax value */
uint32_t y_scale_denominator;
/* Offset of values */
uint32_t y_offset;
/* Adjust the transparency */
uint8_t transparency;
/* For graphs: bit 0 = line on/off
* bit 1 = points on/off
* For text: bit 0 = flag
* bit 1 = text
*/
uint8_t mode; // TODO
/* Thickness of line */
uint8_t line_thickness;
/* RGB color of line */
uint8_t line_color[3];
};
static inline void adp_add_stream_to_axis_get_defaults(struct adp_msg_add_stream_to_axis *const config)
{
Assert(config);
config->graph_id = 0;
config->axis_id = 0;
config->stream_id = 0;
config->sample_rate_numerator = 0;
config->sample_rate_denominator = 0;
config->y_scale_numerator = 0;
config->y_scale_denominator = 0;
config->y_offset = 0;
config->transparency = 0;
config->mode = ADP_AXIS_LINE_bm;
config->line_thickness = 1;
adp_set_color(config->line_color, ADP_COLOR_BLACK);
}
bool adp_add_stream_to_axis(struct adp_msg_add_stream_to_axis *const config);
/* MSG_CONF_CURSOR_TO_GRAPH */
#define MSG_CONF_CURSOR_TO_GRAPH 0x24
#define MSG_CONF_CURSOR_TO_GRAPH_LEN 35
SHORTENUM struct adp_msg_add_cursor_to_graph {
/* ID of streama */
uint16_t stream_id;
/* ID of graph */
uint16_t graph_id;
/* ID of axis */
uint16_t axis_id;
/* Thickness of line */
uint8_t thickness;
/* RGB color of cursor */
uint8_t color[3];
/* Starting point of cursor */
uint32_t initial_value;
/* Minimum allowed value */
uint32_t minimum_value;
/* Maximum */
uint32_t maximum_value;
/* Numerator of scaling value */
uint32_t scale_numerator;
/* Denominator of scaling value */
uint32_t scale_denominator;
/* Offset of value */
uint32_t scale_offset;
/* The style of line: Solid, dashed, dotted.. */
uint8_t line_style; // TODO
};
static inline void adp_add_cursor_to_graph_get_defaults(struct adp_msg_add_cursor_to_graph *const config)
{
Assert(config);
config->stream_id = 0;
config->graph_id = 0;
config->axis_id = 0;
config->thickness = 1;
adp_set_color(config->color, ADP_COLOR_WHITE);
config->initial_value = 0;
config->minimum_value = 0;
config->maximum_value = 0;
config->scale_numerator = 0;
config->scale_denominator = 0;
config->scale_offset = 0;
config->line_style = 0;
}
bool adp_add_cursor_to_graph(struct adp_msg_add_cursor_to_graph *const config, const char* label);
/* MSG_CONF_GPIO_TO_GRAPH */
#define MSG_CONF_GPIO_TO_GRAPH 0x25
#define MSG_CONF_GPIO_TO_GRAPH_LEN 15
SHORTENUM struct adp_msg_conf_gpio_to_graph {
/* ID of graph */
uint16_t graph_id;
/* GPIO number to add to graph. Bit 0: GPIO0. bit 1: GPIO1 etc. */
uint8_t gpio_number;
/* Used to group graphs and cursors to the same scale */
uint8_t group_id;
/* Adjust the transparency */
uint8_t transparency;
/* Mode */
uint16_t mode; // TODO
/* Thickness of line */
uint8_t line_thickness;
/* RGB color of line when GPIO pin is high */
uint8_t line_color_high_state[3];
/* RGB color of line when GPIO pin is low */
uint8_t line_color_low_state[3];
/* The style of line */
uint8_t line_style;
};
static inline void adp_gpio_to_graph_get_defaults(struct adp_msg_conf_gpio_to_graph *const config)
{
Assert(config);
config->graph_id = 0;
config->gpio_number = 0;
config->group_id = 0;
config->transparency = 0;
config->mode = 0;
config->line_thickness = 1;
adp_set_color(config->line_color_high_state, ADP_COLOR_WHITE);
adp_set_color(config->line_color_low_state, ADP_COLOR_WHITE);
config->line_style = 0;
}
bool adp_add_gpio_to_graph(struct adp_msg_conf_gpio_to_graph *const config, \
const char* tag_high_state, const char* tag_low_state);
/* MSG_CONF_TERMINAL */
#define MSG_CONF_TERMINAL 0x26
#define MSG_CONF_TERMINAL_LEN 10
SHORTENUM struct adp_msg_conf_terminal {
/* ID of terminal */
uint16_t terminal_id;
/* Number of characters wide */
uint8_t width;
/* Number of characters high */
uint8_t height;
/* RGB background color */
uint8_t background_color[3];
/* RGB background color */
uint8_t foreground_color[3];
};
static inline void adp_configure_terminal_get_defaults(struct adp_msg_conf_terminal *const config)
{
Assert(config);
config->terminal_id = 0;
config->width = 80;
config->height = 25;
adp_set_color(config->background_color, ADP_COLOR_WHITE);
adp_set_color(config->foreground_color, ADP_COLOR_BLACK);
}
bool adp_configure_terminal(struct adp_msg_conf_terminal *const config, const char* label);
/* MSG_CONF_ADD_TO_TERMINAL */
#define MSG_CONF_ADD_TO_TERMINAL 0x27
#define MSG_CONF_ADD_TO_TERMINAL_LEN 11
SHORTENUM struct adp_msg_add_stream_to_terminal {
/* ID of Terminal */
uint16_t terminal_id;
/* ID of stream */
uint16_t stream_id;
/* 0bx x x N T S F F
* N = implicit newline in incoming text
* T = enable tag
* S = timestamped
* F = format (Hex, decimal, binary, ascii)
*/
uint8_t mode; // TODO
/* RGB color of the text stream received */
uint8_t text_color[3];
/* RGB color of the tag text */
uint8_t tag_text_color[3];
};
static inline void adp_add_stream_to_terminal_get_defaults(struct adp_msg_add_stream_to_terminal *const config)
{
Assert(config);
config->terminal_id = 0;
config->stream_id = 0;
config->mode = 0;
adp_set_color(config->text_color, ADP_COLOR_BLACK);
adp_set_color(config->tag_text_color, ADP_COLOR_BLACK);
}
bool adp_add_stream_to_terminal(struct adp_msg_add_stream_to_terminal *const config, const char* tag_text);
/* MSG_CONF_DASHBOARD */
#define MSG_CONF_DASHBOARD 0x2A
#define MSG_CONF_DASHBOARD_LEN 7
SHORTENUM struct adp_msg_conf_dashboard {
uint16_t dashboard_id;
uint8_t color[3];
uint16_t height;
};
static inline void adp_conf_dashboard_get_defaults(struct adp_msg_conf_dashboard *const config)
{
Assert(config);
config->dashboard_id = 0;
adp_set_color(config->color, ADP_COLOR_BLACK);
config->height = 100;
}
bool adp_add_dashboard(struct adp_msg_conf_dashboard *const config, const char* label);
/* MSG_CONF_DASHBOARD_ELEMENT */
#define MSG_CONF_DASHBOARD_ELEMENT 0x2B
enum adp_dashboard_element_type {
ADP_ELEMENT_TYPE_LABEL,
ADP_ELEMENT_TYPE_BUTTON,
ADP_ELEMENT_TYPE_SLIDER,
ADP_ELEMENT_TYPE_PROGRESS,
ADP_ELEMENT_TYPE_SIGNAL,
ADP_ELEMENT_TYPE_SEGMENT,
ADP_ELEMENT_TYPE_GRAPH,
ADP_ELEMENT_TYPE_TEXT,
ADP_ELEMENT_TYPE_RADIO,
ADP_ELEMENT_TYPE_PIE,
};
#define MSG_CONF_DASHBOARD_COMMON_LEN 14
#define ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS \
uint16_t dashboard_id; \
uint16_t element_id; \
uint8_t z_index; \
uint16_t x; \
uint16_t y; \
uint16_t width; \
uint16_t height; \
enum adp_dashboard_element_type element_type
SHORTENUM struct adp_msg_conf_dashboard_element_common {
/* Dashboard ID */
uint16_t dashboard_id;
/* Unique ID of element */
uint16_t element_id;
/* Order index */
uint8_t z_index;
/* X-coordinate of element location. 0 is leftmost position on dashboard */
uint16_t x;
/* Y-coordinate of element location. 0 is topmost position on dashboard */
uint16_t y;
/* Width of element */
uint16_t width;
/* Height of element */
uint16_t height;
/* See each element type below */
enum adp_dashboard_element_type element_type;
};
static inline void adp_conf_dashboard_element_get_defaults(struct adp_msg_conf_dashboard_element_common *const config)
{
Assert(config);
config->dashboard_id = 0;
config->element_id = 0;
config->z_index = 0;
config->x = 0;
config->y = 0;
config->width = 0;
config->height = 0;
}
enum adp_label_attribute_alignment {
BOLD_OFF_ITALIC_OFF,
BOLD_ON_ITALIC_OFF,
BOLD_OFF_ITALIC_ON,
BOLD_ON_ITALIC_ON,
};
enum adp_label_horisontal_alignment {
HORISONTAL_ALIGNMENT_LEFT,
HORISONTAL_ALIGNMENT_CENTER,
HORISONTAL_ALIGNMENT_RIGHT,
};
enum adp_label_vertical_alignment {
VERTICAL_ALIGNMENT_TOP,
VERTICAL_ALIGNMENT_CENTER,
VERTICAL_ALIGNMENT_BOTTOM,
};
#define ADP_ELEMENT_TYPE_LABEL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
SHORTENUM struct adp_msg_conf_dashboard_element_label {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t font_size;
uint8_t attribute; // TODO
enum adp_label_horisontal_alignment horisontal_alignment;
enum adp_label_vertical_alignment vertical_alignment;
uint8_t background_transparency;
uint8_t background_color[3];
uint8_t foreground_transparency;
uint8_t foreground_color[3];
};
static inline void adp_conf_dashboard_label_get_defaults(struct adp_msg_conf_dashboard_element_label *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_LABEL;
config->font_size = 10;
config->attribute = 0;
config->horisontal_alignment = HORISONTAL_ALIGNMENT_LEFT;
config->vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
config->background_transparency = 0;
adp_set_color(config->background_color, ADP_COLOR_BLACK);
config->foreground_transparency = 0;
adp_set_color(config->foreground_color, ADP_COLOR_BLACK);
}
bool adp_add_label_to_dashboard(struct adp_msg_conf_dashboard_element_label *const config, const char* label);
#define ADP_ELEMENT_TYPE_BUTTON_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 1)
SHORTENUM struct adp_msg_conf_dashboard_element_button {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t font_size;
};
static inline void adp_conf_dashboard_button_get_defaults(struct adp_msg_conf_dashboard_element_button *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_BUTTON;
config->font_size = 10;
}
bool adp_add_button_to_dashboard(struct adp_msg_conf_dashboard_element_button *const config, const char* label);
#define ADP_ELEMENT_TYPE_SLIDER_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
SHORTENUM struct adp_msg_conf_dashboard_element_slider {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint32_t minimum_value;
uint32_t maximum_value;
uint32_t initial_value;
};
static inline void adp_conf_dashboard_slider_get_defaults(struct adp_msg_conf_dashboard_element_slider *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_SLIDER;
config->minimum_value = 0;
config->maximum_value = 100;
config->initial_value = 0;
}
bool adp_add_slider_to_dashboard(struct adp_msg_conf_dashboard_element_slider *const config);
#define ADP_ELEMENT_TYPE_SIGNAL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 8)
SHORTENUM struct adp_msg_conf_dashboard_element_signal {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t on_transparency;
uint8_t on_color[3];
uint8_t off_transparency;
uint8_t off_color[3];
};
static inline void adp_conf_dashboard_signal_get_defaults(struct adp_msg_conf_dashboard_element_signal *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_SIGNAL;
config->on_transparency = 0;
adp_set_color(config->on_color, ADP_COLOR_WHITE);
config->off_transparency = 0;
adp_set_color(config->off_color, ADP_COLOR_BLACK);
}
bool adp_add_signal_to_dashboard(struct adp_msg_conf_dashboard_element_signal *const config);
#define ADP_ELEMENT_TYPE_PROGRESS_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 15)
SHORTENUM struct adp_msg_conf_dashboard_element_progress {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint32_t minimum_value;
uint32_t maximum_value;
uint32_t initial_value;
uint8_t color[3];
};
static inline void adp_conf_dashboard_progress_get_defaults(struct adp_msg_conf_dashboard_element_progress *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_PROGRESS;
config->minimum_value = 0;
config->maximum_value = 100;
config->initial_value = 0;
adp_set_color(config->color, ADP_COLOR_BLACK);
}
bool adp_add_progress_to_dashboard(struct adp_msg_conf_dashboard_element_progress *const config);
#define ADP_ELEMENT_TYPE_SEGMENT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 6)
SHORTENUM struct adp_msg_conf_dashboard_element_segment {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
/* Values: 1 ~ 20 */
uint8_t segment_count;
/* Values: 2 ~ 16*/
uint8_t base;
uint8_t transparency;
uint8_t color[3];
};
static inline void adp_conf_dashboard_segment_get_defaults(struct adp_msg_conf_dashboard_element_segment *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_SEGMENT;
config->segment_count = 1;
config->base = 10;
config->transparency = 0;
adp_set_color(config->color, ADP_COLOR_BLACK);
}
bool adp_add_segment_to_dashboard(struct adp_msg_conf_dashboard_element_segment *const config);
/* MSG_CONF_ADD_GRAPH_TO_ELEMENT */
#define ADP_ELEMENT_TYPE_GRAPH_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 27)
typedef union {
struct {
uint8_t mouse:1;
uint8_t fit_graph:1;
uint8_t :6;
} bit;
uint8_t reg;
} mode_type;
SHORTENUM struct adp_msg_conf_dashboard_element_graph {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t title_color[3];
uint8_t background_color[3];
uint8_t graph_background_color[3];
uint8_t plot_count;
float x_min;
float x_max;
float y_min;
float y_max;
mode_type mode;
};
static inline void adp_conf_dashboard_graph_get_defaults(struct adp_msg_conf_dashboard_element_graph *const config)
{
adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
config->element_type = ADP_ELEMENT_TYPE_GRAPH;
adp_set_color(config->title_color, ADP_COLOR_WHITE);
adp_set_color(config->background_color, ADP_COLOR_BLACK);
adp_set_color(config->graph_background_color, ADP_COLOR_BLACK);
config->plot_count = 1;
config->x_min = 0;
config->x_max = 10;
config->y_min = 0;
config->y_max = 5;
config->mode.bit.fit_graph = 1;
config->mode.bit.mouse = 0;
}
bool adp_add_graph_to_dashboard(struct adp_msg_conf_dashboard_element_graph *const config, const char* title);
/* MSG_CONF_ADD_TEXT_TO_ELEMENT */
#define ADP_ELEMENT_TYPE_TEXT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
SHORTENUM struct adp_msg_conf_dashboard_element_text {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t minimum[4];
uint8_t maximum[4];
uint8_t value[4];
};
bool adp_add_text_to_dashboard(struct adp_msg_conf_dashboard_element_text *const config);
/* MSG_CONF_ADD_RADIO_TO_ELEMENT */
#define ADP_ELEMENT_TYPE_RADIO_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 3)
enum adp_radio_orientation {
HORIZONTAL,
VERTICAL,
};
SHORTENUM struct adp_msg_conf_dashboard_element_radio {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t font_size;
uint8_t number_items;
enum adp_radio_orientation orientation;
};
bool adp_add_radio_to_dashboard(struct adp_msg_conf_dashboard_element_radio *const config, const char* text);
/* MSG_CONF_ADD_PIE_TO_ELEMENT */
#define ADP_ELEMENT_TYPE_PIE_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 7)
SHORTENUM struct adp_msg_conf_dashboard_element_pie {
ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
uint8_t background_color[3];
uint8_t title_color[3];
uint8_t number_slices;
};
bool adp_add_pie_to_dashboard(struct adp_msg_conf_dashboard_element_pie *const config, const char* title);
/* MSG_CONF_ADD_STREAM_TO_ELEMENT */
#define MSG_CONF_ADD_STREAM_TO_ELEMENT 0x2C
#define MSG_CONF_ADD_STREAM_TO_ELEMENT_LEN 6
SHORTENUM struct adp_conf_add_stream_to_element {
uint16_t dashboard_id;
uint16_t element_id;
uint16_t stream_id;
};
bool adp_add_stream_to_element(struct adp_conf_add_stream_to_element *const config);
/* MSG_DATA_STREAM */
#define MSG_DATA_STREAM 0x40
SHORTENUM struct adp_msg_data_stream_data {
uint16_t stream_id;
uint8_t data_size;
uint8_t *data;
};
SHORTENUM struct adp_msg_data_stream {
uint8_t number_of_streams;
struct adp_msg_data_stream_data stream[ADP_MAX_OUTGOING_STREAMS];
};
bool adp_send_stream(struct adp_msg_data_stream *const stream_data, uint8_t* receive_buf);
bool adp_send_single_stream(uint8_t stream_id, uint8_t* data, uint8_t data_size, uint8_t* receive_buf);
bool adp_transceive_stream(struct adp_msg_data_stream *const stream_data, uint8_t *receive_buf);
bool adp_transceive_single_stream(uint16_t stream_id, uint8_t* data, uint8_t data_size, uint8_t* receive_buf);
/* Init SPI/TWI interface used. And some other misc init */
void adp_init(void);
uint16_t adp_add_send_byte(uint8_t* buffer, uint8_t index, uint8_t* data, uint16_t length);
#endif

View File

@ -0,0 +1,55 @@
/**
* \file
*
* \brief ADP interface header file
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef ADP_INTERFACE_H_INCLUDED
#define ADP_INTERFACE_H_INCLUDED
/* Prototypes of communication functions used to setup, send and receive data */
enum status_code adp_interface_init(void);
void adp_interface_transceive_procotol(uint8_t* tx_buf, uint16_t length, uint8_t* rx_buf);
enum status_code adp_interface_read_response(uint8_t* rx_buf, uint16_t length);
#endif

View File

@ -0,0 +1,150 @@
/**
* \file
*
* \brief ADP SPI interface implementation
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include <asf.h>
#include "adp_interface.h"
//! \name Embedded debugger SPI interface definitions
//@{
#define EDBG_SPI_MODULE SPI
//@}
#define SPI_CHIP_SEL SPI_NPCS3_PA5_GPIO
#define SPI_DEVICE_ID 3
#define SPI_BAUDRATE 1500000
struct spi_device SPI_DEVICE = {
/** Board specific select id */
.id = SPI_DEVICE_ID
};
/**
* \brief Send SPI start condition
*
*/
static void adp_interface_send_start(void)
{
spi_select_device(EDBG_SPI_MODULE, &SPI_DEVICE);
}
/**
* \brief Send SPI stop condition
*
*/
static void adp_interface_send_stop(void)
{
spi_deselect_device(EDBG_SPI_MODULE, &SPI_DEVICE);
}
/**
* \brief Sends and reads data byte on SPI
*
* \param[in] data Data byte to send
* \param[in] tx_data SPI character to transmit
* \param[out] rx_data Pointer to store the received SPI character
*/
static void adp_interface_transceive(uint8_t *tx_data, uint8_t *rx_data, uint16_t length)
{
spi_transceive_packet(EDBG_SPI_MODULE, tx_data, rx_data, length);
}
/**
* \brief Initialize EDBG SPI communication for SAM
*
*/
enum status_code adp_interface_init(void)
{
sysclk_init();
/* Configure the SPI interface */
spi_master_init(EDBG_SPI_MODULE);
spi_master_setup_device(EDBG_SPI_MODULE, &SPI_DEVICE, SPI_MODE_0,
SPI_BAUDRATE, 0);
spi_enable(EDBG_SPI_MODULE);
return STATUS_OK;
}
/**
* \brief Sends and reads protocol packet data byte on SPI
*
* \param[in] tx_buf Pointer to send the protocol packet data
* \param[in] length The length of the send protocol packet data
* \param[out] rx_buf Pointer to store the received SPI character
*/
void adp_interface_transceive_procotol(uint8_t* tx_buf, uint16_t length, uint8_t* rx_buf)
{
/* Send SPI start condition */
adp_interface_send_start();
adp_interface_transceive(tx_buf, rx_buf, length);
/* Send SPI end condition */
adp_interface_send_stop();
}
/**
* \brief Read response on SPI from PC
*
* return Status
* \param[in] rx_buf Pointer to receive the data
* \param[in] length The length of the read data
* \param[out] rx_buf Pointer to store the received SPI character
*/
enum status_code adp_interface_read_response(uint8_t* rx_buf, uint16_t length)
{
enum status_code status;
/* Send SPI start condition */
adp_interface_send_start();
status = spi_read_packet(EDBG_SPI_MODULE, rx_buf, length);
/* Send SPI end condition */
adp_interface_send_stop();
return status;
}

View File

@ -0,0 +1,127 @@
/**
* \file
*
* \brief ADP service implementation
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <asf.h>
#include "adp_interface.h"
//! \name Embedded debugger TWI interface definitions
//@{
#define EDBG_TWI_MODULE TWI0
//@}
#define TWI_EDBG_SLAVE_ADDR 0x28
#define TIMEOUT 1000
/**
* \brief Initialize EDBG TWI interface for SAM4S
*
*/
enum status_code adp_interface_init(void)
{
sysclk_init();
/* Configure the TWI interface */
twi_master_options_t opt = {
.speed = 100000,
.chip = TWI_EDBG_SLAVE_ADDR
};
return twi_master_setup(EDBG_TWI_MODULE, &opt);
}
/**
* \brief Send data on TWI
*
* \param[in] data Pointer to data to send
* \param[in] length Number of bytes to send
*/
static enum status_code adp_interface_send(uint8_t* tx_buf, uint16_t length)
{
twi_package_t packet_write = {
.chip = TWI_EDBG_SLAVE_ADDR, /* TWI slave bus address */
.buffer = tx_buf, /* transfer data source buffer */
.length = length /* transfer data size (bytes) */
};
return twi_master_write(EDBG_TWI_MODULE, &packet_write);
}
/**
* \brief Read data on TWI
*
* \param[out] data Pointer to place received data
* \param[in] length Number of bytes to receive
*/
enum status_code adp_interface_read_response(uint8_t *data, uint16_t length)
{
enum status_code status = ERR_IO_ERROR;
uint8_t data_len = 0;
twi_package_t packet_read = {
.chip = TWI_EDBG_SLAVE_ADDR, // TWI slave bus address
.buffer = &data_len, // transfer data destination buffer
.length = 1 // transfer data size (bytes)
};
twi_master_read(EDBG_TWI_MODULE, &packet_read);
if(data_len != 0){
packet_read.length = data_len;
packet_read.buffer = data;
status = twi_master_read(EDBG_TWI_MODULE, &packet_read);
}
return status;
}
/**
* \brief Sends and reads protocol packet data byte on I2C
*
* \param[in] tx_buf Pointer to send the protocol packet data
* \param[in] length The length of the send protocol packet data
* \param[out] rx_buf Pointer to store the received I2C character
*/
void adp_interface_transceive_procotol(uint8_t* tx_buf, uint16_t length, uint8_t* rx_buf)
{
adp_interface_send(tx_buf, length);
adp_interface_read_response(rx_buf, length);
}

View File

@ -0,0 +1,156 @@
/**
* \file
*
* \brief ADP service implementation
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include <system.h>
#include <asf.h>
#include "adp_interface.h"
struct spi_module edbg_spi;
struct spi_slave_inst slave;
/**
* \brief Send SPI start condition
*
*/
static void adp_interface_send_start(void)
{
spi_select_slave(&edbg_spi, &slave, true);
}
/**
* \brief Send SPI stop condition
*
*/
static void adp_interface_send_stop(void)
{
spi_select_slave(&edbg_spi, &slave, false);
}
/**
* \brief Sends and reads data byte on SPI
*
* \param[in] data Data byte to send
* \param[in] tx_data SPI character to transmit
* \param[out] rx_data Pointer to store the received SPI character
*/
static void adp_interface_transceive(uint8_t *tx_data, uint8_t *rx_data, uint16_t length)
{
spi_transceive_buffer_wait(&edbg_spi, tx_data, rx_data, length);
}
/**
* \brief Initialize EDBG SPI communication for SAM0
*
*/
enum status_code adp_interface_init(void)
{
enum status_code return_value;
system_init();
struct spi_slave_inst_config slave_dev_config;
struct spi_config config;
spi_slave_inst_get_config_defaults(&slave_dev_config);
slave_dev_config.ss_pin = (EDBG_SPI_SERCOM_PINMUX_PAD1 >> 16) & 0xFF;
spi_attach_slave(&slave, &slave_dev_config);
spi_get_config_defaults(&config);
config.mode_specific.master.baudrate = 1000000;
config.mux_setting = EDBG_SPI_SERCOM_MUX_SETTING;
config.pinmux_pad0 = EDBG_SPI_SERCOM_PINMUX_PAD0;
config.pinmux_pad1 = PINMUX_UNUSED;
config.pinmux_pad2 = EDBG_SPI_SERCOM_PINMUX_PAD2;
config.pinmux_pad3 = EDBG_SPI_SERCOM_PINMUX_PAD3;
return_value = spi_init(&edbg_spi, EDBG_SPI_MODULE, &config);
spi_enable(&edbg_spi);
return return_value;
}
/**
* \brief Sends and reads protocol packet data byte on SPI
*
* \param[in] tx_buf Pointer to send the protocol packet data
* \param[in] length The length of the send protocol packet data
* \param[out] rx_buf Pointer to store the received SPI character
*/
void adp_interface_transceive_procotol(uint8_t* tx_buf, uint16_t length, uint8_t* rx_buf)
{
/* Send SPI start condition */
adp_interface_send_start();
adp_interface_transceive(tx_buf, rx_buf, length);
/* Send SPI end condition */
adp_interface_send_stop();
}
/**
* \brief Read response on SPI from PC
*
* return Status
* \param[in] rx_buf Pointer to receive the data
* \param[in] length The length of the read data
* \param[out] rx_buf Pointer to store the received SPI character
*/
enum status_code adp_interface_read_response(uint8_t* rx_buf, uint16_t length)
{
bool status;
/* Send SPI start condition */
adp_interface_send_start();
status = spi_read_buffer_wait(&edbg_spi, rx_buf, length, 0xFF);
/* Send SPI end condition */
adp_interface_send_stop();
return status;
}

View File

@ -0,0 +1,133 @@
/**
* \file
*
* \brief ADP service implementation
*
* Copyright (C) 2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include <system.h>
#include <asf.h>
#include <adp_interface.h>
#define EDBG_TWI EDBG_I2C_MODULE
#define TWI_EDBG_SLAVE_ADDR 0x28
#define TIMEOUT 1000
struct i2c_master_module i2c_master_instance;
/**
* \brief Initialize EDBG I2C communication for SAM0
*
*/
enum status_code adp_interface_init(void)
{
enum status_code return_value;
system_init();
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
config_i2c_master.buffer_timeout = 10000;
return_value = i2c_master_init(&i2c_master_instance, EDBG_TWI, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
return return_value;
}
static enum status_code adp_interface_send(uint8_t* tx_buf, uint16_t length)
{
enum status_code status;
struct i2c_master_packet packet = {
.address = TWI_EDBG_SLAVE_ADDR,
.data_length = length,
.data = tx_buf,
};
/* Send data to PC */
status = i2c_master_write_packet_wait(&i2c_master_instance, &packet);
return status;
}
/**
* \brief Read response on I2C from PC
*
* return Status
* \param[in] rx_buf Pointer to receive the data
* \param[in] length The length of the read data
* \param[out] rx_buf Pointer to store the received SPI character
*/
enum status_code adp_interface_read_response(uint8_t* rx_buf, uint16_t length)
{
enum status_code status = STATUS_ERR_IO;
uint8_t data_len = 0;
struct i2c_master_packet packet = {
.address = TWI_EDBG_SLAVE_ADDR,
.data_length = 1,
.data = &data_len,
};
i2c_master_read_packet_wait(&i2c_master_instance, &packet);
if (data_len != 0)
{
packet.data_length = data_len;
packet.data = rx_buf;
status = i2c_master_read_packet_wait(&i2c_master_instance, &packet);
}
return status;
}
/**
* \brief Sends and reads protocol packet data byte on I2C
*
* \param[in] tx_buf Pointer to send the protocol packet data
* \param[in] length The length of the send protocol packet data
* \param[out] rx_buf Pointer to store the received I2C character
*/
void adp_interface_transceive_procotol(uint8_t* tx_buf, uint16_t length, uint8_t* rx_buf)
{
adp_interface_send(tx_buf, length);
adp_interface_read_response(rx_buf, length);
}

View File

@ -0,0 +1,492 @@
/**
* \file
*
* \brief Calendar service.
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "compiler.h"
#include "calendar.h"
#include <stdio.h>
//! Unix epoch year
#define EPOCH_YEAR 1970
//! Number of seconds in a day
#define SECS_PER_DAY 86400UL
//! Number of seconds in an hour
#define SECS_PER_HOUR 3600UL
//! Number of seconds in a minute
#define SECS_PER_MINUTE 60UL
//! Number of days in a specified month. Index 1 for leap year, else 0.
const uint8_t month[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
/**
* \internal
* \brief Check if a year is a leap year
*
* Returns true or false depending if the input year is a leap year or not.
*
* \param year the year in format YYYY to check for leap year or not
*
* \retval true if the year is a leap year
* \retval false if the year is not a leap year
*/
static bool calendar_leapyear(uint16_t year)
{
if(!((year) % 4) && (((year) % 100) || !((year) % 400))) {
return true;
} else {
return false;
}
}
/**
* \internal
* \brief Find number of days in a year
*
* Returns the number of days in a year, depending if the input is leap year
* or not.
*
* \param year the year in format YYYY to check number of days
*
* \retval 366 if the year is a leap year
* \retval 365 if the year is not a leap year
*/
static uint16_t calendar_yearsize(uint16_t year)
{
if (calendar_leapyear(year)) {
return 366;
} else {
return 365;
}
}
/**
* \internal
* \brief Add a year to a date
*
* Adds one year to specified date as long as the current year is before 2105.
*
* \param *date the date to add a year to
*
*/
static void calendar_add_year_to_date(struct calendar_date *date)
{
if (date->year < 2105) {
date->year++;
}
}
/**
* \internal
* \brief Add a month to a date
*
* Adds one month to specified date. If month is december, increment year.
*
* \param *date the date to add a month to
*
*/
static void calendar_add_month_to_date(struct calendar_date *date)
{
uint8_t months = date->month;
months++;
if (months == 12){
months = 0;
calendar_add_year_to_date(date);
}
date->month = months;
}
/**
* \internal
* \brief Add a day to a date
*
* Adds one day to specified date. If day is the last of the month, increment
* month.
*
* \param *date the date to add a day to
*
*/
static void calendar_add_day_to_date(struct calendar_date *date)
{
uint8_t dates = date->date;
uint8_t months = date->month;
uint8_t year = date->year;
dates++;
if (dates == month[calendar_leapyear(year)][months]) {
dates = 0;
calendar_add_month_to_date(date);
}
date->dayofweek++;
if (date->dayofweek == 7) {
date->dayofweek = 0;
}
date->date = dates;
}
/**
* \internal
* \brief Add an hour to a date
*
* Adds one hour to specified date. If hour is 23, increment day.
*
* \param *date the date to add an hour to
*
*/
static void calendar_add_hour_to_date(struct calendar_date *date)
{
int8_t hour = date->hour;
hour++;
if (hour == 24){
hour = 0;
calendar_add_day_to_date(date);
}
date->hour = hour;
}
/**
* \internal
* \brief Add a minute to a date
*
* Adds one minute to specified date. If minute is 59, increment hour.
*
* \param *date the date to add a minute to
*
*/
static void calendar_add_minute_to_date(struct calendar_date *date)
{
uint8_t minute = date->minute;
minute++;
if (minute == 60){
minute = 0;
calendar_add_hour_to_date(date);
}
date->minute = minute;
}
/**
* \brief Check if a date is valid
*
* Checks that number of seconds, minutes and hours is a valid value.
* Checks that number of days does not exceed number of days in current month.
* Checks that number of months is a valid value, and checks that year is
* between 1970 (epoch year) and 2106 (overflow year).
*
* \param *date the date to check if valid
*
*/
bool calendar_is_date_valid(struct calendar_date *date)
{
// Make sure time is valid
if ((date->second >= 60) || (date->minute >= 60) || (date->hour >= 24)) {
return false;
}
// Make sure month and date is valid
if ((date->month >= 12) || (date->date >=31)) {
return false;
}
// Make sure days in month are not more than it should be
if (date->date >= month[calendar_leapyear(date->year)][date->month]) {
return false;
}
// Make sure year is not earlier than 1970 and before 2106
if ((date->year < EPOCH_YEAR) || (date->year >= 2106)) {
return false;
} else {
return true;
}
}
/**
* \brief Convert a UNIX timestamp to a date
*
* Finds the corresponding date and time for a UNIX timestamp.
*
* \param timestamp UNIX timestamp
* \param date_out Date to store result
*
*/
void calendar_timestamp_to_date(uint32_t timestamp,
struct calendar_date *date_out)
{
uint32_t day_number;
uint32_t day_clock;
date_out->year = EPOCH_YEAR;
date_out->month = 0;
day_clock = timestamp % SECS_PER_DAY;
day_number = timestamp / SECS_PER_DAY;
date_out->second = day_clock % SECS_PER_MINUTE;
date_out->minute = (day_clock % SECS_PER_HOUR) / SECS_PER_MINUTE;
date_out->hour = day_clock / SECS_PER_HOUR;
date_out->dayofweek = (day_number + 4) % 7;
while (day_number >= calendar_yearsize(date_out->year)) {
day_number -= calendar_yearsize(date_out->year);
date_out->year++;
}
while (day_number >=
month[calendar_leapyear(date_out->year)][date_out->month]) {
day_number -= month[calendar_leapyear(date_out->year)][date_out->month];
date_out->month++;
}
date_out->date = day_number;
}
/**
* \brief Convert a UNIX timestamp to a date in a given time zone.
*
* The provided UNIX timestamp is converted to the corresponding time in the
* provided time zone.
*
* \param timestamp UNIX timestamp
* \param hour Hour offset from UTC (UTC-12 to UTC+14)
* \param min Minute offset from UTC (0, 15, 30, 45)
* \param date_out Date to store result
*
*/
void calendar_timestamp_to_date_tz(uint32_t timestamp, int8_t hour,
uint8_t min, struct calendar_date *date_out)
{
// Multiply timezone offset by seconds, and add to timestamp
if (hour >= 0) {
calendar_timestamp_to_date((timestamp + (SECS_PER_HOUR * hour) +
(SECS_PER_MINUTE * min)), date_out);
} else {
calendar_timestamp_to_date((timestamp + (SECS_PER_HOUR * hour) -
(SECS_PER_MINUTE * min)), date_out);
}
}
/**
* \brief Convert a date to a UNIX timestamp.
*
* \note
* If date is invalid, timestamp 0 will be returned.
*
* \param date Date
*
* \return The corresponding UNIX timestamp
* \retval 0 if date is not valid
*/
uint32_t calendar_date_to_timestamp(struct calendar_date *date)
{
// Make sure date is valid
if (!calendar_is_date_valid(date))
return 0;
uint32_t timestamp = 0;
uint8_t date_month;
uint16_t date_year;
date_month = date->month;
date_year = date->year;
// Add number of seconds elapsed in current month
timestamp += (date->date * SECS_PER_DAY) + (date->hour * SECS_PER_HOUR) +
(date->minute * SECS_PER_MINUTE) + date->second;
while (date_month != 0) {
date_month--;
// Add number of seconds in months of current year
timestamp += month[calendar_leapyear(date_year)][date_month]
* SECS_PER_DAY;
}
while (date_year > EPOCH_YEAR) {
date_year--;
// Add number of seconds in all years since epoch year
timestamp += calendar_yearsize(date_year) * SECS_PER_DAY;
}
return timestamp;
}
/**
* \brief This function converts a date in a given time zone to a UNIX
* timestamp
* \note
* If date is invalid, timestamp 0 will be returned.
*
* \param date Date
* \param hour Hour offset from UTC (UTC-12 to UTC+14)
* \param min Minute offset from UTC (0, 15, 30, 45)
*
* \return The corresponding UNIX timestamp
* \retval 0 if date is not valid
*/
uint32_t calendar_date_to_timestamp_tz(struct calendar_date *date, int8_t hour,
uint8_t min)
{
uint32_t timestamp = calendar_date_to_timestamp(date);
if (timestamp == 0) {
return 0;
} else {
// Subtract the seconds of offset in time zone offset from timestamp
if (hour >= 0) {
return (timestamp - (SECS_PER_HOUR * hour + SECS_PER_MINUTE *
min));
} else {
return (timestamp - (SECS_PER_HOUR * hour - SECS_PER_MINUTE *
min));
}
}
}
/**
* \brief This function calculates the time difference between to dates.
*
* The time difference is provided as number of years, months, days, hours,
* minutes and seconds between the dates. If end date is before start date,
* the dates are switched.
*
* \param date_end The end date
* \param date_start The start date
* \param date_out The time between the dates
*
*/
void calendar_time_between_dates(struct calendar_date *date_end,
struct calendar_date *date_start, struct calendar_date *date_out)
{
uint32_t timestamp_start;
uint32_t timestamp_end;
struct calendar_date *temp;
timestamp_start = calendar_date_to_timestamp(date_start);
timestamp_end = calendar_date_to_timestamp(date_end);
// Switch dates if date_end is before date_start
if (timestamp_end < timestamp_start) {
temp = date_end;
date_end = date_start;
date_start = temp;
}
// Calculate number of years
date_out->year = date_end->year - date_start->year;
// Check if months wrap around new year
if (date_end->month - date_start->month < 0 ) {
date_end->month += 12;
if (date_out->year != 0) {
date_out->year--;
}
}
// Calculate number of months
date_out->month = date_end->month - date_start->month;
// Check if dates wrap around month
if(date_end->date - date_start->date < 0) {
// Add number of days in last month to get number of days correct
date_end->date +=
month[calendar_leapyear(date_end->year)][date_end->month-1];
if (date_out->month != 0) {
date_out->month--;
}
}
// Calculate number of days
date_out->date = date_end->date - date_start->date;
// Check if hours wrap around midnight
if (date_end->hour - date_start->hour < 0) {
date_end->hour += 24;
if (date_out->date != 0) {
date_out->date--;
}
}
// Calculate number of hours
date_out->hour = date_end->hour - date_start->hour;
// Check if minutes wrap around hour
if (date_end->minute - date_start->minute < 0) {
date_end->minute += 60;
if (date_out->hour != 0) {
date_out->hour--;
}
}
// Calculate number of minutes
date_out->minute = date_end->minute - date_start->minute;
// Check if seconds wrap around minute
if (date_end->second - date_start->second < 0) {
date_end->second += 60;
if (date_out->minute != 0) {
date_out->minute--;
}
}
// Calculate number of seconds
date_out->second = date_end->second - date_start->second;
}
/**
* \brief Increments a date with one second.
*
* This function will add one second to specified date. If second is 59,
* it will increment minute.
*
* \param date The date to add a second to
*
*/
void calendar_add_second_to_date(struct calendar_date *date)
{
// Check if input date is valid
Assert(calendar_is_date_valid(date));
if (++date->second == 60) {
date->second = 0;
calendar_add_minute_to_date(date);
}
}

View File

@ -0,0 +1,205 @@
/**
* \file
*
* \brief Calendar.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _CALENDAR_H_INCLUDED_
#define _CALENDAR_H_INCLUDED_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/**
*
* \defgroup calendar_group Calendar service
*
* See \ref calendar_quickstart.
*
* This is the common API for a calendar service.
* It provides functionality to convert UNIX timestamps to dates and back. It
* also provides functionality for calculating the difference between dates and
* converting timestamps to dates with different time zones and back.
* \note
* This module is a pure software module, and does not interface
* hardware calendar peripherals (e.g. the AST on UC3L)
*
* @{
*/
//! Calendar structure to hold a date
struct calendar_date {
uint8_t second; //!< 0-59
uint8_t minute; //!< 0-59
uint8_t hour; //!< 0-23
uint8_t date; //!< 0-30 \note First day of month is 0, not 1.
uint8_t month; //!< 0 January - 11 December
uint16_t year; //!< 1970-2105
uint8_t dayofweek; //!< 0 Sunday - 6 Saturday
};
bool calendar_is_date_valid(struct calendar_date *date);
void calendar_timestamp_to_date(uint32_t timestamp, struct calendar_date
*date_out);
void calendar_timestamp_to_date_tz(uint32_t timestamp, int8_t hour,
uint8_t min, struct calendar_date *date_out);
uint32_t calendar_date_to_timestamp(struct calendar_date *date);
uint32_t calendar_date_to_timestamp_tz(struct calendar_date *date, int8_t hour,
uint8_t min);
void calendar_time_between_dates(struct calendar_date *date_end,
struct calendar_date *date_start, struct calendar_date *date_out);
void calendar_add_second_to_date(struct calendar_date *date);
/** @} */
#ifdef __cplusplus
}
#endif
/**
* \page calendar_quickstart Quick start guide for Calendar service
*
* This is the quick start guide for the \ref calendar_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section calendar_basic_use_case Basic use case
* \section calendar_use_cases Calendar use cases
* - \ref calendar_basic_use_case
* - \subpage calendar_use_case_1
*
* \section calendar_basic_use_case Basic use case - Calculate timestamp
*
* The use case will let the user calculate the corresponding timestamp to a
* date
*
* \section calendar_basic_use_case_setup Setup steps
*
* \subsection calendar_basic_use_case_setup_prereq Prerequisites
* For the code of this use case to work, the following must
* be added to the project:
* -# A date struct with a date:
* \code
struct calendar_date date = {
.second = 12,
.minute = 1,
.hour = 22,
.date = 8,
.month = 2,
.year = 1985
};
\endcode
*
* \subsection calendar_basic_use_case_setup_code Example code
* No setup code is needed, the service is ready for use as-is.
*
* \section calendar_basic_use_case_usage Usage steps
*
* \subsection calendar_basic_use_case_usage_code Example code
* Add to, e.g. the main loop in the application C-file:
* \code uint32_t timestamp = calendar_date_to_timestamp(&date); \endcode
*
* \subsection calendar_basic_use_case_usage_flow Workflow
* -# Convert date to timestamp:
* - \code uint32_t timestamp = calendar_date_to_timestamp(&date); \endcode
*/
/**
* \page calendar_use_case_1 Calculate time between dates
*
* The use case will let the user calculate the time between two dates, by
* first calculating the dates from two timestamps.
*
* \section calendar_use_case_1_setup Setup steps
*
* \subsection calendar_use_case_1_setup_prereq Prerequisites
* For the code of this use case to work, the following must
* be added to the project:
* -# Three date structs:
* \code
struct calendar_date result;
struct calendar_date end_date;
struct calendar_date start_date;
\endcode
* -# Two timestamps:
* \code
uint32_t end_timestamp = 1309174659;
uint32_t start_timestamp = 123456789;
\endcode
*
* \subsection calendar_use_case_1_setup_code Example code
* No setup code is needed, the service is ready for use as-is.
*
* \section calendar_use_case_1_usage Usage steps
*
* \subsection calendar_use_case_1_usage_code Example code
* Add to, e.g. the main loop in the application C-file:
* \code
calendar_timestamp_to_date(end_timestamp, &end_date);
calendar_timestamp_to_date(start_timestamp, &start_date);
calendar_time_between_dates(&end_date, &start_date, &result);
\endcode
*
* \subsection calendar_use_case_1_usage_flow Workflow
* -# Convert the end timestamp to date:
* - \code calendar_timestamp_to_date(end_timestamp, &end_date); \endcode
* -# Convert the start timestamp to date:
* - \code calendar_timestamp_to_date(start_timestamp, &start_date); \endcode
* -# Calculate the time between the two dates:
* - \code calendar_time_between_dates(&end_date, &start_date, &result);
\endcode
*/
#endif /* _CALENDAR_H_INCLUDED_ */

View File

@ -0,0 +1,402 @@
/**
* \file
*
* \brief DFLL management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CLK_DFLL_H_INCLUDED
#define CLK_DFLL_H_INCLUDED
#include <parts.h>
#include "conf_clock.h"
#if UC3L
# include "uc3l/dfll.h"
#elif SAM4L
# include "sam4l/dfll.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup dfll_group DFLL Management
*
* A Digital Frequency Locked Loop can be used to generate a highly
* accurate frequency from a slower-running reference clock, in much the
* same way as a PLL. DFLLs typically have shorter startup times and
* less jitter. They can also be used in open-loop mode to generate a
* less accurate frequency without the use of a reference clock.
*
* There may be significant variations between platforms in the support
* for certain features.
*
* \par Example: Setting up DFLL0 with default parameters and dithering enabled
*
* The following example shows how to configure and enable DFLL0 in
* closed-loop mode using the default parameters specified through
* configuration symbols.
* \code
dfll_enable_config_defaults(0); \endcode
*
* To configure and enable DFLL0 in closed-loop mode using the default
* parameters and to enable specific feature like dithering for better accuracy,
* you can use this initialization process.
* \code
struct dfll_config dfllcfg;
dfll_enable_source(CONFIG_DFLL0_SOURCE);
dfll_config_defaults(&dfllcfg, 0);
dfll_config_enable_dithering(&dfllcfg);
dfll_enable(&dfllcfg, 0);
dfll_wait_for_accurate_lock(0); \endcode
*
* When the last function call returns, DFLL0 is running at a frequency
* which matches the default configuration as accurately as possible.
* Any additional alterations to the default configuration can be added
* at the same place as the call to dfll_config_enable_dithering(), but
* note that the DFLL will never achieve "accurate" lock if dithering is
* disabled.
*
* @{
*/
//! \name Chip-specific DFLL characteristics
//@{
/**
* \def NR_DFLLS
* \brief Number of on-chip DFLLs.
*/
/**
* \def DFLL_MIN_HZ
* \brief Minimum frequency that the DFLL can generate.
*/
/**
* \def DFLL_MAX_HZ
* \brief Maximum frequency that the DFLL can generate.
*/
//@}
/**
* \typedef dfll_refclk_t
* \brief Type used for identifying a reference clock source for the DFLL.
*/
//! \name DFLL Configuration
//@{
/**
* \struct dfll_config
* \brief Hardware-specific representation of DFLL configuration.
*
* This structure contains one or more device-specific values
* representing the current DFLL configuration. The contents of this
* structure is typically different from platform to platform, and the
* user should not access any fields except through the DFLL
* configuration API.
*/
/**
* \fn void dfll_config_init_open_loop_mode(struct dfll_config *cfg)
* \brief Configure the DFLL configuration \a cfg for open-loop mode.
*
* \param cfg The DFLL configuration to be initialized.
*/
/**
* \fn void dfll_config_init_closed_loop_mode(struct dfll_config *cfg,
* dfll_refclk_t refclk, uint16_t div, uint16_t mul)
* \brief Configure the DFLL configuration \a cfg for closed-loop mode.
*
* \param cfg The DFLL configuration to be initialized.
* \param refclk The reference clock source.
* \param div Reference clock divider.
* \param mul Multiplier (integer part only).
*/
/**
* \def dfll_config_defaults(cfg, dfll_id)
* \brief Initialize DFLL configuration using default parameters.
*
* After this function returns, \a cfg will contain a configuration
* which will make the DFLL run at (CONFIG_DFLLx_MUL / CONFIG_DFLLx_DIV)
* times the frequency of CONFIG_DFLLx_SOURCE. The default configuration
* will always use closed-loop mode with no fractional multiplier.
*
* \param cfg The DFLL configuration to be initialized.
* \param dfll_id Use defaults for this DFLL.
*/
/**
* \def dfll_get_default_rate(dfll_id)
* \brief Return the default rate in Hz of \a dfll_id.
*/
/**
* \fn void dfll_config_set_fractional_multiplier(struct dfll_config *cfg,
* uint16_t mul_i, uint16_t mul_f)
* \brief Set a fractional multiplier.
*
* This function has no effect in open-loop mode, and is only available
* on devices which support fractional multipliers.
*
* The fractional part of the multiplier is assumed to be 16 bits. The
* low-level driver will make sure to shift this value to match the
* hardware if necessary.
*
* \param cfg The DFLL configuration to be modified.
* \param mul_i Integer part of multiplier.
* \param mul_f Fractional part of multiplier.
*/
/**
* \fn void dfll_config_enable_dithering(struct dfll_config *cfg)
* \brief Enable dithering for more accurate frequency generation.
*
* The fine LSB input to the VCO is dithered to achieve fractional
* approximation to the correct multiplication ratio.
*
* \param cfg The DFLL configuration to be modified.
*/
/**
* \fn void dfll_config_disable_dithering(struct dfll_config *cfg)
* \brief Disable dithering.
*
* \see dfll_config_enable_dithering()
*
* \param cfg The DFLL configuration to be modified.
*/
/**
* \fn void dfll_config_set_initial_tuning(struct dfll_config *cfg,
* uint16_t coarse, uint16_t fine)
* \brief Set initial VCO tuning.
*
* In open loop mode, this will determine the frequency of the output.
*
* In closed loop mode, this will provide an initial estimate of the VCO
* tuning. While the DFLL will automatically adjust these values to
* match the desired output frequency, careful selection of initial
* values might reduce the time to achieve coarse and fine lock.
*
* \param cfg The DFLL configuration to be modified.
* \param coarse Coarse tuning of the frequency generator.
* \param fine Fine tuning of the frequency generator.
*/
/**
* \fn void dfll_config_set_max_step(struct dfll_config *cfg,
* uint16_t coarse, uint16_t fine)
* \brief Set the maximum VCO tuning step size.
*
* This function has no effect in open-loop mode.
*
* By default, both of these values are set to 50% of their respective
* maximums. It is not recommended to set the values any higher than
* this, but setting them lower might reduce the frequency overshoot at
* the expense of longer time to achieve coarse and/or fine lock.
*
* \param cfg The DFLL configuration to be modified
* \param coarse The maximum step size of the coarse VCO tuning.
* \param fine The maximum step size of the fine VCO tuning.
*/
/**
* \fn void dfll_config_enable_ssg(struct dfll_config *cfg,
* uint16_t amplitude, uint16_t step_size)
* \brief Enable Spread Spectrum Generator.
*
* \param cfg The DFLL configuration to be modified.
* \param amplitude The amplitude of the spread spectrum.
* \param step_size The step size of the spread spectrum.
*/
/**
* \fn void dfll_config_disable_ssg(struct dfll_config *cfg)
* \brief Disable Spread Spectrum Generator.
*
* \param cfg The DFLL configuration to be modified.
*/
//@}
//! \name Interaction with the DFLL hardware
//@{
/**
* \fn void dfll_enable_open_loop(const struct dfll_config *cfg,
* unsigned int dfll_id)
* \brief Activate the configuration \a cfg and enable DFLL \a dfll_id
* in open-loop mode.
*
* \pre The configuration in \a cfg must represent an open-loop
* configuration.
*
* \param cfg The configuration to be activated.
* \param dfll_id The ID of the DFLL to be enabled.
*/
/**
* \fn void dfll_enable_closed_loop(const struct dfll_config *cfg,
* unsigned int dfll_id)
* \brief Activate the configuration \a cfg and enable DFLL \a dfll_id
* in closed-loop mode.
*
* \pre The configuration in \a cfg must represent a closed-loop
* configuration.
*
* \param cfg The configuration to be activated.
* \param dfll_id The ID of the DFLL to be enabled.
*/
/**
* \fn void dfll_disable_open_loop(unsigned int dfll_id)
* \brief Disable the DFLL identified by \a dfll_id.
*
* \pre The DFLL must have been enabled in open loop mode.
*
* \param dfll_id The ID of the DFLL to be disabled.
*/
/**
* \fn void dfll_disable_closed_loop(unsigned int dfll_id)
* \brief Disable the DFLL identified by \a dfll_id.
*
* \pre The DFLL must have been enabled in closed loop mode.
*
* \param dfll_id The ID of the DFLL to be disabled.
*/
/**
* \fn bool dfll_is_coarse_locked(unsigned int dfll_id)
* \brief Determine whether or not a DFLL has achieved coarse lock.
*
* \param dfll_id The ID of the DFLL to check.
*
* \retval true The DFLL has determined the final value of the coarse
* VCO tuning value.
* \retval false The DFLL has not yet determined the coarse VCO tuning
* value, or has not been enabled.
*/
/**
* \fn bool dfll_is_fine_locked(unsigned int dfll_id)
* \brief Determine whether or not a DFLL has achieved fine lock.
*
* \param dfll_id The ID of the DFLL to check.
*
* \retval true The DFLL has determined the final value of the fine VCO
* tuning value.
* \retval false The DFLL has not yet determined the fine VCO tuning
* value, or has not been enabled.
*/
/**
* \fn bool dfll_is_accurate_locked(unsigned int dfll_id)
* \brief Determine whether or not a DFLL has achieved accurate lock.
*
* \param dfll_id The ID of the DFLL to check.
*
* \retval true The DFLL has determined the final dithering duty cycle.
* \retval false The DFLL has not yet determined the dithering duty
* cycle, or has not been enabled with dithering enabled.
*/
/**
* \fn void dfll_enable_source(enum dfll_refclk_t src)
* \brief Enable the source of the dfll.
* The source is enabled, if the source is not already running.
*
* \param dfll_source src The ID of the DFLL source to enable.
*/
/**
* \fn void dfll_enable_config_defaults(unsigned int dfll_id)
* \brief Enable the dfll with the default configuration.
* DFLL is enabled, if the DFLL is not already locked.
*
* \param dfll_id The ID of the DFLL to enable.
*/
/**
* \brief Wait for the DFLL identified by \a dfll_id to achieve coarse
* lock.
*
* \param dfll_id The ID of the DFLL to wait for.
*
* \retval STATUS_OK The DFLL has achieved coarse lock.
* \retval ERR_TIMEOUT Timed out waiting for lock.
*/
static inline int dfll_wait_for_coarse_lock(unsigned int dfll_id)
{
/* TODO: Add timeout mechanism */
while (!dfll_is_coarse_locked(dfll_id)) {
/* Do nothing */
}
return 0;
}
/**
* \brief Wait for the DFLL identified by \a dfll_id to achieve fine
* lock.
*
* \param dfll_id The ID of the DFLL to wait for.
*
* \retval STATUS_OK The DFLL has achieved fine lock.
* \retval ERR_TIMEOUT Timed out waiting for lock.
*/
static inline int dfll_wait_for_fine_lock(unsigned int dfll_id)
{
/* TODO: Add timeout mechanism */
while (!dfll_is_fine_locked(dfll_id)) {
/* Do nothing */
}
return 0;
}
/**
* \brief Wait for the DFLL identified by \a dfll_id to achieve accurate
* lock.
*
* \param dfll_id The ID of the DFLL to wait for.
*
* \retval STATUS_OK The DFLL has achieved accurate lock.
* \retval ERR_TIMEOUT Timed out waiting for lock.
*/
static inline int dfll_wait_for_accurate_lock(unsigned int dfll_id)
{
/* TODO: Add timeout mechanism */
while (!dfll_is_accurate_locked(dfll_id)) {
/* Do nothing */
}
return 0;
}
//@}
//! @}
#endif /* CLK_DFLL_H_INCLUDED */

View File

@ -0,0 +1,199 @@
/**
* \file
*
* \brief Generic clock management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CLK_GENCLK_H_INCLUDED
#define CLK_GENCLK_H_INCLUDED
#include "parts.h"
#if SAM3S
# include "sam3s/genclk.h"
#elif SAM3U
# include "sam3u/genclk.h"
#elif SAM3N
# include "sam3n/genclk.h"
#elif SAM3XA
# include "sam3x/genclk.h"
#elif SAM4S
# include "sam4s/genclk.h"
#elif SAM4L
# include "sam4l/genclk.h"
#elif SAM4E
# include "sam4e/genclk.h"
#elif SAM4N
# include "sam4n/genclk.h"
#elif SAM4C
# include "sam4c/genclk.h"
#elif SAM4CM
# include "sam4cm/genclk.h"
#elif SAM4CP
# include "sam4cp/genclk.h"
#elif SAMG
# include "samg/genclk.h"
#elif SAMV71
# include "samv71/genclk.h"
#elif SAMV70
# include "samv70/genclk.h"
#elif SAME70
# include "same70/genclk.h"
#elif SAMS70
# include "sams70/genclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/genclk.h"
#elif UC3A3
# include "uc3a3_a4/genclk.h"
#elif UC3B
# include "uc3b0_b1/genclk.h"
#elif UC3C
# include "uc3c/genclk.h"
#elif UC3D
# include "uc3d/genclk.h"
#elif UC3L
# include "uc3l/genclk.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup genclk_group Generic Clock Management
*
* Generic clocks are configurable clocks which run outside the system
* clock domain. They are often connected to peripherals which have an
* asynchronous component running independently of the bus clock, e.g.
* USB controllers, low-power timers and RTCs, etc.
*
* Note that not all platforms have support for generic clocks; on such
* platforms, this API will not be available.
*
* @{
*/
/**
* \def GENCLK_DIV_MAX
* \brief Maximum divider supported by the generic clock implementation
*/
/**
* \enum genclk_source
* \brief Generic clock source ID
*
* Each generic clock may be generated from a different clock source.
* These are the available alternatives provided by the chip.
*/
//! \name Generic clock configuration
//@{
/**
* \struct genclk_config
* \brief Hardware representation of a set of generic clock parameters
*/
/**
* \fn void genclk_config_defaults(struct genclk_config *cfg,
* unsigned int id)
* \brief Initialize \a cfg to the default configuration for the clock
* identified by \a id.
*/
/**
* \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id)
* \brief Read the currently active configuration of the clock
* identified by \a id into \a cfg.
*/
/**
* \fn void genclk_config_write(const struct genclk_config *cfg,
* unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id.
*/
/**
* \fn void genclk_config_set_source(struct genclk_config *cfg,
* enum genclk_source src)
* \brief Select a new source clock \a src in configuration \a cfg.
*/
/**
* \fn void genclk_config_set_divider(struct genclk_config *cfg,
* unsigned int divider)
* \brief Set a new \a divider in configuration \a cfg.
*/
/**
* \fn void genclk_enable_source(enum genclk_source src)
* \brief Enable the source clock \a src used by a generic clock.
*/
//@}
//! \name Enabling and disabling Generic Clocks
//@{
/**
* \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id and enable it.
*/
/**
* \fn void genclk_disable(unsigned int id)
* \brief Disable the generic clock identified by \a id.
*/
//@}
/**
* \brief Enable the configuration defined by \a src and \a divider
* for the generic clock identified by \a id.
*
* \param id The ID of the generic clock.
* \param src The source clock of the generic clock.
* \param divider The divider used to generate the generic clock.
*/
static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider)
{
struct genclk_config gcfg;
genclk_config_defaults(&gcfg, id);
genclk_enable_source(src);
genclk_config_set_source(&gcfg, src);
genclk_config_set_divider(&gcfg, divider);
genclk_enable(&gcfg, id);
}
//! @}
#endif /* CLK_GENCLK_H_INCLUDED */

View File

@ -0,0 +1,185 @@
/**
* \file
*
* \brief Oscillator management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef OSC_H_INCLUDED
#define OSC_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/osc.h"
#elif SAM3XA
# include "sam3x/osc.h"
#elif SAM3U
# include "sam3u/osc.h"
#elif SAM3N
# include "sam3n/osc.h"
#elif SAM4S
# include "sam4s/osc.h"
#elif SAM4E
# include "sam4e/osc.h"
#elif SAM4C
# include "sam4c/osc.h"
#elif SAM4CM
# include "sam4cm/osc.h"
#elif SAM4CP
# include "sam4cp/osc.h"
#elif SAM4L
# include "sam4l/osc.h"
#elif SAM4N
# include "sam4n/osc.h"
#elif SAMG
# include "samg/osc.h"
#elif SAMV71
# include "samv71/osc.h"
#elif SAMV70
# include "samv70/osc.h"
#elif SAME70
# include "same70/osc.h"
#elif SAMS70
# include "sams70/osc.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/osc.h"
#elif UC3A3
# include "uc3a3_a4/osc.h"
#elif UC3B
# include "uc3b0_b1/osc.h"
#elif UC3C
# include "uc3c/osc.h"
#elif UC3D
# include "uc3d/osc.h"
#elif UC3L
# include "uc3l/osc.h"
#elif XMEGA
# include "xmega/osc.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup osc_group Oscillator Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip oscillators. Internal RC-oscillators,
* external crystal oscillators and external clock generators are
* supported by this module. What all of these have in common is that
* they swing at a fixed, nominal frequency which is normally not
* adjustable.
*
* \par Example: Enabling an oscillator
*
* The following example demonstrates how to enable the external
* oscillator on XMEGA A and wait for it to be ready to use. The
* oscillator identifiers are platform-specific, so while the same
* procedure is used on all platforms, the parameter to osc_enable()
* will be different from device to device.
* \code
osc_enable(OSC_ID_XOSC);
osc_wait_ready(OSC_ID_XOSC); \endcode
*
* \section osc_group_board Board-specific Definitions
* If external oscillators are used, the board code must provide the
* following definitions for each of those:
* - \b BOARD_<osc name>_HZ: The nominal frequency of the oscillator.
* - \b BOARD_<osc name>_STARTUP_US: The startup time of the
* oscillator in microseconds.
* - \b BOARD_<osc name>_TYPE: The type of oscillator connected, i.e.
* whether it's a crystal or external clock, and sometimes what kind
* of crystal it is. The meaning of this value is platform-specific.
*
* @{
*/
//! \name Oscillator Management
//@{
/**
* \fn void osc_enable(uint8_t id)
* \brief Enable oscillator \a id
*
* The startup time and mode value is automatically determined based on
* definitions in the board code.
*/
/**
* \fn void osc_disable(uint8_t id)
* \brief Disable oscillator \a id
*/
/**
* \fn osc_is_ready(uint8_t id)
* \brief Determine whether oscillator \a id is ready.
* \retval true Oscillator \a id is running and ready to use as a clock
* source.
* \retval false Oscillator \a id is not running.
*/
/**
* \fn uint32_t osc_get_rate(uint8_t id)
* \brief Return the frequency of oscillator \a id in Hz
*/
#ifndef __ASSEMBLY__
/**
* \brief Wait until the oscillator identified by \a id is ready
*
* This function will busy-wait for the oscillator identified by \a id
* to become stable and ready to use as a clock source.
*
* \param id A number identifying the oscillator to wait for.
*/
static inline void osc_wait_ready(uint8_t id)
{
while (!osc_is_ready(id)) {
/* Do nothing */
}
}
#endif /* __ASSEMBLY__ */
//@}
//! @}
#endif /* OSC_H_INCLUDED */

View File

@ -0,0 +1,341 @@
/**
* \file
*
* \brief PLL management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CLK_PLL_H_INCLUDED
#define CLK_PLL_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/pll.h"
#elif SAM3XA
# include "sam3x/pll.h"
#elif SAM3U
# include "sam3u/pll.h"
#elif SAM3N
# include "sam3n/pll.h"
#elif SAM4S
# include "sam4s/pll.h"
#elif SAM4E
# include "sam4e/pll.h"
#elif SAM4C
# include "sam4c/pll.h"
#elif SAM4CM
# include "sam4cm/pll.h"
#elif SAM4CP
# include "sam4cp/pll.h"
#elif SAM4L
# include "sam4l/pll.h"
#elif SAM4N
# include "sam4n/pll.h"
#elif SAMG
# include "samg/pll.h"
#elif SAMV71
# include "samv71/pll.h"
#elif SAMV70
# include "samv70/pll.h"
#elif SAME70
# include "same70/pll.h"
#elif SAMS70
# include "sams70/pll.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/pll.h"
#elif UC3A3
# include "uc3a3_a4/pll.h"
#elif UC3B
# include "uc3b0_b1/pll.h"
#elif UC3C
# include "uc3c/pll.h"
#elif UC3D
# include "uc3d/pll.h"
#elif (UC3L0128 || UC3L0256 || UC3L3_L4)
# include "uc3l/pll.h"
#elif XMEGA
# include "xmega/pll.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup pll_group PLL Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip PLLs. A PLL will take an input signal
* (the \em source), optionally divide the frequency by a configurable
* \em divider, and then multiply the frequency by a configurable \em
* multiplier.
*
* Some devices don't support input dividers; specifying any other
* divisor than 1 on these devices will result in an assertion failure.
* Other devices may have various restrictions to the frequency range of
* the input and output signals.
*
* \par Example: Setting up PLL0 with default parameters
*
* The following example shows how to configure and enable PLL0 using
* the default parameters specified using the configuration symbols
* listed above.
* \code
pll_enable_config_defaults(0); \endcode
*
* To configure, enable PLL0 using the default parameters and to disable
* a specific feature like Wide Bandwidth Mode (a UC3A3-specific
* PLL option.), you can use this initialization process.
* \code
struct pll_config pllcfg;
if (pll_is_locked(pll_id)) {
return; // Pll already running
}
pll_enable_source(CONFIG_PLL0_SOURCE);
pll_config_defaults(&pllcfg, 0);
pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE);
pll_enable(&pllcfg, 0);
pll_wait_for_lock(0); \endcode
*
* When the last function call returns, PLL0 is ready to be used as the
* main system clock source.
*
* \section pll_group_config Configuration Symbols
*
* Each PLL has a set of default parameters determined by the following
* configuration symbols in the application's configuration file:
* - \b CONFIG_PLLn_SOURCE: The default clock source connected to the
* input of PLL \a n. Must be one of the values defined by the
* #pll_source enum.
* - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL
* \a n.
* - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n.
*
* These configuration symbols determine the result of calling
* pll_config_defaults() and pll_get_default_rate().
*
* @{
*/
//! \name Chip-specific PLL characteristics
//@{
/**
* \def PLL_MAX_STARTUP_CYCLES
* \brief Maximum PLL startup time in number of slow clock cycles
*/
/**
* \def NR_PLLS
* \brief Number of on-chip PLLs
*/
/**
* \def PLL_MIN_HZ
* \brief Minimum frequency that the PLL can generate
*/
/**
* \def PLL_MAX_HZ
* \brief Maximum frequency that the PLL can generate
*/
/**
* \def PLL_NR_OPTIONS
* \brief Number of PLL option bits
*/
//@}
/**
* \enum pll_source
* \brief PLL clock source
*/
//! \name PLL configuration
//@{
/**
* \struct pll_config
* \brief Hardware-specific representation of PLL configuration.
*
* This structure contains one or more device-specific values
* representing the current PLL configuration. The contents of this
* structure is typically different from platform to platform, and the
* user should not access any fields except through the PLL
* configuration API.
*/
/**
* \fn void pll_config_init(struct pll_config *cfg,
* enum pll_source src, unsigned int div, unsigned int mul)
* \brief Initialize PLL configuration from standard parameters.
*
* \note This function may be defined inline because it is assumed to be
* called very few times, and usually with constant parameters. Inlining
* it will in such cases reduce the code size significantly.
*
* \param cfg The PLL configuration to be initialized.
* \param src The oscillator to be used as input to the PLL.
* \param div PLL input divider.
* \param mul PLL loop divider (i.e. multiplier).
*
* \return A configuration which will make the PLL run at
* (\a mul / \a div) times the frequency of \a src
*/
/**
* \def pll_config_defaults(cfg, pll_id)
* \brief Initialize PLL configuration using default parameters.
*
* After this function returns, \a cfg will contain a configuration
* which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV)
* times the frequency of CONFIG_PLLx_SOURCE.
*
* \param cfg The PLL configuration to be initialized.
* \param pll_id Use defaults for this PLL.
*/
/**
* \def pll_get_default_rate(pll_id)
* \brief Get the default rate in Hz of \a pll_id
*/
/**
* \fn void pll_config_set_option(struct pll_config *cfg,
* unsigned int option)
* \brief Set the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be set.
*/
/**
* \fn void pll_config_clear_option(struct pll_config *cfg,
* unsigned int option)
* \brief Clear the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be cleared.
*/
/**
* \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id)
* \brief Read the currently active configuration of \a pll_id.
*
* \param cfg The configuration object into which to store the currently
* active configuration.
* \param pll_id The ID of the PLL to be accessed.
*/
/**
* \fn void pll_config_write(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg on \a pll_id
*
* \param cfg The configuration object representing the PLL
* configuration to be activated.
* \param pll_id The ID of the PLL to be updated.
*/
//@}
//! \name Interaction with the PLL hardware
//@{
/**
* \fn void pll_enable(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg and enable PLL \a pll_id.
*
* \param cfg The PLL configuration to be activated.
* \param pll_id The ID of the PLL to be enabled.
*/
/**
* \fn void pll_disable(unsigned int pll_id)
* \brief Disable the PLL identified by \a pll_id.
*
* After this function is called, the PLL identified by \a pll_id will
* be disabled. The PLL configuration stored in hardware may be affected
* by this, so if the caller needs to restore the same configuration
* later, it should either do a pll_config_read() before disabling the
* PLL, or remember the last configuration written to the PLL.
*
* \param pll_id The ID of the PLL to be disabled.
*/
/**
* \fn bool pll_is_locked(unsigned int pll_id)
* \brief Determine whether the PLL is locked or not.
*
* \param pll_id The ID of the PLL to check.
*
* \retval true The PLL is locked and ready to use as a clock source
* \retval false The PLL is not yet locked, or has not been enabled.
*/
/**
* \fn void pll_enable_source(enum pll_source src)
* \brief Enable the source of the pll.
* The source is enabled, if the source is not already running.
*
* \param src The ID of the PLL source to enable.
*/
/**
* \fn void pll_enable_config_defaults(unsigned int pll_id)
* \brief Enable the pll with the default configuration.
* PLL is enabled, if the PLL is not already locked.
*
* \param pll_id The ID of the PLL to enable.
*/
/**
* \brief Wait for PLL \a pll_id to become locked
*
* \todo Use a timeout to avoid waiting forever and hanging the system
*
* \param pll_id The ID of the PLL to wait for.
*
* \retval STATUS_OK The PLL is now locked.
* \retval ERR_TIMEOUT Timed out waiting for PLL to become locked.
*/
static inline int pll_wait_for_lock(unsigned int pll_id)
{
Assert(pll_id < NR_PLLS);
while (!pll_is_locked(pll_id)) {
/* Do nothing */
}
return 0;
}
//@}
//! @}
#endif /* CLK_PLL_H_INCLUDED */

View File

@ -0,0 +1,194 @@
/**
* \file
*
* \brief System clock management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SYSCLK_H_INCLUDED
#define SYSCLK_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/sysclk.h"
#elif SAM3U
# include "sam3u/sysclk.h"
#elif SAM3N
# include "sam3n/sysclk.h"
#elif SAM3XA
# include "sam3x/sysclk.h"
#elif SAM4S
# include "sam4s/sysclk.h"
#elif SAM4E
# include "sam4e/sysclk.h"
#elif SAM4C
# include "sam4c/sysclk.h"
#elif SAM4CM
# include "sam4cm/sysclk.h"
#elif SAM4CP
# include "sam4cp/sysclk.h"
#elif SAM4L
# include "sam4l/sysclk.h"
#elif SAM4N
# include "sam4n/sysclk.h"
#elif SAMG
# include "samg/sysclk.h"
#elif SAMV71
# include "samv71/sysclk.h"
#elif SAMV70
# include "samv70/sysclk.h"
#elif SAME70
# include "same70/sysclk.h"
#elif SAMS70
# include "sams70/sysclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/sysclk.h"
#elif UC3A3
# include "uc3a3_a4/sysclk.h"
#elif UC3B
# include "uc3b0_b1/sysclk.h"
#elif UC3C
# include "uc3c/sysclk.h"
#elif UC3D
# include "uc3d/sysclk.h"
#elif UC3L
# include "uc3l/sysclk.h"
#elif XMEGA
# include "xmega/sysclk.h"
#elif MEGA
# include "mega/sysclk.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup clk_group Clock Management
*/
/**
* \ingroup clk_group
* \defgroup sysclk_group System Clock Management
*
* See \ref sysclk_quickstart.
*
* The <em>sysclk</em> API covers the <em>system clock</em> and all
* clocks derived from it. The system clock is a chip-internal clock on
* which all <em>synchronous clocks</em>, i.e. CPU and bus/peripheral
* clocks, are based. The system clock is typically generated from one
* of a variety of sources, which may include crystal and RC oscillators
* as well as PLLs. The clocks derived from the system clock are
* sometimes also known as <em>synchronous clocks</em>, since they
* always run synchronously with respect to each other, as opposed to
* <em>generic clocks</em> which may run from different oscillators or
* PLLs.
*
* Most applications should simply call sysclk_init() to initialize
* everything related to the system clock and its source (oscillator,
* PLL or DFLL), and leave it at that. More advanced applications, and
* platform-specific drivers, may require additional services from the
* clock system, some of which may be platform-specific.
*
* \section sysclk_group_platform Platform Dependencies
*
* The sysclk API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms with the same
* parameters and functionality. These functions may be called freely by
* portable applications, drivers and services:
* - sysclk_init()
* - sysclk_set_source()
* - sysclk_get_main_hz()
* - sysclk_get_cpu_hz()
* - sysclk_get_peripheral_bus_hz()
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behavior. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - sysclk_enable_peripheral_clock()
* - sysclk_disable_peripheral_clock()
* - sysclk_enable_module()
* - sysclk_disable_module()
* - sysclk_module_is_enabled()
* - sysclk_set_prescalers()
*
* All other functions should be considered platform-specific.
* Enabling/disabling clocks to specific peripherals as well as
* determining the speed of these clocks should be done by calling
* functions provided by the driver for that peripheral.
*
* @{
*/
//! \name System Clock Initialization
//@{
/**
* \fn void sysclk_init(void)
* \brief Initialize the synchronous clock system.
*
* This function will initialize the system clock and its source. This
* includes:
* - Mask all synchronous clocks except for any clocks which are
* essential for normal operation (for example internal memory
* clocks).
* - Set up the system clock prescalers as specified by the
* application's configuration file.
* - Enable the clock source specified by the application's
* configuration file (oscillator or PLL) and wait for it to become
* stable.
* - Set the main system clock source to the clock specified by the
* application's configuration file.
*
* Since all non-essential peripheral clocks are initially disabled, it
* is the responsibility of the peripheral driver to re-enable any
* clocks that are needed for normal operation.
*/
//@}
//! @}
#endif /* SYSCLK_H_INCLUDED */

View File

@ -0,0 +1,399 @@
/**
* \file
*
* \brief CPU reset cause functions
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef COMMON_DRIVERS_CPU_RESET_CAUSE_H
#define COMMON_DRIVERS_CPU_RESET_CAUSE_H
#include <parts.h>
#include <stdbool.h>
#if XMEGA
# include "xmega_reset_cause.h"
#elif UC3
# include "avr32_reset_cause.h"
#elif SAM4L
# include "sam4l_reset_cause.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup reset_cause_group CPU reset cause
*
* See \ref reset_cause_quickstart
*
* This is a generic interface for getting and clearing the chip reset causes.
*
* \section dependencies Dependencies
*
* The reset cause interface does not depend on any other modules, as it only
* accesses a few registers in the device core.
*
* On the other hand, the software reset call might depend on \ref sysclk_group
* to enable the clock to the debug system, for devices doing software reset
* through the on-chip debug system. This applies only to the 32-bit AVR
* devices.
*
* \section Quick start guide
* See \ref reset_cause_quickstart
*
* @{
*/
/*
* Sanity check of reset causes, define undefined reset causes to 0. Hence they
* will always return false when queried.
*/
#ifndef CHIP_RESET_CAUSE_BOD_CPU
/**
* \brief Brown-out detected on CPU power domain reset cause not available on
* this chip.
*/
# define CHIP_RESET_CAUSE_BOD_CPU 0
#endif
#ifndef CHIP_RESET_CAUSE_BOD_IO
/**
* \brief Brown-out detected on I/O power domain reset cause not available on
* this chip.
*/
# define CHIP_RESET_CAUSE_BOD_IO 0
#endif
#ifndef CHIP_RESET_CAUSE_CPU_ERROR
//! CPU error reset cause not available on this chip.
# define CHIP_RESET_CAUSE_CPU_ERROR 0
#endif
#ifndef CHIP_RESET_CAUSE_EXTRST
//! External reset cause not available on this chip.
# define CHIP_RESET_CAUSE_EXTRST 0
#endif
#ifndef CHIP_RESET_CAUSE_JTAG
//! JTAG reset cause not available on this chip.
# define CHIP_RESET_CAUSE_JTAG 0
#endif
#ifndef CHIP_RESET_CAUSE_OCD
//! On-chip debug system reset cause not available on this chip.
# define CHIP_RESET_CAUSE_OCD 0
#endif
#ifndef CHIP_RESET_CAUSE_POR
//! Power-on-reset reset cause not available on this chip.
# define CHIP_RESET_CAUSE_POR 0
#endif
#ifndef CHIP_RESET_CAUSE_POR_IO
//! Power-on-reset on I/O power domain reset cause not available on this chip.
# define CHIP_RESET_CAUSE_POR_IO 0
#endif
#ifndef CHIP_RESET_CAUSE_SLEEP
//! Wake from Shutdown sleep mode reset cause not available on this chip.
# define CHIP_RESET_CAUSE_SLEEP 0
#endif
#ifndef CHIP_RESET_CAUSE_SOFT
//! Software reset reset cause not available on this chip.
# define CHIP_RESET_CAUSE_SOFT 0
#endif
#ifndef CHIP_RESET_CAUSE_SPIKE
//! Spike detected reset cause not available on this chip.
# define CHIP_RESET_CAUSE_SPIKE 0
#endif
#ifndef CHIP_RESET_CAUSE_WDT
//! Watchdog timeout reset cause not available on this chip.
# define CHIP_RESET_CAUSE_WDT 0
#endif
/**
* \brief List of reset causes in bit-mask format
*/
enum reset_cause {
/** \brief Brown-out detected on CPU power domain reset cause */
RESET_CAUSE_BOD_CPU = CHIP_RESET_CAUSE_BOD_CPU,
/** \brief Brown-out detected on I/O power domain reset cause */
RESET_CAUSE_BOD_IO = CHIP_RESET_CAUSE_BOD_IO,
/** \brief CPU error reset cause */
RESET_CAUSE_CPU_ERROR = CHIP_RESET_CAUSE_CPU_ERROR,
/** \brief External reset cause */
RESET_CAUSE_EXTRST = CHIP_RESET_CAUSE_EXTRST,
/** \brief JTAG reset cause */
RESET_CAUSE_JTAG = CHIP_RESET_CAUSE_JTAG,
/** \brief On-chip debug system reset cause */
RESET_CAUSE_OCD = CHIP_RESET_CAUSE_OCD,
/** \brief Power-on-reset reset cause */
RESET_CAUSE_POR = CHIP_RESET_CAUSE_POR,
/** \brief Power-on-reset reset cause */
RESET_CAUSE_POR_IO = CHIP_RESET_CAUSE_POR_IO,
/** \brief Wake from Shutdown sleep mode reset cause */
RESET_CAUSE_SLEEP = CHIP_RESET_CAUSE_SLEEP,
/** \brief Software reset reset cause */
RESET_CAUSE_SOFT = CHIP_RESET_CAUSE_SOFT,
/** \brief Spike detected reset cause */
RESET_CAUSE_SPIKE = CHIP_RESET_CAUSE_SPIKE,
/** \brief Watchdog timeout reset cause */
RESET_CAUSE_WDT = CHIP_RESET_CAUSE_WDT,
};
//! \name Management
//@{
/**
* \fn void reset_do_soft_reset(void)
* \brief Perform a software reset of the device
*
* \note This function will never return.
* \note This function does not disable interrupts, this is up to the caller to
* handle.
*/
/**
* \fn reset_cause_t reset_cause_get_causes(void)
* \brief Get all reset causes
*
* This function will return a value containing the currently triggered reset
* cause(s).
*
* \return Bit-mask with each active reset cause set to 1.
*/
/**
* \fn reset_cause_clear_causes(reset_cause_t causes)
* \brief Clear a bit-mask of reset causes
*
* This function will clear the provided reset causes in the reset cause
* register.
*
* \param causes bit-mask of reset causes to clear
*/
//@}
//! \name Specific reset cause helper functions
//@{
/**
* \brief Check if chip reset was caused by a CPU power brown-out detection
*
* \return True if reset was caused by a CPU power brown-out detection
*/
static inline bool reset_cause_is_cpu_brown_out_detected(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_BOD_CPU);
}
/**
* \brief Check if chip reset was caused by an I/O power brown-out detection
*
* \return True if reset was caused by an I/O power brown-out detection
*/
static inline bool reset_cause_is_io_brown_out_detected(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_BOD_IO);
}
/**
* \brief Check if chip reset was caused by a brown-out detection on any
* power domain.
*
* \return True if reset was caused by a power brown-out detection
*/
static inline bool reset_cause_is_brown_out_detected(void)
{
return (reset_cause_is_cpu_brown_out_detected() ||
reset_cause_is_io_brown_out_detected());
}
/**
* \brief Check if chip reset was caused by a CPU error, illegal access
*
* \return True if reset was caused by a CPU error, illegal access
*/
static inline bool reset_cause_is_cpu_error(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_CPU_ERROR);
}
/**
* \brief Check if chip reset was caused by an external reset
*
* \return True if reset was caused by an external reset
*/
static inline bool reset_cause_is_external_reset(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_EXTRST);
}
/**
* \brief Check if chip reset was caused by a JTAG reset
*
* \return True if reset was caused by a JTAG reset
*/
static inline bool reset_cause_is_jtag(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_JTAG);
}
/**
* \brief Check if chip reset was caused by the on-chip debug system
*
* \return True if reset was caused by the on-chip debug system
*/
static inline bool reset_cause_is_ocd(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_OCD);
}
/**
* \brief Check if chip reset was caused by a power-on-reset
*
* \return True if reset was caused by a power-on-reset
*/
static inline bool reset_cause_is_power_on_reset(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_POR);
}
/**
* \brief Check if chip reset was caused by an I/O power-on-reset
*
* \return True if reset was caused by a power-on-reset
*/
static inline bool reset_cause_is_io_power_on_reset(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_POR_IO);
}
/**
* \brief Check if chip reset was caused by a wake up from shutdown sleep mode
*
* \return True if reset was caused by a wake up from shutdown sleep mode
*/
static inline bool reset_cause_is_wake_from_shutdown_sleep(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_SLEEP);
}
/**
* \brief Check if chip reset was caused by a software reset
*
* \return True if reset was caused by a software reset
*/
static inline bool reset_cause_is_software_reset(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_SOFT);
}
/**
* \brief Check if chip reset was caused by a power spike detection
*
* \return True if reset was caused by a spike detection
*/
static inline bool reset_cause_is_spike_detected(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_SPIKE);
}
/**
* \brief Check if chip reset was caused by a watchdog timeout
*
* \return True if reset was caused by a watchdog timeout
*/
static inline bool reset_cause_is_watchdog(void)
{
return (reset_cause_get_causes() & RESET_CAUSE_WDT);
}
//@}
//! @}
/**
* \page reset_cause_quickstart Quick start guide for reset cause service
*
* This is the quick start guide for the \ref reset_cause_group
* "Reset Cause service", with step-by-step instructions on how to configure
* and use the driver in a selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section reset_cause_basic_use_case Basic use case
* In this basic use case, the reset cause service is used for checking if the
* last reset was a watchdog reset.
*
* \section reset_cause_basic_use_case_setup Setup steps
*
* \subsection reset_cause_basic_use_case_setup_code Example code
* Add to application C-file:
* \code
if (reset_cause_is_watchdog()) {
// Do action due to last reset being a watchdog reset
reset_cause_clear_causes(RESET_CAUSE_WDT);
}
\endcode
*
* \subsection reset_cause_basic_use_case_setup_flow Workflow
* -# Check for watchdog reset flag:
* - \code if (reset_cause_is_watchdog()) { \endcode
* - \attention Please consult the specific device datasheet on which reset
* causes that are supported.
* -# Insert your own code taking action here. E.g.: Increase a watchdog reset
* counter.
* -# Reset flag if the flag was set to make sure it's not falsely
* detected in another reset:
* - \code reset_cause_clear_causes(RESET_CAUSE_WDT); \endcode
*
* \section reset_cause_use_cases Advanced use cases
* For more advanced use of the Reset Cause service, see the following use cases:
* - \subpage reset_cause_use_case_1 : Software controlled reset
*/
/**
* \page reset_cause_use_case_1 Use case #1
* In this use case, the reset cause service is used to perform a software
* controlled reset.
*
* \section reset_cause_use_case_1_setup Setup steps
*
* \subsection reset_cause_use_case_1_setup_flow Workflow
* -# Call soft reset. This call will not return.
* - \code reset_do_soft_reset(); \endcode
*/
#endif /* COMMON_DRIVERS_CPU_RESET_CAUSE_H */

View File

@ -0,0 +1,171 @@
/**
* \file
*
* \brief 32-bit CRC implementation.
*
* Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "crc32.h"
#include <status_codes.h>
/**
* Convenience typedef for words.
*
* \note This type has an architecture dependent size, and is used to optimize
* the CRC algorithm with regards to the number of databus accesses.
*/
typedef unsigned int word_t;
/** Polynomial for 32-bit CRC in IEEE 802.3. */
#define CRC32_POLYNOMIAL 0xEDB88320UL
/** Convenience macro for inverting the CRC. */
#define COMPLEMENT_CRC(c) ((c) ^ 0xffffffffUL)
/** Convenience macro for size of a word. */
#define WORD_SIZE (sizeof(word_t))
/** Bitmask for word-aligning an address. */
#define WORD_ALIGNMENT_MASK ~((uintptr_t)WORD_SIZE - 1)
/**
* \internal
* \brief Recalculate 32-bit CRC for bytes within a word
*
* \param[in] data Data to recalculate for.
* \param[in] crc Initial/current CRC value.
* \param[in] bytes Number of data bytes in word.
*
* \return New CRC value.
*
* \attention This implementation assumes a little-endian architecture.
*/
static inline crc32_t _crc32_recalculate_bytes_helper(word_t data,
crc32_t crc, uint_fast8_t bytes)
{
uint_fast8_t bit;
crc ^= data;
for (bit = 8 * bytes; bit > 0; bit--) {
if (crc & 1) {
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
} else {
crc >>= 1;
}
}
return crc;
}
/**
* \brief Recalculate 32-bit CRC for another block
*
* This function recalculates the CRC according to the polynomial
* \ref CRC32_POLYNOMIAL for the specified data block and initial CRC value.
*
* To reduce the number of databus accesses and thus speed up the calculation,
* the algorithm is tuned to work with words as much as possible.
*
* \param[in] data Address of data.
* \param[in] length Length of data.
* \param[in,out] crc Address of variable containing current CRC, and to store
* recalculated CRC in.
*
* \return Status of calculation.
* \retval STATUS_OK if calculation succeeded.
* \retval <other> if calculation failed or could not be started.
*
* \note To calculate the CRC of multiple blocks, use \ref crc32_calculate()
* first, then this function for the following blocks.
*
* \attention This implementation assumes a little-endian architecture.
*/
enum status_code crc32_recalculate(const void *data, size_t length, crc32_t *crc)
{
const word_t *word_ptr =
(word_t *)((uintptr_t)data & WORD_ALIGNMENT_MASK);
size_t temp_length;
crc32_t temp_crc = COMPLEMENT_CRC(*crc);
word_t word;
// Calculate for initial bytes to get word-aligned
if (length < WORD_SIZE) {
temp_length = length;
} else {
temp_length = ~WORD_ALIGNMENT_MASK & (WORD_SIZE - (uintptr_t)data);
}
if (temp_length) {
length -= temp_length;
word = *(word_ptr++);
word >>= 8 * (WORD_SIZE - temp_length);
temp_crc = _crc32_recalculate_bytes_helper(word, temp_crc, temp_length);
}
// Calculate for whole words, if any
temp_length = length & WORD_ALIGNMENT_MASK;
if (temp_length) {
length -= temp_length;
temp_length /= WORD_SIZE;
while (temp_length--) {
word = *(word_ptr++);
temp_crc = _crc32_recalculate_bytes_helper(word, temp_crc, WORD_SIZE);
}
}
// Calculate for tailing bytes
if (length) {
word = *word_ptr;
word &= 0xffffffffUL >> (8 * (WORD_SIZE - length));
temp_crc = _crc32_recalculate_bytes_helper(word, temp_crc, length);
}
*crc = COMPLEMENT_CRC(temp_crc);
return STATUS_OK;
}

View File

@ -0,0 +1,138 @@
/**
* \file
*
* \brief 32-bit CRC header.
*
* Copyright (C) 2013-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CRC32_H
#define CRC32_H
#include <compiler.h>
/**
* \defgroup common_services_crc32 CRC-32 calculation service
*
* See \ref common_services_crc32_quickstart.
*
* This service enables the user to calculate 32-bit CRC using the polynomial
* defined in the IEEE 802.3 standard, with support for multiple data blocks
* of arbitrary sizes, and any alignment in memory.
*
* @{
*/
//! Type to contain 32-bit CRC.
typedef uint32_t crc32_t;
#ifdef __cplusplus
extern "C" {
#endif
enum status_code crc32_recalculate(const void *data, size_t length, crc32_t *crc);
#ifdef __cplusplus
}
#endif
/**
* \brief Calculate 32-bit CRC for initial block
*
* This function calculates the CRC for the specified data block, which may be
* first of an arbitrary number of blocks.
*
* The actual calculation is done in \ref crc32_recalculate(), while this
* function just sets up the initial CRC value.
*
* \param[in] data Address of data.
* \param[in] length Length of data.
* \param[out] crc Address of variable to store the calculated CRC in.
*
* \return Status of calculation.
* \retval STATUS_OK if calculation succeeded.
* \retval <other> if calculation failed somehow.
*
* \note To calculate the CRC of multiple blocks, use this function first, then
* \ref crc32_recalculate() for the following blocks.
*/
static inline enum status_code crc32_calculate(const void *data, size_t length,
crc32_t *crc)
{
*crc = 0;
return crc32_recalculate(data, length, crc);
}
/** @} */
/**
* \page common_services_crc32_quickstart Quick Start Guide for CRC-32
*
* To use this service, the user must supply a \ref crc32_t "container" variable
* for the CRC and call \ref crc32_calculate() with the parameters for the first
* block in the dataset. For subsequent blocks, \ref crc32_recalculate() must be
* used.
*
* \note The user may also initialize the container with a known CRC value and
* use that as the "seed" for \ref crc32_recalculate().
*
*
* \section common_services_crc32_quickstart_code Example Code
*
\code
uint8_t block1[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
uint8_t block2[6] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
crc32_t my_crc;
crc32_calculate(block1, sizeof(block1), &my_crc);
crc32_recalculate(block2, sizeof(block2), &my_crc);
\endcode
*
*/
#endif // CRC32_H

View File

@ -0,0 +1,139 @@
/**
* \file
*
* \brief Common Delay Service
*
* Copyright (c) 2014-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _DELAY_H_
#define _DELAY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sysclk.h>
#if UC3
# include <cycle_counter.h>
#elif XMEGA
# include "xmega/cycle_counter.h"
#elif MEGA
# include "mega/cycle_counter.h"
#elif SAM
# include "sam/cycle_counter.h"
#endif
/**
* @defgroup group_common_services_delay Busy-Wait Delay Routines
*
* This module provides simple loop-based delay routines for those
* applications requiring a brief wait during execution. Common API
* for UC3, XMEGA, and AVR MEGA.
*
* @{
*/
/**
* @def F_CPU
* @brief MCU Clock Frequency (Hertz)
*
* @deprecated
* The \ref F_CPU configuration constant is used for compatibility with the
* \ref group_common_services_delay routines. The common loop-based delay
* routines are designed to use the \ref clk_group modules while anticipating
* support for legacy applications assuming a statically defined clock
* frequency. Applications using a statically configured MCU clock frequency
* can define \ref F_CPU (Hertz), in which case the common delay routines will
* use this value rather than calling sysclk_get_cpu_hz() to get the current
* MCU clock frequency.
*/
#ifndef F_CPU
# define F_CPU sysclk_get_cpu_hz()
#endif
/**
* @def delay_init
*
* @brief Initialize the delay driver.
* @param fcpu_hz CPU frequency in Hz
*
* @deprecated
* This function is provided for compatibility with ASF applications that
* may not have been updated to configure the system clock via the common
* clock service; e.g. sysclk_init() and a configuration header file are
* used to configure clocks.
*
* The functions in this module call \ref sysclk_get_cpu_hz() function to
* obtain the system clock frequency.
*/
#define delay_init(fcpu_hz)
/**
* @def delay_s
* @brief Delay in seconds.
* @param delay Delay in seconds
*/
#define delay_s(delay) ((delay) ? cpu_delay_ms(1000 * delay, F_CPU) : cpu_delay_us(1, F_CPU))
/**
* @def delay_ms
* @brief Delay in milliseconds.
* @param delay Delay in milliseconds
*/
#define delay_ms(delay) ((delay) ? cpu_delay_ms(delay, F_CPU) : cpu_delay_us(1, F_CPU))
/**
* @def delay_us
* @brief Delay in microseconds.
* @param delay Delay in microseconds
*/
#define delay_us(delay) ((delay) ? cpu_delay_us(delay, F_CPU) : cpu_delay_us(1, F_CPU))
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* _DELAY_H_ */

View File

@ -0,0 +1,61 @@
/**
* \file
*
* \brief ARM functions for busy-wait delay loops
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "cycle_counter.h"
// Delay loop is put to SRAM so that FWS will not affect delay time
OPTIMIZE_HIGH
RAMFUNC
void portable_delay_cycles(unsigned long n)
{
UNUSED(n);
__asm (
"loop: DMB \n"
"SUBS R0, R0, #1 \n"
"BNE.N loop "
);
}

View File

@ -0,0 +1,126 @@
/**
* \file
*
* \brief ARM functions for busy-wait delay loops
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _cycle_counter_h_
#define _cycle_counter_h_
#ifdef __cplusplus
extern "C" {
#endif
#include <compiler.h>
/**
* @name Convenience functions for busy-wait delay loops
*
* @def delay_cycles
* @brief Delay program execution for a specified number of CPU cycles.
* @param n number of CPU cycles to wait
*
* @def cpu_delay_ms
* @brief Delay program execution for a specified number of milliseconds.
* @param delay number of milliseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_delay_us
* @brief Delay program execution for a specified number of microseconds.
* @param delay number of microseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_ms_2_cy
* @brief Convert milli-seconds into CPU cycles.
* @param ms number of milliseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @def cpu_us_2_cy
* @brief Convert micro-seconds into CPU cycles.
* @param ms number of microseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @{
*/
/**
* \brief Delay loop to delay n number of cycles
*
* \note The function runs in internal RAM so that flash wait states
* will not affect the delay time.
*
* \param n Number of cycles
*/
void portable_delay_cycles(unsigned long n);
/* Cortex-M7 is faster than Cortex-M3/M4/M0+ */
#ifdef __CM7_REV
# define cpu_ms_2_cy(ms, f_cpu) \
(((uint64_t)(ms) * (f_cpu) + (uint64_t)(5.932e3 - 1ul)) / (uint64_t)5.932e3)
# define cpu_us_2_cy(us, f_cpu) \
(((uint64_t)(us) * (f_cpu) + (uint64_t)(5.932e6 - 1ul)) / (uint64_t)5.932e6)
#else
# define cpu_ms_2_cy(ms, f_cpu) \
(((uint64_t)(ms) * (f_cpu) + (uint64_t)(14e3 - 1ul)) / (uint64_t)14e3)
# define cpu_us_2_cy(us, f_cpu) \
(((uint64_t)(us) * (f_cpu) + (uint64_t)(14e6 - 1ul)) / (uint64_t)14e6)
#endif
#define delay_cycles portable_delay_cycles
#define cpu_delay_ms(delay, f_cpu) delay_cycles(cpu_ms_2_cy(delay, f_cpu))
#define cpu_delay_us(delay, f_cpu) delay_cycles(cpu_us_2_cy(delay, f_cpu))
//! @}
#ifdef __cplusplus
}
#endif
#endif /* _cycle_counter_h_ */

View File

@ -0,0 +1,82 @@
/**
* \file
*
* \brief This file controls the software FIFO management.
*
* These functions manages FIFOs thanks to simple a API. The FIFO can
* be 100% full thanks to a double-index range implementation. For example,
* a FIFO of 4 elements can be implemented: the FIFO can really hold up to 4
* elements.
* This is particularly well suited for any kind of application needing a lot of
* small FIFO.
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "fifo.h"
int fifo_init(fifo_desc_t *fifo_desc, void *buffer, uint8_t size)
{
// Check the size parameter. It must be not null...
Assert (size);
// ... must be a 2-power ...
Assert (!(size & (size - 1)));
// ... and must fit in a uint8_t. Since the read and write indexes are using a
// double-index range implementation, the max FIFO size is thus 128 items.
Assert (size <= 128);
// Fifo starts empty.
fifo_desc->read_index = 0;
fifo_desc->write_index = 0;
// Save the size parameter.
fifo_desc->size = size;
// Create a mask to speed up the FIFO management (index swapping).
fifo_desc->mask = (2 * (uint16_t)size) - 1;
// Save the buffer pointer.
fifo_desc->buffer.u8ptr = buffer;
return FIFO_OK;
}

View File

@ -0,0 +1,668 @@
/**
* \file
*
* \brief This file controls the software FIFO management.
*
* These functions manages FIFOs thanks to simple a API. The FIFO can
* be 100% full thanks to a double-index range implementation. For example,
* a FIFO of 4 elements can be implemented: the FIFO can really hold up to 4
* elements.
* This is particularly well suited for any kind of application needing a lot of
* small FIFO.
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _FIFO_H_
#define _FIFO_H_
#include "compiler.h"
/**
* \defgroup fifo_group First-In-First-Out Buffer (FIFO)
*
* See \ref fifo_quickstart.
*
* These functions manages FIFOs thanks to simple a API. The FIFO can
* be 100% full thanks to a double-index range implementation. For example,
* a FIFO of 4 elements can be implemented: the FIFO can really hold up to 4
* elements. This is particularly well suited for any kind of application
* needing a lot of small FIFO. The maximum fifo size is 128 items (uint8,
* uint16 or uint32). Note that the driver, thanks to its conception, does
* not use interrupt protection.
*
* @{
*/
//! Error codes used by FIFO driver.
enum {
FIFO_OK = 0, //!< Normal operation.
FIFO_ERROR_OVERFLOW, //!< Attempt to push something in a FIFO that is full.
FIFO_ERROR_UNDERFLOW, //!< Attempt to pull something from a FIFO that is empty
FIFO_ERROR, //!< Error condition during FIFO initialization
};
//! FIFO descriptor used by FIFO driver.
struct fifo_desc {
union
{
uint32_t *u32ptr; //!< Pointer to unsigned-32 bits location
uint16_t *u16ptr; //!< Pointer to unsigned-16 bits location
uint8_t *u8ptr; //!< Pointer to unsigned-8 bits location
} buffer;
volatile uint8_t read_index; //!< Read index
volatile uint8_t write_index; //!< Write index
uint8_t size; //!< Size of the FIFO (unit is in number of 'element')
uint8_t mask; //!< Mask used to speed up FIFO operation (wrapping)
};
typedef struct fifo_desc fifo_desc_t;
/**
* \brief Initializes a new software FIFO for a certain 'size'.
*
* \pre Both fifo descriptor and buffer must be allocated by the caller before.
*
* \param fifo_desc Pointer on the FIFO descriptor.
* \param buffer Pointer on the FIFO buffer.
* \param size Size of the buffer (unit is in number of 'elements').
* It must be a 2-power and <= to 128.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR when the size is not a 2-power.
*/
int fifo_init(fifo_desc_t *fifo_desc, void *buffer, uint8_t size);
/**
* \brief Returns the number of elements in the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \return The number of used elements.
*/
static inline uint8_t fifo_get_used_size(fifo_desc_t *fifo_desc)
{
return ((fifo_desc->write_index - fifo_desc->read_index) & fifo_desc->mask);
}
/**
* \brief Returns the remaining free spaces of the FIFO (in number of elements).
*
* \param fifo_desc The FIFO descriptor.
*
* \return The number of free elements.
*/
static inline uint8_t fifo_get_free_size(fifo_desc_t *fifo_desc)
{
return fifo_desc->size - fifo_get_used_size(fifo_desc);
}
/**
* \brief Tests if a FIFO is empty.
*
* \param fifo_desc The FIFO descriptor.
*
* \return Status
* \retval true when the FIFO is empty.
* \retval false when the FIFO is not empty.
*/
static inline bool fifo_is_empty(fifo_desc_t *fifo_desc)
{
return (fifo_desc->write_index == fifo_desc->read_index);
}
/**
* \brief Tests if a FIFO is full.
*
* \param fifo_desc The FIFO descriptor.
*
* \return Status
* \retval true when the FIFO is full.
* \retval false when the FIFO is not full.
*/
static inline bool fifo_is_full(fifo_desc_t *fifo_desc)
{
return (fifo_get_used_size(fifo_desc) == fifo_desc->size);
}
/**
* \brief Puts a new 8-bits element into the FIFO.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*/
static inline void fifo_push_uint8_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
write_index = fifo_desc->write_index;
fifo_desc->buffer.u8ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
}
/**
* \brief Puts a new 8-bits element into the FIFO and
* checks for a possible overflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_push_uint8(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
if (fifo_is_full(fifo_desc)) {
return FIFO_ERROR_OVERFLOW;
}
write_index = fifo_desc->write_index;
fifo_desc->buffer.u8ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
return FIFO_OK;
}
/**
* \brief Puts a new 16-bits element into the FIFO.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*/
static inline void fifo_push_uint16_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
write_index = fifo_desc->write_index;
fifo_desc->buffer.u16ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
}
/**
* \brief Puts a new 16-bits element into the FIFO and
* checks for a possible overflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_push_uint16(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
if (fifo_is_full(fifo_desc)) {
return FIFO_ERROR_OVERFLOW;
}
write_index = fifo_desc->write_index;
fifo_desc->buffer.u16ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
return FIFO_OK;
}
/**
* \brief Puts a new 32-bits element into the FIFO.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*/
static inline void fifo_push_uint32_nocheck(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
write_index = fifo_desc->write_index;
fifo_desc->buffer.u32ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
}
/**
* \brief Puts a new 32-bits element into the FIFO and
* checks for a possible overflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_push_uint32(fifo_desc_t *fifo_desc, uint32_t item)
{
uint8_t write_index;
if (fifo_is_full(fifo_desc)) {
return FIFO_ERROR_OVERFLOW;
}
write_index = fifo_desc->write_index;
fifo_desc->buffer.u32ptr[write_index & (fifo_desc->mask >> 1)] = item;
write_index = (write_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->write_index = write_index;
return FIFO_OK;
}
/**
* \brief Gets a 8-bits element from the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \return extracted element.
*/
static inline uint8_t fifo_pull_uint8_nocheck(fifo_desc_t *fifo_desc)
{
uint8_t read_index;
uint8_t item;
read_index = fifo_desc->read_index;
item = fifo_desc->buffer.u8ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return item;
}
/**
* \brief Gets a 8-bits element from the FIFO and
* checks for a possible underflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_pull_uint8(fifo_desc_t *fifo_desc, uint8_t *item)
{
uint8_t read_index;
if (fifo_is_empty(fifo_desc)) {
return FIFO_ERROR_UNDERFLOW;
}
read_index = fifo_desc->read_index;
*item = fifo_desc->buffer.u8ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return FIFO_OK;
}
/**
* \brief Gets a 16-bits element from the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \return extracted element.
*/
static inline uint16_t fifo_pull_uint16_nocheck(fifo_desc_t *fifo_desc)
{
uint8_t read_index;
uint16_t item;
read_index = fifo_desc->read_index;
item = fifo_desc->buffer.u16ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return item;
}
/**
* \brief Gets a 16-bits element from the FIFO and
* checks for a possible underflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_pull_uint16(fifo_desc_t *fifo_desc, uint16_t *item)
{
uint8_t read_index;
if (fifo_is_empty(fifo_desc)) {
return FIFO_ERROR_UNDERFLOW;
}
read_index = fifo_desc->read_index;
*item = fifo_desc->buffer.u16ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return FIFO_OK;
}
/**
* \brief Gets a 32-bits element from the FIFO
*
* \param fifo_desc The FIFO descriptor.
*
* \return extracted element.
*/
static inline uint32_t fifo_pull_uint32_nocheck(fifo_desc_t *fifo_desc)
{
uint8_t read_index;
uint32_t item;
read_index = fifo_desc->read_index;
item = fifo_desc->buffer.u32ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return item;
}
/**
* \brief Gets a 32-bits element from the FIFO and
* checks for a possible underflow.
*
* \param fifo_desc The FIFO descriptor.
* \param item extracted element.
*
* \return Status
* \retval FIFO_OK when no error occurred.
* \retval FIFO_ERROR_UNDERFLOW when the FIFO was empty.
*/
static inline int fifo_pull_uint32(fifo_desc_t *fifo_desc, uint32_t *item)
{
uint8_t read_index;
if (fifo_is_empty(fifo_desc)) {
return FIFO_ERROR_UNDERFLOW;
}
read_index = fifo_desc->read_index;
*item = fifo_desc->buffer.u32ptr[read_index & (fifo_desc->mask >> 1)];
read_index = (read_index + 1) & fifo_desc->mask;
// Must be the last thing to do.
barrier();
fifo_desc->read_index = read_index;
return FIFO_OK;
}
/**
* \brief Gets a 32-bits element from the FIFO but does
* not remove it from the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \retval item extracted element.
*/
static inline uint32_t fifo_peek_uint32(fifo_desc_t *fifo_desc)
{
return fifo_desc->buffer.u32ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
}
/**
* \brief Gets a 16-bits element from the FIFO but does
* not remove it from the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \retval item extracted element.
*/
static inline uint16_t fifo_peek_uint16(fifo_desc_t *fifo_desc)
{
return fifo_desc->buffer.u16ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
}
/**
* \brief Gets a 8-bits element from the FIFO but does
* not remove it from the FIFO.
*
* \param fifo_desc The FIFO descriptor.
*
* \retval item extracted element.
*/
static inline uint8_t fifo_peek_uint8(fifo_desc_t *fifo_desc)
{
return fifo_desc->buffer.u8ptr[fifo_desc->read_index & (fifo_desc->mask >> 1)];
}
/**
* \brief Flushes a software FIFO.
*
* \param fifo_desc The FIFO descriptor.
*/
static inline void fifo_flush(fifo_desc_t *fifo_desc)
{
// Fifo starts empty.
fifo_desc->read_index = fifo_desc->write_index = 0;
}
/**
* @}
*/
/**
* \page fifo_quickstart Quick start guide for First-In-First-Out Buffer (FIFO)
*
* This is the quick start guide for the \ref fifo_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section fifo_use_cases FIFO use cases
* - \ref fifo_basic_use_case
* - \subpage fifo_use_case_1
*
* \section fifo_basic_use_case Basic use case - Push and pull
* In this use case, an element will be pushed to the FIFO, and the same
* element will be pulled from it.
*
* \section fifo_basic_use_case_setup Setup steps
*
* \subsection fifo_basic_use_case_setup_code Example code
* The following must be added to the project:
* \code
#define FIFO_BUFFER_LENGTH 4
#define PUSH_VALUE 0x12345678
union buffer_element {
uint8_t byte;
uint16_t halfword;
uint32_t word;
};
\endcode
*
* Add to application initialization:
* \code
union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH];
fifo_desc_t fifo_desc;
fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH);
\endcode
*
* \subsection fifo_basic_use_case_setup_flow Workflow
* -# Create a FIFO buffer of FIFO_BUFFER_LENGTH elements, capable
* of holding a byte, halfword or word:
* - \code union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH]; \endcode
* -# Create a FIFO buffer descriptor that contains information about the
* location of the FIFO buffer, its size and where to read from or write to
* upon the next buffer pull or push:
* - \code fifo_desc_t fifo_desc; \endcode
* -# Initialize the FIFO:
* - \code fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH); \endcode
*
* \section fifo_basic_use_case_usage Usage steps
*
* \subsection fifo_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
uint8_t status;
uint8_t pull_value;
status = fifo_push_uint8(&fifo_desc, PUSH_VALUE & 0xff);
status = fifo_pull_uint8(&fifo_desc, &pull_value);
\endcode
*
* \subsection fifo_basic_use_case_usage_flow Workflow
* -# Create a variable to hold the return status from the FIFO:
* - \code uint8_t status; \endcode
* -# Create a variable to hold the pulled value from the FIFO:
* - \code uint8_t pull_value; \endcode
* -# Put a new 8-bit element into the FIFO:
* - \code status = fifo_push_uint8(&fifo_desc, PUSH_VALUE & 0xff); \endcode
* \note The status variable will contain \ref FIFO_OK if no error occurred.
* -# Get the 8-bit element from the FIFO:
* - \code status = fifo_pull_uint8(&fifo_desc, &pull_value); \endcode
* \note The status variable will contain \ref FIFO_OK if no error occurred.
*/
/**
* \page fifo_use_case_1 Push and flush
*
* In this use case, two elements will be pushed to the FIFO, and the FIFO
* will be flushed.
*
* \section fifo_use_case_1_setup Setup steps
*
* \subsection fifo_use_case_1_setup_code Example code
* The following must be added to the project:
* \code
#define FIFO_BUFFER_LENGTH 4
#define PUSH_VALUE 0x12345678
union buffer_element {
uint8_t byte;
uint16_t halfword;
uint32_t word;
};
\endcode
*
* Add to application initialization:
* \code
union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH];
fifo_desc_t fifo_desc;
fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH);
\endcode
*
* \subsection fifo_use_case_1_setup_flow Workflow
* -# Create a FIFO buffer of FIFO_BUFFER_LENGTH elements, capable
* of holding a byte, halfword or word:
* - \code union buffer_element fifo_buffer[FIFO_BUFFER_LENGTH]; \endcode
* -# Create a FIFO buffer descriptor that containing information about the
* location of the FIFO buffer, its size and where to read from or write to
* upon the next buffer pull or push:
* - \code fifo_desc_t fifo_desc; \endcode
* -# Initialize the FIFO:
* - \code fifo_init(&fifo_desc, fifo_buffer, FIFO_BUFFER_LENGTH); \endcode
* \section fifo_use_case_1_usage Usage steps
*
* \subsection fifo_use_case_1_usage_code Example code
* Add to application C-file:
* \code
uint8_t status;
bool fifo_empty;
status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff);
status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff);
fifo_flush(&fifo_desc);
fifo_empty = fifo_is_empty(&fifo_desc);
\endcode
*
* \subsection fifo_use_case_1_usage_flow Workflow
* -# Create a variable to hold the return status from the FIFO:
* - \code uint8_t status; \endcode
* -# Create a variable to hold the pulled value from the FIFO:
* - \code uint16_t pull_value; \endcode
* -# Put two new 16-bit element into the FIFO:
* - \code status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff); \endcode
* - \code status = fifo_push_uint16(&fifo_desc, PUSH_VALUE & 0xffff); \endcode
* \note The status variable will contain \ref FIFO_OK if no error occurred.
* -# Flush the FIFO:
* - \code fifo_flush(&fifo_desc); \endcode
* -# Check that the FIFO is empty after flushing:
* - \code fifo_empty = fifo_is_empty(&fifo_desc); \endcode
* \note The fifo_empty variable will be true if the FIFO is empty.
*/
#endif // _FIFO_H_

View File

@ -0,0 +1,86 @@
/**
* \file
*
* \brief Common GPIO API.
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
# include "sam_gpio/sam_gpio.h"
#elif XMEGA
# include "xmega_gpio/xmega_gpio.h"
#elif MEGA || MEGA_RF
# include "mega_gpio/mega_gpio.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup gpio_group General Purpose Input/Output
*
* This is the common API for GPIO. Additional features are available
* in the documentation of the specific modules.
*
* \section io_group_platform Platform Dependencies
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - gpio_pin_is_low()
* - gpio_pin_is_high()
* - gpio_set_pin_high()
* - gpio_set_pin_group_high()
* - gpio_set_pin_low()
* - gpio_set_pin_group_low()
* - gpio_toggle_pin()
* - gpio_toggle_pin_group()
* - gpio_configure_pin()
* - gpio_configure_group()
*/
#endif /* _GPIO_H_ */

View File

@ -0,0 +1,83 @@
/**
* \file
*
* \brief GPIO service for SAM.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SAM_GPIO_H_INCLUDED
#define SAM_GPIO_H_INCLUDED
#include "compiler.h"
#include "pio.h"
#define gpio_pin_is_low(io_id) \
(pio_get_pin_value(io_id) ? 0 : 1)
#define gpio_pin_is_high(io_id) \
(pio_get_pin_value(io_id) ? 1 : 0)
#define gpio_set_pin_high(io_id) \
pio_set_pin_high(io_id)
#define gpio_set_pin_low(io_id) \
pio_set_pin_low(io_id)
#define gpio_toggle_pin(io_id) \
pio_toggle_pin(io_id)
#define gpio_configure_pin(io_id,io_flags) \
pio_configure_pin(io_id,io_flags)
#define gpio_configure_group(port_id,port_mask,io_flags) \
pio_configure_pin_group(port_id,port_mask,io_flags)
#define gpio_set_pin_group_high(port_id,mask) \
pio_set_pin_group_high(port_id,mask)
#define gpio_set_pin_group_low(port_id,mask) \
pio_set_pin_group_low(port_id,mask)
#define gpio_toggle_pin_group(port_id,mask) \
pio_toggle_pin_group(port_id,mask)
#endif /* SAM_GPIO_H_INCLUDED */

View File

@ -0,0 +1,115 @@
/**
* \file
*
* \brief Generic implementation of huge data memory access
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef GENERIC_HUGEMEM_H_INCLUDED
#define GENERIC_HUGEMEM_H_INCLUDED
#include <stdint.h>
#include <string.h>
/**
* \weakgroup hugemem_group
* @{
*/
/**
* \internal
* \defgroup hugemem_generic_group Generic hugemem implementation.
*
* These functions are needed for code compatibility between 8- and 32-bit AVR,
* as well as a different application configurations on 8-bit AVR, i.e., if huge
* data memory is optional.
*/
typedef void * hugemem_ptr_t;
#define HUGEMEM_NULL NULL
static inline uint8_t hugemem_read8(const hugemem_ptr_t from)
{
return *(uint8_t *)from;
}
static inline uint16_t hugemem_read16(const hugemem_ptr_t from)
{
return *(uint16_t *)from;
}
static inline uint32_t hugemem_read32(const hugemem_ptr_t from)
{
return *(uint32_t *)from;
}
static inline void hugemem_read_block(void *to, const hugemem_ptr_t from,
size_t size)
{
memcpy(to, from, size);
}
static inline void hugemem_write8(hugemem_ptr_t to, uint8_t val)
{
*(uint8_t *)to = val;
}
static inline void hugemem_write16(hugemem_ptr_t to, uint16_t val)
{
*(uint16_t *)to = val;
}
static inline void hugemem_write32(hugemem_ptr_t to, uint32_t val)
{
*(uint32_t *)to = val;
}
static inline void hugemem_write_block(hugemem_ptr_t to, const void *from,
size_t size)
{
memcpy(to, from, size);
}
//@}
#endif /* GENERIC_HUGEMEM_H */

View File

@ -0,0 +1,143 @@
/**
* \file
*
* \brief Huge data memory space access
*
* Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef HUGEMEM_H_INCLUDED
#define HUGEMEM_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
#if defined(__AVR32__) || defined(__ICCAVR32__)
# include <generic/hugemem.h>
#elif defined(__AVR__) || defined (__ICCAVR__)
# include <avr8/hugemem.h>
#else
# error Unknown architecture passed to hugemem interface.
# error Expected __AVR32__ or __AVR__.
#endif
/**
* \defgroup hugemem_group Data in Huge Data Memory Space
*
* Due to shortcomings of the GCC compiler for 8-bit AVR, custom functions are
* needed for access to data beyond the 64 kB boundary, i.e., addresses that
* are larger than 16-bit.
*
* The definition of huge memory space can differ between architectures, so the
* implementation is architecture specific.
*
* This module supplies functions for copying a number of bytes between huge
* and 64 kB data memory space, and is needed solely for code compatibility
* across compilers.
*
* @{
*/
/**
* \typedef hugemem_ptr_t
*
* \brief Type to use for pointers to huge memory.
*/
/**
* \def HUGEMEM_NULL
*
* \brief Hugemem null pointer, similar to NULL, but works across different
* platforms.
*/
/**
* \fn uint_fast8_t hugemem_read8(const hugemem_ptr_t from)
*
* \brief Read 8-bit value stored at huge memory address \a from.
*/
/**
* \fn uint_fast16_t hugemem_read16(const hugemem_ptr_t from)
*
* \brief Read 16-bit value stored at huge memory address \a from.
*/
/**
* \fn void hugemem_read_block(void *to, const hugemem_ptr_t from, size_t size)
*
* \brief Read \a size bytes from huge memory address \a from into buffer at
* address \a to.
*/
/**
* \fn uint_fast32_t hugemem_read32(const hugemem_ptr_t from)
*
* \brief Read 32-bit value stored at huge memory address \a from.
*/
/**
* \fn void hugemem_write8(hugemem_ptr_t to, uint_fast8_t val)
*
* \brief Write 8-bit value \a val to huge memory address \a to.
*/
/**
* \fn void hugemem_write16(hugemem_ptr_t to, uint_fast16_t val)
*
* \brief Write 16-bit value \a val to huge memory address \a to.
*/
/**
* \fn void hugemem_write32(hugemem_ptr_t to, uint_fast32_t val)
*
* \brief Write 32-bit value \a val to huge memory address \a to.
*/
/**
* \fn void hugemem_write_block(hugemem_ptr_t to, const void *from, size_t size)
*
* \brief Write \a size bytes from buffer at address \a from to huge memory
* address \a to.
*/
//@}
#endif /* HUGEMEM_H_INCLUDED */

View File

@ -0,0 +1,548 @@
/**
* \file
*
* \brief Common IOPORT service main header file for AVR, UC3 and ARM
* architectures.
*
* Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef IOPORT_H
#define IOPORT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <parts.h>
#include <compiler.h>
/**
* \defgroup ioport_group Common IOPORT API
*
* See \ref ioport_quickstart.
*
* This is common IOPORT service for GPIO pin configuration and control in a
* standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices.
*
* Port pin control code is optimized for each platform, and should produce
* both compact and fast execution times when used with constant values.
*
* \section dependencies Dependencies
* This driver depends on the following modules:
* - \ref sysclk_group for clock speed and functions.
* @{
*/
/**
* \def IOPORT_CREATE_PIN(port, pin)
* \brief Create IOPORT pin number
*
* Create a IOPORT pin number for use with the IOPORT functions.
*
* \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen
* architecture)
* \param pin IOPORT zero-based index of the I/O pin
*/
/** \brief IOPORT pin directions */
enum ioport_direction {
IOPORT_DIR_INPUT, /*!< IOPORT input direction */
IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */
};
/** \brief IOPORT levels */
enum ioport_value {
IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */
IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */
};
#if MEGA_RF
/** \brief IOPORT edge sense modes */
enum ioport_sense {
IOPORT_SENSE_LEVEL, /*!< IOPORT sense low level */
IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
};
#elif SAM && !SAM4L
/** \brief IOPORT edge sense modes */
enum ioport_sense {
IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */
IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level */
};
#elif XMEGA
enum ioport_sense {
IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */
};
#else
enum ioport_sense {
IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
};
#endif
#if XMEGA
# include "xmega/ioport.h"
# if defined(IOPORT_XMEGA_COMPAT)
# include "xmega/ioport_compat.h"
# endif
#elif MEGA
# include "mega/ioport.h"
#elif UC3
# include "uc3/ioport.h"
#elif SAM
# if SAM4L
# include "sam/ioport_gpio.h"
# elif (SAMD20 | SAMD21 | SAML21)
# include "sam0/ioport.h"
# else
# include "sam/ioport_pio.h"
# endif
#endif
/**
* \brief Initializes the IOPORT service, ready for use.
*
* This function must be called before using any other functions in the IOPORT
* service.
*/
static inline void ioport_init(void)
{
arch_ioport_init();
}
/**
* \brief Enable an IOPORT pin, based on a pin created with \ref
* IOPORT_CREATE_PIN().
*
* \param pin IOPORT pin to enable
*/
static inline void ioport_enable_pin(ioport_pin_t pin)
{
arch_ioport_enable_pin(pin);
}
/**
* \brief Enable multiple pins in a single IOPORT port.
*
* \param port IOPORT port to enable
* \param mask Mask of pins within the port to enable
*/
static inline void ioport_enable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_enable_port(port, mask);
}
/**
* \brief Disable IOPORT pin, based on a pin created with \ref
* IOPORT_CREATE_PIN().
*
* \param pin IOPORT pin to disable
*/
static inline void ioport_disable_pin(ioport_pin_t pin)
{
arch_ioport_disable_pin(pin);
}
/**
* \brief Disable multiple pins in a single IOPORT port.
*
* \param port IOPORT port to disable
* \param mask Pin mask of pins to disable
*/
static inline void ioport_disable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_disable_port(port, mask);
}
/**
* \brief Set multiple pin modes in a single IOPORT port, such as pull-up,
* pull-down, etc. configuration.
*
* \param port IOPORT port to configure
* \param mask Pin mask of pins to configure
* \param mode Mode masks to configure for the specified pins (\ref
* ioport_modes)
*/
static inline void ioport_set_port_mode(ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
arch_ioport_set_port_mode(port, mask, mode);
}
/**
* \brief Set pin mode for one single IOPORT pin.
*
* \param pin IOPORT pin to configure
* \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
*/
static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode)
{
arch_ioport_set_pin_mode(pin, mode);
}
/**
* \brief Reset multiple pin modes in a specified IOPORT port to defaults.
*
* \param port IOPORT port to configure
* \param mask Mask of pins whose mode configuration is to be reset
*/
static inline void ioport_reset_port_mode(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_set_port_mode(port, mask, 0);
}
/**
* \brief Reset pin mode configuration for a single IOPORT pin
*
* \param pin IOPORT pin to configure
*/
static inline void ioport_reset_pin_mode(ioport_pin_t pin)
{
arch_ioport_set_pin_mode(pin, 0);
}
/**
* \brief Set I/O direction for a group of pins in a single IOPORT.
*
* \param port IOPORT port to configure
* \param mask Pin mask of pins to configure
* \param dir Direction to set for the specified pins (\ref ioport_direction)
*/
static inline void ioport_set_port_dir(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_direction dir)
{
arch_ioport_set_port_dir(port, mask, dir);
}
/**
* \brief Set direction for a single IOPORT pin.
*
* \param pin IOPORT pin to configure
* \param dir Direction to set for the specified pin (\ref ioport_direction)
*/
static inline void ioport_set_pin_dir(ioport_pin_t pin,
enum ioport_direction dir)
{
arch_ioport_set_pin_dir(pin, dir);
}
/**
* \brief Set an IOPORT pin to a specified logical value.
*
* \param pin IOPORT pin to configure
* \param level Logical value of the pin
*/
static inline void ioport_set_pin_level(ioport_pin_t pin, bool level)
{
arch_ioport_set_pin_level(pin, level);
}
/**
* \brief Set a group of IOPORT pins in a single port to a specified logical
* value.
*
* \param port IOPORT port to write to
* \param mask Pin mask of pins to modify
* \param level Level of the pins to be modified
*/
static inline void ioport_set_port_level(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_value level)
{
arch_ioport_set_port_level(port, mask, level);
}
/**
* \brief Get current value of an IOPORT pin, which has been configured as an
* input.
*
* \param pin IOPORT pin to read
* \return Current logical value of the specified pin
*/
static inline bool ioport_get_pin_level(ioport_pin_t pin)
{
return arch_ioport_get_pin_level(pin);
}
/**
* \brief Get current value of several IOPORT pins in a single port, which have
* been configured as an inputs.
*
* \param port IOPORT port to read
* \param mask Pin mask of pins to read
* \return Logical levels of the specified pins from the read port, returned as
* a mask.
*/
static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port,
ioport_port_mask_t mask)
{
return arch_ioport_get_port_level(port, mask);
}
/**
* \brief Toggle the value of an IOPORT pin, which has previously configured as
* an output.
*
* \param pin IOPORT pin to toggle
*/
static inline void ioport_toggle_pin_level(ioport_pin_t pin)
{
arch_ioport_toggle_pin_level(pin);
}
/**
* \brief Toggle the values of several IOPORT pins located in a single port.
*
* \param port IOPORT port to modify
* \param mask Pin mask of pins to toggle
*/
static inline void ioport_toggle_port_level(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_toggle_port_level(port, mask);
}
/**
* \brief Set the pin sense mode of a single IOPORT pin.
*
* \param pin IOPORT pin to configure
* \param pin_sense Edge to sense for the pin (\ref ioport_sense)
*/
static inline void ioport_set_pin_sense_mode(ioport_pin_t pin,
enum ioport_sense pin_sense)
{
arch_ioport_set_pin_sense_mode(pin, pin_sense);
}
/**
* \brief Set the pin sense mode of a multiple IOPORT pins on a single port.
*
* \param port IOPORT port to configure
* \param mask Bitmask if pins whose edge sense is to be configured
* \param pin_sense Edge to sense for the pins (\ref ioport_sense)
*/
static inline void ioport_set_port_sense_mode(ioport_port_t port,
ioport_port_mask_t mask,
enum ioport_sense pin_sense)
{
arch_ioport_set_port_sense_mode(port, mask, pin_sense);
}
/**
* \brief Convert a pin ID into a its port ID.
*
* \param pin IOPORT pin ID to convert
* \retval Port ID for the given pin ID
*/
static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin)
{
return arch_ioport_pin_to_port_id(pin);
}
/**
* \brief Convert a pin ID into a bitmask mask for the given pin on its port.
*
* \param pin IOPORT pin ID to convert
* \retval Bitmask with a bit set that corresponds to the given pin ID in its port
*/
static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin)
{
return arch_ioport_pin_to_mask(pin);
}
/** @} */
/**
* \page ioport_quickstart Quick start guide for the common IOPORT service
*
* This is the quick start guide for the \ref ioport_group, with
* step-by-step instructions on how to configure and use the service in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section ioport_quickstart_basic Basic use case
* In this use case we will configure one IO pin for button input and one for
* LED control. Then it will read the button state and output it on the LED.
*
* \section ioport_quickstart_basic_setup Setup steps
*
* \subsection ioport_quickstart_basic_setup_code Example code
* \code
#define MY_LED IOPORT_CREATE_PIN(PORTA, 5)
#define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
ioport_init();
ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT);
ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT);
ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP);
\endcode
*
* \subsection ioport_quickstart_basic_setup_flow Workflow
* -# It's useful to give the GPIOs symbolic names and this can be done with
* the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a
* button.
* - \code
#define MY_LED IOPORT_CREATE_PIN(PORTA, 5)
#define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
\endcode
* - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names
* differ between architectures:
* - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions
* PORTA, PORTB ...
* - UC3: Most convenient to pick up the device header file pin definition
* and us it directly. E.g.: AVR32_PIN_PB06
* - SAM: Most convenient to pick up the device header file pin definition
* and us it directly. E.g.: PIO_PA5_IDX<br>
* \ref IOPORT_CREATE_PIN can also be used with port definitions
* PIOA, PIOB ...
* -# Initialize the ioport service. This typically enables the IO module if
* needed.
* - \code ioport_init(); \endcode
* -# Set the LED GPIO as output:
* - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode
* -# Set the button GPIO as input:
* - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode
* -# Enable pull-up for the button GPIO:
* - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode
*
* \section ioport_quickstart_basic_usage Usage steps
*
* \subsection ioport_quickstart_basic_usage_code Example code
* \code
bool value;
value = ioport_get_pin_level(MY_BUTTON);
ioport_set_pin_level(MY_LED, value);
\endcode
*
* \subsection ioport_quickstart_basic_usage_flow Workflow
* -# Define a boolean variable for state storage:
* - \code bool value; \endcode
* -# Read out the button level into variable value:
* - \code value = ioport_get_pin_level(MY_BUTTON); \endcode
* -# Set the LED to read out value from the button:
* - \code ioport_set_pin_level(MY_LED, value); \endcode
*
* \section ioport_quickstart_advanced Advanced use cases
* - \subpage ioport_quickstart_use_case_1 : Port access
*/
/**
* \page ioport_quickstart_use_case_1 Advanced use case doing port access
*
* In this case we will read out the pins from one whole port and write the
* read value to another port.
*
* \section ioport_quickstart_use_case_1_setup Setup steps
*
* \subsection ioport_quickstart_use_case_1_setup_code Example code
* \code
#define IN_PORT IOPORT_PORTA
#define OUT_PORT IOPORT_PORTB
#define MASK 0x00000060
ioport_init();
ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT);
ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT);
\endcode
*
* \subsection ioport_quickstart_basic_setup_flow Workflow
* -# It's useful to give the ports symbolic names:
* - \code
#define IN_PORT IOPORT_PORTA
#define OUT_PORT IOPORT_PORTB
\endcode
* - \note The port names differ between architectures:
* - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA,
* IOPORT_PORTB ...
* - UC3: Use the index value of the different IO blocks: 0, 1 ...
* - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB
* ...
* -# Also useful to define a mask for the bits to work with:
* - \code #define MASK 0x00000060 \endcode
* -# Initialize the ioport service. This typically enables the IO module if
* needed.
* - \code ioport_init(); \endcode
* -# Set one of the ports as input:
* - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode
* -# Set the other port as output:
* - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode
*
* \section ioport_quickstart_basic_usage Usage steps
*
* \subsection ioport_quickstart_basic_usage_code Example code
* \code
ioport_port_mask_t value;
value = ioport_get_port_level(IN_PORT, MASK);
ioport_set_port_level(OUT_PORT, MASK, value);
\endcode
*
* \subsection ioport_quickstart_basic_usage_flow Workflow
* -# Define a variable for port date storage:
* - \code ioport_port_mask_t value; \endcode
* -# Read out from one port:
* - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode
* -# Put the read data out on the other port:
* - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode
*/
#ifdef __cplusplus
}
#endif
#endif /* IOPORT_H */

View File

@ -0,0 +1,307 @@
/**
* \file
*
* \brief SAM architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef IOPORT_SAM_H
#define IOPORT_SAM_H
#include <sysclk.h>
#define IOPORT_CREATE_PIN(port, pin) ((port) * 32 + (pin))
// Aliases
#define IOPORT_GPIOA 0
#define IOPORT_GPIOB 1
#define IOPORT_GPIOC 2
#define IOPORT_GPIOD 3
#define IOPORT_GPIOE 4
#define IOPORT_GPIOF 5
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the device datasheet.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_MUX_MASK (7 << 0) /*!< MUX bits mask */
#define IOPORT_MODE_MUX_BIT0 (1 << 0) /*!< MUX BIT0 mask */
#define IOPORT_MODE_MUX_BIT1 (1 << 1) /*!< MUX BIT1 mask */
#define IOPORT_MODE_MUX_A (0 << 0) /*!< MUX function A */
#define IOPORT_MODE_MUX_B (1 << 0) /*!< MUX function B */
#define IOPORT_MODE_MUX_C (2 << 0) /*!< MUX function C */
#define IOPORT_MODE_MUX_D (3 << 0) /*!< MUX function D */
#define IOPORT_MODE_MUX_BIT2 (1 << 2) /*!< MUX BIT2 mask */
#define IOPORT_MODE_MUX_E (4 << 0) /*!< MUX function E */
#define IOPORT_MODE_MUX_F (5 << 0) /*!< MUX function F */
#define IOPORT_MODE_MUX_G (6 << 0) /*!< MUX function G */
#define IOPORT_MODE_MUX_H (7 << 0) /*!< MUX function H */
#define IOPORT_MODE_PULLUP (1 << 3) /*!< Pull-up */
#define IOPORT_MODE_PULLDOWN (1 << 4) /*!< Pull-down */
#define IOPORT_MODE_GLITCH_FILTER (1 << 6) /*!< Glitch filter */
#define IOPORT_MODE_DRIVE_STRENGTH (1 << 7) /*!< Extra drive strength */
/** @} */
/** @} */
typedef uint32_t ioport_mode_t;
typedef uint32_t ioport_pin_t;
typedef uint32_t ioport_port_t;
typedef uint32_t ioport_port_mask_t;
__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin)
{
return pin >> 5;
}
__always_inline static volatile GpioPort *arch_ioport_port_to_base(
ioport_port_t port)
{
return (volatile GpioPort *)(GPIO_ADDR
+ port * sizeof(GpioPort));
}
__always_inline static volatile GpioPort *arch_ioport_pin_to_base(ioport_pin_t pin)
{
return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin));
}
__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin)
{
return 1U << (pin & 0x1F);
}
__always_inline static void arch_ioport_init(void)
{
sysclk_enable_peripheral_clock(GPIO);
}
__always_inline static void arch_ioport_enable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->GPIO_GPERS = mask;
}
__always_inline static void arch_ioport_disable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->GPIO_GPERC = mask;
}
__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin)
{
arch_ioport_enable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin)
{
arch_ioport_disable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_set_port_mode(ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
volatile GpioPort *base = arch_ioport_port_to_base(port);
if (mode & IOPORT_MODE_PULLUP) {
base->GPIO_PUERS = mask;
} else {
base->GPIO_PUERC = mask;
}
#ifdef IOPORT_MODE_PULLDOWN
if (mode & IOPORT_MODE_PULLDOWN) {
base->GPIO_PDERS = mask;
} else {
base->GPIO_PDERC = mask;
}
#endif
if (mode & IOPORT_MODE_GLITCH_FILTER) {
base->GPIO_GFERS = mask;
} else {
base->GPIO_GFERC = mask;
}
#ifdef IOPORT_MODE_DRIVE_STRENGTH
if (mode & IOPORT_MODE_DRIVE_STRENGTH) {
base->GPIO_ODCR0S = mask;
} else {
base->GPIO_ODCR0C = mask;
}
#endif
if (mode & IOPORT_MODE_MUX_BIT0) {
base->GPIO_PMR0S = mask;
} else {
base->GPIO_PMR0C = mask;
}
if (mode & IOPORT_MODE_MUX_BIT1) {
base->GPIO_PMR1S = mask;
} else {
base->GPIO_PMR1C = mask;
}
#ifdef IOPORT_MODE_MUX_BIT2
if (mode & IOPORT_MODE_MUX_BIT2) {
base->GPIO_PMR2S = mask;
} else {
base->GPIO_PMR2C = mask;
}
#endif
}
__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin,
ioport_mode_t mode)
{
arch_ioport_set_port_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), mode);
}
__always_inline static void arch_ioport_set_port_dir(ioport_port_t port,
ioport_port_mask_t mask, unsigned char group_direction)
{
if (group_direction == IOPORT_DIR_OUTPUT) {
arch_ioport_port_to_base(port)->GPIO_ODERS = mask;
// Always disable the Schmitt trigger for output pins.
arch_ioport_port_to_base(port)->GPIO_STERC = mask;
} else if (group_direction == IOPORT_DIR_INPUT) {
arch_ioport_port_to_base(port)->GPIO_ODERC = mask;
// Always enable the Schmitt trigger for input pins.
arch_ioport_port_to_base(port)->GPIO_STERS = mask;
}
}
__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin,
enum ioport_direction dir)
{
if (dir == IOPORT_DIR_OUTPUT) {
arch_ioport_pin_to_base(pin)->GPIO_ODERS = arch_ioport_pin_to_mask(pin);
// Always disable the Schmitt trigger for output pins.
arch_ioport_pin_to_base(pin)->GPIO_STERC = arch_ioport_pin_to_mask(pin);
} else if (dir == IOPORT_DIR_INPUT) {
arch_ioport_pin_to_base(pin)->GPIO_ODERC = arch_ioport_pin_to_mask(pin);
// Always enable the Schmitt trigger for input pins.
arch_ioport_pin_to_base(pin)->GPIO_STERS = arch_ioport_pin_to_mask(pin);
}
}
__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin,
bool level)
{
if (level) {
arch_ioport_pin_to_base(pin)->GPIO_OVRS = arch_ioport_pin_to_mask(pin);
} else {
arch_ioport_pin_to_base(pin)->GPIO_OVRC = arch_ioport_pin_to_mask(pin);
}
}
__always_inline static void arch_ioport_set_port_level(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_value level)
{
volatile GpioPort *base = arch_ioport_port_to_base(port);
if (level){
base->GPIO_OVRS = mask;
} else{
base->GPIO_OVRC = mask;
}
}
__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin)
{
return arch_ioport_pin_to_base(pin)->GPIO_PVR & arch_ioport_pin_to_mask(pin);
}
__always_inline static ioport_port_mask_t arch_ioport_get_port_level(
ioport_port_t port, ioport_port_mask_t mask)
{
return arch_ioport_port_to_base(port)->GPIO_PVR & mask;
}
__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
{
arch_ioport_pin_to_base(pin)->GPIO_OVRT = arch_ioport_pin_to_mask(pin);
}
__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->GPIO_OVRT = mask;
}
__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_sense pin_sense)
{
volatile GpioPort *base = arch_ioport_port_to_base(port);
if (pin_sense & 0x01) {
base->GPIO_IMR0S = mask;
} else {
base->GPIO_IMR0C = mask;
}
if (pin_sense & 0x02) {
base->GPIO_IMR1S = mask;
} else {
base->GPIO_IMR1C = mask;
}
}
__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin,
enum ioport_sense pin_sense)
{
arch_ioport_set_port_sense_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), pin_sense);
}
#endif /* IOPORT_SAM_H */

View File

@ -0,0 +1,383 @@
/**
* \file
*
* \brief SAM architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef IOPORT_SAM_H
#define IOPORT_SAM_H
#include <sysclk.h>
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 32 + (pin))
#define IOPORT_BASE_ADDRESS (uintptr_t)PIOA
#define IOPORT_PIO_OFFSET ((uintptr_t)PIOB - (uintptr_t)PIOA)
#define IOPORT_PIOA 0
#define IOPORT_PIOB 1
#define IOPORT_PIOC 2
#define IOPORT_PIOD 3
#define IOPORT_PIOE 4
#define IOPORT_PIOF 5
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the SAM Manual.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_MUX_MASK (0x7 << 0) /*!< MUX bits mask */
#define IOPORT_MODE_MUX_BIT0 ( 1 << 0) /*!< MUX BIT0 mask */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_MUX_BIT1 ( 1 << 1) /*!< MUX BIT1 mask */
#endif
#define IOPORT_MODE_MUX_A ( 0 << 0) /*!< MUX function A */
#define IOPORT_MODE_MUX_B ( 1 << 0) /*!< MUX function B */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_MUX_C ( 2 << 0) /*!< MUX function C */
#define IOPORT_MODE_MUX_D ( 3 << 0) /*!< MUX function D */
#endif
#define IOPORT_MODE_PULLUP ( 1 << 3) /*!< Pull-up */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_PULLDOWN ( 1 << 4) /*!< Pull-down */
#endif
#define IOPORT_MODE_OPEN_DRAIN ( 1 << 5) /*!< Open drain */
#define IOPORT_MODE_GLITCH_FILTER ( 1 << 6) /*!< Glitch filter */
#define IOPORT_MODE_DEBOUNCE ( 1 << 7) /*!< Input debounce */
/** @} */
/** @} */
typedef uint32_t ioport_mode_t;
typedef uint32_t ioport_pin_t;
typedef uint32_t ioport_port_t;
typedef uint32_t ioport_port_mask_t;
__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin)
{
return pin >> 5;
}
__always_inline static Pio *arch_ioport_port_to_base(ioport_port_t port)
{
#if (SAM4C || SAM4CM || SAM4CP)
if (port == IOPORT_PIOC) {
return (Pio *)(uintptr_t)PIOC;
# ifdef ID_PIOD
} else if (port == IOPORT_PIOD) {
return (Pio *)(uintptr_t)PIOD;
# endif
} else {
return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
(IOPORT_PIO_OFFSET * port));
}
#else
return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
(IOPORT_PIO_OFFSET * port));
#endif
}
__always_inline static Pio *arch_ioport_pin_to_base(ioport_pin_t pin)
{
return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin));
}
__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin)
{
return 1U << (pin & 0x1F);
}
__always_inline static void arch_ioport_init(void)
{
#ifdef ID_PIOA
sysclk_enable_peripheral_clock(ID_PIOA);
#endif
#ifdef ID_PIOB
sysclk_enable_peripheral_clock(ID_PIOB);
#endif
#ifdef ID_PIOC
sysclk_enable_peripheral_clock(ID_PIOC);
#endif
#ifdef ID_PIOD
sysclk_enable_peripheral_clock(ID_PIOD);
#endif
#ifdef ID_PIOE
sysclk_enable_peripheral_clock(ID_PIOE);
#endif
#ifdef ID_PIOF
sysclk_enable_peripheral_clock(ID_PIOF);
#endif
}
__always_inline static void arch_ioport_enable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_PER = mask;
}
__always_inline static void arch_ioport_disable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_PDR = mask;
}
__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin)
{
arch_ioport_enable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin)
{
arch_ioport_disable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_set_port_mode(ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
Pio *base = arch_ioport_port_to_base(port);
if (mode & IOPORT_MODE_PULLUP) {
base->PIO_PUER = mask;
} else {
base->PIO_PUDR = mask;
}
#if defined(IOPORT_MODE_PULLDOWN)
if (mode & IOPORT_MODE_PULLDOWN) {
base->PIO_PPDER = mask;
} else {
base->PIO_PPDDR = mask;
}
#endif
if (mode & IOPORT_MODE_OPEN_DRAIN) {
base->PIO_MDER = mask;
} else {
base->PIO_MDDR = mask;
}
if (mode & (IOPORT_MODE_GLITCH_FILTER | IOPORT_MODE_DEBOUNCE)) {
base->PIO_IFER = mask;
} else {
base->PIO_IFDR = mask;
}
if (mode & IOPORT_MODE_DEBOUNCE) {
#if SAM3U || SAM3XA
base->PIO_DIFSR = mask;
#else
base->PIO_IFSCER = mask;
#endif
} else {
#if SAM3U || SAM3XA
base->PIO_SCIFSR = mask;
#else
base->PIO_IFSCDR = mask;
#endif
}
#if !defined(IOPORT_MODE_MUX_BIT1)
if (mode & IOPORT_MODE_MUX_BIT0) {
base->PIO_ABSR |= mask;
} else {
base->PIO_ABSR &= ~mask;
}
#else
if (mode & IOPORT_MODE_MUX_BIT0) {
base->PIO_ABCDSR[0] |= mask;
} else {
base->PIO_ABCDSR[0] &= ~mask;
}
if (mode & IOPORT_MODE_MUX_BIT1) {
base->PIO_ABCDSR[1] |= mask;
} else {
base->PIO_ABCDSR[1] &= ~mask;
}
#endif
}
__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin,
ioport_mode_t mode)
{
arch_ioport_set_port_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), mode);
}
__always_inline static void arch_ioport_set_port_dir(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_direction group_direction)
{
Pio *base = arch_ioport_port_to_base(port);
if (group_direction == IOPORT_DIR_OUTPUT) {
base->PIO_OER = mask;
} else if (group_direction == IOPORT_DIR_INPUT) {
base->PIO_ODR = mask;
}
base->PIO_OWER = mask;
}
__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin,
enum ioport_direction dir)
{
Pio *base = arch_ioport_pin_to_base(pin);
if (dir == IOPORT_DIR_OUTPUT) {
base->PIO_OER = arch_ioport_pin_to_mask(pin);
} else if (dir == IOPORT_DIR_INPUT) {
base->PIO_ODR = arch_ioport_pin_to_mask(pin);
}
base->PIO_OWER = arch_ioport_pin_to_mask(pin);
}
__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin,
bool level)
{
Pio *base = arch_ioport_pin_to_base(pin);
if (level) {
base->PIO_SODR = arch_ioport_pin_to_mask(pin);
} else {
base->PIO_CODR = arch_ioport_pin_to_mask(pin);
}
}
__always_inline static void arch_ioport_set_port_level(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_value level)
{
Pio *base = arch_ioport_port_to_base(port);
if (level){
base->PIO_SODR = mask;
} else {
base->PIO_CODR = mask;
}
}
__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin)
{
return arch_ioport_pin_to_base(pin)->PIO_PDSR & arch_ioport_pin_to_mask(pin);
}
__always_inline static ioport_port_mask_t arch_ioport_get_port_level(
ioport_port_t port, ioport_port_mask_t mask)
{
return arch_ioport_port_to_base(port)->PIO_PDSR & mask;
}
__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
{
Pio *port = arch_ioport_pin_to_base(pin);
ioport_port_mask_t mask = arch_ioport_pin_to_mask(pin);
if (port->PIO_PDSR & arch_ioport_pin_to_mask(pin)) {
port->PIO_CODR = mask;
} else {
port->PIO_SODR = mask;
}
}
__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_ODSR ^= mask;
}
__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_sense pin_sense)
{
Pio *base = arch_ioport_port_to_base(port);
/* AIMMR ELSR FRLHSR
* 0 X X IOPORT_SENSE_BOTHEDGES (Default)
* 1 0 0 IOPORT_SENSE_FALLING
* 1 0 1 IOPORT_SENSE_RISING
* 1 1 0 IOPORT_SENSE_LEVEL_LOW
* 1 1 1 IOPORT_SENSE_LEVEL_HIGH
*/
switch(pin_sense) {
case IOPORT_SENSE_LEVEL_LOW:
base->PIO_LSR = mask;
base->PIO_FELLSR = mask;
break;
case IOPORT_SENSE_LEVEL_HIGH:
base->PIO_LSR = mask;
base->PIO_REHLSR = mask;
break;
case IOPORT_SENSE_FALLING:
base->PIO_ESR = mask;
base->PIO_FELLSR = mask;
break;
case IOPORT_SENSE_RISING:
base->PIO_ESR = mask;
base->PIO_REHLSR = mask;
break;
default:
base->PIO_AIMDR = mask;
return;
}
base->PIO_AIMER = mask;
}
__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin,
enum ioport_sense pin_sense)
{
arch_ioport_set_port_sense_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), pin_sense);
}
#endif /* IOPORT_SAM_H */

View File

@ -0,0 +1,305 @@
/**
* \file
*
* \brief SAM architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef IOPORT_SAM0_H
#define IOPORT_SAM0_H
#include <compiler.h>
#define IOPORT_CREATE_PIN(port, pin) ((port) * 32 + (pin))
// Aliases
#if (PORT_GROUPS > 0)
# define IOPORT_PORTA 0
#endif
#if (PORT_GROUPS > 1)
# define IOPORT_PORTB 1
#endif
#if (PORT_GROUPS > 2)
# define IOPORT_PORTC 2
#endif
#if (PORT_GROUPS > 3)
# define IOPORT_PORTD 3
#endif
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the device datasheet.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_MUX_MASK (0xF << 0) /*!< MUX bits mask */
#define IOPORT_MODE_MUX_BIT0 (1 << 0) /*!< MUX BIT0 mask */
#define IOPORT_MODE_MUX_BIT1 (1 << 1) /*!< MUX BIT1 mask */
#define IOPORT_MODE_MUX_BIT2 (1 << 2) /*!< MUX BIT2 mask */
#define IOPORT_MODE_MUX_BIT3 (1 << 3) /*!< MUX BIT3 mask */
#define IOPORT_MODE_MUX_A (0 << 0) /*!< MUX function A */
#define IOPORT_MODE_MUX_B (1 << 0) /*!< MUX function B */
#define IOPORT_MODE_MUX_C (2 << 0) /*!< MUX function C */
#define IOPORT_MODE_MUX_D (3 << 0) /*!< MUX function D */
#define IOPORT_MODE_MUX_E (4 << 0) /*!< MUX function E */
#define IOPORT_MODE_MUX_F (5 << 0) /*!< MUX function F */
#define IOPORT_MODE_MUX_G (6 << 0) /*!< MUX function G */
#define IOPORT_MODE_MUX_H (7 << 0) /*!< MUX function H */
#define IOPORT_MODE_PULLUP (1 << 4) /*!< Pull-up */
#define IOPORT_MODE_PULLDOWN (1 << 5) /*!< Pull-down */
#define IOPORT_MODE_OPEN_DRAIN (1 << 6) /*!< Open Drain */
#define IOPORT_MODE_DRIVE_STRENGTH (1 << 7) /*!< Extra drive strength */
/** @} */
/** @} */
typedef uint32_t ioport_mode_t;
typedef uint32_t ioport_pin_t;
typedef uint32_t ioport_port_t;
typedef uint32_t ioport_port_mask_t;
inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin)
{
return pin >> 5;
}
inline static PortGroup *arch_ioport_port_to_base(
ioport_port_t port)
{
return &PORT->Group[port];
}
inline static PortGroup *arch_ioport_pin_to_base(ioport_pin_t pin)
{
return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin));
}
inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin)
{
return 1U << (pin & 0x1F);
}
inline static void arch_ioport_init(void)
{
/* No implementation for SAM0 */
}
inline static void arch_ioport_enable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
volatile PortGroup *base = arch_ioport_port_to_base(port);
for (uint32_t i = 0; i < 32; i++) {
if (mask & (1 << i)) {
base->PINCFG[i].reg &= ~PORT_PINCFG_PMUXEN;
}
}
}
inline static void arch_ioport_disable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
volatile PortGroup *base = arch_ioport_port_to_base(port);
for (uint32_t i = 0; i < 32; i++) {
if (mask & (1 << i)) {
base->PINCFG[i].reg |= PORT_PINCFG_PMUXEN;
}
}
}
inline static void arch_ioport_enable_pin(ioport_pin_t pin)
{
arch_ioport_enable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
inline static void arch_ioport_disable_pin(ioport_pin_t pin)
{
arch_ioport_disable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
inline static void arch_ioport_set_port_mode(ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
PortGroup *base = arch_ioport_port_to_base(port);
uint32_t config_mask = 0;
uint32_t config_mux = 0;
config_mask |= PORT_WRCONFIG_INEN;
if ((mode & IOPORT_MODE_PULLDOWN) || (mode & IOPORT_MODE_PULLUP)) {
config_mask |= PORT_WRCONFIG_PULLEN;
}
#ifdef PORT_WRCONFIG_ODRAIN
if (mode & IOPORT_MODE_OPEN_DRAIN) {
config_mask |= PORT_WRCONFIG_ODRAIN;
}
#endif
if (mode & IOPORT_MODE_DRIVE_STRENGTH) {
config_mask |= PORT_WRCONFIG_DRVSTR;
}
config_mux = (mode & IOPORT_MODE_MUX_MASK) << PORT_WRCONFIG_PMUX_Pos;
uint32_t lower_pin_mask = (mask & 0xFFFF);
uint32_t upper_pin_mask = (mask >> 16);
base->WRCONFIG.reg =
(lower_pin_mask << PORT_WRCONFIG_PINMASK_Pos) |
config_mask | config_mux |
PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_WRPINCFG;
base->WRCONFIG.reg =
(upper_pin_mask << PORT_WRCONFIG_PINMASK_Pos) |
config_mask | config_mux |
PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_WRPINCFG |
PORT_WRCONFIG_HWSEL;
if (mode & IOPORT_MODE_PULLDOWN) {
base->OUTCLR.reg = mask;
}
else if (mode & IOPORT_MODE_PULLUP) {
base->OUTSET.reg = mask;
}
}
inline static void arch_ioport_set_pin_mode(ioport_pin_t pin,
ioport_mode_t mode)
{
arch_ioport_set_port_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), mode);
}
inline static void arch_ioport_set_port_dir(ioport_port_t port,
ioport_port_mask_t mask, unsigned char dir)
{
if (dir == IOPORT_DIR_OUTPUT) {
arch_ioport_port_to_base(port)->DIRSET.reg = mask;
} else if (dir == IOPORT_DIR_INPUT) {
arch_ioport_port_to_base(port)->DIRCLR.reg = mask;
}
}
inline static void arch_ioport_set_pin_dir(ioport_pin_t pin,
enum ioport_direction dir)
{
PortGroup *base = arch_ioport_pin_to_base(pin);
if (dir == IOPORT_DIR_OUTPUT) {
base->DIRSET.reg = arch_ioport_pin_to_mask(pin);
} else if (dir == IOPORT_DIR_INPUT) {
base->DIRCLR.reg = arch_ioport_pin_to_mask(pin);
}
base->PINCFG[pin].reg |= PORT_PINCFG_INEN;
}
inline static void arch_ioport_set_pin_level(ioport_pin_t pin,
bool level)
{
if (level) {
arch_ioport_pin_to_base(pin)->OUTSET.reg = arch_ioport_pin_to_mask(pin);
} else {
arch_ioport_pin_to_base(pin)->OUTCLR.reg = arch_ioport_pin_to_mask(pin);
}
}
inline static void arch_ioport_set_port_level(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_value level)
{
volatile PortGroup *base = arch_ioport_port_to_base(port);
if (level){
base->OUTSET.reg = mask;
} else {
base->OUTCLR.reg = mask;
}
}
inline static bool arch_ioport_get_pin_level(ioport_pin_t pin)
{
return arch_ioport_pin_to_base(pin)->IN.reg & arch_ioport_pin_to_mask(pin);
}
inline static ioport_port_mask_t arch_ioport_get_port_level(
ioport_port_t port, ioport_port_mask_t mask)
{
return arch_ioport_port_to_base(port)->IN.reg & mask;
}
inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
{
arch_ioport_pin_to_base(pin)->OUTTGL.reg = arch_ioport_pin_to_mask(pin);
}
inline static void arch_ioport_toggle_port_level(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->OUTTGL.reg = mask;
}
inline static void arch_ioport_set_port_sense_mode(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_sense pin_sense)
{
// TODO
Assert(false);
}
inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin,
enum ioport_sense pin_sense)
{
arch_ioport_set_port_sense_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), pin_sense);
}
#endif /* IOPORT_SAM0_H */

View File

@ -0,0 +1,253 @@
/**
* \file
*
* \brief FLIP protocol definitions.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _FLIP_PROTOCOL_H_
#define _FLIP_PROTOCOL_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup flip_protocol Atmel FLIP Protocol definitions
*
* To perform firmware upgrade, Atmel has developed an application called "FLIP"
* This software is a flexible application which lets you program and
* configure Atmel's microcontroller devices in their final environment
* without needing any dedicated hardware.
* @{
*/
//! \defgroup FLIP Protocol versions
//@{
#define FLIP_PROTOCOL_VERSION_2 2 // Used by UC3 parts and Xmega parts
#define FLIP_PROTOCOL_VERSION_1 1 // Used by Mega
#define FLIP_PROTOCOL_VERSION_0 0 // Used by C51 parts
//@}
/**
* \defgroup flip_pv1 Definitions for FLIP Protocol version 1
*
* Note: Used by Mega parts.
*
* @{
*/
COMPILER_PACK_SET(1)
/**
* \brief FLIP message structure
*/
typedef struct {
uint8_t cmd_id;
uint8_t arg[5];
} flip_msg_v1_t;
COMPILER_PACK_RESET()
//! Size of buffer used by FLIP to receive or send data
#define FLIP_V1_BUF_TRANS_SIZE 1024
//! \name FLIP commands
//@{
#define FLIP_V1_CMD_PROG_START 0x01
#define FLIP_V1_CMD_READ 0x03
#define FLIP_V1_CMD_WRITE 0x04
#define FLIP_V1_CMD_READ_ID 0x05
#define FLIP_V1_CMD_CHANGE_BASE_ADDR 0x06
//! \name FLIP_V1_CMD_PROG_START first argument
//@{
#define FLIP_V1_CMD_PROG_START_ARG_FLASH 0x00
#define FLIP_V1_CMD_PROG_START_ARG_EEPROM 0x01
#define FLIP_V1_CMD_PROG_START_ARG_CUSTOM 0x08
//@}
//! \name FLIP_V1_CMD_READ first argument
//@{
#define FLIP_V1_CMD_READ_ARG_FLASH 0x00
#define FLIP_V1_CMD_READ_ARG_FLASHCHECK 0x01
#define FLIP_V1_CMD_READ_ARG_EEPROM 0x02
#define FLIP_V1_CMD_READ_ARG_CUSTOM 0x03
//@}
//! \name FLIP_V1_CMD_WRITE first argument
//@{
#define FLIP_V1_CMD_WRITE_ARG_ERASE 0x00
#define FLIP_V1_CMD_WRITE_ARG_RST 0x03
//! \name FLIP_V1_CMD_WRITE_ARG_ERASE following argument
//@{
#define FLIP_V1_CMD_WRITE_ARG_ERASE_CHIP 0xFF
//@}
//! \name FLIP_V1_CMD_WRITE_ARG_RST following arguments
//@{
#define FLIP_V1_CMD_WRITE_ARG_RST_HW 0x00
#define FLIP_V1_CMD_WRITE_ARG_RST_SF 0x01
//@}
//@}
//! \name FLIP_V1_CMD_READ_ID first argument
//@{
#define FLIP_V1_CMD_READ_ID_ARG_BOOTLOADER 0x00
#define FLIP_V1_CMD_READ_ID_ARG_SIGNATURE 0x01
//! \name FLIP_V1_CMD_READ_ID_ARG_SIGNATURE following arguments
//@{
#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_MANUF 0x30
#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_FAMILY 0x31
#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_PRODUCT 0x60
#define FLIP_V1_CMD_READ_ID_SIGNATURE_ARG_REVISION 0x61
//@}
//@}
//! \name FLIP_V1_CMD_CHANGE_BASE_ADDR first argument
//@{
#define FLIP_V1_CMD_CHANGE_BASE_ADDR_ARG0 0x03
#define FLIP_V1_CMD_CHANGE_BASE_ADDR_ARG1 0x00
//@}
//@}
//@}
/**
* \defgroup flip_pv2 Definitions for Atmel FLIP Protocol version 2
*
* Note: Used by uc3 and Xmega parts
*
* @{
*/
COMPILER_PACK_SET(1)
/**
* \brief FLIP message structure
*/
typedef struct {
uint8_t group;
uint8_t cmd_id;
uint8_t arg[4];
} flip_msg_v2_t;
COMPILER_PACK_RESET()
//! Size of buffer used by FLIP to receive or send data
//! Note: Write uses 2K and Read uses 1KB
#define FLIP_V2_BUF_TRANS_SIZE (2*1024)
//! \name Command Groups
//@{
#define FLIP_V2_CMD_GRP_DNLOAD 0x01
#define FLIP_V2_CMD_GRP_UPLOAD 0x03
#define FLIP_V2_CMD_GRP_EXEC 0x04
#define FLIP_V2_CMD_GRP_SELECT 0x06
//@}
//! \name FLIP_V2_CMD_GRP_DNLOAD first argument
//@{
#define FLIP_V2_CMD_PROGRAM_START 0x00
//@}
//! \name FLIP_V2_CMD_GRP_UPLOAD first argument
//@{
#define FLIP_V2_CMD_READ_MEMORY 0x00
#define FLIP_V2_CMD_BLANK_CHECK 0x01
//@}
//! \name FLIP_V2_CMD_GRP_EXEC first argument
//@{
#define FLIP_V2_CMD_ERASE 0x00
#define FLIP_V2_CMD_START_APPLI 0x03
//! \name FLIP_V2_CMD_ERASE following argument
//@{
#define FLIP_V2_CMD_ERASE_ARG_CHIP 0xFF
//@}
//! \name FLIP_V2_CMD_START_APPLI following arguments
//@{
#define FLIP_V2_CMD_START_APPLI_ARG_RESET 0x00
#define FLIP_V2_CMD_START_APPLI_ARG_NO_RESET 0x01
//@}
//@}
//! \name FLIP_V2_CMD_GRP_SELECT first argument
//@{
#define FLIP_V2_CMD_SELECT_MEMORY 0x03
//! \name FLIP_V2_CMD_SELECT_MEMORY following arguments
//@{
#define FLIP_V2_CMD_SELECT_MEMORY_ARG_UNIT 0x00
#define FLIP_V2_CMD_SELECT_MEMORY_ARG_PAGE 0x01
//@}
//! \name FLIP_V2_CMD_SELECT_MEMORY_ARG_UNIT following arguments
//! Memory units field
//@{
#define FLIP_V2_CMD_SELECT_MEM_FLASH 0x00
#define FLIP_V2_CMD_SELECT_MEM_EEPROM 0x01
#define FLIP_V2_CMD_SELECT_MEM_SECURITY 0x02
#define FLIP_V2_CMD_SELECT_MEM_CONFIGURATION 0x03
#define FLIP_V2_CMD_SELECT_MEM_BOOTLOADER 0x04
#define FLIP_V2_CMD_SELECT_MEM_SIGNATURE 0x05
#define FLIP_V2_CMD_SELECT_MEM_USER 0x06
#define FLIP_V2_CMD_SELECT_MEM_INT_RAM 0x07
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS0 0x08
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS1 0x09
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS2 0x0A
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS3 0x0B
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS4 0x0C
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS5 0x0D
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS6 0x0E
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_CS7 0x0F
#define FLIP_V2_CMD_SELECT_MEM_EXT_MEM_DF 0x10
#define FLIP_V2_CMD_SELECT_MEM_COUNT 0x11 // Number of memory units
//@}
//@}
//@}
//@}
#ifdef __cplusplus
}
#endif
#endif // _FLIP_PROTOCOL_H_

View File

@ -0,0 +1,229 @@
/**
* \file
*
* \brief In System Programming API
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _ISP_H_
#define _ISP_H_
#include "conf_isp.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup isp In System Programming API
*
* @{
*/
/**
* \name Main In System Programming functions
* @{
*/
/**
* \brief Initializes the ISP interface
*
* Example, load the JTAG ID in signature memory
*/
void isp_init(void);
/**
* \brief Gives the security state of the chip
*
* \return \c 1 if chip is secured, otherwise \c 0.
*/
bool isp_is_security(void);
/**
* \brief Change the boot process configuration
* to enable/disable the ISP mode for the next startup.
*
* \param force Enable the ISP mode for the next startup if true
*/
void isp_force_boot_isp(bool force);
/**
* \brief Erase the application flash area and eventually the eeprom
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
bool isp_erase_chip(void);
/**
* \brief Erase a part of the application flash area
* This function must be called again as long as it returns 0.
*
* \return \c 1 if the whole application flash area is erased, otherwise it is
* not finished.
*
* This function has been created to split a long erase so that
* the ISP application is able to answer external pending requests.
*/
bool isp_erase_chip_split(void);
/**
* \brief Resets the device to start the user application
*
* The ISP mode must be disabled before (See isp_force_boot_isp(false))
* to allow the boot process to jump to the user application.
*
* \note: this function is usually implemented by using a watchdog reset
* or a software reset to restart the CPU.
*/
void isp_start_appli(void);
//! @}
//! Data type for holding flash memory addresses
#ifdef ISP_SMALL_MEMORY_SIZE
typedef uint16_t isp_addr_t;
#else
typedef uint32_t isp_addr_t;
#endif
//! Memory API definition
typedef struct {
//! Size of the memory (unit Byte)
uint32_t size;
//! Function to read memory
void (*fnct_read) (void *dst, isp_addr_t src, uint16_t nbytes);
//! Function to write memory
void (*fnct_write) (isp_addr_t dst, const void *src, uint16_t nbytes);
} isp_mem_t;
/**
* \name Memory units index values
* Used to access at a memory through \ref isp_memories list.
* @{
*/
#define ISP_MEM_FLASH 0x00
#define ISP_MEM_EEPROM 0x01
#define ISP_MEM_SECURITY 0x02
#define ISP_MEM_CONFIGURATION 0x03
#define ISP_MEM_BOOTLOADER 0x04
#define ISP_MEM_SIGNATURE 0x05
#define ISP_MEM_USER 0x06
#define ISP_MEM_INT_RAM 0x07
#define ISP_MEM_EXT_MEM_CS0 0x08
#define ISP_MEM_EXT_MEM_CS1 0x09
#define ISP_MEM_EXT_MEM_CS2 0x0A
#define ISP_MEM_EXT_MEM_CS3 0x0B
#define ISP_MEM_EXT_MEM_CS4 0x0C
#define ISP_MEM_EXT_MEM_CS5 0x0D
#define ISP_MEM_EXT_MEM_CS6 0x0E
#define ISP_MEM_EXT_MEM_CS7 0x0F
#define ISP_MEM_EXT_MEM_DF 0x10
#define ISP_MEM_COUNT 0x11 // Number of memory units
//! @}
//! Memories list structure
typedef union {
isp_mem_t const *mem[ISP_MEM_COUNT];
struct {
isp_mem_t const *flash;
isp_mem_t const *eeprom;
isp_mem_t const *security;
isp_mem_t const *conf;
isp_mem_t const *bootloader;
isp_mem_t const *signature;
isp_mem_t const *user;
isp_mem_t const *int_ram;
isp_mem_t const *ext_mem_cs0;
isp_mem_t const *ext_mem_cs1;
isp_mem_t const *ext_mem_cs2;
isp_mem_t const *ext_mem_cs3;
isp_mem_t const *ext_mem_cs4;
isp_mem_t const *ext_mem_cs5;
isp_mem_t const *ext_mem_cs6;
isp_mem_t const *ext_mem_cs7;
isp_mem_t const *ext_mem_df;
}list;
} isp_mems_t;
//! Memories list declaration
extern const isp_mems_t isp_memories;
COMPILER_PACK_SET(1) // alignment requested to simulate a memory
//! Memory signature structure to store JTAG ID
typedef union {
uint8_t mem[4];
struct {
uint8_t manufacture;
uint8_t product_number_msb;
uint8_t product_number_lsb;
uint8_t product_revision;
};
} isp_mem_signature_t;
/**
* Memory bootloader structure
*
* In the FLIP protocol, this structure is used to store medium
* and minor bootloader versions:
* - Example, Version 0x00 give 1.0.0 on batchisp log
* - Example, Version 0x03 give 1.0.3 on batchisp log
* - Example, Version 0x25 give 1.2.5 on batchisp log
* - id1 & id2 are not used and must always be 0.
*/
typedef struct {
uint8_t version;
uint8_t id1;
uint8_t id2;
} isp_mem_bootloader_t;
COMPILER_PACK_RESET()
//! @}
#ifdef __cplusplus
}
#endif
#endif // _ISP_H_

View File

@ -0,0 +1,73 @@
/**
* \file
*
* \brief ISP configuration file template.
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _CONF_ISP_H_
#define _CONF_ISP_H_
// Bootloader Versions
// Example: Version 0x00 gives 1.0.0 on batchisp log
// Example: Version 0x03 gives 1.0.3 on batchisp log
// Example: Version 0x25 gives 1.2.5 on batchisp log
//
// Note: a specific UC3 rule is defined:
// - 1.0.X for USB bootloaders that follow the AVR32784 application note
// specification
// - 1.1.X for USB bootloaders that follow the AVR32806 application note
// specification
//
#define BOOTLOADER_VERSION 0x00 // 1.0.0
// If all memories (flash,eeprom,...) do not exceed 64KB.
// then the ISP interface can be optimized to save CODE.
#define ISP_SMALL_MEMORY_SIZE
// Definition of hardware condition to enter in ISP mode on AVR Xmega devices
#define ISP_PORT_DIR PORTX_DIR
#define ISP_PORT_PINCTRL PORTX_PIN5CTRL
#define ISP_PORT_IN PORTX_IN
#define ISP_PORT_PIN 0 to 7
#endif // _CONF_ISP_H_

View File

@ -0,0 +1,151 @@
/**
* \file
*
* \brief USART Serial wrapper service for the SAM D/L/C/R devices.
*
* Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _USART_SERIAL_H_
#define _USART_SERIAL_H_
#include "compiler.h"
#include "status_codes.h"
#include "usart.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \name Serial Management Configuration */
typedef Sercom * usart_inst_t;
//struct usart_module usart;
/*! \brief Initializes the Usart in serial mode.
*
* \param[in,out] module Software instance of the USART to initialize.
* \param[in] hw Base address of the hardware USART.
* \param[in] config Configuration settings for the USART.
*
* \retval true if the initialization was successful
* \retval false if initialization failed (error in baud rate calculation)
*/
static inline bool usart_serial_init(
struct usart_module *const module,
usart_inst_t const hw,
const struct usart_config *const config)
{
if (usart_init(module, hw, config) == STATUS_OK) {
return true;
}
else {
return false;
}
}
/** \brief Sends a character with the USART.
*
* \param[in,out] module Software instance of the USART.
* \param[in] c Character to write.
*
* \return Status code
*/
static inline enum status_code usart_serial_putchar(
struct usart_module *const module,
uint8_t c)
{
while(STATUS_OK !=usart_write_wait(module, c));
return STATUS_OK;
}
/** \brief Waits until a character is received, and returns it.
*
* \param[in,out] module Software instance of the USART.
* \param[out] c Destination for the read character.
*/
static inline void usart_serial_getchar(
struct usart_module *const module,
uint8_t *c)
{
uint16_t temp = 0;
while(STATUS_OK != usart_read_wait(module, &temp));
*c = temp;
}
/**
* \brief Send a sequence of bytes to USART device
*
* \param[in,out] module Software instance of the USART.
* \param[in] tx_data Data buffer to read the data to write from.
* \param[in] length Length of data to write.
*/
static inline enum status_code usart_serial_write_packet(
struct usart_module *const module,
const uint8_t *tx_data,
uint16_t length)
{
return usart_write_buffer_wait(module, tx_data, length);
}
/**
* \brief Receive a sequence of bytes from USART device
*
* \param[in,out] module Software instance of the USART.
* \param[out] rx_data Data buffer to store the read data into.
* \param[in] length Length of data to read.
*/
static inline enum status_code usart_serial_read_packet(
struct usart_module *const module,
uint8_t *rx_data,
uint16_t length)
{
return usart_read_buffer_wait(module, rx_data, length);
}
#ifdef __cplusplus
}
#endif
#endif // _USART_SERIAL_H_

View File

@ -0,0 +1,71 @@
/**
* \file
*
* \brief Serial USART service configuration.
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_USART_SERIAL_H
#define CONF_USART_SERIAL_H
/* A reference setting for UART */
/** UART Interface */
//#define CONF_UART CONSOLE_UART
/** Baudrate setting */
//#define CONF_UART_BAUDRATE 115200
/** Parity setting */
//#define CONF_UART_PARITY UART_MR_PAR_NO
/* A reference setting for USART */
/** USART Interface */
//#define CONF_UART USART1
/** Baudrate setting */
//#define CONF_UART_BAUDRATE 115200
/** Character length setting */
//#define CONF_UART_CHAR_LENGTH US_MR_CHRL_8_BIT
/** Parity setting */
//#define CONF_UART_PARITY US_MR_PAR_NO
/** Stop bits setting */
//#define CONF_UART_STOP_BITS US_MR_NBSTOP_1_BIT
#endif/* CONF_USART_SERIAL_H_INCLUDED */

View File

@ -0,0 +1,689 @@
/**
* \file
*
* \brief Uart Serial for SAM.
*
* Copyright (c) 2011-2017 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _UART_SERIAL_H_
#define _UART_SERIAL_H_
#include "compiler.h"
#include "sysclk.h"
#if (SAMG55)
#include "flexcom.h"
#endif
#if ((!SAM4L) && (!SAMG55))
#include "uart.h"
#endif
#include "usart.h"
/**
* \name Serial Management Configuration
*/
//! @{
#include "conf_uart_serial.h"
//! @}
/** Input parameters when initializing RS232 and similar modes. */
typedef struct uart_rs232_options {
/** Set baud rate of the USART (unused in slave modes). */
uint32_t baudrate;
/** Number of bits to transmit as a character (5-bit to 9-bit). */
uint32_t charlength;
/**
* Parity type: USART_PMODE_DISABLED_gc, USART_PMODE_EVEN_gc,
* USART_PMODE_ODD_gc.
*/
uint32_t paritytype;
/** 1, 1.5 or 2 stop bits. */
uint32_t stopbits;
} usart_rs232_options_t;
typedef usart_rs232_options_t usart_serial_options_t;
typedef Usart *usart_if;
/**
* \brief Initializes the Usart in master mode.
*
* \param p_usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see
* \ref usart_options_t).
*/
static inline void usart_serial_init(usart_if p_usart,
usart_serial_options_t *opt)
{
#if ((!SAM4L) && (!SAMG55))
sam_uart_opt_t uart_settings;
uart_settings.ul_mck = sysclk_get_peripheral_hz();
uart_settings.ul_baudrate = opt->baudrate;
uart_settings.ul_mode = opt->paritytype;
#endif
sam_usart_opt_t usart_settings;
usart_settings.baudrate = opt->baudrate;
usart_settings.char_length = opt->charlength;
usart_settings.parity_type = opt->paritytype;
usart_settings.stop_bits= opt->stopbits;
usart_settings.channel_mode= US_MR_CHMODE_NORMAL;
#ifdef UART
if (UART == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
#else
# ifdef UART0
if (UART0 == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART0);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
# endif
# ifdef UART1
if (UART1 == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART1);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
# endif
# ifdef UART2
if (UART2 == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART2);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
# endif
# ifdef UART3
if (UART3 == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART3);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
# endif
# ifdef UART4
if (UART4 == (Uart*)p_usart) {
sysclk_enable_peripheral_clock(ID_UART4);
/* Configure UART */
uart_init((Uart*)p_usart, &uart_settings);
}
# endif
#endif /* ifdef UART */
#ifdef USART
if (USART == p_usart) {
#if (!SAM4L)
sysclk_enable_peripheral_clock(ID_USART);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
#else
# ifdef USART0
if (USART0 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM0);
flexcom_set_opmode(FLEXCOM0, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART0);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART1
if (USART1 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM1);
flexcom_set_opmode(FLEXCOM1, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART1);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART2
if (USART2 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM2);
flexcom_set_opmode(FLEXCOM2, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART2);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART3
if (USART3 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM3);
flexcom_set_opmode(FLEXCOM3, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART3);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART4
if (USART4 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM4);
flexcom_set_opmode(FLEXCOM4, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART4);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART5
if (USART5 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM5);
flexcom_set_opmode(FLEXCOM5, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART5);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART6
if (USART6 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM6);
flexcom_set_opmode(FLEXCOM6, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART6);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
# ifdef USART7
if (USART7 == p_usart) {
#if (!SAM4L)
#if (SAMG55)
flexcom_enable(FLEXCOM7);
flexcom_set_opmode(FLEXCOM7, FLEXCOM_USART);
#else
sysclk_enable_peripheral_clock(ID_USART7);
#endif
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_hz());
#endif
#if (SAM4L)
sysclk_enable_peripheral_clock(p_usart);
/* Configure USART */
usart_init_rs232(p_usart, &usart_settings,
sysclk_get_peripheral_bus_hz(p_usart));
#endif
/* Enable the receiver and transmitter. */
usart_enable_tx(p_usart);
usart_enable_rx(p_usart);
}
# endif
#endif /* ifdef USART */
}
/**
* \brief Sends a character with the USART.
*
* \param p_usart Base address of the USART instance.
* \param c Character to write.
*
* \return Status.
* \retval 1 The character was written.
* \retval 0 The function timed out before the USART transmitter became
* ready to send.
*/
static inline int usart_serial_putchar(usart_if p_usart, const uint8_t c)
{
#ifdef UART
if (UART == (Uart*)p_usart) {
while (uart_write((Uart*)p_usart, c)!=0);
return 1;
}
#else
# ifdef UART0
if (UART0 == (Uart*)p_usart) {
while (uart_write((Uart*)p_usart, c)!=0);
return 1;
}
# endif
# ifdef UART1
if (UART1 == (Uart*)p_usart) {
while (uart_write((Uart*)p_usart, c)!=0);
return 1;
}
# endif
# ifdef UART2
if (UART2 == (Uart*)p_usart) {
while (uart_write((Uart*)p_usart, c)!=0);
return 1;
}
# endif
# ifdef UART3
if (UART3 == (Uart*)p_usart) {
while (uart_write((Uart*)p_usart, c)!=0);
return 1;
}
# endif
#endif /* ifdef UART */
#ifdef USART
if (USART == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
#else
# ifdef USART0
if (USART0 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART1
if (USART1 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART2
if (USART2 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART3
if (USART3 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART4
if (USART4 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART5
if (USART5 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART6
if (USART6 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
# ifdef USART7
if (USART7 == p_usart) {
while (usart_write(p_usart, c)!=0);
return 1;
}
# endif
#endif /* ifdef USART */
return 0;
}
/**
* \brief Waits until a character is received, and returns it.
*
* \param p_usart Base address of the USART instance.
* \param data Data to read
*
*/
static inline void usart_serial_getchar(usart_if p_usart, uint8_t *data)
{
uint32_t val = 0;
/* Avoid Cppcheck Warning */
UNUSED(val);
#ifdef UART
if (UART == (Uart*)p_usart) {
while (uart_read((Uart*)p_usart, data));
}
#else
# ifdef UART0
if (UART0 == (Uart*)p_usart) {
while (uart_read((Uart*)p_usart, data));
}
# endif
# ifdef UART1
if (UART1 == (Uart*)p_usart) {
while (uart_read((Uart*)p_usart, data));
}
# endif
# ifdef UART2
if (UART2 == (Uart*)p_usart) {
while (uart_read((Uart*)p_usart, data));
}
# endif
# ifdef UART3
if (UART3 == (Uart*)p_usart) {
while (uart_read((Uart*)p_usart, data));
}
# endif
#endif /* ifdef UART */
#ifdef USART
if (USART == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
#else
# ifdef USART0
if (USART0 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART1
if (USART1 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART2
if (USART2 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART3
if (USART3 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART4
if (USART4 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART5
if (USART5 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART6
if (USART6 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
# ifdef USART7
if (USART7 == p_usart) {
while (usart_read(p_usart, &val));
*data = (uint8_t)(val & 0xFF);
}
# endif
#endif /* ifdef USART */
}
/**
* \brief Check if Received data is ready.
*
* \param p_usart Base address of the USART instance.
*
* \retval 1 One data has been received.
* \retval 0 No data has been received.
*/
static inline uint32_t usart_serial_is_rx_ready(usart_if p_usart)
{
#ifdef UART
if (UART == (Uart*)p_usart) {
return uart_is_rx_ready((Uart*)p_usart);
}
#else
# ifdef UART0
if (UART0 == (Uart*)p_usart) {
return uart_is_rx_ready((Uart*)p_usart);
}
# endif
# ifdef UART1
if (UART1 == (Uart*)p_usart) {
return uart_is_rx_ready((Uart*)p_usart);
}
# endif
# ifdef UART2
if (UART2 == (Uart*)p_usart) {
return uart_is_rx_ready((Uart*)p_usart);
}
# endif
# ifdef UART3
if (UART3 == (Uart*)p_usart) {
return uart_is_rx_ready((Uart*)p_usart);
}
# endif
#endif /* ifdef UART */
#ifdef USART
if (USART == p_usart) {
return usart_is_rx_ready(p_usart);
}
#else
# ifdef USART0
if (USART0 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART1
if (USART1 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART2
if (USART2 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART3
if (USART3 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART4
if (USART4 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART5
if (USART5 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART6
if (USART6 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
# ifdef USART7
if (USART7 == p_usart) {
return usart_is_rx_ready(p_usart);
}
# endif
#endif /* ifdef USART */
return 0;
}
/**
* \brief Send a sequence of bytes to a USART device
*
* \param usart Base address of the USART instance.
* \param data data buffer to write
* \param len Length of data
*
*/
status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data,
size_t len);
/**
* \brief Receive a sequence of bytes to a USART device
*
* \param usart Base address of the USART instance.
* \param data data buffer to write
* \param len Length of data
*
*/
status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data,
size_t len);
#endif /* _UART_SERIAL_H_ */

View File

@ -0,0 +1,279 @@
/**
* \file
*
* \brief Serial Mode management
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SERIAL_H_INCLUDED
#define SERIAL_H_INCLUDED
#include <parts.h>
#include "status_codes.h"
/**
* \typedef usart_if
*
* This type can be used independently to refer to USART module for the
* architecture used. It refers to the correct type definition for the
* architecture, ie. USART_t* for XMEGA or avr32_usart_t* for UC3.
*/
#if XMEGA
# include "xmega_usart/usart_serial.h"
#elif MEGA_RF
# include "megarf_usart/usart_serial.h"
#elif UC3
# include "uc3_usart/usart_serial.h"
#elif (SAMB)
#include "samb_uart/uart_serial.h"
#elif (SAM0)
#include "sam0_usart/usart_serial.h"
#elif SAM
# include "sam_uart/uart_serial.h"
#else
# error Unsupported chip type
#endif
/**
*
* \defgroup serial_group Serial Interface (Serial)
*
* See \ref serial_quickstart.
*
* This is the common API for serial interface. Additional features are available
* in the documentation of the specific modules.
*
* \section serial_group_platform Platform Dependencies
*
* The serial API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - usart_serial_init()
* - usart_serial_putchar()
* - usart_serial_getchar()
* - usart_serial_write_packet()
* - usart_serial_read_packet()
*
*
* @{
*/
//! @}
/**
* \page serial_quickstart Quick start guide for Serial Interface service
*
* This is the quick start guide for the \ref serial_group "Serial Interface module", with
* step-by-step instructions on how to configure and use the serial in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section serial_use_cases Serial use cases
* - \ref serial_basic_use_case
* - \subpage serial_use_case_1
*
* \section serial_basic_use_case Basic use case - transmit a character
* In this use case, the serial module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case waits for a received character on the configured USART and
* echoes the character back to the same USART.
*
* \section serial_basic_use_case_setup Setup steps
*
* \subsection serial_basic_use_case_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_basic_use_case_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_uart_serial.h file, but it can also be added to your main application file.)
*
* \note The following takes SAM3X configuration for example, other devices have similar
* configuration, but their parameters may be different, refer to corresponding header files.
*
* \code
#define USART_SERIAL &USARTD0
#define USART_SERIAL_BAUDRATE 9600
#define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
#define USART_SERIAL_PARITY US_MR_PAR_NO
#define USART_SERIAL_STOP_BIT false
\endcode
*
* A variable for the received byte must be added:
* \code uint8_t received_byte; \endcode
*
* Add to application initialization:
* \code
sysclk_init();
static usart_serial_options_t usart_options = {
.baudrate = USART_SERIAL_BAUDRATE,
.charlength = USART_SERIAL_CHAR_LENGTH,
.paritytype = USART_SERIAL_PARITY,
.stopbits = USART_SERIAL_STOP_BIT
};
usart_serial_init(USART_SERIAL, &usart_options);
\endcode
*
* \subsection serial_basic_use_case_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create serial USART options struct:
* - \code
static usart_serial_options_t usart_options = {
.baudrate = USART_SERIAL_BAUDRATE,
.charlength = USART_SERIAL_CHAR_LENGTH,
.paritytype = USART_SERIAL_PARITY,
.stopbits = USART_SERIAL_STOP_BIT
};
\endcode
* -# Initialize the serial service:
* - \code usart_serial_init(USART_SERIAL, &usart_options);\endcode
*
* \section serial_basic_use_case_usage Usage steps
*
* \subsection serial_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
usart_serial_getchar(USART_SERIAL, &received_byte);
usart_serial_putchar(USART_SERIAL, received_byte);
\endcode
*
* \subsection serial_basic_use_case_usage_flow Workflow
* -# Wait for reception of a character:
* - \code usart_serial_getchar(USART_SERIAL, &received_byte); \endcode
* -# Echo the character back:
* - \code usart_serial_putchar(USART_SERIAL, received_byte); \endcode
*/
/**
* \page serial_use_case_1 Advanced use case - Send a packet of serial data
*
* In this use case, the USART module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case sends a string of text through the USART.
*
* \section serial_use_case_1_setup Setup steps
*
* \subsection serial_use_case_1_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_use_case_1_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_uart_serial.h file, but it can also be added to your main application file.):
*
* \note The following takes SAM3X configuration for example, other devices have similar
* configuration, but their parameters may be different, refer to corresponding header files.
*
* \code
#define USART_SERIAL &USARTD0
#define USART_SERIAL_BAUDRATE 9600
#define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
#define USART_SERIAL_PARITY US_MR_PAR_NO
#define USART_SERIAL_STOP_BIT false
\endcode
*
* Add to application initialization:
* \code
sysclk_init();
static usart_serial_options_t usart_options = {
.baudrate = USART_SERIAL_BAUDRATE,
.charlength = USART_SERIAL_CHAR_LENGTH,
.paritytype = USART_SERIAL_PARITY,
.stopbits = USART_SERIAL_STOP_BIT
};
usart_serial_init(USART_SERIAL, &usart_options);
\endcode
*
* \subsection serial_use_case_1_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create USART options struct:
* - \code
static usart_serial_options_t usart_options = {
.baudrate = USART_SERIAL_BAUDRATE,
.charlength = USART_SERIAL_CHAR_LENGTH,
.paritytype = USART_SERIAL_PARITY,
.stopbits = USART_SERIAL_STOP_BIT
};
\endcode
* -# Initialize in RS232 mode:
* - \code usart_serial_init(USART_SERIAL_EXAMPLE, &usart_options); \endcode
*
* \section serial_use_case_1_usage Usage steps
*
* \subsection serial_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String"));
\endcode
*
* \subsection serial_use_case_1_usage_flow Workflow
* -# Write a string of text to the USART:
* - \code usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); \endcode
*/
#endif /* SERIAL_H_INCLUDED */

View File

@ -0,0 +1,87 @@
/**
*
* \file
*
* \brief USART Serial driver functions.
*
*
* Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "serial.h"
/**
* \brief Send a sequence of bytes to USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to read
* \param len Length of data
*
*/
status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data,
size_t len)
{
while (len) {
usart_serial_putchar(usart, *data);
len--;
data++;
}
return STATUS_OK;
}
/**
* \brief Receive a sequence of bytes from USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to write
* \param len Length of data
*
*/
status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data,
size_t len)
{
while (len) {
usart_serial_getchar(usart, data);
len--;
data++;
}
return STATUS_OK;
}

View File

@ -0,0 +1,52 @@
/**
* \file
*
* \brief Chip-specific sleep manager configuration
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_SLEEPMGR_H
#define CONF_SLEEPMGR_H
// Sleep manager options
#define CONFIG_SLEEPMGR_ENABLE
#endif /* CONF_SLEEPMGR_H */

View File

@ -0,0 +1,54 @@
/**
* \file
*
* \brief SAM3/SAM4 Sleep manager implementation.
*
* Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include <sleepmgr.h>
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
#endif /* CONFIG_SLEEPMGR_ENABLE */

View File

@ -0,0 +1,121 @@
/**
* \file
*
* \brief SAM3/SAM4 Sleep manager implementation.
*
* Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SAM_SLEEPMGR_INCLUDED
#define SAM_SLEEPMGR_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include <compiler.h>
#include <conf_sleepmgr.h>
#include <sleep.h>
#include <interrupt.h>
/**
* \weakgroup sleepmgr_group
* @{
*/
enum sleepmgr_mode {
//! Active mode.
SLEEPMGR_ACTIVE = 0,
/*! WFE sleep mode.
* Potential Wake Up sources:
* fast startup events (USB, RTC, RTT, WKUPs),
* interrupt, and events. */
SLEEPMGR_SLEEP_WFE,
/*! WFI sleep mode.
* Potential Wake Up sources: fast startup events and interrupt. */
SLEEPMGR_SLEEP_WFI,
/*! Wait mode, wakeup fast (in 3ms).
* XTAL is not disabled when sleep.
* Potential Wake Up sources: fast startup events */
SLEEPMGR_WAIT_FAST,
/*! Wait mode.
* Potential Wake Up sources: fast startup events */
SLEEPMGR_WAIT,
#if (!(SAMG51 || SAMG53 || SAMG54))
//! Backup mode. Potential Wake Up sources: WKUPs, SM, RTT, RTC.
SLEEPMGR_BACKUP,
#endif
SLEEPMGR_NR_OF_MODES,
};
/**
* \internal
* \name Internal arrays
* @{
*/
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
//! Sleep mode lock counters
extern uint8_t sleepmgr_locks[];
#endif /* CONFIG_SLEEPMGR_ENABLE */
//! @}
static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode)
{
Assert(sleep_mode != SLEEPMGR_ACTIVE);
#ifdef CONFIG_SLEEPMGR_ENABLE
cpu_irq_disable();
// Atomically enable the global interrupts and enter the sleep mode.
pmc_sleep(sleep_mode);
#else
UNUSED(sleep_mode);
cpu_irq_enable();
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
//! @}
#ifdef __cplusplus
}
#endif
#endif /* SAM_SLEEPMGR_INCLUDED */

View File

@ -0,0 +1,52 @@
/**
* \file
*
* \brief Chip-specific sleep manager configuration
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CONF_SLEEPMGR_INCLUDED
#define CONF_SLEEPMGR_INCLUDED
// Sleep manager options
#define CONFIG_SLEEPMGR_ENABLE
#endif /* CONF_SLEEPMGR_INCLUDED */

View File

@ -0,0 +1,53 @@
/**
* \file
*
* \brief Chip-specific sleep manager configuration
*
* Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include <sleepmgr.h>
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
#endif /* CONFIG_SLEEPMGR_ENABLE */

Some files were not shown because too many files have changed in this diff Show More