diff --git a/hardware/arduino/sam/libraries/CAN/arduino_due_x.h b/hardware/arduino/sam/libraries/CAN/arduino_due_x.h new file mode 100644 index 000000000..354ecd99a --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/arduino_due_x.h @@ -0,0 +1,866 @@ +/** + * \file + * + * \brief Arduino Due/X Board Definition. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef ARDUINO_DUE_X_H_INCLUDED +#define ARDUINO_DUE_X_H_INCLUDED + +#include "compiler.h" +#include "system_sam3x.h" +//#include "exceptions.h" + +/* ------------------------------------------------------------------------ */ + +/** + * \page arduino_due_x_opfreq "Arduino Due/X - Operating frequencies" + * This page lists several definition related to the board operating frequency + * + * \section Definitions + * - \ref BOARD_FREQ_* + * - \ref BOARD_MCK + */ + +/*! Board oscillator settings */ +#define BOARD_FREQ_SLCK_XTAL (32768U) +#define BOARD_FREQ_SLCK_BYPASS (32768U) +#define BOARD_FREQ_MAINCK_XTAL (12000000U) +#define BOARD_FREQ_MAINCK_BYPASS (12000000U) + +/*! Master clock frequency */ +#define BOARD_MCK CHIP_FREQ_CPU_MAX +#define BOARD_NO_32K_XTAL + +/** board main clock xtal statup time */ +#define BOARD_OSC_STARTUP_US 15625 + +/* ------------------------------------------------------------------------ */ + +/** + * \page arduino_due_x_board_info "Arduino Due/X - Board informations" + * This page lists several definition related to the board description. + * + * \section Definitions + * - \ref BOARD_NAME + */ + +/*! Name of the board */ +#define BOARD_NAME "Arduino Due/X" +/*! Board definition */ +#define arduinoduex +/*! Family definition (already defined) */ +#define sam3x +/*! Core definition */ +#define cortexm3 + +/* ------------------------------------------------------------------------ */ + +/** + * \page arduino_due_x_piodef "Arduino Due/X - PIO definitions" + * This pages lists all the pio definitions. The constants + * are named using the following convention: PIN_* for a constant which defines + * a single Pin instance (but may include several PIOs sharing the same + * controller), and PINS_* for a list of Pin instances. + * + */ + +/** + * \file + * ADC + * - \ref PIN_ADC0_AD1 + * - \ref PINS_ADC + * + */ + +/** + * \note ADC pins are automatically configured by the ADC peripheral as soon as + * the corresponding channel is enabled. + * + * \note On Arduino Due/X, Channel 1 is labelled A6 on the PCB. + */ + +/*! ADC_AD1 pin definition. */ +#define PIN_ADC0_AD1 {PIO_PA3X1_AD1, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT} +#define PINS_ADC_TRIG PIO_PA11_IDX +#define PINS_ADC_TRIG_FLAG (PIO_PERIPH_B | PIO_DEFAULT) +/*! Pins ADC */ +#define PINS_ADC PIN_ADC0_AD1 + +/** + * \file + * DAC + * + */ + +/** + * \note DAC pins are automatically configured by the DAC peripheral as soon + * as the corresponding channel is enabled. + * + * \note On Arduino Due/X, channel 0 is labelled A12 and channel 1 is labelled + * A13 on the PCB. + */ + + +/** + * \file + * LEDs + * + */ + +/* ------------------------------------------------------------------------ */ +/* LEDS */ +/* ------------------------------------------------------------------------ */ +/*! Power LED pin definition (ORANGE). L */ +#define PIN_POWER_LED {PIO_PB27, PIOB, ID_PIOB, PIO_OUTPUT_1, PIO_DEFAULT} +/*! LED #1 pin definition */ +#define PIN_USER_LED1 {PIO_PC21, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} +/*! LED #2 pin definition */ +#define PIN_USER_LED2 {PIO_PC22, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} +/*! LED #3 pin definition */ +#define PIN_USER_LED3 {PIO_PC23, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} + +/*! List of all LEDs definitions. */ +#define PINS_LEDS PIN_USER_LED1, PIN_USER_LED2, PIN_USER_LED3, PIN_POWER_LED + +/*! LED #0 "L" pin definition (ORANGE).*/ +#define LED_0_NAME "Orange_LED" +#define LED0_GPIO (PIO_PB27_IDX) +#define LED0_FLAGS (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT) +#define LED0_ACTIVE_LEVEL 0 + +#define PIN_LED_0 {1 << 27, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT} +#define PIN_LED_0_MASK (1 << 27) +#define PIN_LED_0_PIO PIOB +#define PIN_LED_0_ID ID_PIOB +#define PIN_LED_0_TYPE PIO_OUTPUT_0 +#define PIN_LED_0_ATTR PIO_DEFAULT + +/*! LED #1 pin definition */ +#define LED_1_NAME "External_LED_on_PWM9_connector_output" +#define LED1_GPIO (PIO_PC21_IDX) +#define LED1_FLAGS (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT) +#define LED1_ACTIVE_LEVEL 0 + +#define PIN_LED_1 {1 << 21, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_LED_1_MASK (1 << 21) +#define PIN_LED_1_PIO PIOC +#define PIN_LED_1_ID ID_PIOC +#define PIN_LED_1_TYPE PIO_OUTPUT_1 +#define PIN_LED_1_ATTR PIO_DEFAULT + +/*! LED #2 pin detection */ +#define LED2_GPIO (PIO_PC22_IDX) +#define LED2_FLAGS (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT) +#define LED2_ACTIVE_LEVEL 0 + +#define PIN_LED_2 {1 << 22, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_LED_2_MASK (1 << 22) +#define PIN_LED_2_PIO PIOC +#define PIN_LED_2_ID ID_PIOC +#define PIN_LED_2_TYPE PIO_OUTPUT_1 +#define PIN_LED_2_ATTR PIO_DEFAULT + +/*! LED #3 pin detection */ +#define LED3_GPIO (PIO_PC23_IDX) +#define LED3_FLAGS (PIO_TYPE_PIO_OUTPUT_1 | PIO_DEFAULT) +#define LED3_ACTIVE_LEVEL 1 + +#define BOARD_NUM_OF_LED 4 +#define PIN_LED_3 {1 << 23, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_LED_3_MASK (1 << 23) +#define PIN_LED_3_PIO PIOC +#define PIN_LED_3_ID ID_PIOC +#define PIN_LED_3_TYPE PIO_OUTPUT_1 +#define PIN_LED_3_ATTR PIO_DEFAULT + +/** + * \file + * Push buttons + * - \ref PIN_PB_LEFT_CLICK + * - \ref PIN_PB_RIGHT_CLICK + * - \ref PINS_PUSHBUTTONS + * - \ref PUSHBUTTON_BP1 + * - \ref PUSHBUTTON_BP2 + * + */ + +/* ------------------------------------------------------------------------ */ +/* PUSHBUTTONS */ +/* ------------------------------------------------------------------------ */ + +/**************************changing**********************************/ + +/** Push button LEFT CLICK definition. + * Attributes = pull-up + debounce + interrupt on falling edge. */ +#define PIN_PB_LEFT_CLICK {PIO_PD8, PIOD, ID_PIOD, PIO_INPUT,\ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE} + +/** Push button RIGHT CLICK definition. + * Attributes = pull-up + debounce + interrupt on falling edge. */ +#define PIN_PB_RIGHT_CLICK {PIO_PC28, PIOC, ID_PIOC, PIO_INPUT,\ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE} + +/*! List of all push button definitions. */ +#define PINS_PUSHBUTTONS PIN_PB_LEFT_CLICK, PIN_PB_RIGHT_CLICK + +/*! Push button #1 index. */ +#define PUSHBUTTON_BP1 0 +/*! Push button #2 index. */ +#define PUSHBUTTON_BP2 1 + +/*! Push button LEFT CLICK index. */ +#define PUSHBUTTON_LEFT 0 +/*! Push button RIGHT CLICK index. */ +#define PUSHBUTTON_RIGHT 1 + +/** Push button #0 definition. + * Attributes = pull-up + debounce + interrupt on rising edge. */ +#define PUSHBUTTON_1_NAME "External_PB1_on_PWM12_connector_output" + +#define GPIO_PUSH_BUTTON_1 (PIO_PD8_IDX) +#define GPIO_PUSH_BUTTON_1_FLAGS\ + (PIO_INPUT | PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE) + +#define PIN_PUSHBUTTON_1 {PIO_PD8, PIOD, ID_PIOD, PIO_INPUT,\ + PIO_PULLUP } +#define PIN_PUSHBUTTON_1_MASK PIO_PD8 +#define PIN_PUSHBUTTON_1_PIO PIOD +#define PIN_PUSHBUTTON_1_ID ID_PIOD +#define PIN_PUSHBUTTON_1_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_1_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE) + +/** Push button #1 definition. + * Attributes = pull-up + debounce + interrupt on falling edge. */ +#define PUSHBUTTON_2_NAME "External_PB2_on_PWM3_connector_output" +#define GPIO_PUSH_BUTTON_2 (PIO_PC28_IDX) +#define GPIO_PUSH_BUTTON_2_FLAGS\ + (PIO_INPUT | PIO_PULLUP) + +#define PIN_PUSHBUTTON_2 {PIO_PC28, PIOC, ID_PIOC, PIO_INPUT,\ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE} +#define PIN_PUSHBUTTON_2_MASK PIO_PC28 +#define PIN_PUSHBUTTON_2_PIO PIOC +#define PIN_PUSHBUTTON_2_ID ID_PIOC +#define PIN_PUSHBUTTON_2_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_2_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE) + + + +#define PIN_TC0_TIOA1 (PIO_PA2_IDX) +#define PIN_TC0_TIOA1_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +#define PIN_TC0_TIOA1_PIO PIOA +#define PIN_TC0_TIOA1_MASK PIO_PA2 +#define PIN_TC0_TIOA1_ID ID_PIOA +#define PIN_TC0_TIOA1_TYPE PIO_PERIPH_A +#define PIN_TC0_TIOA1_ATTR PIO_DEFAULT + + +#define PIN_TC0_TIOA0 (PIO_PB25_IDX) +#define PIN_TC0_TIOA0_FLAGS (PIO_INPUT | PIO_DEFAULT) + +#define PIN_TC0_TIOA0_PIO PIOB +#define PIN_TC0_TIOA0_MASK PIO_PB25 +#define PIN_TC0_TIOA0_ID ID_PIOB +#define PIN_TC0_TIOA0_TYPE PIO_INPUT +#define PIN_TC0_TIOA0_ATTR PIO_DEFAULT + +/** + * \file + * PWMC + * - \ref PIN_PWMC_PWMH0 + * - \ref PIN_PWMC_PWML4 + * - \ref PIN_PWMC_PWML5 + * - \ref PIN_PWMC_PWML6 + * - \ref PIN_PWM_LED0 + * - \ref PIN_PWM_LED1 + * - \ref PIN_PWM_LED2 + * + */ + +/* ------------------------------------------------------------------------ */ +/* PWM */ +/* ------------------------------------------------------------------------ */ +/*! PWMC PWM0 TRIG pin definition: Output High. */ +#define PIN_PWMC_PWMH0_TRIG PIO_PB12_IDX +#define PIN_PWMC_PWMH0_TRIG_FLAG PIO_PERIPH_B | PIO_DEFAULT + +/*! PWMC PWM4 pin definition: Output Low. */ +#define PIN_PWMC_PWML4\ + {PIO_PC21B_PWML4, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT} +/*! PWMC PWM5 pin definition: Output Low. */ +#define PIN_PWMC_PWML5\ + {PIO_PC22B_PWML5, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT} +/*! PWMC PWM6 pin definition: Output High. */ +#define PIN_PWMC_PWML6\ + {PIO_PC23B_PWML6, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT} + +/*! PWM pins definition for LED0 */ +#define PIN_PWM_LED0 PIN_PWMC_PWML4 +/*! PWM pins definition for LED1 */ +#define PIN_PWM_LED1 PIN_PWMC_PWML5 +/*! PWM pins definition for LED2 */ +#define PIN_PWM_LED2 PIN_PWMC_PWML6 + + +/*! PWM channel for LED0 */ +#define CHANNEL_PWM_LED0 PWM_CHANNEL_4 +/*! PWM channel for LED1 */ +#define CHANNEL_PWM_LED1 PWM_CHANNEL_5 +/*! PWM channel for LED2 */ +#define CHANNEL_PWM_LED2 PWM_CHANNEL_6 + +/*! PWM "PWM7" LED0 pin definitions.*/ +#define PIN_PWM_LED0_GPIO PIO_PC21_IDX +#define PIN_PWM_LED0_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +#define PIN_PWM_LED0_CHANNEL PWM_CHANNEL_4 + +/*! PWM "PWM8" LED1 pin definitions.*/ +#define PIN_PWM_LED1_GPIO PIO_PC22_IDX +#define PIN_PWM_LED1_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +#define PIN_PWM_LED1_CHANNEL PWM_CHANNEL_5 + +/*! PWM "PWM9" LED2 pin definitions.*/ +#define PIN_PWM_LED2_GPIO PIO_PC23_IDX +#define PIN_PWM_LED2_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +#define PIN_PWM_LED2_CHANNEL PWM_CHANNEL_6 + +/** + * \file + * SPI + * + */ + +/* ------------------------------------------------------------------------ */ +/* SPI */ +/* ------------------------------------------------------------------------ */ +/*! SPI0 MISO pin definition. */ +#define SPI0_MISO_GPIO (PIO_PA25_IDX) +#define SPI0_MISO_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI0 MOSI pin definition. */ +#define SPI0_MOSI_GPIO (PIO_PA26_IDX) +#define SPI0_MOSI_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI0 SPCK pin definition. */ +#define SPI0_SPCK_GPIO (PIO_PA27_IDX) +#define SPI0_SPCK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/*! SPI0 chip select 0 pin definition. (Only one configuration is possible) */ +#define SPI0_NPCS0_GPIO (PIO_PA28_IDX) +#define SPI0_NPCS0_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI0 chip select 1 pin definition. (multiple configurations are possible) */ +#define SPI0_NPCS1_PA29_GPIO (PIO_PA29_IDX) +#define SPI0_NPCS1_PA29_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +#define SPI0_NPCS1_PB20_GPIO (PIO_PB20_IDX) +#define SPI0_NPCS1_PB20_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/*! SPI0 chip select 2 pin definition. (multiple configurations are possible) */ +#define SPI0_NPCS2_PA30_GPIO (PIO_PA30_IDX) +#define SPI0_NPCS2_PA30_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +#define SPI0_NPCS2_PB21_GPIO (PIO_PB21_IDX) +#define SPI0_NPCS2_PB21_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/*! SPI0 chip select 3 pin definition. (multiple configurations are possible) */ +#define SPI0_NPCS3_PA31_GPIO (PIO_PA31_IDX) +#define SPI0_NPCS3_PA31_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +#define SPI0_NPCS3_PB23_GPIO (PIO_PB23_IDX) +#define SPI0_NPCS3_PB23_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) + +/*! SPI1 MISO pin definition. */ +#define SPI1_MISO_GPIO (PIO_PE28_IDX) +#define SPI1_MISO_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 MOSI pin definition. */ +#define SPI1_MOSI_GPIO (PIO_PE29_IDX) +#define SPI1_MOSI_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 SPCK pin definition. */ +#define SPI1_SPCK_GPIO (PIO_PE30_IDX) +#define SPI1_SPCK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 chip select 0 pin definition. (Only one configuration is possible) */ +#define SPI1_NPCS0_GPIO (PIO_PE31_IDX) +#define SPI1_NPCS0_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 chip select 1 pin definition. (Only one configuration is possible) */ +#define SPI1_NPCS1_GPIO (PIO_PF0_IDX) +#define SPI1_NPCS1_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 chip select 2 pin definition. (Only one configuration is possible) */ +#define SPI1_NPCS2_GPIO (PIO_PF1_IDX) +#define SPI1_NPCS2_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! SPI1 chip select 3 pin definition. (Only one configuration is possible) */ +#define SPI1_NPCS3_GPIO (PIO_PF2_IDX) +#define SPI1_NPCS3_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** + * \file + * SSC + * - \ref PIN_SSC_TD + * - \ref PIN_SSC_TK + * - \ref PIN_SSC_TF + * - \ref PIN_SSC_RD + * - \ref PIN_SSC_RK + * - \ref PIN_SSC_RF + * + */ +/* ------------------------------------------------------------------------ */ +/* SSC */ +/* ------------------------------------------------------------------------ */ +/** SSC pin Transmitter Data (TD) */ +#define PIN_SSC_TD (PIO_PA16_IDX) +#define PIN_SSC_TD_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/** SSC pin Transmitter Clock (TK) */ +#define PIN_SSC_TK (PIO_PA14_IDX) +#define PIN_SSC_TK_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/** SSC pin Transmitter FrameSync (TF) */ +#define PIN_SSC_TF (PIO_PA15_IDX) +#define PIN_SSC_TF_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/** SSC pin Receiver Data (RD) */ +#define PIN_SSC_RD (PIO_PB18_IDX) +#define PIN_SSC_RD_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/** SSC pin Receiver Clock (RK) */ +#define PIN_SSC_RK (PIO_PB19_IDX) +#define PIN_SSC_RK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/** SSC pin Receiver FrameSync (RF) */ +#define PIN_SSC_RF (PIO_PB17_IDX) +#define PIN_SSC_RF_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** + * \file + * PCK0 + * - \ref PIN_PCK0 + * + */ + +/* ------------------------------------------------------------------------ */ +/* PCK */ +/* ------------------------------------------------------------------------ */ +/*! PCK0 */ +#define PIN_PCK0 (PIO_PA1_IDX) +#define PIN_PCK0_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) + +#define PIN_PCK_0_MASK PIO_PA1 +#define PIN_PCK_0_PIO PIOA +#define PIN_PCK_0_ID ID_PIOA +#define PIN_PCK_0_TYPE PIO_PERIPH_B +#define PIN_PCK_0_ATTR PIO_DEFAULT +/** + * \file + * UART + * - \ref PINS_UART + * + */ + +/* ------------------------------------------------------------------------ */ +/* UART */ +/* ------------------------------------------------------------------------ */ +/*! UART pins (UTXD0 and URXD0) definitions, PA8,9. (labeled RX0->0 and TX0->1)*/ +#define PINS_UART (PIO_PA8A_URXD | PIO_PA9A_UTXD) +#define PINS_UART_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +#define PINS_UART_MASK (PIO_PA8A_URXD | PIO_PA9A_UTXD) +#define PINS_UART_PIO PIOA +#define PINS_UART_ID ID_PIOA +#define PINS_UART_TYPE PIO_PERIPH_A +#define PINS_UART_ATTR PIO_DEFAULT + +/** + * \file + * USART0 + * - \ref PIN_USART0_RXD + * - \ref PIN_USART0_TXD + */ +/* ------------------------------------------------------------------------ */ +/* USART0 */ +/* ------------------------------------------------------------------------ */ +/*! USART0 pin RX (labeled RX1 19)*/ +#define PIN_USART0_RXD\ + {PIO_PA10A_RXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} +#define PIN_USART0_RXD_IDX (PIO_PA10_IDX) +#define PIN_USART0_RXD_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/*! USART0 pin TX (labeled TX1 18) */ +#define PIN_USART0_TXD\ + {PIO_PA11A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} +#define PIN_USART0_TXD_IDX (PIO_PA11_IDX) +#define PIN_USART0_TXD_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** + * \file + * USART1 + * - \ref PIN_USART1_RXD + * - \ref PIN_USART1_TXD + */ +/* ------------------------------------------------------------------------ */ +/* USART1 */ +/* ------------------------------------------------------------------------ */ +/*! USART1 pin RX (labeled RX2 17) */ +#define PIN_USART1_RXD\ + {PIO_PA12A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} +#define PIN_USART1_RXD_IDX (PIO_PA12_IDX) +#define PIN_USART1_RXD_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! USART1 pin TX (labeled TX2 16) */ +#define PIN_USART1_TXD\ + {PIO_PA13A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} +#define PIN_USART1_TXD_IDX (PIO_PA13_IDX) +#define PIN_USART1_TXD_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/** + * \file + * USART3 + * - \ref PIN_USART3_RXD + * - \ref PIN_USART3_TXD + */ + +/* ------------------------------------------------------------------------ */ +/* USART3 */ +/* ------------------------------------------------------------------------ */ +/*! USART3 pin RX (labeled RX3 15) */ +#define PIN_USART3_RXD\ + {PIO_PD5B_RXD3, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT} +#define PIN_USART3_RXD_IDX (PIO_PD5_IDX) +#define PIN_USART3_RXD_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/*! USART3 pin TX (labeled RX3 14) */ +#define PIN_USART3_TXD\ + {PIO_PD4B_TXD3, PIOD, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT} +#define PIN_USART3_TXD_IDX (PIO_PD4_IDX) +#define PIN_USART3_TXD_FLAGS (PIO_PERIPH_B | PIO_DEFAULT) +/** + * \file + * USB + * - \ref PIN_USBOTG_VBOF + * - \ref PIN_USB_FAULT + * + */ + +/* ------------------------------------------------------------------------ */ +/* USB */ +/* ------------------------------------------------------------------------ */ +/*! USB OTG VBus On/Off: Bus Power Control Port. */ +#define PIN_UOTGHS_VBOF { PIO_PB10, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP } +/*! USB OTG Identification: Mini Connector Identification Port. */ +#define PIN_UOTGHS_ID { PIO_PB11, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP } + +/*! Multiplexed pin used for USB_ID: */ +#define USB_ID PIO_PB11_IDX +#define USB_ID_GPIO (PIO_PB11_IDX) +#define USB_ID_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! Multiplexed pin used for USB_VBOF: */ +#define USB_VBOF PIO_PB10_IDX +#define USB_VBOF_GPIO (PIO_PB10_IDX) +#define USB_VBOF_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +/*! Active level of the USB_VBOF output pin. */ +#define USB_VBOF_ACTIVE_LEVEL LOW +/* ------------------------------------------------------------------------ */ + + +/** + * \file + * CAN + * \ref PIN_CAN0_TRANSCEIVER_RXEN + * \ref PIN_CAN0_TRANSCEIVER_RS + * \ref PIN_CAN0_TXD + * \ref PIN_CAN0_RXD + * \ref PINS_CAN0 + * + * \ref PIN_CAN1_TRANSCEIVER_RXEN + * \ref PIN_CAN1_TRANSCEIVER_RS + * \ref PIN_CAN1_TXD + * \ref PIN_CAN1_RXD + * \ref PINS_CAN1 + */ + +/* ------------------------------------------------------------------------ */ +/* CAN */ +/* ------------------------------------------------------------------------ */ +/** CAN0 transceiver PIN RS. */ +#define PIN_CAN0_TR_RS_IDX PIO_PB20_IDX +#define PIN_CAN0_TR_RS_FLAGS (PIO_TYPE_PIO_OUTPUT_0 | PIO_DEFAULT) + +/** CAN0 transceiver PIN EN. */ +#define PIN_CAN0_TR_EN_IDX PIO_PB21_IDX +#define PIN_CAN0_TR_EN_FLAGS (PIO_TYPE_PIO_OUTPUT_0 | PIO_DEFAULT) + +/** CAN0 PIN RX. */ +#define PIN_CAN0_RX_IDX (PIO_PA1_IDX) +#define PIN_CAN0_RX_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** CAN0 PIN TX. */ +#define PIN_CAN0_TX_IDX (PIO_PA0_IDX) +#define PIN_CAN0_TX_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** CAN1 transceiver PIN RS. */ +#define PIN_CAN1_TR_RS_IDX PIO_PE15_IDX +#define PIN_CAN1_TR_RS_FLAGS (PIO_TYPE_PIO_OUTPUT_0 | PIO_DEFAULT) + +/** CAN1 transceiver PIN EN. */ +#define PIN_CAN1_TR_EN_IDX PIO_PE16_IDX +#define PIN_CAN1_TR_EN_FLAGS (PIO_TYPE_PIO_OUTPUT_0 | PIO_DEFAULT) + +/** CAN1 PIN RX. */ +#define PIN_CAN1_RX_IDX (PIO_PB15_IDX) +#define PIN_CAN1_RX_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** CAN1 PIN TX. */ +#define PIN_CAN1_TX_IDX (PIO_PB14_IDX) +#define PIN_CAN1_TX_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/** + +/** + * \file + * TWI + */ +/* ------------------------------------------------------------------------ */ +/* TWI */ +/* ------------------------------------------------------------------------ */ +/*! TWI0 pins definition */ +#define TWI0_DATA_GPIO PIO_PA17_IDX +#define TWI0_DATA_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +#define TWI0_CLK_GPIO PIO_PA18_IDX +#define TWI0_CLK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/*! TWI1 pins definition */ +#define TWI1_DATA_GPIO PIO_PB12_IDX +#define TWI1_DATA_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) +#define TWI1_CLK_GPIO PIO_PB13_IDX +#define TWI1_CLK_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) + +/* ------------------------------------------------------------------------ */ +/** + * \file + * NMA7341 + * - \NMA7341L_CHANNEL + * - \PIN_NMA7341L + */ + + +/** Definition of MMA7341L x,y,z axis channel number */ +#define MMA7341L_ADC_CHANNEL_X 2 +#define MMA7341L_ADC_CHANNEL_Y 6 +#define MMA7341L_ADC_CHANNEL_Z 7 + +/** MMA7341L mode set pin definition. */ +#define PIN_MMA7341L_MODE PIO_PC13_IDX +#define PIN_MMA7341L_MODE_FLAG PIO_OUTPUT_1 | PIO_DEFAULT + +/** MMA7341L X,Y,Z axis pin definition. */ +#define PIN_MMA7341L_X_AXIS PIO_PB3_IDX +#define PIN_MMA7341L_X_AXIS_FLAG PIO_INPUT | PIO_DEFAULT +#define PIN_MMA7341L_Y_AXIS PIO_PC17_IDX +#define PIN_MMA7341L_Y_AXIS_FLAG PIO_INPUT | PIO_DEFAULT +#define PIN_MMA7341L_Z_AXIS PIO_PC18_IDX +#define PIN_MMA7341L_Z_AXIS_FLAG PIO_INPUT | PIO_DEFAULT +/* ------------------------------------------------------------------------ */ +/** + * \file + * TouchScreen + * + * - \ref PIN_TSC_IRQ + * - \ref PIN_TSC_BUSY + * - \ref BOARD_TSC_SPI_BASE + * - \ref BOARD_TSC_SPI_ID + * - \ref BOARD_TSC_SPI_PINS + * - \ref BOARD_TSC_NPCS + * - \ref BOARD_TSC_NPCS_PIN + * + */ + +/* ------------------------------------------------------------------------ */ +/* Touchscreen */ +/* ------------------------------------------------------------------------ */ +/*! Touchscreen controller IRQ pin definition. */ +#define PIN_TSC_IRQ {PIO_PA31, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP} +/*! Touchscreen controller Busy pin definition. */ +#define PIN_TSC_BUSY {PIO_PA30, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP} + +/*! Chip select pin connected to the touchscreen controller. */ +/* We use PIO mode for chip select to meet ADS7843's timing specification */ +#define BOARD_TSC_NPCS_PIN\ + {PIO_PA28A_SPI0_NPCS0, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_PULLUP} + +/** + * \file + * EMAC + * - BOARD_EMAC_PHY_ADDR: Phy MAC address + * - BOARD_EMAC_MODE_RMII: Enable RMII connection with the PHY + */ +/*! EMAC pins */ +#define PIN_EEMAC_EREFCK PIO_PB0_IDX +#define PIN_EMAC_ETXEN PIO_PB1_IDX +#define PIN_EMAC_ETX0 PIO_PB2_IDX +#define PIN_EMAC_ETX1 PIO_PB3_IDX +#define PIN_EMAC_ECRSDV PIO_PB4_IDX +#define PIN_EMAC_ERX0 PIO_PB5_IDX +#define PIN_EMAC_ERX1 PIO_PB6_IDX +#define PIN_EMAC_ERXER PIO_PB7_IDX +#define PIN_EMAC_EMDC PIO_PB8_IDX +#define PIN_EMAC_EMDIO PIO_PB9_IDX +#define PIN_EMAC_FLAGS PIO_PERIPH_A | PIO_DEFAULT + +/*! EMAC PHY address */ +#define BOARD_EMAC_PHY_ADDR 0 +/*! EMAC RMII mode */ +#define BOARD_EMAC_MODE_RMII 1 + +/* ------------------------------------------------------------------------ */ +/* NAND FLASH */ +/* ------------------------------------------------------------------------ */ +/* Chip select number for nand */ +#define BOARD_NAND_CS 0 + +/*! Address for transferring command bytes to the nandflash. */ +#define BOARD_NF_COMMAND_ADDR 0x60400000 +/*! Address for transferring address bytes to the nandflash. */ +#define BOARD_NF_ADDRESS_ADDR 0x60200000 +/*! Address for transferring data bytes to the nandflash. */ +#define BOARD_NF_DATA_ADDR 0x60000000 +/* Bus width for NAND */ +#define CONF_NF_BUSWIDTH 8 +/* SMC NFC using five address cycle */ +#define CONF_NF_NEED_FIVE_ADDRESS_CYCLES 1 +/* Access timing for NAND */ +#define CONF_NF_SETUP_TIMING (SMC_SETUP_NWE_SETUP(0) \ + | SMC_SETUP_NCS_WR_SETUP(0) \ + | SMC_SETUP_NRD_SETUP(0) \ + | SMC_SETUP_NCS_RD_SETUP(0)) +#define CONF_NF_PULSE_TIMING (SMC_PULSE_NWE_PULSE(2) \ + | SMC_PULSE_NCS_WR_PULSE(3) \ + | SMC_PULSE_NRD_PULSE(2) \ + | SMC_PULSE_NCS_RD_PULSE(3)) +#define CONF_NF_CYCLE_TIMING (SMC_CYCLE_NWE_CYCLE(3) \ + | SMC_CYCLE_NRD_CYCLE(3)) +#define CONF_NF_TIMING (SMC_TIMINGS_TCLR(1) \ + | SMC_TIMINGS_TADL(6) \ + | SMC_TIMINGS_TAR(4) \ + | SMC_TIMINGS_TRR(2) \ + | SMC_TIMINGS_TWB(9) \ + | SMC_TIMINGS_RBNSEL(7) \ + | (SMC_TIMINGS_NFSEL)) +/* Support DMA */ +#define CONF_NF_USE_DMA +#ifdef CONF_NF_USE_DMA +/* DMA channel used for NF */ +#define CONF_NF_DMA_CHANNEL 0 +#endif + +/* ------------------------------------------------------------------------ */ +/* SDRAM */ +/* ------------------------------------------------------------------------ */ +/*! Board SDRAM size for MT48LC16M16A2 */ +#define BOARD_SDRAM_SIZE (32 * 1024 * 1024) /* 32 MB */ + +/*! List of all SDRAM pins definitions */ +#define PIO_SDRAM_SDCKE PIO_PD13 +#define PIO_SDRAM_SDCS PIO_PD12 +#define PIO_SDRAM_RAS PIO_PD15 +#define PIO_SDRAM_CAS PIO_PD16 +#define PIO_SDRAM_BA0 PIO_PD6 +#define PIO_SDRAM_BA1 PIO_PD7 +#define PIO_SDRAM_SDWE PIO_PD14 +//#define PIO_SDRAM_NBS0 PIO_PC21 +#define PIO_SDRAM_NBS1 PIO_PD10 +#define PIO_SDRAM_DATA (0xffff << 2) /*PIO_PC2--PIO_PC17 */ +//#define PIO_SDRAM_SDA0_A7 (0xff << 23) /*PIO_PC23--PIO_PC30 */ +#define PIO_SDRAM_SDA8 PIO_PD22 +#define PIO_SDRAM_SDA9 PIO_PD23 +#define PIO_SDRAM_SDA11 PIO_PD25 +#define PIO_SDRAM_SDA12 PIO_PD4 +#define PIO_SDRAM_SDA10 PIO_PD11 + +/*! List of all SDRAM pins definitions */ +#define PINS_SDRAM_PIOC\ + { PIO_SDRAM_DATA | PIO_SDRAM_NBS0 | PIO_SDRAM_SDA0_A7,\ + PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP } + +#define PINS_SDRAM_PIOD\ + { PIO_SDRAM_SDCKE | PIO_SDRAM_SDCS |\ + PIO_SDRAM_RAS | PIO_SDRAM_CAS |\ + PIO_SDRAM_BA0 | PIO_SDRAM_BA1 |\ + PIO_SDRAM_SDWE | PIO_SDRAM_NBS1 |\ + PIO_SDRAM_SDA10 |\ + PIO_SDRAM_SDA8 | PIO_SDRAM_SDA9 |\ + PIO_SDRAM_SDA11 | PIO_SDRAM_SDA12,\ + PIOD, ID_PIOD, PIO_PERIPH_A, PIO_PULLUP } + +/* PIO18 is used as SDRAM Enable on EK-REVB board */ +#define PINS_SDRAM_EN\ + { (1 << 18), PIOD, ID_PIOD, PIO_OUTPUT_1, PIO_DEFAULT } + +#define PINS_SDRAM PINS_SDRAM_PIOC, PINS_SDRAM_PIOD, PINS_SDRAM_EN + +/*! SDRAM bus width */ +#define BOARD_SDRAM_BUSWIDTH 16 + +/* SDRAMC clock speed */ +#define SDRAMC_CLK (BOARD_MCK) + +/** + * \file + * \section NorFlash + * - \ref BOARD_NORFLASH_ADDR + * + */ + +/* ------------------------------------------------------------------------ */ +/* NOR FLASH */ +/* ------------------------------------------------------------------------ */ +/*! Address for transferring command bytes to the norflash. */ +#define BOARD_NORFLASH_ADDR 0x60000000 + +/*! TWI ID for EEPROM application to use */ +#define BOARD_ID_TWI_EEPROM ID_TWI0 +/*! TWI Base for TWI EEPROM application to use */ +#define BOARD_BASE_TWI_EEPROM TWI0 + +/*! USART RX pin for application */ +#define BOARD_PIN_USART_RXD PIN_USART0_RXD +/*! USART TX pin for application */ +#define BOARD_PIN_USART_TXD PIN_USART0_TXD +/*! USART Base for application */ +#define BOARD_USART_BASE USART0 +/*! USART ID for application */ +#define BOARD_ID_USART ID_USART0 +/*! USART1 Base for application */ +#define BOARD_USART1_BASE USART1 +/*! USART1 ID for application */ +#define BOARD_ID_USART1 ID_USART1 +/*! USART3 Base for application */ +#define BOARD_USART3_BASE USART3 +/*! USART3 ID for application */ +#define BOARD_ID_USART3 ID_USART3 + +#define CONSOLE_UART UART +#define CONSOLE_UART_ID ID_UART + +#endif /* ARDUINO_DUE_X_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/board.h b/hardware/arduino/sam/libraries/CAN/board.h new file mode 100644 index 000000000..0262bbdc7 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/board.h @@ -0,0 +1,195 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2012 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 + * + */ + +#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 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 SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for 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 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF231 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). +//! @} + +# include "arduino_due_x.h" +//# include "system_sam3x.h" + +#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_ diff --git a/hardware/arduino/sam/libraries/CAN/can.cpp b/hardware/arduino/sam/libraries/CAN/can.cpp new file mode 100644 index 000000000..ac6830498 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/can.cpp @@ -0,0 +1,786 @@ +/** + * \file + * + * \brief Controller Area Network (CAN) driver module for SAM. + * + * Copyright (c) 2011 - 2012 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 "can.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Define the timemark mask. */ +#define TIMEMARK_MASK 0x0000ffff + +/* CAN timeout for synchronization. */ +#define CAN_TIMEOUT 100000 + +/** The max value for CAN baudrate prescale. */ +#define CAN_BAUDRATE_MAX_DIV 128 + +/** Define the scope for TQ. */ +#define CAN_MIN_TQ_NUM 8 +#define CAN_MAX_TQ_NUM 25 + +/** Define the fixed bit time value. */ +#define CAN_BIT_SYNC 1 +#define CAN_BIT_IPT 2 + +typedef struct { + uint8_t uc_tq; //! CAN_BIT_SYNC + uc_prog + uc_phase1 + uc_phase2 = uc_tq, 8 <= uc_tq <= 25. + uint8_t uc_prog; //! Propagation segment, (3-bits + 1), 1~8; + uint8_t uc_phase1; //! Phase segment 1, (3-bits + 1), 1~8; + uint8_t uc_phase2; //! Phase segment 2, (3-bits + 1), 1~8, CAN_BIT_IPT <= uc_phase2; + uint8_t uc_sjw; //! Resynchronization jump width, (2-bits + 1), min(uc_phase1, 4); + uint8_t uc_sp; //! Sample point value, 0~100 in percent. +} can_bit_timing_t; + +/** Values of bit time register for different baudrates, Sample point = ((1 + uc_prog + uc_phase1) / uc_tq) * 100%. */ +const can_bit_timing_t can_bit_time[] = { + {8, (2 + 1), (1 + 1), (1 + 1), (2 + 1), 75}, + {9, (1 + 1), (2 + 1), (2 + 1), (1 + 1), 67}, + {10, (2 + 1), (2 + 1), (2 + 1), (2 + 1), 70}, + {11, (3 + 1), (2 + 1), (2 + 1), (3 + 1), 72}, + {12, (2 + 1), (3 + 1), (3 + 1), (3 + 1), 67}, + {13, (3 + 1), (3 + 1), (3 + 1), (3 + 1), 77}, + {14, (3 + 1), (3 + 1), (4 + 1), (3 + 1), 64}, + {15, (3 + 1), (4 + 1), (4 + 1), (3 + 1), 67}, + {16, (4 + 1), (4 + 1), (4 + 1), (3 + 1), 69}, + {17, (5 + 1), (4 + 1), (4 + 1), (3 + 1), 71}, + {18, (4 + 1), (5 + 1), (5 + 1), (3 + 1), 67}, + {19, (5 + 1), (5 + 1), (5 + 1), (3 + 1), 68}, + {20, (6 + 1), (5 + 1), (5 + 1), (3 + 1), 70}, + {21, (7 + 1), (5 + 1), (5 + 1), (3 + 1), 71}, + {22, (6 + 1), (6 + 1), (6 + 1), (3 + 1), 68}, + {23, (7 + 1), (7 + 1), (6 + 1), (3 + 1), 70}, + {24, (6 + 1), (7 + 1), (7 + 1), (3 + 1), 67}, + {25, (7 + 1), (7 + 1), (7 + 1), (3 + 1), 68} +}; + +/** + * \brief Configure CAN baudrate. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param ul_mck The input main clock for the CAN module. + * \param ul_baudrate Baudrate value (kB/s), allowed values: + * 1000, 800, 500, 250, 125, 50, 25, 10, 5. + * + * \retval Set the baudrate successfully or not. + */ +static uint32_t can_set_baudrate(Can *p_can, uint32_t ul_mck, uint32_t ul_baudrate) +{ + uint8_t uc_tq; + uint8_t uc_prescale; + uint32_t ul_mod; + uint32_t ul_cur_mod; + can_bit_timing_t *p_bit_time; + + /* Check whether the baudrate prescale will be greater than the max divide value. */ + if (((ul_mck + (ul_baudrate * CAN_MAX_TQ_NUM * 1000 - 1)) / + (ul_baudrate * CAN_MAX_TQ_NUM * 1000)) > CAN_BAUDRATE_MAX_DIV) { + return 0; + } + + /* Check whether the input MCK is too small. */ + if (ul_mck < ul_baudrate * CAN_MIN_TQ_NUM * 1000) { + return 0; + } + + /* Initialize it as the minimum Time Quantum. */ + uc_tq = CAN_MIN_TQ_NUM; + + /* Initialize the remainder as the max value. When the remainder is 0, get the right TQ number. */ + ul_mod = 0xffffffff; + /* Find out the approximate Time Quantum according to the baudrate. */ + for (uint8_t i = CAN_MIN_TQ_NUM; i <= CAN_MAX_TQ_NUM; i++) { + if ((ul_mck / (ul_baudrate * i * 1000)) <= CAN_BAUDRATE_MAX_DIV) { + ul_cur_mod = ul_mck % (ul_baudrate * i * 1000); + if (ul_cur_mod < ul_mod){ + ul_mod = ul_cur_mod; + uc_tq = i; + if (!ul_mod) { + break; + } + } + } + } + + /* Calculate the baudrate prescale value. */ + uc_prescale = ul_mck / (ul_baudrate * uc_tq * 1000); + + /* Get the right CAN BIT Timing group. */ + p_bit_time = (can_bit_timing_t *)&can_bit_time[uc_tq - CAN_MIN_TQ_NUM]; + + /* Before modifying the CANBR register, disable the CAN controller. */ + can_disable(p_can); + + /* Write into the CAN baudrate register. */ + p_can->CAN_BR = CAN_BR_PHASE2(p_bit_time->uc_phase2 - 1) | + CAN_BR_PHASE1(p_bit_time->uc_phase1 - 1) | + CAN_BR_PROPAG(p_bit_time->uc_prog - 1) | + CAN_BR_SJW(p_bit_time->uc_sjw - 1) | + CAN_BR_BRP(uc_prescale - 1); + return 1; +} + + +/** + * \brief Initialize CAN controller. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param ul_mck CAN module input clock. + * \param ul_baudrate CAN communication baudrate in kbs. + * + * \retval 0 If failed to initialize the CAN module; otherwise successful. + * + * \note PMC clock for CAN peripheral should be enabled before calling this function. + */ +uint32_t can_init(Can *p_can, uint32_t ul_mck, uint32_t ul_baudrate) +{ + uint32_t ul_flag; + uint32_t ul_tick; + + /* Initialize the baudrate for CAN module. */ + ul_flag = can_set_baudrate(p_can, ul_mck, ul_baudrate); + if (ul_flag == 0) { + return 0; + } + + /* Reset the CAN eight message mailbox. */ + can_reset_all_mailbox(p_can); + + /* Enable the CAN controller. */ + can_enable(p_can); + + /* Wait until the CAN is synchronized with the bus activity. */ + ul_flag = 0; + ul_tick = 0; + while (!(ul_flag & CAN_SR_WAKEUP) && (ul_tick < CAN_TIMEOUT)) { + ul_flag = can_get_status(p_can); + ul_tick++; + } + + /* Timeout or the CAN module has been synchronized with the bus. */ + if (CAN_TIMEOUT == ul_tick) { + return 0; + } else { + return 1; + } +} + +/** + * \brief Enable CAN Controller. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_CANEN; +} + +/** + * \brief Disable CAN Controller. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_CANEN; +} + +/** + * \brief Disable CAN Controller low power mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_low_power_mode(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_LPM; +} + +/** + * \brief Enable CAN Controller low power mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_low_power_mode(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_LPM; +} + +/** + * \brief Disable CAN Controller autobaud/listen mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_autobaud_listen_mode(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_ABM; +} + +/** + * \brief Enable CAN Controller autobaud/listen mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_autobaud_listen_mode(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_ABM; +} + +/** + * \brief CAN Controller won't generate overload frame. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_overload_frame(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_OVL; +} + +/** + * \brief CAN Controller will generate an overload frame after each successful + * reception for mailboxes configured in Receive mode, Producer and Consumer. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_overload_frame(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_OVL; +} + +/** + * \brief Configure the timestamp capture point, at the start or the end of frame. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param ul_flag 0: Timestamp is captured at each start of frame; + * 1: Timestamp is captured at each end of frame. + */ +void can_set_timestamp_capture_point(Can *p_can, uint32_t ul_flag) +{ + if (ul_flag) { + p_can->CAN_MR |= CAN_MR_TEOF; + } else { + p_can->CAN_MR &= ~CAN_MR_TEOF; + } +} + +/** + * \brief Disable CAN Controller time triggered mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_time_triggered_mode(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_TTM; +} + +/** + * \brief Enable CAN Controller time triggered mode. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_time_triggered_mode(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_TTM; +} + +/** + * \brief Disable CAN Controller timer freeze. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_timer_freeze(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_TIMFRZ; +} + +/** + * \brief Enable CAN Controller timer freeze. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_timer_freeze(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_TIMFRZ; +} + +/** + * \brief Disable CAN Controller transmit repeat function. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_disable_tx_repeat(Can *p_can) +{ + p_can->CAN_MR |= CAN_MR_DRPT; +} + +/** + * \brief Enable CAN Controller transmit repeat function. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_enable_tx_repeat(Can *p_can) +{ + p_can->CAN_MR &= ~CAN_MR_DRPT; +} + +/** + * \brief Configure CAN Controller reception synchronization stage. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param ul_stage The reception stage to be configured. + * + * \note This is just for debug purpose only. + */ +void can_set_rx_sync_stage(Can *p_can, uint32_t ul_stage) +{ + p_can->CAN_MR = (p_can->CAN_MR & ~CAN_MR_RXSYNC_Msk) | ul_stage; +} + +/** + * \brief Enable CAN interrupt. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param dw_mask Interrupt to be enabled. + */ +void can_enable_interrupt(Can *p_can, uint32_t dw_mask) +{ + p_can->CAN_IER = dw_mask; +} + +/** + * \brief Disable CAN interrupt. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param dw_mask Interrupt to be disabled. + */ +void can_disable_interrupt(Can *p_can, uint32_t dw_mask) +{ + p_can->CAN_IDR = dw_mask; +} + +/** + * \brief Get CAN Interrupt Mask. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval CAN interrupt mask. + */ +uint32_t can_get_interrupt_mask(Can *p_can) +{ + return (p_can->CAN_IMR); +} + +/** + * \brief Get CAN status. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval CAN status. + */ +uint32_t can_get_status(Can *p_can) +{ + return (p_can->CAN_SR); +} + +/** + * \brief Get the 16-bit free-running internal timer count. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval The internal CAN free-running timer counter. + */ +uint32_t can_get_internal_timer_value(Can *p_can) +{ + return (p_can->CAN_TIM); +} + +/** + * \brief Get CAN timestamp register value. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval The timestamp value. + */ +uint32_t can_get_timestamp_value(Can *p_can) +{ + return (p_can->CAN_TIMESTP); +} + +/** + * \brief Get CAN transmit error counter. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval Transmit error counter. + */ +uint8_t can_get_tx_error_cnt(Can *p_can) +{ + return (uint8_t) (p_can->CAN_ECR >> CAN_ECR_TEC_Pos); +} + +/** + * \brief Get CAN receive error counter. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \retval Receive error counter. + */ +uint8_t can_get_rx_error_cnt(Can *p_can) +{ + return (uint8_t) (p_can->CAN_ECR >> CAN_ECR_REC_Pos); +} + +/** + * \brief Reset the internal free-running 16-bit timer. + * + * \param p_can Pointer to a CAN peripheral instance. + * + * \note If the internal timer counter is frozen, this function automatically + * re-enables it. + */ +void can_reset_internal_timer(Can *p_can) +{ + p_can->CAN_TCR |= CAN_TCR_TIMRST; +} + +/** + * \brief Send global transfer request. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_mask Mask for mailboxes that are requested to transfer. + */ +void can_global_send_transfer_cmd(Can *p_can, uint8_t uc_mask) +{ + uint32_t ul_reg; + + ul_reg = p_can->CAN_TCR & ((uint32_t)~GLOBAL_MAILBOX_MASK); + p_can->CAN_TCR = ul_reg | uc_mask; +} + +/** + * \brief Send global abort request. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_mask Mask for mailboxes that are requested to abort. + */ +void can_global_send_abort_cmd(Can *p_can, uint8_t uc_mask) +{ + uint32_t ul_reg; + + ul_reg = p_can->CAN_ACR & ((uint32_t)~GLOBAL_MAILBOX_MASK); + p_can->CAN_ACR = ul_reg | uc_mask; +} + +/** + * \brief Configure the timemark for the mailbox. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_index Indicate which mailbox is to be configured. + * \param us_cnt The timemark to be set. + * + * \note The timemark is active in Time Triggered mode only. + */ +void can_mailbox_set_timemark(Can *p_can, uint8_t uc_index, uint16_t us_cnt) +{ + uint32_t ul_reg; + + ul_reg = p_can->CAN_MB[uc_index].CAN_MMR & ((uint32_t)~TIMEMARK_MASK); + p_can->CAN_MB[uc_index].CAN_MMR = ul_reg | us_cnt; +} + +/** + * \brief Get status of the mailbox. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_index Indicate which mailbox is to be read. + * + * \retval The mailbox status. + */ +uint32_t can_mailbox_get_status(Can *p_can, uint8_t uc_index) +{ + return (p_can->CAN_MB[uc_index].CAN_MSR); +} + +/** + * \brief Send single mailbox transfer request. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_index Indicate which mailbox is to be configured. + */ +void can_mailbox_send_transfer_cmd(Can *p_can, uint8_t uc_index) +{ + p_can->CAN_MB[uc_index].CAN_MCR |= CAN_MCR_MTCR; +} + +/** + * \brief Send single mailbox abort request. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param uc_index Indicate which mailbox is to be configured. + */ +void can_mailbox_send_abort_cmd(Can *p_can, uint8_t uc_index) +{ + p_can->CAN_MB[uc_index].CAN_MCR |= CAN_MCR_MACR; +} + +/** + * \brief Initialize the mailbox in different mode and set up related configuration. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param p_mailbox Pointer to a CAN mailbox instance. + */ +void can_mailbox_init(Can *p_can, can_mb_conf_t *p_mailbox) +{ + uint8_t uc_index; + + uc_index = (uint8_t)p_mailbox->ul_mb_idx; + /* Check the object type of the mailbox. If it's used to disable the mailbox, reset the whole mailbox. */ + if (!p_mailbox->uc_obj_type) { + p_can->CAN_MB[uc_index].CAN_MMR = 0; + p_can->CAN_MB[uc_index].CAN_MAM = 0; + p_can->CAN_MB[uc_index].CAN_MID = 0; + p_can->CAN_MB[uc_index].CAN_MDL = 0; + p_can->CAN_MB[uc_index].CAN_MDH = 0; + p_can->CAN_MB[uc_index].CAN_MCR = 0; + return; + } + + /* Set the priority in Transmit mode. */ + p_can->CAN_MB[uc_index].CAN_MMR = (p_can->CAN_MB[uc_index].CAN_MMR & + ~CAN_MMR_PRIOR_Msk) | (p_mailbox-> uc_tx_prio << CAN_MMR_PRIOR_Pos); + + /* Set the message ID and message acceptance mask for the mailbox in other modes. */ + if (p_mailbox->uc_id_ver) { + p_can->CAN_MB[uc_index].CAN_MAM = p_mailbox->ul_id_msk | CAN_MAM_MIDE; + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id | CAN_MAM_MIDE; + } else { + p_can->CAN_MB[uc_index].CAN_MAM = p_mailbox->ul_id_msk; + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id; + } + + /* Set up mailbox in one of the five different modes. */ + p_can->CAN_MB[uc_index].CAN_MMR = (p_can->CAN_MB[uc_index].CAN_MMR & + ~CAN_MMR_MOT_Msk) | (p_mailbox-> uc_obj_type << CAN_MMR_MOT_Pos); +} + +/** + * \brief Read receive information for the mailbox. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param p_mailbox Pointer to a CAN mailbox instance. + * + * \retval Different CAN mailbox transfer status. + * + * \note Read the mailbox status before calling this function. + */ +uint32_t can_mailbox_read(Can *p_can, can_mb_conf_t *p_mailbox) +{ + uint32_t ul_status; + uint8_t uc_index; + uint32_t ul_retval; + + ul_retval = 0; + uc_index = (uint8_t)p_mailbox->ul_mb_idx; + ul_status = p_mailbox->ul_status; + + /* Check whether there is overwriting happening in Receive with Overwrite mode, + or there're messages lost in Receive mode. */ + if ((ul_status & CAN_MSR_MRDY) && (ul_status & CAN_MSR_MMI)) { + ul_retval = CAN_MAILBOX_RX_OVER; + } + + /* Read the message family ID. */ + p_mailbox->ul_fid = p_can->CAN_MB[uc_index].CAN_MFID & CAN_MFID_MFID_Msk; + + /* Read received data length. */ + p_mailbox->uc_length = (ul_status & CAN_MSR_MDLC_Msk) >> CAN_MSR_MDLC_Pos; + + /* Read received data. */ + p_mailbox->ul_datal = p_can->CAN_MB[uc_index].CAN_MDL; + if (p_mailbox->uc_length > 4) { + p_mailbox->ul_datah = p_can->CAN_MB[uc_index].CAN_MDH; + } + + /* Read the mailbox status again to check whether the software needs to re-read mailbox data register. */ + p_mailbox->ul_status = p_can->CAN_MB[uc_index].CAN_MSR; + ul_status = p_mailbox->ul_status; + if (ul_status & CAN_MSR_MMI) { + ul_retval |= CAN_MAILBOX_RX_NEED_RD_AGAIN; + } else { + ul_retval |= CAN_MAILBOX_TRANSFER_OK; + } + + /* Enable next receive process. */ + can_mailbox_send_transfer_cmd(p_can, uc_index); + + return ul_retval; +} + +/** + * \brief Prepare transmit information and write them into the mailbox. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param p_mailbox Pointer to a CAN mailbox instance. + * + * \retval CAN_MAILBOX_NOT_READY: Failed because mailbox isn't ready. + * CAN_MAILBOX_TRANSFER_OK: Successfully write message into mailbox. + * + * \note After calling this function, the mailbox message won't be sent out until + * can_mailbox_send_transfer_cmd() is called. + */ +uint32_t can_mailbox_write(Can *p_can, can_mb_conf_t *p_mailbox) +{ + uint32_t ul_status; + uint8_t uc_index; + + uc_index = (uint8_t)p_mailbox->ul_mb_idx; + /* Read the mailbox status firstly to check whether the mailbox is ready or not. */ + p_mailbox->ul_status = can_mailbox_get_status(p_can, uc_index); + ul_status = p_mailbox->ul_status; + if (!(ul_status & CAN_MSR_MRDY)) { + return CAN_MAILBOX_NOT_READY; + } + + /* Write transmit identifier. */ + if (p_mailbox->uc_id_ver) { + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id | CAN_MAM_MIDE; + } else { + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id; + } + + /* Write transmit data into mailbox data register. */ + p_can->CAN_MB[uc_index].CAN_MDL = p_mailbox->ul_datal; + if (p_mailbox->uc_length > 4) { + p_can->CAN_MB[uc_index].CAN_MDH = p_mailbox->ul_datah; + } + + /* Write transmit data length into mailbox control register. */ + p_can->CAN_MB[uc_index].CAN_MCR = (p_can->CAN_MB[uc_index].CAN_MCR & + ~CAN_MCR_MDLC_Msk) | CAN_MCR_MDLC(p_mailbox->uc_length); + + return CAN_MAILBOX_TRANSFER_OK; +} + +/** + * \brief Require to send out a remote frame. + * + * \param p_can Pointer to a CAN peripheral instance. + * \param p_mailbox Pointer to a CAN mailbox instance. + * + * \retval CAN_MAILBOX_NOT_READY: Failed because mailbox isn't ready for transmitting message. + * CAN_MAILBOX_TRANSFER_OK: Successfully send out a remote frame. + */ +uint32_t can_mailbox_tx_remote_frame(Can *p_can, can_mb_conf_t *p_mailbox) +{ + uint32_t ul_status; + uint8_t uc_index; + + uc_index = (uint8_t)p_mailbox->ul_mb_idx; + /* Read the mailbox status firstly to check whether the mailbox is ready or not. */ + p_mailbox->ul_status = p_can->CAN_MB[uc_index].CAN_MSR; + ul_status = p_mailbox->ul_status; + if (!(ul_status & CAN_MSR_MRDY)) { + return CAN_MAILBOX_NOT_READY; + } + + /* Write transmit identifier. */ + if (p_mailbox->uc_id_ver) { + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id | CAN_MAM_MIDE; + } else { + p_can->CAN_MB[uc_index].CAN_MID = p_mailbox->ul_id; + } + + /* Set the RTR bit in the sent frame. */ + p_can->CAN_MB[uc_index].CAN_MCR |= CAN_MCR_MRTR; + + /* Set the MBx bit in the Transfer Command Register to send out the remote frame. */ + can_global_send_transfer_cmd(p_can, (1 << uc_index)); + + return CAN_MAILBOX_TRANSFER_OK; +} + +/** + * \brief Reset the eight mailboxes. + * + * \param p_can Pointer to a CAN peripheral instance. + */ +void can_reset_all_mailbox(Can *p_can) +{ + can_mb_conf_t mb_config_t; + + /* Set the mailbox object type parameter to disable the mailbox. */ + mb_config_t.uc_obj_type = CAN_MB_DISABLE_MODE; + + for (uint8_t i = 0; i < CANMB_NUMBER; i++) { + mb_config_t.ul_mb_idx = i; + can_mailbox_init(p_can, &mb_config_t); + } +} + +void reset_mailbox_conf(can_mb_conf_t *p_mailbox) +{ + p_mailbox->ul_mb_idx = 0; + p_mailbox->uc_obj_type = 0; + p_mailbox->uc_id_ver = 0; + p_mailbox->uc_length = 0; + p_mailbox->uc_tx_prio = 0; + p_mailbox->ul_status = 0; + p_mailbox->ul_id_msk = 0; + p_mailbox->ul_id = 0; + p_mailbox->ul_fid = 0; + p_mailbox->ul_datal = 0; + p_mailbox->ul_datah = 0; +} + + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/hardware/arduino/sam/libraries/CAN/can.h b/hardware/arduino/sam/libraries/CAN/can.h new file mode 100644 index 000000000..8264d48b9 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/can.h @@ -0,0 +1,470 @@ +/** + * \file + * + * \brief Controller Area Network (CAN) driver module for SAM. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef CAN_H_INCLUDED +#define CAN_H_INCLUDED + +#include "compiler.h" + +/** @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/** @endcond */ + +/** Define the Mailbox mask for eight mailboxes. */ +#define GLOBAL_MAILBOX_MASK 0x000000ff + +/** Disable all interrupt mask */ +#define CAN_DISABLE_ALL_INTERRUPT_MASK 0xffffffff + +/** Define the typical baudrate for CAN communication in KHz. */ +#define CAN_BPS_1000K 1000 +#define CAN_BPS_800K 800 +#define CAN_BPS_500K 500 +#define CAN_BPS_250K 250 +#define CAN_BPS_125K 125 +#define CAN_BPS_50K 50 +#define CAN_BPS_25K 25 +#define CAN_BPS_10K 10 +#define CAN_BPS_5K 5 + +/** Define the mailbox mode. */ +#define CAN_MB_DISABLE_MODE 0 +#define CAN_MB_RX_MODE 1 +#define CAN_MB_RX_OVER_WR_MODE 2 +#define CAN_MB_TX_MODE 3 +#define CAN_MB_CONSUMER_MODE 4 +#define CAN_MB_PRODUCER_MODE 5 + +/** Define CAN mailbox transfer status code. */ +#define CAN_MAILBOX_TRANSFER_OK 0 //! Read from or write into mailbox successfully. +#define CAN_MAILBOX_NOT_READY 0x01 //! Receiver is empty or transmitter is busy. +#define CAN_MAILBOX_RX_OVER 0x02 //! Message overwriting happens or there're messages lost in different receive modes. +#define CAN_MAILBOX_RX_NEED_RD_AGAIN 0x04 //! Application needs to re-read the data register in Receive with Overwrite mode. + +/** Define the struct for CAN message mailbox. */ +typedef struct { + uint32_t ul_mb_idx; + uint8_t uc_obj_type; //! Mailbox object type, one of the six different objects. + uint8_t uc_id_ver; //! 0 stands for standard frame, 1 stands for extended frame. + uint8_t uc_length; //! Received data length or transmitted data length. + uint8_t uc_tx_prio; //! Mailbox priority, no effect in receive mode. + uint32_t ul_status; //! Mailbox status register value. + uint32_t ul_id_msk; //! No effect in transmit mode. + uint32_t ul_id; //! Received frame ID or the frame ID to be transmitted. + uint32_t ul_fid; //! Family ID. + uint32_t ul_datal; + uint32_t ul_datah; +} can_mb_conf_t; + +/** + * \defgroup sam_driver_can_group Controller Area Network (CAN) Driver + * + * See \ref sam_can_quickstart. + * + * \par Purpose + * + * The CAN controller provides all the features required to implement + * the serial communication protocol CAN defined by Robert Bosch GmbH, + * the CAN specification. This is a driver for configuration, enabling, + * disabling and use of the CAN peripheral. + * + * @{ + */ + +uint32_t can_init(Can *p_can, uint32_t ul_mck, uint32_t ul_baudrate); +void can_enable(Can *p_can); +void can_disable(Can *p_can); +void can_disable_low_power_mode(Can *p_can); +void can_enable_low_power_mode(Can *p_can); +void can_disable_autobaud_listen_mode(Can *p_can); +void can_enable_autobaud_listen_mode(Can *p_can); +void can_disable_overload_frame(Can *p_can); +void can_enable_overload_frame(Can *p_can); +void can_set_timestamp_capture_point(Can *p_can, uint32_t ul_flag); +void can_disable_time_triggered_mode(Can *p_can); +void can_enable_time_triggered_mode(Can *p_can); +void can_disable_timer_freeze(Can *p_can); +void can_enable_timer_freeze(Can *p_can); +void can_disable_tx_repeat(Can *p_can); +void can_enable_tx_repeat(Can *p_can); +void can_set_rx_sync_stage(Can *p_can, uint32_t ul_stage); +void can_enable_interrupt(Can *p_can, uint32_t dw_mask); +void can_disable_interrupt(Can *p_can, uint32_t dw_mask); +uint32_t can_get_interrupt_mask(Can *p_can); +uint32_t can_get_status(Can *p_can); +uint32_t can_get_internal_timer_value(Can *p_can); +uint32_t can_get_timestamp_value(Can *p_can); +uint8_t can_get_tx_error_cnt(Can *p_can); +uint8_t can_get_rx_error_cnt(Can *p_can); +void can_reset_internal_timer(Can *p_can); +void can_global_send_transfer_cmd(Can *p_can, uint8_t uc_mask); +void can_global_send_abort_cmd(Can *p_can, uint8_t uc_mask); +void can_mailbox_set_timemark(Can *p_can, uint8_t uc_index, uint16_t us_cnt); +uint32_t can_mailbox_get_status(Can *p_can, uint8_t uc_index); +void can_mailbox_send_transfer_cmd(Can *p_can, uint8_t uc_index); +void can_mailbox_send_abort_cmd(Can *p_can, uint8_t uc_index); +void can_mailbox_init(Can *p_can, can_mb_conf_t *p_mailbox); +uint32_t can_mailbox_read(Can *p_can, can_mb_conf_t *p_mailbox); +uint32_t can_mailbox_write(Can *p_can, can_mb_conf_t *p_mailbox); +uint32_t can_mailbox_tx_remote_frame(Can *p_can, can_mb_conf_t *p_mailbox); +void can_reset_all_mailbox(Can *p_can); +void reset_mailbox_conf(can_mb_conf_t *p_mailbox); + + +/** @} */ + +/** @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/** @endcond */ + +/** + * \page sam_can_quickstart Quickstart guide for SAM CAN module. + * + * This is the quickstart guide for the \ref sam_drivers_can_group "SAM CAN module", + * with step-by-step instructions on how to configure and use the drivers 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 can_basic_use_case Basic use case + * In this basic use case, as CAN module needs to work in network, two CAN modules + * need to be configured. CAN0 mailbox 0 is configured as transmitter, and CAN1 mailbox 0 + * is configured as receiver. The communication baudrate is 1Mbit/s. + * + * \section can_basic_use_case_setup Setup steps + * + * \subsection can_basic_use_case_setup_prereq Prerequisites + * - \ref group_pmc "Power Management Controller driver" + * - \ref group_sn65hvd234_transceiver "CAN transceiver driver" + * + * \subsection can_basic_use_case_setup_code Example code + * Add to application initialization: + * \code + * can_mb_conf_t can0_mailbox; + * can_mb_conf_t can1_mailbox; + * + * pmc_enable_periph_clk(ID_CAN0); + * pmc_enable_periph_clk(ID_CAN1); + * + * can_init(CAN0, ul_sysclk, CAN_BPS_1000K); + * can_init(CAN1, ul_sysclk, CAN_BPS_1000K); + * + * can_reset_all_mailbox(CAN0); + * can_reset_all_mailbox(CAN1); + * + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.uc_obj_type = CAN_MB_RX_MODE; + * can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk; + * can1_mailbox.ul_id = CAN_MID_MIDvA(0x07); + * can_mailbox_init(CAN1, &can1_mailbox); + * + * can0_mailbox.ul_mb_idx = 0; + * can0_mailbox.uc_obj_type = CAN_MB_TX_MODE; + * can0_mailbox.uc_tx_prio = 15; + * can0_mailbox.uc_id_ver = 0; + * can0_mailbox.ul_id_msk = 0; + * can_mailbox_init(CAN0, &can0_mailbox); + * + * can0_mailbox.ul_id = CAN_MID_MIDvA(0x07); + * can0_mailbox.ul_datal = 0x12345678; + * can0_mailbox.ul_datah = 0x87654321; + * can0_mailbox.uc_length = 8; + * can_mailbox_write(CAN0, &can0_mailbox); + * \endcode + * + * \subsection can_basic_use_case_setup_flow Workflow + * -# Define the CAN0 and CAN1 Transfer mailbox structure: + * - \code + * can_mb_conf_t can0_mailbox; + * can_mb_conf_t can1_mailbox; + * \endcode + * -# Enable the module clock for CAN0 and CAN1: + * - \code + * pmc_enable_periph_clk(ID_CAN0); + * pmc_enable_periph_clk(ID_CAN1); + * \endcode + * -# Initialize CAN0 and CAN1, baudrate is 1Mb/s: + * - \code + * can_init(CAN0, ul_sysclk, CAN_BPS_1000K); + * can_init(CAN1, ul_sysclk, CAN_BPS_1000K); + * \endcode + * - \note The CAN transceiver should be configured before initializing the CAN module. + * -# Reset all CAN0 and CAN1 mailboxes: + * - \code + * can_reset_all_mailbox(CAN0); + * can_reset_all_mailbox(CAN1); + * \endcode + * -# Initialize CAN1 mailbox 0 as receiver, frame ID is 0x07: + * - \code + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.uc_obj_type = CAN_MB_RX_MODE; + * can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk; + * can1_mailbox.ul_id = CAN_MID_MIDvA(0x07); + * can_mailbox_init(CAN1, &can1_mailbox); + * \endcode + * -# Initialize CAN0 mailbox 0 as transmitter, transmit priority is 15: + * - \code + * can0_mailbox.ul_mb_idx = 0; + * can0_mailbox.uc_obj_type = CAN_MB_TX_MODE; + * can0_mailbox.uc_tx_prio = 15; + * can0_mailbox.uc_id_ver = 0; + * can0_mailbox.ul_id_msk = 0; + * can_mailbox_init(CAN0, &can0_mailbox); + * \endcode + * -# Prepare transmit ID, data and data length in CAN0 mailbox 0: + * - \code + * can0_mailbox.ul_id = CAN_MID_MIDvA(0x07); + * can0_mailbox.ul_datal = 0x12345678; + * can0_mailbox.ul_datah = 0x87654321; + * can0_mailbox.uc_length = 8; + * can_mailbox_write(CAN0, &can0_mailbox); + * \endcode + * + * \section can_basic_use_case_usage Usage steps + * + * \subsection can_basic_use_case_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + * can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); + * + * while (!(can_mailbox_get_status(CAN1, 0) & CAN_MSR_MRDY)) { + * } + * + * can_mailbox_read(CAN1, &can1_mailbox); + * \endcode + * + * \subsection can_basic_use_case_usage_flow Workflow + * -# Send out data in CAN0 mailbox 0: + * - \code can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); \endcode + * -# Wait for CAN1 mailbox 0 to receive the data: + * - \code + * while (!(can_mailbox_get_status(CAN1, 0) & CAN_MSR_MRDY)) { + * } + * \endcode + * -# Read the received data from CAN1 mailbox 0: + * - \code can_mailbox_read(CAN1, &can1_mailbox); \endcode + * + * \section can_use_cases Advanced use cases + * For more advanced use of the CAN driver, see the following use cases: + * - \subpage can_use_case_1 : Two CAN modules work in PRODUCER and CONSUMER mode + * respectively, use CAN interrupt handler to check whether the communication has been + * completed. + */ + +/** + * \page can_use_case_1 Use case #1 + * + * In this use case, CAN0 mailbox 0 works in PRODUCER mode, and CAN1 mailbox 0 + * works in CONSUMER mode. While CAN1 mailbox 0 receives a data frame from the bus, + * an interrupt is triggered. + * + * \section can_use_case_1_setup Setup steps + * + * \subsection can_basic_use_case_setup_prereq Prerequisites + * - \ref group_pmc "Power Management Controller driver" + * - \ref group_sn65hvd234_transceiver "CAN transceiver driver" + * + * \subsection can_use_case_1_setup_code Example code + * Add to application C-file: + * \code + * can_mb_conf_t can0_mailbox; + * can_mb_conf_t can1_mailbox; + * volatile uint32_t g_ul_recv_status = 0; + * \endcode + * + * \code + * void CAN1_Handler(void) + * { + * uint32_t ul_status; + * + * ul_status = can_mailbox_get_status(CAN1, 0); + * if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) { + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.ul_status = ul_status; + * can_mailbox_read(CAN1, &can1_mailbox); + * g_ul_recv_status = 1; + * } + * } + * \endcode + * + * \code + * pmc_enable_periph_clk(ID_CAN0); + * pmc_enable_periph_clk(ID_CAN1); + * + * can_init(CAN0, ul_sysclk, CAN_BPS_1000K); + * can_init(CAN1, ul_sysclk, CAN_BPS_1000K); + * + * can_reset_all_mailbox(CAN0); + * can_reset_all_mailbox(CAN1); + * + * can0_mailbox.ul_mb_idx = 0; + * can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE; + * can0_mailbox.ul_id_msk = 0; + * can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b); + * can_mailbox_init(CAN0, &can0_mailbox); + * + * can0_mailbox.ul_datal = 0x11223344; + * can0_mailbox.ul_datah = 0x44332211; + * can0_mailbox.uc_length = 8; + * can_mailbox_write(CAN0, &can0_mailbox); + * + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.uc_obj_type = CAN_MB_CONSUMER_MODE; + * can1_mailbox.uc_tx_prio = 15; + * can1_mailbox.ul_id_msk = CAN_MID_MIDvA_Msk | CAN_MID_MIDvB_Msk; + * can1_mailbox.ul_id = CAN_MID_MIDvA(0x0b); + * can_mailbox_init(CAN1, &can1_mailbox); + * + * can_enable_interrupt(CAN1, CAN_IER_MB0); + * NVIC_EnableIRQ(CAN1_IRQn); + * \endcode + * + * \subsection can_use_case_1_setup_flow Workflow + * -# Define the CAN0 and CAN1 Transfer mailbox structure: + * - \code + * can_mb_conf_t can0_mailbox; + * can_mb_conf_t can1_mailbox; + * \endcode + * -# Define the receive flag that is changed in CAN1 ISR handler: + * - \code volatile uint32_t g_ul_recv_status = 0; \endcode + * -# Define the CAN1 ISR handler in the application: + * - \code void CAN1_Handler(void); \endcode + * -# In CAN1_Handler(), get CAN1 mailbox 0 status: + * - \code ul_status = can_mailbox_get_status(CAN1, 0); \endcode + * -# In CAN1_Handler(), check whether the mailbox 0 has received a data frame: + * - \code + * if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) { + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.ul_status = ul_status; + * can_mailbox_read(CAN1, &can1_mailbox); + * g_ul_recv_status = 1; + * } + * \endcode + * -# In CAN1_Handler(), if mailbox 0 is ready, read the received data from CAN1 mailbox 0: + * - \code + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.ul_status = ul_status; + * can_mailbox_read(CAN1, &can1_mailbox); + * \endcode + * -# In CAN1_Handler(), if mailbox 0 is ready, set up the receive flag: + * - \code g_ul_recv_status = 1; \endcode + * -# Enable the module clock for CAN0 and CAN1: + * - \code + * pmc_enable_periph_clk(ID_CAN0); + * pmc_enable_periph_clk(ID_CAN1); + * \endcode + * -# Initialize CAN0 and CAN1, baudrate is 1Mb/s: + * - \code + * can_init(CAN0, ul_sysclk, CAN_BPS_1000K); + * can_init(CAN1, ul_sysclk, CAN_BPS_1000K); + * \endcode + * - \note The CAN transceiver should be configured before initializing the CAN module. + * -# Reset all CAN0 and CAN1 mailboxes: + * - \code + * can_reset_all_mailbox(CAN0); + * can_reset_all_mailbox(CAN1); + * \endcode + * -# Initialize CAN0 mailbox 0 as PRODUCER: + * - \code + * can0_mailbox.ul_mb_idx = 0; + * can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE; + * can0_mailbox.ul_id_msk = 0; + * can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b); + * can_mailbox_init(CAN0, &can0_mailbox); + * \endcode + * -# Prepare the response information when it receives a remote frame: + * - \code + * can0_mailbox.ul_datal = 0x11223344; + * can0_mailbox.ul_datah = 0x44332211; + * can0_mailbox.uc_length = 8; + * can_mailbox_write(CAN0, &can0_mailbox); + * \endcode + * -# Initialize CAN1 mailbox 0 as CONSUMER: + * - \code + * can1_mailbox.ul_mb_idx = 0; + * can1_mailbox.uc_obj_type = CAN_MB_CONSUMER_MODE; + * can1_mailbox.uc_tx_prio = 15; + * can1_mailbox.ul_id_msk = CAN_MID_MIDvA_Msk | CAN_MID_MIDvB_Msk; + * can1_mailbox.ul_id = CAN_MID_MIDvA(0x0b); + * can_mailbox_init(CAN1, &can1_mailbox); + * \endcode + * -# Enable the CAN1 mailbox 0 interrupt: + * - \code + * can_enable_interrupt(CAN1, CAN_IER_MB0); + * NVIC_EnableIRQ(CAN1_IRQn); + * \endcode + * + * \section can_use_case_1_usage Usage steps + * + * \subsection can_use_case_1_usage_code Example code + * \code + * can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); + * can_global_send_transfer_cmd(CAN1, CAN_TCR_MB0); + * + * while (!g_ul_recv_status) { + * } + * \endcode + * + * \subsection can_use_case_1_usage_flow Workflow + * -# Enable CAN0 mailbox 0 to receive remote frame and respond it: + * - \code can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); \endcode + * -# Enable CAN1 mailbox 0 to send out a remote frame and then receive data frame from bus: + * - \code can_global_send_transfer_cmd(CAN1, CAN_TCR_MB0); \endcode + * -# Wait for the communication to be completed. + * - \code + * while (!g_ul_recv_status) { + * } + * \endcode + */ + +#endif /* CAN_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/compiler.h b/hardware/arduino/sam/libraries/CAN/compiler.h new file mode 100644 index 000000000..060ccd050 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/compiler.h @@ -0,0 +1,1022 @@ +/** + * \file + * + * \brief Commonly used includes, types and macros. + * + * Copyright (c) 2010-2012 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 + * + */ + +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup group_sam_utils Compiler abstraction layer and code utilities + * + * Compiler abstraction layer and code utilities for AT91SAM. + * This module provides various abstraction layers and utilities to make code compatible between different compilers. + * + * \{ + */ +#include + +#if (defined __ICCARM__) +# include +#endif + +#include +//#include "preprocessor.h" + +#include "sam3x8e.h" +//#include + +//_____ D E C L A R A T I O N S ____________________________________________ + +#ifndef __ASSEMBLY__ // Not defined for assembling. + +#include +#include +#include +#include + +#ifdef __ICCARM__ +/*! \name Compiler Keywords + * + * Port of some keywords from GCC to IAR Embedded Workbench. + */ +//! @{ +#define __asm__ asm +#define __inline__ inline +#define __volatile__ +//! @} + +#endif + +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +/** + * \def unused + * \brief Marking \a v as a unused parameter or value. + */ +#define unused(v) do { (void)(v); } while(0) + +/** + * \def barrier + * \brief Memory barrier + */ +#define barrier() __DMB() + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/** + * \def COMPILER_PACK_SET(alignment) + * \brief Set maximum alignment for subsequent struct and union + * definitions to \a alignment. + */ +#define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) + +/** + * \def COMPILER_PACK_RESET() + * \brief Set default alignment for subsequent struct and union + * definitions. + */ +#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) + + +/** + * \brief Set aligned boundary. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif (defined __ICCARM__) +# define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#endif + +/** + * \brief Set word-aligned boundary. + */ +#if (defined __GNUC__) || defined(__CC_ARM) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) +#elif (defined __ICCARM__) +#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) +#endif + +/** + * \def __always_inline + * \brief The function should always be inlined. + * + * This annotation instructs the compiler to ignore its inlining + * heuristics and inline the function no matter how big it thinks it + * becomes. + */ +#if defined(__CC_ARM) +# define __always_inline __forceinline +#elif (defined __GNUC__) +# define __always_inline inline __attribute__((__always_inline__)) +#elif (defined __ICCARM__) +# define __always_inline _Pragma("inline=forced") +#endif + +/*! \brief This macro is used to test fatal errors. + * + * The macro tests if the expression is false. If it is, a fatal error is + * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO + * is defined, a unit test version of the macro is used, to allow execution + * of further tests after a false expression. + * + * \param expr Expression to evaluate and supposed to be nonzero. + */ +#if defined(_ASSERT_ENABLE_) +# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) + // Assert() is defined in unit_test/suite.h +# include "unit_test/suite.h" +# else +#undef TEST_SUITE_DEFINE_ASSERT_MACRO +# define Assert(expr) \ + {\ + if (!(expr)) while (true);\ + } +# endif +#else +# define Assert(expr) ((void) 0) +#endif + +/* Define WEAK attribute */ +#if defined ( __CC_ARM ) /* Keil µVision 4 */ +# define WEAK __attribute__ ((weak)) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +# define WEAK __weak +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ +# define WEAK __attribute__ ((weak)) +#endif + +/* Define NO_INIT attribute */ +#if defined ( __CC_ARM ) +# define NO_INIT __attribute__((zero_init)) +#elif defined ( __ICCARM__ ) +# define NO_INIT __no_init +#elif defined ( __GNUC__ ) +# define NO_INIT __attribute__((section(".no_init"))) +#endif + +/* Define RAMFUNC attribute */ +#if defined ( __CC_ARM ) /* Keil µVision 4 */ +# define RAMFUNC __attribute__ ((section(".ramfunc"))) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +# define RAMFUNC __ramfunc +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ +# define RAMFUNC __attribute__ ((section(".ramfunc"))) +#endif + +# include "interrupt_sam_nvic.h" + +/*! \name Usual Types + */ +//! @{ +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8 ; //!< 8-bit signed integer. +typedef uint8_t U8 ; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef int64_t S64; //!< 64-bit signed integer. +typedef uint64_t U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint32_t iram_size_t; +//! @} + + +/*! \name Status Types + */ +//! @{ +typedef bool Status_bool_t; //!< Boolean status. +typedef U8 Status_t; //!< 8-bit-coded status. +//! @} + + +/*! \name Aliasing Aggregate Types + */ +//! @{ + +//! 16-bit union. +typedef union +{ + S16 s16 ; + U16 u16 ; + S8 s8 [2]; + U8 u8 [2]; +} Union16; + +//! 32-bit union. +typedef union +{ + S32 s32 ; + U32 u32 ; + S16 s16[2]; + U16 u16[2]; + S8 s8 [4]; + U8 u8 [4]; +} Union32; + +//! 64-bit union. +typedef union +{ + S64 s64 ; + U64 u64 ; + S32 s32[2]; + U32 u32[2]; + S16 s16[4]; + U16 u16[4]; + S8 s8 [8]; + U8 u8 [8]; +} Union64; + +//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} UnionPtr; + +//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} UnionVPtr; + +//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} UnionCPtr; + +//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} UnionCVPtr; + +//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} StructPtr; + +//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} StructVPtr; + +//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} StructCPtr; + +//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} StructCVPtr; + +//! @} + +#endif // #ifndef __ASSEMBLY__ + +/*! \name Usual Constants + */ +//! @{ +#define DISABLE 0 +#define ENABLE 1 +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +#define false 0 +#define true 1 +#endif +#endif +#define PASS 0 +#define FAIL 1 +#define LOW 0 +#define HIGH 1 +//! @} + + +#ifndef __ASSEMBLY__ // not for assembling. + +//! \name Optimization Control +//@{ + +/** + * \def likely(exp) + * \brief The expression \a exp is likely to be true + */ +#ifndef likely +# define likely(exp) (exp) +#endif + +/** + * \def unlikely(exp) + * \brief The expression \a exp is unlikely to be true + */ +#ifndef unlikely +# define unlikely(exp) (exp) +#endif + +/** + * \def is_constant(exp) + * \brief Determine if an expression evaluates to a constant value. + * + * \param exp Any expression + * + * \return true if \a exp is constant, false otherwise. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define is_constant(exp) __builtin_constant_p(exp) +#else +# define is_constant(exp) (0) +#endif + +//! @} + +/*! \name Bit-Field Handling + */ +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value) & (mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask))) + +//! @} + + +/*! \name Zero-Bit Counting + * + * Under GCC, __builtin_clz and __builtin_ctz behave like macros when + * applied to constant expressions (values known at compile time), so they are + * more optimized than the use of the corresponding assembly instructions and + * they can be used as constant expressions e.g. to initialize objects having + * static storage duration, and like the corresponding assembly instructions + * when applied to non-constant expressions (values unknown at compile time), so + * they are more optimized than an assembly periphrasis. Hence, clz and ctz + * ensure a possible and optimized behavior for both constant and non-constant + * expressions. + */ +//! @{ + +/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the leading zero bits. + * + * \return The count of leading zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define clz(u) __builtin_clz(u) +#elif (defined __ICCARM__) +# define clz(u) __CLZ(u) +#else +# define clz(u) (((u) == 0) ? 32 : \ + ((u) & (1ul << 31)) ? 0 : \ + ((u) & (1ul << 30)) ? 1 : \ + ((u) & (1ul << 29)) ? 2 : \ + ((u) & (1ul << 28)) ? 3 : \ + ((u) & (1ul << 27)) ? 4 : \ + ((u) & (1ul << 26)) ? 5 : \ + ((u) & (1ul << 25)) ? 6 : \ + ((u) & (1ul << 24)) ? 7 : \ + ((u) & (1ul << 23)) ? 8 : \ + ((u) & (1ul << 22)) ? 9 : \ + ((u) & (1ul << 21)) ? 10 : \ + ((u) & (1ul << 20)) ? 11 : \ + ((u) & (1ul << 19)) ? 12 : \ + ((u) & (1ul << 18)) ? 13 : \ + ((u) & (1ul << 17)) ? 14 : \ + ((u) & (1ul << 16)) ? 15 : \ + ((u) & (1ul << 15)) ? 16 : \ + ((u) & (1ul << 14)) ? 17 : \ + ((u) & (1ul << 13)) ? 18 : \ + ((u) & (1ul << 12)) ? 19 : \ + ((u) & (1ul << 11)) ? 20 : \ + ((u) & (1ul << 10)) ? 21 : \ + ((u) & (1ul << 9)) ? 22 : \ + ((u) & (1ul << 8)) ? 23 : \ + ((u) & (1ul << 7)) ? 24 : \ + ((u) & (1ul << 6)) ? 25 : \ + ((u) & (1ul << 5)) ? 26 : \ + ((u) & (1ul << 4)) ? 27 : \ + ((u) & (1ul << 3)) ? 28 : \ + ((u) & (1ul << 2)) ? 29 : \ + ((u) & (1ul << 1)) ? 30 : \ + 31) +#endif + +/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the trailing zero bits. + * + * \return The count of trailing zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define ctz(u) __builtin_ctz(u) +#else +# define ctz(u) ((u) & (1ul << 0) ? 0 : \ + (u) & (1ul << 1) ? 1 : \ + (u) & (1ul << 2) ? 2 : \ + (u) & (1ul << 3) ? 3 : \ + (u) & (1ul << 4) ? 4 : \ + (u) & (1ul << 5) ? 5 : \ + (u) & (1ul << 6) ? 6 : \ + (u) & (1ul << 7) ? 7 : \ + (u) & (1ul << 8) ? 8 : \ + (u) & (1ul << 9) ? 9 : \ + (u) & (1ul << 10) ? 10 : \ + (u) & (1ul << 11) ? 11 : \ + (u) & (1ul << 12) ? 12 : \ + (u) & (1ul << 13) ? 13 : \ + (u) & (1ul << 14) ? 14 : \ + (u) & (1ul << 15) ? 15 : \ + (u) & (1ul << 16) ? 16 : \ + (u) & (1ul << 17) ? 17 : \ + (u) & (1ul << 18) ? 18 : \ + (u) & (1ul << 19) ? 19 : \ + (u) & (1ul << 20) ? 20 : \ + (u) & (1ul << 21) ? 21 : \ + (u) & (1ul << 22) ? 22 : \ + (u) & (1ul << 23) ? 23 : \ + (u) & (1ul << 24) ? 24 : \ + (u) & (1ul << 25) ? 25 : \ + (u) & (1ul << 26) ? 26 : \ + (u) & (1ul << 27) ? 27 : \ + (u) & (1ul << 28) ? 28 : \ + (u) & (1ul << 29) ? 29 : \ + (u) & (1ul << 30) ? 30 : \ + (u) & (1ul << 31) ? 31 : \ + 32) +#endif + +//! @} + + +/*! \name Bit Reversing + */ +//! @{ + +/*! \brief Reverses the bits of \a u8. + * + * \param u8 U8 of which to reverse the bits. + * + * \return Value resulting from \a u8 with reversed bits. + */ +#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) + +/*! \brief Reverses the bits of \a u16. + * + * \param u16 U16 of which to reverse the bits. + * + * \return Value resulting from \a u16 with reversed bits. + */ +#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) + +/*! \brief Reverses the bits of \a u32. + * + * \param u32 U32 of which to reverse the bits. + * + * \return Value resulting from \a u32 with reversed bits. + */ +#define bit_reverse32(u32) __RBIT(u32) + +/*! \brief Reverses the bits of \a u64. + * + * \param u64 U64 of which to reverse the bits. + * + * \return Value resulting from \a u64 with reversed bits. + */ +#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ + ((U64)bit_reverse32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Alignment + */ +//! @{ + +/*! \brief Tests alignment of the number \a val with the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. + */ +#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) + +/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Alignment of the number \a val with respect to the \a n boundary. + */ +#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) + +/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. + * + * \param lval Input/output lvalue. + * \param n Boundary. + * \param alg Alignment. + * + * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. + */ +#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) + +/*! \brief Aligns the number \a val with the upper \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the upper \a n boundary. + */ +#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) + +/*! \brief Aligns the number \a val with the lower \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the lower \a n boundary. + */ +#define Align_down(val, n ) ( (val) & ~((n) - 1)) + +//! @} + + +/*! \name Mathematics + * + * The same considerations as for clz and ctz apply here but GCC does not + * provide built-in functions to access the assembly instructions abs, min and + * max and it does not produce them by itself in most cases, so two sets of + * macros are defined here: + * - Abs, Min and Max to apply to constant expressions (values known at + * compile time); + * - abs, min and max to apply to non-constant expressions (values unknown at + * compile time), abs is found in stdlib.h. + */ +//! @{ + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values known at compile time. + */ +#define Abs(a) (((a) < 0 ) ? -(a) : (a)) + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Min(a, b) (((a) < (b)) ? (a) : (b)) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + +// abs() is already defined by stdlib.h + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define min(a, b) Min(a, b) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define max(a, b) Max(a, b) + +//! @} + + +/*! \brief Calls the routine at address \a addr. + * + * It generates a long call opcode. + * + * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if + * it is invoked from the CPU supervisor mode. + * + * \param addr Address of the routine to call. + * + * \note It may be used as a long jump opcode in some special cases. + */ +#define Long_call(addr) ((*(void (*)(void))(addr))()) + + +/*! \name MCU Endianism Handling + * ARM is MCU little endianism. + */ +//! @{ +#define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16. +#define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16. + +#define MSH(u32) (((U16 *)&(u32))[1]) //!< Most significant half-word of \a u32. +#define LSH(u32) (((U16 *)&(u32))[0]) //!< Least significant half-word of \a u32. +#define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. +#define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. +#define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. +#define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. +#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. +#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. + +#define MSW(u64) (((U32 *)&(u64))[1]) //!< Most significant word of \a u64. +#define LSW(u64) (((U32 *)&(u64))[0]) //!< Least significant word of \a u64. +#define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64. +#define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64. +#define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64. +#define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64. +#define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64. +#define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64. +#define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64. +#define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64. +#define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64. +#define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64. +#define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64. +#define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64. +#define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64. +#define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64. +#define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64. +#define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64. +#define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64. +#define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64. +#define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64. +#define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64. +#define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64. +#define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64. +#define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64. +#define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64. + +#define BE16(x) Swap16(x) +#define LE16(x) (x) + +#define le16_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define LE16_TO_CPU(x) (x) +#define CPU_TO_LE16(x) (x) + +#define be16_to_cpu(x) Swap16(x) +#define cpu_to_be16(x) Swap16(x) +#define BE16_TO_CPU(x) Swap16(x) +#define CPU_TO_BE16(x) Swap16(x) + +#define le32_to_cpu(x) (x) +#define cpu_to_le32(x) (x) +#define LE32_TO_CPU(x) (x) +#define CPU_TO_LE32(x) (x) + +#define be32_to_cpu(x) swap32(x) +#define cpu_to_be32(x) swap32(x) +#define BE32_TO_CPU(x) swap32(x) +#define CPU_TO_BE32(x) swap32(x) +//! @} + + +/*! \name Endianism Conversion + * + * The same considerations as for clz and ctz apply here but GCC's + * __builtin_bswap_32 and __builtin_bswap_64 do not behave like macros when + * applied to constant expressions, so two sets of macros are defined here: + * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known + * at compile time); + * - swap16, swap32 and swap64 to apply to non-constant expressions (values + * unknown at compile time). + */ +//! @{ + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ + ((U16)(u16) << 8))) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ + ((U32)Swap16((U32)(u32)) << 16))) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ + ((U64)Swap32((U64)(u64)) << 32))) + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap16(u16) Swap16(u16) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) +# define swap32(u32) ((U32)__builtin_bswap32((U32)(u32))) +#else +# define swap32(u32) Swap32(u32) +#endif + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) +# define swap64(u64) ((U64)__builtin_bswap64((U64)(u64))) +#else +# define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ + ((U64)swap32((U64)(u64)) << 32))) +#endif + +//! @} + + +/*! \name Target Abstraction + */ +//! @{ + +#define _GLOBEXT_ extern //!< extern storage-class specifier. +#define _CONST_TYPE_ const //!< const type qualifier. +#define _MEM_TYPE_SLOW_ //!< Slow memory type. +#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. +#define _MEM_TYPE_FAST_ //!< Fast memory type. + +typedef U8 Byte; //!< 8-bit unsigned integer. + +#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. +#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. +#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. +#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. + +#define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32. +#define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32. +#define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32. +#define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32. +#define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32. +#define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32. + +//! @} + +/** + * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using + * integer arithmetic. + * + * \param a An integer + * \param b Another integer + * + * \return (\a a / \a b) rounded up to the nearest integer. + */ +#define div_ceil(a, b) (((a) + (b) - 1) / (b)) + +#endif // #ifndef __ASSEMBLY__ + +/** + * \} + */ + +#endif /* UTILS_COMPILER_H */ diff --git a/hardware/arduino/sam/libraries/CAN/conf_board.h b/hardware/arduino/sam/libraries/CAN/conf_board.h new file mode 100644 index 000000000..fc99af904 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/conf_board.h @@ -0,0 +1,125 @@ +/** + * \file + * + * \brief Board configuration. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef CONF_BOARD_H_INCLUDED +#define CONF_BOARD_H_INCLUDED + +/** Enable Com Port. */ +#define CONF_BOARD_UART_CONSOLE + +/** Pins description corresponding to Rxd,Txd, (UART pins) */ +#define CONSOLE_PINS {PINS_UART} + +/* Usart Hw ID used by the console (UART0) */ +#define CONSOLE_UART_ID ID_UART + +/* Configure UART pins */ +#define CONF_BOARD_UART_CONSOLE + +#define CONF_BOARD_CAN0 + +#define CONF_BOARD_CAN1 + +/* Configure ADC example pins */ +//#define CONF_BOARD_ADC + +/* Configure PWM LED0 pin */ +//#define CONF_BOARD_PWM_LED0 + +/* Configure PWM LED1 pin */ +//#define CONF_BOARD_PWM_LED1 + +/* Configure PWM LED2 pin */ +//#define CONF_BOARD_PWM_LED2 + +/* Configure SPI0 pins */ +//#define CONF_BOARD_SPI0 +//#define CONF_BOARD_SPI0_NPCS0 +//#define CONF_BOARD_SPI0_NPCS1 +//#define CONF_BOARD_SPI0_NPCS2 +//#define CONF_BOARD_SPI0_NPCS3 + +/* Configure SPI1 pins */ +//#define CONF_BOARD_SPI1 +//#define CONF_BOARD_SPI1_NPCS0 +//#define CONF_BOARD_SPI1_NPCS1 +//#define CONF_BOARD_SPI1_NPCS2 +//#define CONF_BOARD_SPI1_NPCS3 + +//#define CONF_BOARD_TWI0 + +//#define CONF_BOARD_TWI1 + +/* Configure USART RXD pin */ +//#define CONF_BOARD_USART_RXD + +/* Configure USART TXD pin */ +//#define CONF_BOARD_USART_TXD + +/* Configure USART CTS pin */ +//#define CONF_BOARD_USART_CTS + +/* Configure USART RTS pin */ +//#define CONF_BOARD_USART_RTS + +/* Configure USART synchronous communication SCK pin */ +//#define CONF_BOARD_USART_SCK + +/* Configure ADM3312 enable pin */ +//#define CONF_BOARD_ADM3312_EN + +/* Configure IrDA transceiver shutdown pin */ +//#define CONF_BOARD_TFDU4300_SD + +/* Configure RS485 transceiver ADM3485 RE pin */ +//#define CONF_BOARD_ADM3485_RE + +//#define CONF_BOARD_SMC_PSRAM + +/* Configure LCD EBI pins */ +//#define CONF_BOARD_HX8347A + +/* Configure Backlight control pin */ +//#define CONF_BOARD_AAT3194 + +#endif /* CONF_BOARD_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/conf_clock.h b/hardware/arduino/sam/libraries/CAN/conf_clock.h new file mode 100644 index 000000000..a3dc12a2b --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/conf_clock.h @@ -0,0 +1,97 @@ +/** + * \file + * + * \brief SAM3X clock configuration. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +// ===== System Clock (MCK) Source Options +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_UPLLCK + +// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES)) +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3 + +// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div) +// Use mul and div effective values here. +#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL +#define CONFIG_PLL0_MUL 14 +#define CONFIG_PLL0_DIV 1 + +// ===== UPLL (UTMI) Hardware fixed at 480 MHz. + +// ===== USB Clock Source Options (Fusb = FpllX / USB_div) +// Use div effective value here. +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL +//#define CONFIG_USBCLK_DIV 1 + +// ===== Target frequency (System clock) +// - XTAL frequency: 12MHz +// - System clock source: PLLA +// - System clock prescaler: 2 (divided by 2) +// - PLLA source: XTAL +// - PLLA output: XTAL * 14 / 1 +// - System clock is: 12 * 14 / 1 /2 = 84MHz +// ===== Target frequency (USB Clock) +// - USB clock source: UPLL +// - USB clock divider: 1 (not divided) +// - UPLL frequency: 480MHz +// - USB clock: 480 / 1 = 480MHz + + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/examples/Arduino_Due_CAN_Sample_1/Arduino_Due_CAN_Sample_1.ino b/hardware/arduino/sam/libraries/CAN/examples/Arduino_Due_CAN_Sample_1/Arduino_Due_CAN_Sample_1.ino new file mode 100644 index 000000000..35312995c --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/examples/Arduino_Due_CAN_Sample_1/Arduino_Due_CAN_Sample_1.ino @@ -0,0 +1,100 @@ + +// Brief CAN example for Arduino Due +// Test the transmission from CAN0 Mailbox 0 to CAN1 Mailbox 0 +// Modified from Atmel ASF SAM3X-EK CAN sample by Wilfredo Molina 2012 + +// Required libraries +#include +#include +#include + +#define TEST1_CAN_COMM_MB_IDX 0 +#define TEST1_CAN_TRANSFER_ID 0x07 +#define TEST1_CAN0_TX_PRIO 15 +#define CAN_MSG_DUMMY_DATA 0x55AAAA55 + +/** CAN frame max data length */ +#define MAX_CAN_FRAME_DATA_LEN 8 + +//Message variable to be send +uint32_t CAN_MSG_1 = 0; + +// Define the struct for CAN message mailboxes needed +can_mb_conf_t can0_mailbox; +can_mb_conf_t can1_mailbox; + +void setup() +{ + // start serial port at 9600 bps: + Serial.begin(9600); + Serial.println("Type CAN message to send"); + while (Serial.available() == 0); +} + +void loop(){ + + while (Serial.available() > 0) { + CAN_MSG_1 = Serial.parseInt(); + if (Serial.read() == '\n') { + Serial.print("Sent value= "); + Serial.println(CAN_MSG_1); + delay(1000); + } + } + + uint32_t ul_sysclk; + + /* Initialize the SAM system. */ + sysclk_init(); + board_init(); + + // Enable CAN0 & CAN1 clock + pmc_enable_periph_clk(ID_CAN0); + pmc_enable_periph_clk(ID_CAN1); + + // Initialize CAN0 and CAN1, baudrate is 1Mb/s + ul_sysclk = sysclk_get_cpu_hz(); + can_init(CAN0, ul_sysclk, CAN_BPS_1000K); + can_init(CAN1, ul_sysclk, CAN_BPS_1000K); + + // Reset all CAN0 and CAN1 mailboxes + can_reset_all_mailbox(CAN0); + can_reset_all_mailbox(CAN1); + + // Initialize CAN1 mailbox 0 as receiver, frame ID is 0x07 + reset_mailbox_conf(&can1_mailbox); + can1_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX; + can1_mailbox.uc_obj_type = CAN_MB_RX_MODE; + can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk; + can1_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID); + can_mailbox_init(CAN1, &can1_mailbox); + + // Initialize CAN0 mailbox 0 as transmitter, transmit priority is 15 + reset_mailbox_conf(&can0_mailbox); + can0_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX; + can0_mailbox.uc_obj_type = CAN_MB_TX_MODE; + can0_mailbox.uc_tx_prio = TEST1_CAN0_TX_PRIO; + can0_mailbox.uc_id_ver = 0; + can0_mailbox.ul_id_msk = 0; + can_mailbox_init(CAN0, &can0_mailbox); + + // Prepare transmit ID, data and data length in CAN0 mailbox 0 + can0_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID); + can0_mailbox.ul_datal = CAN_MSG_1; + can0_mailbox.ul_datah = CAN_MSG_DUMMY_DATA; + can0_mailbox.uc_length = MAX_CAN_FRAME_DATA_LEN; + can_mailbox_write(CAN0, &can0_mailbox); + + // Send out the information in the mailbox + can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); + + // Wait for CAN1 mailbox 0 to receive the data + while (!(can_mailbox_get_status(CAN1, 0) & CAN_MSR_MRDY)) { + } + // Read the received data from CAN1 mailbox 0 + can_mailbox_read(CAN1, &can1_mailbox); + Serial.print("CAN message received= "); + Serial.println(can1_mailbox.ul_datal); + + while (1) {} +} diff --git a/hardware/arduino/sam/libraries/CAN/gpio.h b/hardware/arduino/sam/libraries/CAN/gpio.h new file mode 100644 index 000000000..a6d0d7966 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/gpio.h @@ -0,0 +1,86 @@ +/** + * \file + * + * \brief Common GPIO API. + * + * Copyright (c) 2010-2012 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 + * + */ +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include + + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S) +# include "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_ */ diff --git a/hardware/arduino/sam/libraries/CAN/init.c b/hardware/arduino/sam/libraries/CAN/init.c new file mode 100644 index 000000000..e6730a9ff --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/init.c @@ -0,0 +1,209 @@ +/** + * \file + * + * \brief Arduino Due/X board init. + * + * Copyright (c) 2011 - 2012 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 "board.h" +#include "conf_board.h" +#include "gpio.h" + +void board_init(void) +{ +#ifndef CONF_BOARD_KEEP_WATCHDOG_AT_INIT + /* Disable the watchdog */ + WDT->WDT_MR = WDT_MR_WDDIS; +#endif + + /* Configure LED pins */ + gpio_configure_pin(LED0_GPIO, LED0_FLAGS); + gpio_configure_pin(LED1_GPIO, LED1_FLAGS); + gpio_configure_pin(LED2_GPIO, LED2_FLAGS); + + /* Configure Push Button pins */ + gpio_configure_pin(GPIO_PUSH_BUTTON_1, GPIO_PUSH_BUTTON_1_FLAGS); + gpio_configure_pin(GPIO_PUSH_BUTTON_2, GPIO_PUSH_BUTTON_2_FLAGS); + +#ifdef CONF_BOARD_UART_CONSOLE + /* Configure UART pins */ + gpio_configure_group(PINS_UART_PIO, PINS_UART, PINS_UART_FLAGS); +#endif + + /* Configure ADC example pins */ +#ifdef CONF_BOARD_ADC + /* TC TIOA configuration */ + gpio_configure_pin(PIN_TC0_TIOA0,PIN_TC0_TIOA0_FLAGS); + + /* ADC Trigger configuration */ + gpio_configure_pin(PINS_ADC_TRIG, PINS_ADC_TRIG_FLAG); + + /* PWMH0 configuration */ + gpio_configure_pin(PIN_PWMC_PWMH0_TRIG, PIN_PWMC_PWMH0_TRIG_FLAG); +#endif + +#ifdef CONF_BOARD_PWM_LED0 + /* Configure PWM LED0 pin */ + gpio_configure_pin(PIN_PWM_LED0_GPIO, PIN_PWM_LED0_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED1 + /* Configure PWM LED1 pin */ + gpio_configure_pin(PIN_PWM_LED1_GPIO, PIN_PWM_LED1_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED2 + /* Configure PWM LED2 pin */ + gpio_configure_pin(PIN_PWM_LED2_GPIO, PIN_PWM_LED2_FLAGS); +#endif + + /* Configure SPI0 pins */ +#ifdef CONF_BOARD_SPI0 + gpio_configure_pin(SPI0_MISO_GPIO, SPI0_MISO_FLAGS); + gpio_configure_pin(SPI0_MOSI_GPIO, SPI0_MOSI_FLAGS); + gpio_configure_pin(SPI0_SPCK_GPIO, SPI0_SPCK_FLAGS); + + /** + * For NPCS 1, 2, and 3, different PINs can be used to access the same + * NPCS line. + * Depending on the application requirements, the default PIN may not be + * available. + * Hence a different PIN should be selected using the + * CONF_BOARD_SPI_NPCS_GPIO and + * CONF_BOARD_SPI_NPCS_FLAGS macros. + */ + +# ifdef CONF_BOARD_SPI0_NPCS0 + gpio_configure_pin(SPI0_NPCS0_GPIO, SPI0_NPCS0_FLAGS); +# endif + +# ifdef CONF_BOARD_SPI0_NPCS1 + gpio_configure_pin(SPI0_NPCS1_PA29_GPIO,SPI0_NPCS1_PA29_FLAGS); +# endif +#endif // #ifdef CONF_BOARD_SPI0 + + /* Configure SPI1 pins */ +#ifdef CONF_BOARD_SPI1 + gpio_configure_pin(SPI1_MISO_GPIO, SPI1_MISO_FLAGS); + gpio_configure_pin(SPI1_MOSI_GPIO, SPI1_MOSI_FLAGS); + gpio_configure_pin(SPI1_SPCK_GPIO, SPI1_SPCK_FLAGS); + +# ifdef CONF_BOARD_SPI1_NPCS0 + gpio_configure_pin(SPI1_NPCS0_GPIO, SPI1_NPCS0_FLAGS); +# endif + +# ifdef CONF_BOARD_SPI1_NPCS1 + gpio_configure_pin(SPI1_NPCS1_GPIO, SPI1_NPCS1_FLAGS); +# endif + +# ifdef CONF_BOARD_SPI1_NPCS2 + gpio_configure_pin(SPI1_NPCS2_GPIO, SPI1_NPCS2_FLAGS); +# endif + +# ifdef CONF_BOARD_SPI1_NPCS3 + gpio_configure_pin(SPI1_NPCS3_GPIO, SPI1_NPCS3_FLAGS); +# endif +#endif + +#ifdef CONF_BOARD_TWI0 + gpio_configure_pin(TWI0_DATA_GPIO, TWI0_DATA_FLAGS); + gpio_configure_pin(TWI0_CLK_GPIO, TWI0_CLK_FLAGS); +#endif + +#ifdef CONF_BOARD_TWI1 + gpio_configure_pin(TWI1_DATA_GPIO, TWI1_DATA_FLAGS); + gpio_configure_pin(TWI1_CLK_GPIO, TWI1_CLK_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_RXD + /* Configure USART RXD pin */ + gpio_configure_pin(PIN_USART0_RXD_IDX, PIN_USART0_RXD_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_TXD + /* Configure USART TXD pin */ + gpio_configure_pin(PIN_USART0_TXD_IDX, PIN_USART0_TXD_FLAGS); +#endif + +#ifdef CONF_BOARD_USB_PORT + /* Configure USB_ID (UOTGID) pin */ + gpio_configure_pin(USB_ID_GPIO, USB_ID_FLAGS); + /* Configure USB_VBOF (UOTGVBOF) pin */ + gpio_configure_pin(USB_VBOF_GPIO, USB_VBOF_FLAGS); +#endif + +#ifdef CONF_BOARD_CAN0 + /* Configure the CAN0 TX and RX pins. */ + gpio_configure_pin(PIN_CAN0_RX_IDX, PIN_CAN0_RX_FLAGS); + gpio_configure_pin(PIN_CAN0_TX_IDX, PIN_CAN0_TX_FLAGS); + /* Configure the transiver0 RS & EN pins. */ + gpio_configure_pin(PIN_CAN0_TR_RS_IDX, PIN_CAN0_TR_RS_FLAGS); + gpio_configure_pin(PIN_CAN0_TR_EN_IDX, PIN_CAN0_TR_EN_FLAGS); +#endif + +#ifdef CONF_BOARD_CAN1 + /* Configure the CAN1 TX and RX pin. */ + gpio_configure_pin(PIN_CAN1_RX_IDX, PIN_CAN1_RX_FLAGS); + gpio_configure_pin(PIN_CAN1_TX_IDX, PIN_CAN1_TX_FLAGS); + /* Configure the transiver1 RS & EN pins. */ + //gpio_configure_pin(PIN_CAN1_TR_RS_IDX, PIN_CAN1_TR_RS_FLAGS); + //gpio_configure_pin(PIN_CAN1_TR_EN_IDX, PIN_CAN1_TR_EN_FLAGS); +#endif + + +#ifdef CONF_BOARD_MMA7341L + /* Configure MMA7341L mode set control pin */ + gpio_configure_pin(PIN_MMA7341L_MODE, PIN_MMA7341L_MODE_FLAG); + /* Configure MMA7341L x,y,z axis output voltage pin */ + gpio_configure_pin(PIN_MMA7341L_X_AXIS, PIN_MMA7341L_X_AXIS_FLAG); + gpio_configure_pin(PIN_MMA7341L_Y_AXIS, PIN_MMA7341L_Y_AXIS_FLAG); + gpio_configure_pin(PIN_MMA7341L_Z_AXIS, PIN_MMA7341L_Z_AXIS_FLAG); +#endif + +#ifdef CONF_BOARD_ADS7843 + /* Configure Touchscreen SPI pins */ + gpio_configure_pin(BOARD_ADS7843_IRQ_GPIO,BOARD_ADS7843_IRQ_FLAGS); + gpio_configure_pin(BOARD_ADS7843_BUSY_GPIO, BOARD_ADS7843_BUSY_FLAGS); + gpio_configure_pin(SPI0_MISO_GPIO, SPI0_MISO_FLAGS); + gpio_configure_pin(SPI0_MOSI_GPIO, SPI0_MOSI_FLAGS); + gpio_configure_pin(SPI0_SPCK_GPIO, SPI0_SPCK_FLAGS); + gpio_configure_pin(SPI0_NPCS0_GPIO, SPI0_NPCS0_FLAGS); +#endif +} diff --git a/hardware/arduino/sam/libraries/CAN/interrupt_sam_nvic.h b/hardware/arduino/sam/libraries/CAN/interrupt_sam_nvic.h new file mode 100644 index 000000000..0997b4775 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/interrupt_sam_nvic.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief Global interrupt management for SAM3 and SAM4 (NVIC based) + * + * Copyright (c) 2012 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 + * + */ + +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +/** + * \name Interrupt Service Routine definition + * + * @{ + */ + +/** + * \brief Define service routine + * + * \note For NVIC devices the interrupt service routines are predefined to + * add to vector table in binary generation, so there is no service + * register at run time. The routine collections are in exceptions.h. + * + * Usage: + * \code + * ISR(foo_irq_handler) + * { + * // Function definition + * ... + * } + * \endcode + * + * \param func Name for the function. + */ +# define ISR(func) \ + void func (void) + +/** + * \brief Initialize interrupt vectors + * + * For NVIC the interrupt vectors are put in vector table. So nothing + * to do to initialize them, except defined the vector function with + * right name. + * + * This must be called prior to \ref irq_register_handler. + */ +# define irq_initialize_vectors() \ + do { \ + } while(0) + +/** + * \brief Register handler for interrupt + * + * For NVIC the interrupt vectors are put in vector table. So nothing + * to do to register them, except defined the vector function with + * right name. + * + * Usage: + * \code + * irq_initialize_vectors(); + * irq_register_handler(foo_irq_handler); + * \endcode + * + * \note The function \a func must be defined with the \ref ISR macro. + * \note The functions prototypes can be found in the device exception header + * files (exceptions.h). + */ +# define irq_register_handler(int_num, int_prio) \ + NVIC_ClearPendingIRQ( (IRQn_Type)int_num); \ + NVIC_SetPriority( (IRQn_Type)int_num, int_prio); \ + NVIC_EnableIRQ( (IRQn_Type)int_num); \ + +//@} + +# define cpu_irq_enable() \ + do { \ + g_interrupt_enabled = true; \ + __DMB(); \ + __enable_irq(); \ + } while (0) +# define cpu_irq_disable() \ + do { \ + __disable_irq(); \ + __DMB(); \ + g_interrupt_enabled = false; \ + } while (0) + +typedef uint32_t irqflags_t; +extern bool g_interrupt_enabled; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = g_interrupt_enabled; + cpu_irq_disable(); + return flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ + return (flags); +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + if (cpu_irq_is_enabled_flags(flags)) + cpu_irq_enable(); +} + +#define cpu_irq_is_enabled() g_interrupt_enabled + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ + +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() + +//@} + +//@} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/hardware/arduino/sam/libraries/CAN/osc.h b/hardware/arduino/sam/libraries/CAN/osc.h new file mode 100644 index 000000000..1e21c15c0 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/osc.h @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2012 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 + * + */ +#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 SAM4L +# include "sam4l/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__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__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 */ diff --git a/hardware/arduino/sam/libraries/CAN/parts.h b/hardware/arduino/sam/libraries/CAN/parts.h new file mode 100644 index 000000000..801a6e4ce --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/parts.h @@ -0,0 +1,862 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012 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 + * + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRF group */ +#define MEGA_RF ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(ATSAM4LS2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LS4C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(ATSAM4LC2A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC2C) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4A) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4B) || \ + SAM_PART_IS_DEFINED(ATSAM4LC4C) \ + ) +/** @} */ + +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L) + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/hardware/arduino/sam/libraries/CAN/pio.c b/hardware/arduino/sam/libraries/CAN/pio.c new file mode 100644 index 000000000..01c065573 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/pio.c @@ -0,0 +1,1114 @@ +/** + * \file + * + * \brief Parallel Input/Output (PIO) Controller driver for SAM. + * + * Copyright (c) 2011 - 2012 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 "pio.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_pio_group Peripheral Parallel Input/Output (PIO) Controller + * + * \par Purpose + * + * The Parallel Input/Output Controller (PIO) manages up to 32 fully + * programmable input/output lines. Each I/O line may be dedicated as a + * general-purpose I/O or be assigned to a function of an embedded peripheral. + * This assures effective optimization of the pins of a product. + * + * @{ + */ + +#ifndef FREQ_SLOW_CLOCK_EXT +/* External slow clock frequency (hz) */ +#define FREQ_SLOW_CLOCK_EXT 32768 +#endif + +/** + * \brief Configure PIO internal pull-up. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_pull_up_enable Indicates if the pin(s) internal pull-up shall be + * configured. + */ +void pio_pull_up(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_pull_up_enable) +{ + /* Enable the pull-up(s) if necessary */ + if (ul_pull_up_enable) { + p_pio->PIO_PUER = ul_mask; + } else { + p_pio->PIO_PUDR = ul_mask; + } +} + +/** + * \brief Configure Glitch or Debouncing filter for the specified input(s). + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_cut_off Cuts off frequency for debouncing filter. + */ +void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_cut_off) +{ +#if (SAM3S || SAM3N || SAM4S) + /* Set Debouncing, 0 bit field no effect */ + p_pio->PIO_IFSCER = ul_mask; +#elif (SAM3XA || SAM3U) + /* Set Debouncing, 0 bit field no effect */ + p_pio->PIO_DIFSR = ul_mask; +#else +#error "Unsupported device" +#endif + + /* The debouncing filter can filter a pulse of less than 1/2 Period of a + programmable Divided Slow Clock: + Tdiv_slclk = ((DIV+1)*2).Tslow_clock */ + p_pio->PIO_SCDR = PIO_SCDR_DIV((FREQ_SLOW_CLOCK_EXT / + (2 * (ul_cut_off))) - 1); +} + +/** + * \brief Set a high output level on all the PIOs defined in ul_mask. + * This has no immediate effects on PIOs that are not output, but the PIO + * controller will save the value if they are changed to outputs. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_set(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_SODR = ul_mask; +} + +/** + * \brief Set a low output level on all the PIOs defined in ul_mask. + * This has no immediate effects on PIOs that are not output, but the PIO + * controller will save the value if they are changed to outputs. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_clear(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_CODR = ul_mask; +} + +/** + * \brief Return 1 if one or more PIOs of the given Pin instance currently have + * a high level; otherwise returns 0. This method returns the actual value that + * is being read on the pin. To return the supposed output value of a pin, use + * pio_get_output_data_status() instead. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_type PIO type. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * + * \retval 1 at least one PIO currently has a high level. + * \retval 0 all PIOs have a low level. + */ +uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask) +{ + uint32_t ul_reg; + + if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) { + ul_reg = p_pio->PIO_ODSR; + } else { + ul_reg = p_pio->PIO_PDSR; + } + + if ((ul_reg & ul_mask) == 0) { + return 0; + } else { + return 1; + } +} + +/** + * \brief Configure IO of a PIO controller as being controlled by a specific + * peripheral. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_type PIO type. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask) +{ + uint32_t ul_sr; + + /* Disable interrupts on the pin(s) */ + p_pio->PIO_IDR = ul_mask; + +#if (SAM3S || SAM3N || SAM4S) + switch (ul_type) { + case PIO_PERIPH_A: + ul_sr = p_pio->PIO_ABCDSR[0]; + p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr); + + ul_sr = p_pio->PIO_ABCDSR[1]; + p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr); + break; + + case PIO_PERIPH_B: + ul_sr = p_pio->PIO_ABCDSR[0]; + p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr); + + ul_sr = p_pio->PIO_ABCDSR[1]; + p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr); + break; + + case PIO_PERIPH_C: + ul_sr = p_pio->PIO_ABCDSR[0]; + p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr); + + ul_sr = p_pio->PIO_ABCDSR[1]; + p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr); + break; + + case PIO_PERIPH_D: + ul_sr = p_pio->PIO_ABCDSR[0]; + p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr); + + ul_sr = p_pio->PIO_ABCDSR[1]; + p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr); + break; + + // other types are invalid in this function + case PIO_INPUT: + case PIO_OUTPUT_0: + case PIO_OUTPUT_1: + case PIO_NOT_A_PIN: + return; + } +#elif (SAM3XA|| SAM3U) + switch (ul_type) { + case PIO_PERIPH_A: + ul_sr = p_pio->PIO_ABSR; + p_pio->PIO_ABSR &= (~ul_mask & ul_sr); + break; + + case PIO_PERIPH_B: + ul_sr = p_pio->PIO_ABSR; + p_pio->PIO_ABSR = (ul_mask | ul_sr); + break; + + // other types are invalid in this function + case PIO_INPUT: + case PIO_OUTPUT_0: + case PIO_OUTPUT_1: + case PIO_NOT_A_PIN: + return; + } +#else +#error "Unsupported device" +#endif + + // Remove the pins from under the control of PIO + p_pio->PIO_PDR = ul_mask; +} + +/** + * \brief Configure one or more pin(s) or a PIO controller as inputs. + * Optionally, the corresponding internal pull-up(s) and glitch filter(s) can + * be enabled. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask indicating which pin(s) to configure as input(s). + * \param ul_attribute PIO attribute(s). + */ +void pio_set_input(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_attribute) +{ + pio_disable_interrupt(p_pio, ul_mask); + pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP); + + /* Enable Input Filter if necessary */ + if (ul_attribute & (PIO_DEGLITCH | PIO_DEBOUNCE)) { + p_pio->PIO_IFER = ul_mask; + } else { + p_pio->PIO_IFDR = ul_mask; + } + +#if (SAM3S || SAM3N || SAM4S) + /* Enable de-glitch or de-bounce if necessary */ + if (ul_attribute & PIO_DEGLITCH) { + p_pio->PIO_IFSCDR = ul_mask; + } else { + if (ul_attribute & PIO_DEBOUNCE) { + p_pio->PIO_IFSCER = ul_mask; + } + } +#elif (SAM3XA|| SAM3U) + /* Enable de-glitch or de-bounce if necessary */ + if (ul_attribute & PIO_DEGLITCH) { + p_pio->PIO_SCIFSR = ul_mask; + } else { + if (ul_attribute & PIO_DEBOUNCE) { + p_pio->PIO_SCIFSR = ul_mask; + } + } +#else +#error "Unsupported device" +#endif + + /* Configure pin as input */ + p_pio->PIO_ODR = ul_mask; + p_pio->PIO_PER = ul_mask; +} + +/** + * \brief Configure one or more pin(s) of a PIO controller as outputs, with + * the given default value. Optionally, the multi-drive feature can be enabled + * on the pin(s). + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask indicating which pin(s) to configure. + * \param ul_default_level Default level on the pin(s). + * \param ul_multidrive_enable Indicates if the pin(s) shall be configured as + * open-drain. + * \param ul_pull_up_enable Indicates if the pin shall have its pull-up + * activated. + */ +void pio_set_output(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_default_level, + const uint32_t ul_multidrive_enable, + const uint32_t ul_pull_up_enable) +{ + pio_disable_interrupt(p_pio, ul_mask); + pio_pull_up(p_pio, ul_mask, ul_pull_up_enable); + + /* Enable multi-drive if necessary */ + if (ul_multidrive_enable) { + p_pio->PIO_MDER = ul_mask; + } else { + p_pio->PIO_MDDR = ul_mask; + } + + /* Set default value */ + if (ul_default_level) { + p_pio->PIO_SODR = ul_mask; + } else { + p_pio->PIO_CODR = ul_mask; + } + + /* Configure pin(s) as output(s) */ + p_pio->PIO_OER = ul_mask; + p_pio->PIO_PER = ul_mask; +} + +/** + * \brief Perform complete pin(s) configuration; general attributes and PIO init + * if necessary. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_type PIO type. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_attribute Pins attributes. + * + * \return Whether the pin(s) have been configured properly. + */ +uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask, const uint32_t ul_attribute) +{ + /* Configure pins */ + switch (ul_type) { + case PIO_PERIPH_A: + case PIO_PERIPH_B: +# if (SAM3S || SAM3N || SAM4S) + case PIO_PERIPH_C: + case PIO_PERIPH_D: +# endif + pio_set_peripheral(p_pio, ul_type, ul_mask); + pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP)); + break; + + case PIO_INPUT: + pio_set_input(p_pio, ul_mask, ul_attribute); + break; + + case PIO_OUTPUT_0: + case PIO_OUTPUT_1: + pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1), + (ul_attribute & PIO_OPENDRAIN) ? 1 : 0, + (ul_attribute & PIO_PULLUP) ? 1 : 0); + break; + + default: + return 0; + } + + return 1; +} + +/** + * \brief Return 1 if one or more PIOs of the given Pin are configured to + * output a high level (even if they are not output). + * To get the actual value of the pin, use PIO_Get() instead. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s). + * + * \retval 1 At least one PIO is configured to output a high level. + * \retval 0 All PIOs are configured to output a low level. + */ +uint32_t pio_get_output_data_status(const Pio *p_pio, + const uint32_t ul_mask) +{ + if ((p_pio->PIO_ODSR & ul_mask) == 0) { + return 0; + } else { + return 1; + } +} + +/** + * \brief Configure PIO pin multi-driver. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_multi_driver_enable Indicates if the pin(s) multi-driver shall be + * configured. + */ +void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_multi_driver_enable) +{ + /* Enable the multi-driver if necessary */ + if (ul_multi_driver_enable) { + p_pio->PIO_MDER = ul_mask; + } else { + p_pio->PIO_MDDR = ul_mask; + } +} + +/** + * \brief Get multi-driver status. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The multi-driver mask value. + */ +uint32_t pio_get_multi_driver_status(const Pio *p_pio) +{ + return p_pio->PIO_MDSR; +} + + +#if (SAM3S || SAM3N || SAM4S) +/** + * \brief Configure PIO pin internal pull-down. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_pull_down_enable Indicates if the pin(s) internal pull-down shall + * be configured. + */ +void pio_pull_down(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_pull_down_enable) +{ + /* Enable the pull-down if necessary */ + if (ul_pull_down_enable) { + p_pio->PIO_PPDER = ul_mask; + } else { + p_pio->PIO_PPDDR = ul_mask; + } +} +#endif + +/** + * \brief Enable PIO output write for synchronous data output. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_OWER = ul_mask; +} + +/** + * \brief Disable PIO output write. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_OWDR = ul_mask; +} + +/** + * \brief Read PIO output write status. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The output write mask value. + */ +uint32_t pio_get_output_write_status(const Pio *p_pio) +{ + return p_pio->PIO_OWSR; +} + +/** + * \brief Synchronously write on output pins. + * \note Only bits unmasked by PIO_OWSR (Output Write Status Register) are + * written. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_ODSR = ul_mask; +} + +#if (SAM3S || SAM3N || SAM4S) +/** + * \brief Configure PIO pin schmitt trigger. By default the Schmitt trigger is + * active. + * Disabling the Schmitt Trigger is requested when using the QTouch Library. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_SCHMITT = ul_mask; +} + +/** + * \brief Get PIO pin schmitt trigger status. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The schmitt trigger mask value. + */ +uint32_t pio_get_schmitt_trigger(const Pio *p_pio) +{ + return p_pio->PIO_SCHMITT; +} +#endif + +/** + * \brief Configure the given interrupt source. + * Interrupt can be configured to trigger on rising edge, falling edge, + * high level, low level or simply on level change. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt source bit map. + * \param ul_attr Interrupt source attributes. + */ +void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_attr) +{ + /* Configure additional interrupt mode registers. */ + if (ul_attr & PIO_IT_AIME) { + /* Enable additional interrupt mode. */ + p_pio->PIO_AIMER = ul_mask; + + /* If bit field of the selected pin is 1, set as + Rising Edge/High level detection event. */ + if (ul_attr & PIO_IT_RE_OR_HL) { + /* Rising Edge or High Level */ + p_pio->PIO_REHLSR = ul_mask; + } else { + /* Falling Edge or Low Level */ + p_pio->PIO_FELLSR = ul_mask; + } + + /* If bit field of the selected pin is 1, set as + edge detection source. */ + if (ul_attr & PIO_IT_EDGE) { + /* Edge select */ + p_pio->PIO_ESR = ul_mask; + } else { + /* Level select */ + p_pio->PIO_LSR = ul_mask; + } + } else { + /* Disable additional interrupt mode. */ + p_pio->PIO_AIMDR = ul_mask; + } +} + +/** + * \brief Enable the given interrupt source. + * The PIO must be configured as an NVIC interrupt source as well. + * The status register of the corresponding PIO controller is cleared + * prior to enabling the interrupt. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt sources bit map. + */ +void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_ISR; + p_pio->PIO_IER = ul_mask; +} + +/** + * \brief Disable a given interrupt source, with no added side effects. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt sources bit map. + */ +void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_IDR = ul_mask; +} + +/** + * \brief Read PIO interrupt status. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The interrupt status mask value. + */ +uint32_t pio_get_interrupt_status(const Pio *p_pio) +{ + return p_pio->PIO_ISR; +} + +/** + * \brief Read PIO interrupt mask. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The interrupt mask value. + */ +uint32_t pio_get_interrupt_mask(const Pio *p_pio) +{ + return p_pio->PIO_IMR; +} + +/** + * \brief Set additional interrupt mode. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt sources bit map. + * \param ul_attribute Pin(s) attributes. + */ +void pio_set_additional_interrupt_mode(Pio *p_pio, + const uint32_t ul_mask, const uint32_t ul_attribute) +{ + /* Enables additional interrupt mode if needed */ + if (ul_attribute & PIO_IT_AIME) { + /* Enables additional interrupt mode */ + p_pio->PIO_AIMER = ul_mask; + + /* Configures the Polarity of the event detection */ + /* (Rising/Falling Edge or High/Low Level) */ + if (ul_attribute & PIO_IT_RE_OR_HL) { + /* Rising Edge or High Level */ + p_pio->PIO_REHLSR = ul_mask; + } else { + /* Falling Edge or Low Level */ + p_pio->PIO_FELLSR = ul_mask; + } + + /* Configures the type of event detection (Edge or Level) */ + if (ul_attribute & PIO_IT_EDGE) { + /* Edge select */ + p_pio->PIO_ESR = ul_mask; + } else { + /* Level select */ + p_pio->PIO_LSR = ul_mask; + } + } else { + /* Disable additional interrupt mode */ + p_pio->PIO_AIMDR = ul_mask; + } +} + +#define PIO_WPMR_WPKEY_VALUE PIO_WPMR_WPKEY(0x50494Fu) + +/** + * \brief Enable or disable write protect of PIO registers. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_enable 1 to enable, 0 to disable. + */ +void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable) +{ + p_pio->PIO_WPMR = PIO_WPMR_WPKEY_VALUE | ul_enable; +} + +/** + * \brief Read write protect status. + * + * \param p_pio Pointer to a PIO instance. + * + * \return Return write protect status. + */ +uint32_t pio_get_writeprotect_status(const Pio *p_pio) +{ + return p_pio->PIO_WPSR; +} + +#define PIO_DELTA ((uint32_t) PIOB - (uint32_t) PIOA) + +/** + * \brief Return the value of a pin. + * + * \param ul_pin The pin number. + * + * \return The pin value. + * + * \note If pin is output: a pull-up or pull-down could hide the actual value. + * The function \ref pio_get can be called to get the actual pin output + * level. + * \note If pin is input: PIOx must be clocked to sample the signal. + * See PMC driver. + */ +uint32_t pio_get_pin_value(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1; +} + +/** + * \brief Drive a GPIO pin to 1. + * + * \param ul_pin The pin index. + * + * \note The function \ref pio_configure_pin must be called beforehand. + */ +void pio_set_pin_high(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + // Value to be driven on the I/O line: 1. + p_pio->PIO_SODR = 1 << (ul_pin & 0x1F); +} + +/** + * \brief Drive a GPIO pin to 0. + * + * \param ul_pin The pin index. + * + * \note The function \ref pio_configure_pin must be called before. + */ +void pio_set_pin_low(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + // Value to be driven on the I/O line: 0. + p_pio->PIO_CODR = 1 << (ul_pin & 0x1F); +} + +/** + * \brief Toggle a GPIO pin. + * + * \param ul_pin The pin index. + * + * \note The function \ref pio_configure_pin must be called before. + */ +void pio_toggle_pin(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + if (p_pio->PIO_ODSR & (1 << (ul_pin & 0x1F))) { + // Value to be driven on the I/O line: 0. + p_pio->PIO_CODR = 1 << (ul_pin & 0x1F); + } else { + // Value to be driven on the I/O line: 1. + p_pio->PIO_SODR = 1 << (ul_pin & 0x1F); + } +} + +/** + * \brief Perform complete pin(s) configuration; general attributes and PIO init + * if necessary. + * + * \param ul_pin Bitmask of one or more pin(s) to configure. + * \param ul_flags Pins attributes. + * + * \return Whether the pin(s) have been configured properly. + */ +uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + + /* Configure pins */ + switch (ul_flags & PIO_TYPE_Msk) { + case PIO_TYPE_PIO_PERIPH_A: + pio_set_peripheral(p_pio, PIO_PERIPH_A, (1 << (ul_pin & 0x1F))); + pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), + (ul_flags & PIO_PULLUP)); + break; + case PIO_TYPE_PIO_PERIPH_B: + pio_set_peripheral(p_pio, PIO_PERIPH_B, (1 << (ul_pin & 0x1F))); + pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), + (ul_flags & PIO_PULLUP)); + break; +# if (SAM3S || SAM3N || SAM4S) + case PIO_TYPE_PIO_PERIPH_C: + pio_set_peripheral(p_pio, PIO_PERIPH_C, (1 << (ul_pin & 0x1F))); + pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), + (ul_flags & PIO_PULLUP)); + break; + case PIO_TYPE_PIO_PERIPH_D: + pio_set_peripheral(p_pio, PIO_PERIPH_D, (1 << (ul_pin & 0x1F))); + pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), + (ul_flags & PIO_PULLUP)); + break; +# endif + + case PIO_TYPE_PIO_INPUT: + pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags); + break; + + case PIO_TYPE_PIO_OUTPUT_0: + case PIO_TYPE_PIO_OUTPUT_1: + pio_set_output(p_pio, (1 << (ul_pin & 0x1F)), + ((ul_flags & PIO_TYPE_PIO_OUTPUT_1) + == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0, + (ul_flags & PIO_OPENDRAIN) ? 1 : 0, + (ul_flags & PIO_PULLUP) ? 1 : 0); + break; + + default: + return 0; + } + + return 1; +} + +/** + * \brief Drive a GPIO port to 1. + * + * \param p_pio Base address of the PIO port. + * \param ul_mask Bitmask of one or more pin(s) to toggle. + */ +void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask) +{ + // Value to be driven on the I/O line: 1. + p_pio->PIO_SODR = ul_mask; +} + +/** + * \brief Drive a GPIO port to 0. + * + * \param p_pio Base address of the PIO port. + * \param ul_mask Bitmask of one or more pin(s) to toggle. + */ +void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask) +{ + // Value to be driven on the I/O line: 0. + p_pio->PIO_CODR = ul_mask; +} + +/** + * \brief Toggle a GPIO group. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + */ +void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask) +{ + if (p_pio->PIO_ODSR & ul_mask) { + // Value to be driven on the I/O line: 0. + p_pio->PIO_CODR = ul_mask; + } else { + // Value to be driven on the I/O line: 1. + p_pio->PIO_SODR = ul_mask; + } +} + +/** + * \brief Perform complete pin(s) configuration; general attributes and PIO init + * if necessary. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Bitmask of one or more pin(s) to configure. + * \param ul_flags Pin(s) attributes. + * + * \return Whether the pin(s) have been configured properly. + */ +uint32_t pio_configure_pin_group(Pio *p_pio, + uint32_t ul_mask, const uint32_t ul_flags) +{ + /* Configure pins */ + switch (ul_flags & PIO_TYPE_Msk) { + case PIO_TYPE_PIO_PERIPH_A: + pio_set_peripheral(p_pio, PIO_PERIPH_A, ul_mask); + pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); + break; + case PIO_TYPE_PIO_PERIPH_B: + pio_set_peripheral(p_pio, PIO_PERIPH_B, ul_mask); + pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); + break; +# if (SAM3S || SAM3N || SAM4S) + case PIO_TYPE_PIO_PERIPH_C: + pio_set_peripheral(p_pio, PIO_PERIPH_C, ul_mask); + pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); + break; + case PIO_TYPE_PIO_PERIPH_D: + pio_set_peripheral(p_pio, PIO_PERIPH_D, ul_mask); + pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); + break; +# endif + + case PIO_TYPE_PIO_INPUT: + pio_set_input(p_pio, ul_mask, ul_flags); + break; + + case PIO_TYPE_PIO_OUTPUT_0: + case PIO_TYPE_PIO_OUTPUT_1: + pio_set_output(p_pio, ul_mask, + ((ul_flags & PIO_TYPE_PIO_OUTPUT_1) + == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0, + (ul_flags & PIO_OPENDRAIN) ? 1 : 0, + (ul_flags & PIO_PULLUP) ? 1 : 0); + break; + + default: + return 0; + } + + return 1; +} + +/** + * \brief Enable interrupt for a GPIO pin. + * + * \param ul_pin The pin index. + * + * \note The function \ref gpio_configure_pin must be called before. + */ +void pio_enable_pin_interrupt(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + p_pio->PIO_IER = 1 << (ul_pin & 0x1F); +} + + +/** + * \brief Disable interrupt for a GPIO pin. + * + * \param ul_pin The pin index. + * + * \note The function \ref gpio_configure_pin must be called before. + */ +void pio_disable_pin_interrupt(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + p_pio->PIO_IDR = 1 << (ul_pin & 0x1F); +} + + +/** + * \brief Return GPIO port for a GPIO pin. + * + * \param ul_pin The pin index. + * + * \return Pointer to \ref Pio struct for GPIO port. + */ +Pio *pio_get_pin_group(uint32_t ul_pin) +{ + Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); + return p_pio; +} + +/** + * \brief Return GPIO port peripheral ID for a GPIO pin. + * + * \param ul_pin The pin index. + * + * \return GPIO port peripheral ID. + */ +uint32_t pio_get_pin_group_id(uint32_t ul_pin) +{ + uint32_t ul_id = ID_PIOA + (ul_pin >> 5); + return ul_id; +} + + +/** + * \brief Return GPIO port pin mask for a GPIO pin. + * + * \param ul_pin The pin index. + * + * \return GPIO port pin mask. + */ +uint32_t pio_get_pin_group_mask(uint32_t ul_pin) +{ + uint32_t ul_mask = 1 << (ul_pin & 0x1F); + return ul_mask; +} + + + +#if (SAM3S || SAM4S) +/** + * \brief Configure PIO capture mode. + * \note PIO capture mode will be disabled automatically. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mode Bitmask of one or more modes. + */ +void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode) +{ + ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */ + p_pio->PIO_PCMR = ul_mode; +} + +/** + * \brief Enable PIO capture mode. + * + * \param p_pio Pointer to a PIO instance. + */ +void pio_capture_enable(Pio *p_pio) +{ + p_pio->PIO_PCMR |= PIO_PCMR_PCEN; +} + +/** + * \brief Disable PIO capture mode. + * + * \param p_pio Pointer to a PIO instance. + */ +void pio_capture_disable(Pio *p_pio) +{ + p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN); +} + +/** + * \brief Read from Capture Reception Holding Register. + * Data presence should be tested before any read attempt. + * + * \param p_pio Pointer to a PIO instance. + * \param pul_data Pointer to store the data. + * + * \retval 0 Success. + * \retval 1 I/O Failure, Capture data is not ready. + */ +uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data) +{ + /* Check if the data is ready */ + if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) { + return 1; + } + + /* Read data */ + *pul_data = p_pio->PIO_PCRHR; + return 0; +} + +/** + * \brief Enable the given interrupt source of PIO capture. The status + * register of the corresponding PIO capture controller is cleared prior + * to enabling the interrupt. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt sources bit map. + */ +void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_PCISR; + p_pio->PIO_PCIER = ul_mask; +} + +/** + * \brief Disable a given interrupt source of PIO capture. + * + * \param p_pio Pointer to a PIO instance. + * \param ul_mask Interrupt sources bit map. + */ +void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask) +{ + p_pio->PIO_PCIDR = ul_mask; +} + +/** + * \brief Read PIO interrupt status of PIO capture. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The interrupt status mask value. + */ +uint32_t pio_capture_get_interrupt_status(const Pio *p_pio) +{ + return p_pio->PIO_PCISR; +} + +/** + * \brief Read PIO interrupt mask of PIO capture. + * + * \param p_pio Pointer to a PIO instance. + * + * \return The interrupt mask value. + */ +uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio) +{ + return p_pio->PIO_PCIMR; +} + +/** + * \brief Get PDC registers base address. + * + * \param p_pio Pointer to an PIO peripheral. + * + * \return PIOA PDC register base address. + */ +Pdc *pio_capture_get_pdc_base(const Pio *p_pio) +{ + p_pio = p_pio; /* Stop warning */ + return PDC_PIOA; +} +#endif + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/hardware/arduino/sam/libraries/CAN/pio.h b/hardware/arduino/sam/libraries/CAN/pio.h new file mode 100644 index 000000000..77401b6ad --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/pio.h @@ -0,0 +1,345 @@ +/** + * \file + * + * \brief Parallel Input/Output (PIO) Controller driver for SAM. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef PIO_H_INCLUDED +#define PIO_H_INCLUDED + +#include "compiler.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +#define PIO_DELTA ((uint32_t) PIOB - (uint32_t) PIOA) /* Compute PIO register length */ + +/* GPIO Support */ +#define PIO_TYPE_Pos 27 +/* PIO Type Mask */ +#define PIO_TYPE_Msk (0xFu << PIO_TYPE_Pos) +/* The pin is not a function pin. */ +#define PIO_TYPE_NOT_A_PIN (0x0u << PIO_TYPE_Pos) +/* The pin is controlled by the peripheral A. */ +#define PIO_TYPE_PIO_PERIPH_A (0x1u << PIO_TYPE_Pos) +/* The pin is controlled by the peripheral B. */ +#define PIO_TYPE_PIO_PERIPH_B (0x2u << PIO_TYPE_Pos) +/* The pin is controlled by the peripheral C. */ +#define PIO_TYPE_PIO_PERIPH_C (0x3u << PIO_TYPE_Pos) +/* The pin is controlled by the peripheral D. */ +#define PIO_TYPE_PIO_PERIPH_D (0x4u << PIO_TYPE_Pos) +/* The pin is an input. */ +#define PIO_TYPE_PIO_INPUT (0x5u << PIO_TYPE_Pos) +/* The pin is an output and has a default level of 0. */ +#define PIO_TYPE_PIO_OUTPUT_0 (0x6u << PIO_TYPE_Pos) +/* The pin is an output and has a default level of 1. */ +#define PIO_TYPE_PIO_OUTPUT_1 (0x7u << PIO_TYPE_Pos) + +typedef enum _pio_type { + PIO_NOT_A_PIN = PIO_TYPE_NOT_A_PIN, + PIO_PERIPH_A = PIO_TYPE_PIO_PERIPH_A, + PIO_PERIPH_B = PIO_TYPE_PIO_PERIPH_B, +#if (SAM3S || SAM3N || SAM4S) + PIO_PERIPH_C = PIO_TYPE_PIO_PERIPH_C, + PIO_PERIPH_D = PIO_TYPE_PIO_PERIPH_D, +#endif + PIO_INPUT = PIO_TYPE_PIO_INPUT, + PIO_OUTPUT_0 = PIO_TYPE_PIO_OUTPUT_0, + PIO_OUTPUT_1 = PIO_TYPE_PIO_OUTPUT_1 +} pio_type_t; + +/* Default pin configuration (no attribute). */ +#define PIO_DEFAULT (0u << 0) +/* The internal pin pull-up is active. */ +#define PIO_PULLUP (1u << 0) +/* The internal glitch filter is active. */ +#define PIO_DEGLITCH (1u << 1) +/* The pin is open-drain. */ +#define PIO_OPENDRAIN (1u << 2) + +/* The internal debouncing filter is active. */ +#define PIO_DEBOUNCE (1u << 3) + +/* Enable additional interrupt modes. */ +#define PIO_IT_AIME (1u << 4) + +/* Interrupt High Level/Rising Edge detection is active. */ +#define PIO_IT_RE_OR_HL (1u << 5) +/* Interrupt Edge detection is active. */ +#define PIO_IT_EDGE (1u << 6) + +/* Low level interrupt is active */ +#define PIO_IT_LOW_LEVEL (0 | 0 | PIO_IT_AIME) +/* High level interrupt is active */ +#define PIO_IT_HIGH_LEVEL (PIO_IT_RE_OR_HL | 0 | PIO_IT_AIME) +/* Falling edge interrupt is active */ +#define PIO_IT_FALL_EDGE (0 | PIO_IT_EDGE | PIO_IT_AIME) +/* Rising edge interrupt is active */ +#define PIO_IT_RISE_EDGE (PIO_IT_RE_OR_HL | PIO_IT_EDGE | PIO_IT_AIME) + +/* + * The #attribute# field is a bitmask that can either be set to PIO_DEFAULT, + * or combine (using bitwise OR '|') any number of the following constants: + * - PIO_PULLUP + * - PIO_DEGLITCH + * - PIO_DEBOUNCE + * - PIO_OPENDRAIN + * - PIO_IT_LOW_LEVEL + * - PIO_IT_HIGH_LEVEL + * - PIO_IT_FALL_EDGE + * - PIO_IT_RISE_EDGE + */ +void pio_pull_up(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_pull_up_enable); +void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_cut_off); +void pio_set(Pio *p_pio, const uint32_t ul_mask); +void pio_clear(Pio *p_pio, const uint32_t ul_mask); +uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask); +void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask); +void pio_set_input(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_attribute); +void pio_set_output(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_default_level, + const uint32_t ul_multidrive_enable, + const uint32_t ul_pull_up_enable); +uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type, + const uint32_t ul_mask, const uint32_t ul_attribute); +uint32_t pio_get_output_data_status(const Pio *p_pio, + const uint32_t ul_mask); +void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_multi_driver_enable); +uint32_t pio_get_multi_driver_status(const Pio *p_pio); + +#if (SAM3S || SAM3N || SAM4S) +void pio_pull_down(Pio *p_pio, const uint32_t ul_mask, + const uint32_t ul_pull_down_enable); +#endif + +void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask); +void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask); +uint32_t pio_get_output_write_status(const Pio *p_pio); +void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask); + +#if (SAM3S || SAM3N || SAM4S) +void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask); +uint32_t pio_get_schmitt_trigger(const Pio *p_pio); +#endif + +void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask, const uint32_t ul_attr); +void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask); +void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask); +uint32_t pio_get_interrupt_status(const Pio *p_pio); +uint32_t pio_get_interrupt_mask(const Pio *p_pio); +void pio_set_additional_interrupt_mode(Pio *p_pio, + const uint32_t ul_mask, const uint32_t ul_attribute); +void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable); +uint32_t pio_get_writeprotect_status(const Pio *p_pio); + +#if (SAM3S || SAM4S) +void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode); +void pio_capture_enable(Pio *p_pio); +void pio_capture_disable(Pio *p_pio); +uint32_t pio_capture_read(const Pio *p_pio, uint32_t * pul_data); +void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask); +void pio_capture_disable_interrupt(Pio * p_pio, const uint32_t ul_mask); +uint32_t pio_capture_get_interrupt_status(const Pio *p_pio); +uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio); +Pdc *pio_capture_get_pdc_base(const Pio *p_pio); +#endif + +/* GPIO Support */ +uint32_t pio_get_pin_value(uint32_t pin); +void pio_set_pin_high(uint32_t pin); +void pio_set_pin_low(uint32_t pin); +void pio_toggle_pin(uint32_t pin); +void pio_enable_pin_interrupt(uint32_t pin); +void pio_disable_pin_interrupt(uint32_t pin); +Pio *pio_get_pin_group(uint32_t pin); +uint32_t pio_get_pin_group_id(uint32_t pin); +uint32_t pio_get_pin_group_mask(uint32_t pin); +uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags); +void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask); +void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask); +void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask); +uint32_t pio_configure_pin_group(Pio *p_pio, uint32_t ul_mask, const uint32_t ul_flags); + +/** + * \page sam_pio_quickstart Quick Start Guide for the SAM PIO driver + * + * This is the quick start guide for the \ref sam_drivers_pio_group "PIO Driver", + * with step-by-step instructions on how to configure and use the driver for + * specific use cases. + * + * The section described below can be compiled into e.g. the main application + * loop or any other function that will need to interface with the IO port. + * + * \section sam_pio_usecases PIO use cases + * - \ref sam_pio_quickstart_basic + * - \ref sam_pio_quickstart_use_case_2 + * + * \section sam_pio_quickstart_basic Basic usage of the PIO driver + * This section will present a basic use case for the PIO driver. This use case + * will configure pin 23 on port A as output and pin 16 as an input with pullup, + * and then toggle the output pin's value to match that of the input pin. + * + * \subsection sam_pio_quickstart_use_case_1_prereq Prerequisites + * - \ref group_pmc "Power Management Controller driver" + * + * \subsection sam_pio_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * pmc_enable_periph_clk(ID_PIOA); + * + * pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); + * pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); + * \endcode + * + * \subsection sam_pio_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Enable the module clock to the PIOA peripheral: + * \code pmc_enable_periph_clk(ID_PIOA); \endcode + * -# Set pin 23 direction on PIOA as output, default low level: + * \code pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); \endcode + * -# Set pin 16 direction on PIOA as input, with pullup: + * \code pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); \endcode + * + * \subsection sam_pio_quickstart_use_case_1_example_code Example code + * Set the state of output pin 23 to match input pin 16: + * \code + * if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16)) + * pio_clear(PIOA, PIO_PA23); + * else + * pio_set(PIOA, PIO_PA23); + * \endcode + * + * \subsection sam_pio_quickstart_use_case_1_example_workflow Workflow + * -# We check the value of the pin: + * \code + * if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16)) + * \endcode + * -# Then we set the new output value based on the read pin value: + * \code + * pio_clear(PIOA, PIO_PA23); + * else + * pio_set(PIOA, PIO_PA23); + * \endcode + */ + +/** + * \page sam_pio_quickstart_use_case_2 Advanced use case - Interrupt driven edge detection + * + * \section sam_pio_quickstart_use_case_2 Advanced Use Case 1 + * This section will present a more advanced use case for the PIO driver. This use case + * will configure pin 23 on port A as output and pin 16 as an input with pullup, + * and then toggle the output pin's value to match that of the input pin using the interrupt + * controller within the device. + * + * \subsection sam_pio_quickstart_use_case_2_prereq Prerequisites + * - \ref group_pmc "Power Management Controller driver" + * + * \subsection sam_pio_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * pmc_enable_periph_clk(ID_PIOA); + * + * pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); + * pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); + * + * pio_handler_set(PIOA, ID_PIOA, PIO_PA16, PIO_IT_EDGE, pin_edge_handler); + * pio_enable_interrupt(PIOA, PIO_PA16); + * + * NVIC_EnableIRQ(PIOA_IRQn); + * \endcode + * + * \subsection sam_pio_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Enable the module clock to the PIOA peripheral: + * \code pmc_enable_periph_clk(ID_PIOA); \endcode + * -# Set pin 23 direction on PIOA as output, default low level: + * \code pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); \endcode + * -# Set pin 16 direction on PIOA as input, with pullup: + * \code pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); \endcode + * -# Configure the input pin 16 interrupt mode and handler: + * \code pio_handler_set(PIOA, ID_PIOA, PIO_PA16, PIO_IT_EDGE, pin_edge_handler); \endcode + * -# Enable the interrupt for the configured input pin: + * \code pio_enable_interrupt(PIOA, PIO_PA16); \endcode + * -# Enable interrupt handling from the PIOA module: + * \code NVIC_EnableIRQ(PIOA_IRQn); \endcode + * + * \subsection sam_pio_quickstart_use_case_2_example_code Example code + * Add the following function to your application: + * \code + * void pin_edge_handler(void) + * { + * if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16)) + * pio_clear(PIOA, PIO_PA23); + * else + * pio_set(PIOA, PIO_PA23); + * } + * \endcode + * + * \subsection sam_pio_quickstart_use_case_2_example_workflow Workflow + * -# We check the value of the pin: + * \code + * if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16)) + * \endcode + * -# Then we set the new output value based on the read pin value: + * \code + * pio_clear(PIOA, PIO_PA23); + * else + * pio_set(PIOA, PIO_PA23); + * \endcode + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* PIO_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/pll.h b/hardware/arduino/sam/libraries/CAN/pll.h new file mode 100644 index 000000000..83aafe02e --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/pll.h @@ -0,0 +1,318 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2012 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 + * + */ +#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 SAM4L +# include "sam4l/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 */ diff --git a/hardware/arduino/sam/libraries/CAN/pmc.h b/hardware/arduino/sam/libraries/CAN/pmc.h new file mode 100644 index 000000000..947bcd2ba --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/pmc.h @@ -0,0 +1,458 @@ +/** + * \file + * + * \brief Power Management Controller (PMC) driver for SAM. + * + * Copyright (c) 2011-2012 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 + * + */ + +#ifndef PMC_H_INCLUDED +#define PMC_H_INCLUDED + +#include "compiler.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Bit mask for peripheral clocks (PCER0) */ +#define PMC_MASK_STATUS0 (0xFFFFFFFC) + +/** Bit mask for peripheral clocks (PCER1) */ +#define PMC_MASK_STATUS1 (0xFFFFFFFF) + +/** Loop counter timeout value */ +#define PMC_TIMEOUT (2048) + +/** Key to unlock CKGR_MOR register */ +#define PMC_CKGR_MOR_KEY_VALUE CKGR_MOR_KEY(0x37) + +/** Key used to write SUPC registers */ +#define SUPC_KEY_VALUE ((uint32_t) 0xA5) + +/** Mask to access fast startup input */ +#define PMC_FAST_STARTUP_Msk (0x7FFFFu) + +/** PMC_WPMR Write Protect KEY, unlock it */ +#define PMC_WPMR_WPKEY_VALUE PMC_WPMR_WPKEY((uint32_t) 0x504D43) + +/** Using external oscillator */ +#define PMC_OSC_XTAL 0 + +/** Oscillator in bypass mode */ +#define PMC_OSC_BYPASS 1 + +#define PMC_PCK_0 0 /* PCK0 ID */ +#define PMC_PCK_1 1 /* PCK1 ID */ +#define PMC_PCK_2 2 /* PCK2 ID */ + +/** Convert startup time from us to MOSCXTST */ +#define pmc_us_to_moscxtst(startup_us, slowck_freq) \ + ((startup_us * slowck_freq / 8 / 1000000) < 0x100 ? \ + (startup_us * slowck_freq / 8 / 1000000) : \ + 0xFF) + +/** + * \name Master clock (MCK) Source and Prescaler configuration + * + * The following functions may be used to select the clock source and + * prescaler for the master clock. + */ +//@{ + +void pmc_mck_set_prescaler(uint32_t ul_pres); +void pmc_mck_set_source(uint32_t ul_source); +uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres); +#if (SAM3S || SAM4S) +uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres); +#endif +#if SAM4S +void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state); +#endif + + +//@} + +/** + * \name Slow clock (SLCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_32kxtal(void); + +//@} + +/** + * \name Main Clock (MAINCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf); +void pmc_osc_enable_fastrc(uint32_t ul_rc); +void pmc_osc_disable_fastrc(void); +void pmc_switch_mainck_to_xtal(uint32_t ul_bypass, + uint32_t ul_xtal_startup_time); +void pmc_osc_disable_xtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_mainck(void); + +//@} + +/** + * \name PLL oscillator and configuration + * + */ +//@{ + +void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva); +void pmc_disable_pllack(void); +uint32_t pmc_is_locked_pllack(void); + +#if (SAM3S || SAM4S) +void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb); +void pmc_disable_pllbck(void); +uint32_t pmc_is_locked_pllbck(void); +#endif + +#if (SAM3XA || SAM3U) +void pmc_enable_upll_clock(void); +void pmc_disable_upll_clock(void); +uint32_t pmc_is_locked_upll(void); +#endif + +//@} + +/** + * \name Peripherals clock configuration + * + */ +//@{ + +uint32_t pmc_enable_periph_clk(uint32_t ul_id); +uint32_t pmc_disable_periph_clk(uint32_t ul_id); +void pmc_enable_all_periph_clk(void); +void pmc_disable_all_periph_clk(void); +uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id); + +//@} + +/** + * \name Programmable clock Source and Prescaler configuration + * + * The following functions may be used to select the clock source and + * prescaler for the specified programmable clock. + */ +//@{ + +void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres); +void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source); +uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres); +#if (SAM3S || SAM4S) +uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres); +#endif +void pmc_enable_pck(uint32_t ul_id); +void pmc_disable_pck(uint32_t ul_id); +void pmc_enable_all_pck(void); +void pmc_disable_all_pck(void); +uint32_t pmc_is_pck_enabled(uint32_t ul_id); + +//@} + +/** + * \name USB clock configuration + * + */ +//@{ + +#if (SAM3S || SAM3XA || SAM4S) +void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM4S) +void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv); +#endif +#if (SAM3XA) +void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM3XA || SAM4S) +void pmc_enable_udpck(void); +void pmc_disable_udpck(void); +#endif + +//@} + +/** + * \name Interrupt and status management + * + */ +//@{ + +void pmc_enable_interrupt(uint32_t ul_sources); +void pmc_disable_interrupt(uint32_t ul_sources); +uint32_t pmc_get_interrupt_mask(void); +uint32_t pmc_get_status(void); + +//@} + +/** + * \name Power management + * + * The following functions are used to configure sleep mode and additional + * wake up inputs. + */ +//@{ + +void pmc_set_fast_startup_input(uint32_t ul_inputs); +void pmc_clr_fast_startup_input(uint32_t ul_inputs); +void pmc_enable_sleepmode(uint8_t uc_type); +void pmc_enable_waitmode(void); +void pmc_enable_backupmode(void); + +//@} + +/** + * \name Failure detector + * + */ +//@{ + +void pmc_enable_clock_failure_detector(void); +void pmc_disable_clock_failure_detector(void); + +//@} + +/** + * \name Write protection + * + */ +//@{ + +void pmc_set_writeprotect(uint32_t ul_enable); +uint32_t pmc_get_writeprotect_status(void); + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +//! @} + +/** + * \page sam_pmc_quickstart Quick start guide for the SAM PMC module + * + * This is the quick start guide for the \ref pmc_group "PMC module", 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 pmc_use_cases PMC use cases + * - \ref pmc_basic_use_case Basic use case - Switch Main Clock sources + * - \ref pmc_use_case_2 Advanced use case - Configure Programmable Clocks + * + * \section pmc_basic_use_case Basic use case - Switch Main Clock sources + * In this use case, the PMC module is configured for a variety of system clock + * sources and speeds. A LED is used to visually indicate the current clock + * speed as the source is switched. + * + * \section pmc_basic_use_case_setup Setup + * + * \subsection pmc_basic_use_case_setup_prereq Prerequisites + * -# \ref gpio_group "General Purpose I/O Management (gpio)" + * + * \subsection pmc_basic_use_case_setup_code Code + * The following function needs to be added to the user application, to flash a + * board LED a variable number of times at a rate given in CPU ticks. + * + * \code + * #define FLASH_TICK_COUNT 0x00012345 + * + * void flash_led(uint32_t tick_count, uint8_t flash_count) + * { + * SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; + * SysTick->LOAD = tick_count; + * + * while (flash_count--) + * { + * gpio_toggle_pin(LED0_GPIO); + * while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + * gpio_toggle_pin(LED0_GPIO); + * while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + * } + * } + * \endcode + * + * \section pmc_basic_use_case_usage Use case + * + * \subsection pmc_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + * for (;;) + * { + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_xtal(0); + * flash_led(FLASH_TICK_COUNT, 5); + * } + * \endcode + * + * \subsection pmc_basic_use_case_usage_flow Workflow + * -# Wrap the code in an infinite loop: + * \code + * for (;;) + * \endcode + * -# Switch the Master CPU frequency to the internal 12MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the internal 8MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the internal 4MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the external crystal oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + */ + +/** + * \page pmc_use_case_2 Use case #2 - Configure Programmable Clocks + * In this use case, the PMC module is configured to start the Slow Clock from + * an attached 32KHz crystal, and start one of the Programmable Clock modules + * sourced from the Slow Clock divided down with a prescale factor of 64. + * + * \section pmc_use_case_2_setup Setup + * + * \subsection pmc_use_case_2_setup_prereq Prerequisites + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * + * \subsection pmc_use_case_2_setup_code Code + * The following code must be added to the user application: + * \code + * pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); + * \endcode + * + * \subsection pmc_use_case_2_setup_code_workflow Workflow + * -# Configure the PCK1 pin to output on a specific port pin (in this case, + * PIOA pin 17) of the microcontroller. + * \code + * pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); + * \endcode + * \note The peripheral selection and pin will vary according to your selected + * SAM device model. Refer to the "Peripheral Signal Multiplexing on I/O + * Lines" of your device's datasheet. + * + * \section pmc_use_case_2_usage Use case + * The generated PCK1 clock output can be viewed on an oscilloscope attached to + * the correct pin of the microcontroller. + * + * \subsection pmc_use_case_2_usage_code Example code + * Add to application C-file: + * \code + * pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + * pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); + * pmc_enable_pck(PMC_PCK_1); + * + * for (;;) + * { + * // Do Nothing + * } + * \endcode + * + * \subsection pmc_use_case_2_usage_flow Workflow + * -# Switch the Slow Clock source input to an external 32KHz crystal: + * \code + * pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + * \endcode + * -# Switch the Programmable Clock module PCK1 source clock to the Slow Clock, + * with a prescaler of 64: + * \code + * pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); + * \endcode + * -# Enable Programmable Clock module PCK1: + * \code + * pmc_enable_pck(PMC_PCK_1); + * \endcode + * -# Enter an infinite loop: + * \code + * for (;;) + * { + * // Do Nothing + * } + * \endcode + */ + +#endif /* PMC_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/sam3x/osc.h b/hardware/arduino/sam/libraries/CAN/sam3x/osc.h new file mode 100644 index 000000000..d1d090404 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sam3x/osc.h @@ -0,0 +1,223 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions. + * + * Copyright (c) 2011-2012 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 + * + */ + +#ifndef CHIP_OSC_H_INCLUDED +#define CHIP_OSC_H_INCLUDED + +#include "board.h" +#include "pmc.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup osc_group + * @{ + */ + +//! \name Oscillator identifiers +//@{ +#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator. +//@} + +//! \name Oscillator clock speed in hertz +//@{ +#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator. +//@} + +static inline void osc_enable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + break; + + case OSC_SLCK_32K_XTAL: + pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + break; + + case OSC_SLCK_32K_BYPASS: + pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS); + break; + + + case OSC_MAINCK_4M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + break; + + case OSC_MAINCK_8M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + break; + + case OSC_MAINCK_12M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + break; + + + case OSC_MAINCK_XTAL: + pmc_switch_mainck_to_xtal(PMC_OSC_XTAL, + pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, + OSC_SLCK_32K_RC_HZ)); + break; + + case OSC_MAINCK_BYPASS: + pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS, + pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, + OSC_SLCK_32K_RC_HZ)); + break; + } +} + +static inline void osc_disable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + break; + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + pmc_osc_disable_fastrc(); + break; + + case OSC_MAINCK_XTAL: + pmc_osc_disable_xtal(PMC_OSC_XTAL); + break; + + case OSC_MAINCK_BYPASS: + pmc_osc_disable_xtal(PMC_OSC_BYPASS); + break; + } +} + +static inline bool osc_is_ready(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return 1; + + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + return pmc_osc_is_ready_32kxtal(); + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + case OSC_MAINCK_XTAL: + case OSC_MAINCK_BYPASS: + return pmc_osc_is_ready_mainck(); + } + + return 0; +} + +static inline uint32_t osc_get_rate(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return OSC_SLCK_32K_RC_HZ; + +#ifdef BOARD_FREQ_SLCK_XTAL + case OSC_SLCK_32K_XTAL: + return BOARD_FREQ_SLCK_XTAL; +#endif + +#ifdef BOARD_FREQ_SLCK_BYPASS + case OSC_SLCK_32K_BYPASS: + return BOARD_FREQ_SLCK_BYPASS; +#endif + + case OSC_MAINCK_4M_RC: + return OSC_MAINCK_4M_RC_HZ; + + case OSC_MAINCK_8M_RC: + return OSC_MAINCK_8M_RC_HZ; + + case OSC_MAINCK_12M_RC: + return OSC_MAINCK_12M_RC_HZ; + +#ifdef BOARD_FREQ_MAINCK_XTAL + case OSC_MAINCK_XTAL: + return BOARD_FREQ_MAINCK_XTAL; +#endif + +#ifdef BOARD_FREQ_MAINCK_BYPASS + case OSC_MAINCK_BYPASS: + return BOARD_FREQ_MAINCK_BYPASS; +#endif + } + + return 0; +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_OSC_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/sam3x/pll.h b/hardware/arduino/sam/libraries/CAN/sam3x/pll.h new file mode 100644 index 000000000..6a4db7be5 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sam3x/pll.h @@ -0,0 +1,261 @@ +/** + * \file + * + * \brief Chip-specific PLL definitions. + * + * Copyright (c) 2011-2012 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 + * + */ + +#ifndef CHIP_PLL_H_INCLUDED +#define CHIP_PLL_H_INCLUDED + +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup pll_group + * @{ + */ + +#define PLL_OUTPUT_MIN_HZ 84000000 +#define PLL_OUTPUT_MAX_HZ 192000000 + +#define PLL_INPUT_MIN_HZ 8000000 +#define PLL_INPUT_MAX_HZ 16000000 + +#define NR_PLLS 2 +#define PLLA_ID 0 +#define UPLL_ID 1 //!< USB UTMI PLL. + +#define PLL_UPLL_HZ 480000000 + +#define PLL_COUNT 0x3fU + +enum pll_source { + PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator. + PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator. + PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator. + PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator. + PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator. + PLL_NR_SOURCES, //!< Number of PLL sources. +}; + +struct pll_config { + uint32_t ctrl; +}; + +#define pll_get_default_rate(pll_id) \ + ((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \ + * CONFIG_PLL##pll_id##_MUL) \ + / CONFIG_PLL##pll_id##_DIV) + +/* Force UTMI PLL parameters (Hardware defined) */ +#ifdef CONFIG_PLL1_SOURCE +# undef CONFIG_PLL1_SOURCE +#endif +#ifdef CONFIG_PLL1_MUL +# undef CONFIG_PLL1_MUL +#endif +#ifdef CONFIG_PLL1_DIV +# undef CONFIG_PLL1_DIV +#endif +#define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL +#define CONFIG_PLL1_MUL 0 +#define CONFIG_PLL1_DIV 0 + +/** + * \note The SAM3X PLL hardware interprets mul as mul+1. For readability the hardware mul+1 + * is hidden in this implementation. Use mul as mul effective value. + */ +static inline void pll_config_init(struct pll_config *p_cfg, + enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul) +{ + uint32_t vco_hz; + + Assert(e_src < PLL_NR_SOURCES); + + if (ul_div == 0 && ul_mul == 0) { /* Must only be true for UTMI PLL */ + p_cfg->ctrl = CKGR_UCKR_UPLLCOUNT(PLL_COUNT); + } else { /* PLLA */ + /* Calculate internal VCO frequency */ + vco_hz = osc_get_rate(e_src) / ul_div; + Assert(vco_hz >= PLL_INPUT_MIN_HZ); + Assert(vco_hz <= PLL_INPUT_MAX_HZ); + + vco_hz *= ul_mul; + Assert(vco_hz >= PLL_OUTPUT_MIN_HZ); + Assert(vco_hz <= PLL_OUTPUT_MAX_HZ); + + /* PMC hardware will automatically make it mul+1 */ + p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) | CKGR_PLLAR_PLLACOUNT(PLL_COUNT); + } +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + p_cfg->ctrl = PMC->CKGR_PLLAR; + else + p_cfg->ctrl = PMC->CKGR_UCKR; +} + +static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } else { + PMC->CKGR_UCKR = p_cfg->ctrl; + } +} + +static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } else { + PMC->CKGR_UCKR = p_cfg->ctrl | CKGR_UCKR_UPLLEN; + } +} + +/** + * \note This will only disable the selected PLL, not the underlying oscillator (mainck). + */ +static inline void pll_disable(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + pmc_disable_pllack(); + else + PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; +} + +static inline uint32_t pll_is_locked(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + return pmc_is_locked_pllack(); + else + return pmc_is_locked_upll(); +} + +static inline void pll_enable_source(enum pll_source e_src) +{ + switch (e_src) { + case PLL_SRC_MAINCK_4M_RC: + case PLL_SRC_MAINCK_8M_RC: + case PLL_SRC_MAINCK_12M_RC: + case PLL_SRC_MAINCK_XTAL: + case PLL_SRC_MAINCK_BYPASS: + osc_enable(e_src); + osc_wait_ready(e_src); + break; + + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int ul_pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(ul_pll_id)) { + return; // Pll already running + } + switch (ul_pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif +#ifdef CONFIG_PLL1_SOURCE + case 1: + pll_enable_source(CONFIG_PLL1_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL1_SOURCE, + CONFIG_PLL1_DIV, + CONFIG_PLL1_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, ul_pll_id); + while (!pll_is_locked(ul_pll_id)); +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_PLL_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/sam3x8e_.h b/hardware/arduino/sam/libraries/CAN/sam3x8e_.h new file mode 100644 index 000000000..378216062 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sam3x8e_.h @@ -0,0 +1,591 @@ +/** + * \file + * + * Copyright (c) 2012 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 + * + */ + +#ifndef _SAM3X8E_ +#define _SAM3X8E_ + +/** \addtogroup SAM3X8E_definitions SAM3X8E definitions + This file defines all structures and symbols for SAM3X8E: + - registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +#endif + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_cmsis CMSIS Definitions */ +/*@{*/ + +/**< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M3 Processor Exceptions Numbers ******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /**< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M3 System Tick Interrupt */ +/****** SAM3X8E specific Interrupt Numbers *********************************/ + + SUPC_IRQn = 0, /**< 0 SAM3X8E Supply Controller (SUPC) */ + RSTC_IRQn = 1, /**< 1 SAM3X8E Reset Controller (RSTC) */ + RTC_IRQn = 2, /**< 2 SAM3X8E Real Time Clock (RTC) */ + RTT_IRQn = 3, /**< 3 SAM3X8E Real Time Timer (RTT) */ + WDT_IRQn = 4, /**< 4 SAM3X8E Watchdog Timer (WDT) */ + PMC_IRQn = 5, /**< 5 SAM3X8E Power Management Controller (PMC) */ + EFC0_IRQn = 6, /**< 6 SAM3X8E Enhanced Flash Controller 0 (EFC0) */ + EFC1_IRQn = 7, /**< 7 SAM3X8E Enhanced Flash Controller 1 (EFC1) */ + UART_IRQn = 8, /**< 8 SAM3X8E Universal Asynchronous Receiver Transceiver (UART) */ + SMC_IRQn = 9, /**< 9 SAM3X8E Static Memory Controller (SMC) */ + PIOA_IRQn = 11, /**< 11 SAM3X8E Parallel I/O Controller A, (PIOA) */ + PIOB_IRQn = 12, /**< 12 SAM3X8E Parallel I/O Controller B (PIOB) */ + PIOC_IRQn = 13, /**< 13 SAM3X8E Parallel I/O Controller C (PIOC) */ + PIOD_IRQn = 14, /**< 14 SAM3X8E Parallel I/O Controller D (PIOD) */ + USART0_IRQn = 17, /**< 17 SAM3X8E USART 0 (USART0) */ + USART1_IRQn = 18, /**< 18 SAM3X8E USART 1 (USART1) */ + USART2_IRQn = 19, /**< 19 SAM3X8E USART 2 (USART2) */ + USART3_IRQn = 20, /**< 20 SAM3X8E USART 3 (USART3) */ + HSMCI_IRQn = 21, /**< 21 SAM3X8E Multimedia Card Interface (HSMCI) */ + TWI0_IRQn = 22, /**< 22 SAM3X8E Two-Wire Interface 0 (TWI0) */ + TWI1_IRQn = 23, /**< 23 SAM3X8E Two-Wire Interface 1 (TWI1) */ + SPI0_IRQn = 24, /**< 24 SAM3X8E Serial Peripheral Interface (SPI0) */ + SSC_IRQn = 26, /**< 26 SAM3X8E Synchronous Serial Controller (SSC) */ + TC0_IRQn = 27, /**< 27 SAM3X8E Timer Counter 0 (TC0) */ + TC1_IRQn = 28, /**< 28 SAM3X8E Timer Counter 1 (TC1) */ + TC2_IRQn = 29, /**< 29 SAM3X8E Timer Counter 2 (TC2) */ + TC3_IRQn = 30, /**< 30 SAM3X8E Timer Counter 3 (TC3) */ + TC4_IRQn = 31, /**< 31 SAM3X8E Timer Counter 4 (TC4) */ + TC5_IRQn = 32, /**< 32 SAM3X8E Timer Counter 5 (TC5) */ + TC6_IRQn = 33, /**< 33 SAM3X8E Timer Counter 6 (TC6) */ + TC7_IRQn = 34, /**< 34 SAM3X8E Timer Counter 7 (TC7) */ + TC8_IRQn = 35, /**< 35 SAM3X8E Timer Counter 8 (TC8) */ + PWM_IRQn = 36, /**< 36 SAM3X8E Pulse Width Modulation Controller (PWM) */ + ADC_IRQn = 37, /**< 37 SAM3X8E ADC Controller (ADC) */ + DACC_IRQn = 38, /**< 38 SAM3X8E DAC Controller (DACC) */ + DMAC_IRQn = 39, /**< 39 SAM3X8E DMA Controller (DMAC) */ + UOTGHS_IRQn = 40, /**< 40 SAM3X8E USB OTG High Speed (UOTGHS) */ + TRNG_IRQn = 41, /**< 41 SAM3X8E True Random Number Generator (TRNG) */ + EMAC_IRQn = 42, /**< 42 SAM3X8E Ethernet MAC (EMAC) */ + CAN0_IRQn = 43, /**< 43 SAM3X8E CAN Controller 0 (CAN0) */ + CAN1_IRQn = 44 /**< 44 SAM3X8E CAN Controller 1 (CAN1) */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pfnReserved5_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnSUPC_Handler; /* 0 Supply Controller */ + void* pfnRSTC_Handler; /* 1 Reset Controller */ + void* pfnRTC_Handler; /* 2 Real Time Clock */ + void* pfnRTT_Handler; /* 3 Real Time Timer */ + void* pfnWDT_Handler; /* 4 Watchdog Timer */ + void* pfnPMC_Handler; /* 5 Power Management Controller */ + void* pfnEFC0_Handler; /* 6 Enhanced Flash Controller 0 */ + void* pfnEFC1_Handler; /* 7 Enhanced Flash Controller 1 */ + void* pfnUART_Handler; /* 8 Universal Asynchronous Receiver Transceiver */ + void* pfnSMC_Handler; /* 9 Static Memory Controller */ + void* pvReserved10; + void* pfnPIOA_Handler; /* 11 Parallel I/O Controller A, */ + void* pfnPIOB_Handler; /* 12 Parallel I/O Controller B */ + void* pfnPIOC_Handler; /* 13 Parallel I/O Controller C */ + void* pfnPIOD_Handler; /* 14 Parallel I/O Controller D */ + void* pvReserved15; + void* pvReserved16; + void* pfnUSART0_Handler; /* 17 USART 0 */ + void* pfnUSART1_Handler; /* 18 USART 1 */ + void* pfnUSART2_Handler; /* 19 USART 2 */ + void* pfnUSART3_Handler; /* 20 USART 3 */ + void* pfnHSMCI_Handler; /* 21 Multimedia Card Interface */ + void* pfnTWI0_Handler; /* 22 Two-Wire Interface 0 */ + void* pfnTWI1_Handler; /* 23 Two-Wire Interface 1 */ + void* pfnSPI0_Handler; /* 24 Serial Peripheral Interface */ + void* pvReserved25; + void* pfnSSC_Handler; /* 26 Synchronous Serial Controller */ + void* pfnTC0_Handler; /* 27 Timer Counter 0 */ + void* pfnTC1_Handler; /* 28 Timer Counter 1 */ + void* pfnTC2_Handler; /* 29 Timer Counter 2 */ + void* pfnTC3_Handler; /* 30 Timer Counter 3 */ + void* pfnTC4_Handler; /* 31 Timer Counter 4 */ + void* pfnTC5_Handler; /* 32 Timer Counter 5 */ + void* pfnTC6_Handler; /* 33 Timer Counter 6 */ + void* pfnTC7_Handler; /* 34 Timer Counter 7 */ + void* pfnTC8_Handler; /* 35 Timer Counter 8 */ + void* pfnPWM_Handler; /* 36 Pulse Width Modulation Controller */ + void* pfnADC_Handler; /* 37 ADC Controller */ + void* pfnDACC_Handler; /* 38 DAC Controller */ + void* pfnDMAC_Handler; /* 39 DMA Controller */ + void* pfnUOTGHS_Handler; /* 40 USB OTG High Speed */ + void* pfnTRNG_Handler; /* 41 True Random Number Generator */ + void* pfnEMAC_Handler; /* 42 Ethernet MAC */ + void* pfnCAN0_Handler; /* 43 CAN Controller 0 */ + void* pfnCAN1_Handler; /* 44 CAN Controller 1 */ +} DeviceVectors; + +/* Cortex-M3 core handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void MemManage_Handler ( void ); +void BusFault_Handler ( void ); +void UsageFault_Handler ( void ); +void SVC_Handler ( void ); +void DebugMon_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void ADC_Handler ( void ); +void CAN0_Handler ( void ); +void CAN1_Handler ( void ); +void DACC_Handler ( void ); +void DMAC_Handler ( void ); +void EFC0_Handler ( void ); +void EFC1_Handler ( void ); +void EMAC_Handler ( void ); +void HSMCI_Handler ( void ); +void PIOA_Handler ( void ); +void PIOB_Handler ( void ); +void PIOC_Handler ( void ); +void PIOD_Handler ( void ); +void PMC_Handler ( void ); +void PWM_Handler ( void ); +void RSTC_Handler ( void ); +void RTC_Handler ( void ); +void RTT_Handler ( void ); +void SMC_Handler ( void ); +void SPI0_Handler ( void ); +void SSC_Handler ( void ); +void SUPC_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void TC8_Handler ( void ); +void TRNG_Handler ( void ); +void TWI0_Handler ( void ); +void TWI1_Handler ( void ); +void UART_Handler ( void ); +void UOTGHS_Handler ( void ); +void USART0_Handler ( void ); +void USART1_Handler ( void ); +void USART2_Handler ( void ); +void USART3_Handler ( void ); +void WDT_Handler ( void ); + +/** + * \brief Configuration of the Cortex-M3 Processor and Core Peripherals + */ + +#define __CM3_REV 0x0200 /**< SAM3X8E core revision number ([15:8] revision number, [7:0] patch number) */ +#define __MPU_PRESENT 1 /**< SAM3X8E does provide a MPU */ +#define __NVIC_PRIO_BITS 4 /**< SAM3X8E uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /**< Set to 1 if different SysTick Config is used */ + +/* + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_sam3x.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_api Peripheral Software API */ +/*@{*/ + +#include "component/component_adc.h" +#include "component/component_can.h" +#include "component/component_chipid.h" +#include "component/component_dacc.h" +#include "component/component_dmac.h" +#include "component/component_efc.h" +#include "component/component_emac.h" +#include "component/component_gpbr.h" +#include "component/component_hsmci.h" +#include "component/component_matrix.h" +#include "component/component_pdc.h" +#include "component/component_pio.h" +#include "component/component_pmc.h" +#include "component/component_pwm.h" +#include "component/component_rstc.h" +#include "component/component_rtc.h" +#include "component/component_rtt.h" +#include "component/component_smc.h" +#include "component/component_spi.h" +#include "component/component_ssc.h" +#include "component/component_supc.h" +#include "component/component_tc.h" +#include "component/component_trng.h" +#include "component/component_twi.h" +#include "component/component_uart.h" +#include "component/component_uotghs.h" +#include "component/component_usart.h" +#include "component/component_wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* REGISTER ACCESS DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/instance_hsmci.h" +#include "instance/instance_ssc.h" +#include "instance/instance_spi0.h" +#include "instance/instance_tc0.h" +#include "instance/instance_tc1.h" +#include "instance/instance_tc2.h" +#include "instance/instance_twi0.h" +#include "instance/instance_twi1.h" +#include "instance/instance_pwm.h" +#include "instance/instance_usart0.h" +#include "instance/instance_usart1.h" +#include "instance/instance_usart2.h" +#include "instance/instance_usart3.h" +#include "instance/instance_uotghs.h" +#include "instance/instance_emac.h" +#include "instance/instance_can0.h" +#include "instance/instance_can1.h" +#include "instance/instance_trng.h" +#include "instance/instance_adc.h" +#include "instance/instance_dmac.h" +#include "instance/instance_dacc.h" +#include "instance/instance_smc.h" +#include "instance/instance_matrix.h" +#include "instance/instance_pmc.h" +#include "instance/instance_uart.h" +#include "instance/instance_chipid.h" +#include "instance/instance_efc0.h" +#include "instance/instance_efc1.h" +#include "instance/instance_pioa.h" +#include "instance/instance_piob.h" +#include "instance/instance_pioc.h" +#include "instance/instance_piod.h" +#include "instance/instance_rstc.h" +#include "instance/instance_supc.h" +#include "instance/instance_rtt.h" +#include "instance/instance_wdt.h" +#include "instance/instance_rtc.h" +#include "instance/instance_gpbr.h" +/*@}*/ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_id Peripheral Ids Definitions */ +/*@{*/ + +#define ID_SUPC ( 0) /**< \brief Supply Controller (SUPC) */ +#define ID_RSTC ( 1) /**< \brief Reset Controller (RSTC) */ +#define ID_RTC ( 2) /**< \brief Real Time Clock (RTC) */ +#define ID_RTT ( 3) /**< \brief Real Time Timer (RTT) */ +#define ID_WDT ( 4) /**< \brief Watchdog Timer (WDT) */ +#define ID_PMC ( 5) /**< \brief Power Management Controller (PMC) */ +#define ID_EFC0 ( 6) /**< \brief Enhanced Flash Controller 0 (EFC0) */ +#define ID_EFC1 ( 7) /**< \brief Enhanced Flash Controller 1 (EFC1) */ +#define ID_UART ( 8) /**< \brief Universal Asynchronous Receiver Transceiver (UART) */ +#define ID_SMC ( 9) /**< \brief Static Memory Controller (SMC) */ +#define ID_PIOA (11) /**< \brief Parallel I/O Controller A, (PIOA) */ +#define ID_PIOB (12) /**< \brief Parallel I/O Controller B (PIOB) */ +#define ID_PIOC (13) /**< \brief Parallel I/O Controller C (PIOC) */ +#define ID_PIOD (14) /**< \brief Parallel I/O Controller D (PIOD) */ +#define ID_USART0 (17) /**< \brief USART 0 (USART0) */ +#define ID_USART1 (18) /**< \brief USART 1 (USART1) */ +#define ID_USART2 (19) /**< \brief USART 2 (USART2) */ +#define ID_USART3 (20) /**< \brief USART 3 (USART3) */ +#define ID_HSMCI (21) /**< \brief Multimedia Card Interface (HSMCI) */ +#define ID_TWI0 (22) /**< \brief Two-Wire Interface 0 (TWI0) */ +#define ID_TWI1 (23) /**< \brief Two-Wire Interface 1 (TWI1) */ +#define ID_SPI0 (24) /**< \brief Serial Peripheral Interface (SPI0) */ +#define ID_SSC (26) /**< \brief Synchronous Serial Controller (SSC) */ +#define ID_TC0 (27) /**< \brief Timer Counter 0 (TC0) */ +#define ID_TC1 (28) /**< \brief Timer Counter 1 (TC1) */ +#define ID_TC2 (29) /**< \brief Timer Counter 2 (TC2) */ +#define ID_TC3 (30) /**< \brief Timer Counter 3 (TC3) */ +#define ID_TC4 (31) /**< \brief Timer Counter 4 (TC4) */ +#define ID_TC5 (32) /**< \brief Timer Counter 5 (TC5) */ +#define ID_TC6 (33) /**< \brief Timer Counter 6 (TC6) */ +#define ID_TC7 (34) /**< \brief Timer Counter 7 (TC7) */ +#define ID_TC8 (35) /**< \brief Timer Counter 8 (TC8) */ +#define ID_PWM (36) /**< \brief Pulse Width Modulation Controller (PWM) */ +#define ID_ADC (37) /**< \brief ADC Controller (ADC) */ +#define ID_DACC (38) /**< \brief DAC Controller (DACC) */ +#define ID_DMAC (39) /**< \brief DMA Controller (DMAC) */ +#define ID_UOTGHS (40) /**< \brief USB OTG High Speed (UOTGHS) */ +#define ID_TRNG (41) /**< \brief True Random Number Generator (TRNG) */ +#define ID_EMAC (42) /**< \brief Ethernet MAC (EMAC) */ +#define ID_CAN0 (43) /**< \brief CAN Controller 0 (CAN0) */ +#define ID_CAN1 (44) /**< \brief CAN Controller 1 (CAN1) */ +/*@}*/ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_base Peripheral Base Address Definitions */ +/*@{*/ + +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define HSMCI (0x40000000U) /**< \brief (HSMCI ) Base Address */ +#define SSC (0x40004000U) /**< \brief (SSC ) Base Address */ +#define SPI0 (0x40008000U) /**< \brief (SPI0 ) Base Address */ +#define TC0 (0x40080000U) /**< \brief (TC0 ) Base Address */ +#define TC1 (0x40084000U) /**< \brief (TC1 ) Base Address */ +#define TC2 (0x40088000U) /**< \brief (TC2 ) Base Address */ +#define TWI0 (0x4008C000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 (0x4008C100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 (0x40090000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 (0x40090100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define PWM (0x40094000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM (0x40094100U) /**< \brief (PDC_PWM ) Base Address */ +#define USART0 (0x40098000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 (0x40098100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 (0x4009C000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 (0x4009C100U) /**< \brief (PDC_USART1) Base Address */ +#define USART2 (0x400A0000U) /**< \brief (USART2 ) Base Address */ +#define PDC_USART2 (0x400A0100U) /**< \brief (PDC_USART2) Base Address */ +#define USART3 (0x400A4000U) /**< \brief (USART3 ) Base Address */ +#define PDC_USART3 (0x400A4100U) /**< \brief (PDC_USART3) Base Address */ +#define UOTGHS (0x400AC000U) /**< \brief (UOTGHS ) Base Address */ +#define EMAC (0x400B0000U) /**< \brief (EMAC ) Base Address */ +#define CAN0 (0x400B4000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 (0x400B8000U) /**< \brief (CAN1 ) Base Address */ +#define TRNG (0x400BC000U) /**< \brief (TRNG ) Base Address */ +#define ADC (0x400C0000U) /**< \brief (ADC ) Base Address */ +#define PDC_ADC (0x400C0100U) /**< \brief (PDC_ADC ) Base Address */ +#define DMAC (0x400C4000U) /**< \brief (DMAC ) Base Address */ +#define DACC (0x400C8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC (0x400C8100U) /**< \brief (PDC_DACC ) Base Address */ +#define SMC (0x400E0000U) /**< \brief (SMC ) Base Address */ +#define MATRIX (0x400E0400U) /**< \brief (MATRIX ) Base Address */ +#define PMC (0x400E0600U) /**< \brief (PMC ) Base Address */ +#define UART (0x400E0800U) /**< \brief (UART ) Base Address */ +#define PDC_UART (0x400E0900U) /**< \brief (PDC_UART ) Base Address */ +#define CHIPID (0x400E0940U) /**< \brief (CHIPID ) Base Address */ +#define EFC0 (0x400E0A00U) /**< \brief (EFC0 ) Base Address */ +#define EFC1 (0x400E0C00U) /**< \brief (EFC1 ) Base Address */ +#define PIOA (0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PIOB (0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC (0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD (0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC (0x400E1A00U) /**< \brief (RSTC ) Base Address */ +#define SUPC (0x400E1A10U) /**< \brief (SUPC ) Base Address */ +#define RTT (0x400E1A30U) /**< \brief (RTT ) Base Address */ +#define WDT (0x400E1A50U) /**< \brief (WDT ) Base Address */ +#define RTC (0x400E1A60U) /**< \brief (RTC ) Base Address */ +#define GPBR (0x400E1A90U) /**< \brief (GPBR ) Base Address */ +#else +#define HSMCI ((Hsmci *)0x40000000U) /**< \brief (HSMCI ) Base Address */ +#define SSC ((Ssc *)0x40004000U) /**< \brief (SSC ) Base Address */ +#define SPI0 ((Spi *)0x40008000U) /**< \brief (SPI0 ) Base Address */ +#define TC0 ((Tc *)0x40080000U) /**< \brief (TC0 ) Base Address */ +#define TC1 ((Tc *)0x40084000U) /**< \brief (TC1 ) Base Address */ +#define TC2 ((Tc *)0x40088000U) /**< \brief (TC2 ) Base Address */ +#define TWI0 ((Twi *)0x4008C000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 ((Pdc *)0x4008C100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 ((Twi *)0x40090000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 ((Pdc *)0x40090100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define PWM ((Pwm *)0x40094000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM ((Pdc *)0x40094100U) /**< \brief (PDC_PWM ) Base Address */ +#define USART0 ((Usart *)0x40098000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 ((Pdc *)0x40098100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 ((Usart *)0x4009C000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 ((Pdc *)0x4009C100U) /**< \brief (PDC_USART1) Base Address */ +#define USART2 ((Usart *)0x400A0000U) /**< \brief (USART2 ) Base Address */ +#define PDC_USART2 ((Pdc *)0x400A0100U) /**< \brief (PDC_USART2) Base Address */ +#define USART3 ((Usart *)0x400A4000U) /**< \brief (USART3 ) Base Address */ +#define PDC_USART3 ((Pdc *)0x400A4100U) /**< \brief (PDC_USART3) Base Address */ +#define UOTGHS ((Uotghs *)0x400AC000U) /**< \brief (UOTGHS ) Base Address */ +#define EMAC ((Emac *)0x400B0000U) /**< \brief (EMAC ) Base Address */ +#define CAN0 ((Can *)0x400B4000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 ((Can *)0x400B8000U) /**< \brief (CAN1 ) Base Address */ +#define TRNG ((Trng *)0x400BC000U) /**< \brief (TRNG ) Base Address */ +#define ADC ((Adc *)0x400C0000U) /**< \brief (ADC ) Base Address */ +#define PDC_ADC ((Pdc *)0x400C0100U) /**< \brief (PDC_ADC ) Base Address */ +#define DMAC ((Dmac *)0x400C4000U) /**< \brief (DMAC ) Base Address */ +#define DACC ((Dacc *)0x400C8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC ((Pdc *)0x400C8100U) /**< \brief (PDC_DACC ) Base Address */ +#define SMC ((Smc *)0x400E0000U) /**< \brief (SMC ) Base Address */ +#define MATRIX ((Matrix *)0x400E0400U) /**< \brief (MATRIX ) Base Address */ +#define PMC ((Pmc *)0x400E0600U) /**< \brief (PMC ) Base Address */ +#define UART ((Uart *)0x400E0800U) /**< \brief (UART ) Base Address */ +#define PDC_UART ((Pdc *)0x400E0900U) /**< \brief (PDC_UART ) Base Address */ +#define CHIPID ((Chipid *)0x400E0940U) /**< \brief (CHIPID ) Base Address */ +#define EFC0 ((Efc *)0x400E0A00U) /**< \brief (EFC0 ) Base Address */ +#define EFC1 ((Efc *)0x400E0C00U) /**< \brief (EFC1 ) Base Address */ +#define PIOA ((Pio *)0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PIOB ((Pio *)0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC ((Pio *)0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD ((Pio *)0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC ((Rstc *)0x400E1A00U) /**< \brief (RSTC ) Base Address */ +#define SUPC ((Supc *)0x400E1A10U) /**< \brief (SUPC ) Base Address */ +#define RTT ((Rtt *)0x400E1A30U) /**< \brief (RTT ) Base Address */ +#define WDT ((Wdt *)0x400E1A50U) /**< \brief (WDT ) Base Address */ +#define RTC ((Rtc *)0x400E1A60U) /**< \brief (RTC ) Base Address */ +#define GPBR ((Gpbr *)0x400E1A90U) /**< \brief (GPBR ) Base Address */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ +/** \addtogroup SAM3X8E_pio Peripheral Pio Definitions */ +/*@{*/ + +#include "pio/pio_sam3x8e.h" +/*@}*/ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ + +#define IFLASH0_SIZE (0x40000u) +#define IFLASH0_PAGE_SIZE (256u) +#define IFLASH0_LOCK_REGION_SIZE (16384u) +#define IFLASH0_NB_OF_PAGES (1024u) +#define IFLASH1_SIZE (0x40000u) +#define IFLASH1_PAGE_SIZE (256u) +#define IFLASH1_LOCK_REGION_SIZE (16384u) +#define IFLASH1_NB_OF_PAGES (1024u) +#define IRAM0_SIZE (0x10000u) +#define IRAM1_SIZE (0x8000u) +#define NFCRAM_SIZE (0x1000u) +#define IFLASH_SIZE (IFLASH0_SIZE+IFLASH1_SIZE) +#define IRAM_SIZE (IRAM0_SIZE+IRAM1_SIZE) + +#define IFLASH0_ADDR (0x00080000u) /**< Internal Flash 0 base address */ +#if defined IFLASH0_SIZE +#define IFLASH1_ADDR (IFLASH0_ADDR+IFLASH0_SIZE) /**< Internal Flash 1 base address */ +#endif +#define IROM_ADDR (0x00100000u) /**< Internal ROM base address */ +#define IRAM0_ADDR (0x20000000u) /**< Internal RAM 0 base address */ +#define IRAM1_ADDR (0x20080000u) /**< Internal RAM 1 base address */ +#define NFC_RAM_ADDR (0x20100000u) /**< NAND Flash Controller RAM base address */ +#define UOTGHS_RAM_ADDR (0x20180000u) /**< USB On-The-Go Interface RAM base address */ +#define EBI_CS0_ADDR (0x60000000u) /**< EBI Chip Select 0 base address */ +#define EBI_CS1_ADDR (0x61000000u) /**< EBI Chip Select 1 base address */ +#define EBI_CS2_ADDR (0x62000000u) /**< EBI Chip Select 2 base address */ +#define EBI_CS3_ADDR (0x63000000u) /**< EBI Chip Select 3 base address */ +#define EBI_CS4_ADDR (0x64000000u) /**< EBI Chip Select 4 base address */ +#define EBI_CS5_ADDR (0x65000000u) /**< EBI Chip Select 5 base address */ +#define EBI_CS6_ADDR (0x66000000u) /**< EBI Chip Select 6 base address */ +#define EBI_CS7_ADDR (0x67000000u) /**< EBI Chip Select 7 base address */ + +/* ************************************************************************** */ +/* ELECTRICAL DEFINITIONS FOR SAM3X8E */ +/* ************************************************************************** */ + +/* Device characteristics */ +#define CHIP_FREQ_SLCK_RC_MIN (20000UL) +#define CHIP_FREQ_SLCK_RC (32000UL) +#define CHIP_FREQ_SLCK_RC_MAX (44000UL) +#define CHIP_FREQ_MAINCK_RC_4MHZ (4000000UL) +#define CHIP_FREQ_MAINCK_RC_8MHZ (8000000UL) +#define CHIP_FREQ_MAINCK_RC_12MHZ (12000000UL) +#define CHIP_FREQ_CPU_MAX (84000000UL) +#define CHIP_FREQ_XTAL_32K (32768UL) +#define CHIP_FREQ_XTAL_12M (12000000UL) + +/* Embedded Flash Write Wait State */ +#define CHIP_FLASH_WRITE_WAIT_STATE (6U) + +/* Embedded Flash Read Wait State (VDDCORE set at 1.65V) */ +#define CHIP_FREQ_FWS_0 (22500000UL) /**< \brief Maximum operating frequency when FWS is 0 */ +#define CHIP_FREQ_FWS_1 (34000000UL) /**< \brief Maximum operating frequency when FWS is 1 */ +#define CHIP_FREQ_FWS_2 (53000000UL) /**< \brief Maximum operating frequency when FWS is 2 */ +#define CHIP_FREQ_FWS_3 (78000000UL) /**< \brief Maximum operating frequency when FWS is 3 */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _SAM3X8E_ */ diff --git a/hardware/arduino/sam/libraries/CAN/sam_gpio.h b/hardware/arduino/sam/libraries/CAN/sam_gpio.h new file mode 100644 index 000000000..0319af5c4 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sam_gpio.h @@ -0,0 +1,80 @@ +/** + * \file + * + * \brief GPIO service for SAM. + * + * Copyright (c) 2011-2012 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 + * + */ + +#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 */ diff --git a/hardware/arduino/sam/libraries/CAN/sysclk.c b/hardware/arduino/sam/libraries/CAN/sysclk.c new file mode 100644 index 000000000..452f4aadd --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sysclk.c @@ -0,0 +1,260 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * Copyright (c) 2011-2012 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 + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +/** + * \brief boolean signalling that the sysclk_init is done. + */ +uint32_t sysclk_initialized = 0; +#endif + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param cpu_shift The CPU clock will be divided by \f$2^{mck\_pres}\f$ + */ +void sysclk_set_prescalers(uint32_t ul_pres) +{ + pmc_mck_set_prescaler(ul_pres); + SystemCoreClockUpdate(); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +void sysclk_set_source(uint32_t ul_src) +{ + switch (ul_src) { + case SYSCLK_SRC_SLCK_RC: + case SYSCLK_SRC_SLCK_XTAL: + case SYSCLK_SRC_SLCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK); + break; + + case SYSCLK_SRC_MAINCK_4M_RC: + case SYSCLK_SRC_MAINCK_8M_RC: + case SYSCLK_SRC_MAINCK_12M_RC: + case SYSCLK_SRC_MAINCK_XTAL: + case SYSCLK_SRC_MAINCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK); + break; + + case SYSCLK_SRC_PLLACK: + pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK); + break; + + case SYSCLK_SRC_UPLLCK: + pmc_mck_set_source(PMC_MCKR_CSS_UPLL_CLK); + break; + } + + SystemCoreClockUpdate(); +} + +#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +/** + * \brief Enable full speed USB clock. + * + * \note The SAM3X UDP hardware interprets div as div+1. For readability the hardware div+1 + * is hidden in this implementation. Use div as div effective value. + * + * \param pll_id Source of the USB clock. + * \param div Actual clock divisor. Must be superior to 0. + */ +void sysclk_enable_usb(void) +{ + Assert(CONFIG_USBCLK_DIV > 0); + + switch (CONFIG_USBCLK_SOURCE) { +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL0: { + struct pll_config pllcfg; + + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); + pmc_enable_udpck(); + break; + } +#endif + + case USBCLK_SRC_UPLL: { + + pmc_enable_upll_clock(); + pmc_switch_udpck_to_upllck(CONFIG_USBCLK_DIV - 1); + pmc_enable_udpck(); + break; + } + + } +} + +/** + * \brief Disable full speed USB clock. + * + * \note This implementation does not switch off the PLL, it just turns off the USB clock. + */ +void sysclk_disable_usb(void) +{ + pll_disable(1); +} +#endif // CONFIG_USBCLK_SOURCE + +void sysclk_init(void) +{ + struct pll_config pllcfg; + + /* Set a flash wait state depending on the new cpu frequency */ + system_init_flash(sysclk_get_cpu_hz()); + + /* Config system clock setting */ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_SLCK_RC: + osc_enable(OSC_SLCK_32K_RC); + osc_wait_ready(OSC_SLCK_32K_RC); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_SLCK_XTAL: + osc_enable(OSC_SLCK_32K_XTAL); + osc_wait_ready(OSC_SLCK_32K_XTAL); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_SLCK_BYPASS: + osc_enable(OSC_SLCK_32K_BYPASS); + osc_wait_ready(OSC_SLCK_32K_BYPASS); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_4M_RC: + /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ + break; + + case SYSCLK_SRC_MAINCK_8M_RC: + osc_enable(OSC_MAINCK_8M_RC); + osc_wait_ready(OSC_MAINCK_8M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_12M_RC: + osc_enable(OSC_MAINCK_12M_RC); + osc_wait_ready(OSC_MAINCK_12M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + + case SYSCLK_SRC_MAINCK_XTAL: + osc_enable(OSC_MAINCK_XTAL); + osc_wait_ready(OSC_MAINCK_XTAL); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_BYPASS: + osc_enable(OSC_MAINCK_BYPASS); + osc_wait_ready(OSC_MAINCK_BYPASS); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLLACK: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); + break; +#endif + + case SYSCLK_SRC_UPLLCK: + pll_enable_source(CONFIG_PLL1_SOURCE); + pll_config_defaults(&pllcfg, 1); + pll_enable(&pllcfg, 1); + pll_wait_for_lock(1); + pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES); + break; + } + + /* Update the SystemFrequency variable */ + SystemCoreClockUpdate(); + +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + /* Signal that the internal frequencies are setup */ + sysclk_initialized = 1; +#endif +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/hardware/arduino/sam/libraries/CAN/sysclk.h b/hardware/arduino/sam/libraries/CAN/sysclk.h new file mode 100644 index 000000000..00a9f877c --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/sysclk.h @@ -0,0 +1,372 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * Copyright (c) 2011 - 2012 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 + * + */ + +#ifndef CHIP_SYSCLK_H_INCLUDED +#define CHIP_SYSCLK_H_INCLUDED + +#include +#include + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (SAM3A) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 84MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL0_MUL (84000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / BUS_div + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode + * -# Configure the PLL module to use the fast external fast crystal oscillator as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL module to multiply the external fast crystal oscillator frequency up to 84MHz: + * \code + * #define CONFIG_PLL0_MUL (84000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration + * file as the frequency of the fast crystal attached to the microcontroller. + * -# Configure the main clock to run at the full 84MHz, disable scaling of the main system clock speed: + * \code + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +//! \name Configuration Symbols +//@{ +/** + * \def CONFIG_SYSCLK_SOURCE + * \brief Initial/static main system clock source + * + * The main system clock will be configured to use this clock during + * initialization. + */ +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +#endif +/** + * \def CONFIG_SYSCLK_PRES + * \brief Initial CPU clock divider (mck) + * + * The MCK will run at + * \f[ + * f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz} + * \f] + * after initialization. + */ +#ifndef CONFIG_SYSCLK_PRES +# define CONFIG_SYSCLK_PRES 0 +#endif + +//@} + +//! \name Master Clock Sources (MCK) +//@{ +#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock +#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock +#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock +#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock +#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock +#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock +#define SYSCLK_SRC_UPLLCK 9 //!< Use UPLLCK as master source clock +//@} + +//! \name Master Clock Prescalers (MCK) +//@{ +#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1 +#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2 +#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4 +#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8 +#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16 +#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32 +#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64 +#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3 +//@} + +//! \name USB Clock Sources +//@{ +#define USBCLK_SRC_PLL0 0 //!< Use PLLA +#define USBCLK_SRC_UPLL 1 //!< Use UPLL +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB generic clock source + * + * Sets the clock source to use for the USB. The source must also be properly + * configured. + * + * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if + * USB is not required. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +/** + * \def CONFIG_USBCLK_DIV + * \brief Configuration symbol for the USB generic clock divider setting + * + * Sets the clock division for the USB generic clock. If a USB clock source is + * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be + * defined. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_DIV +#endif + +/** + * \name Querying the system clock + * + * The following functions may be used to query the current frequency of + * the system clock and the CPU and bus clocks derived from it. + * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be + * available on all platforms, although some platforms may define + * additional accessors for various chip-internal bus clocks. These are + * usually not intended to be queried directly by generic code. + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + */ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +extern uint32_t sysclk_initialized; +#endif +static inline uint32_t sysclk_get_main_hz(void) +{ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + if (!sysclk_initialized ) { + return OSC_MAINCK_4M_RC_HZ; + } +#endif + + /* Config system clock setting */ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_SLCK_RC: + return OSC_SLCK_32K_RC_HZ; + + case SYSCLK_SRC_SLCK_XTAL: + return OSC_SLCK_32K_XTAL_HZ; + + case SYSCLK_SRC_SLCK_BYPASS: + return OSC_SLCK_32K_BYPASS_HZ; + + + case SYSCLK_SRC_MAINCK_4M_RC: + return OSC_MAINCK_4M_RC_HZ; + + case SYSCLK_SRC_MAINCK_8M_RC: + return OSC_MAINCK_8M_RC_HZ; + + case SYSCLK_SRC_MAINCK_12M_RC: + return OSC_MAINCK_12M_RC_HZ; + + case SYSCLK_SRC_MAINCK_XTAL: + return OSC_MAINCK_XTAL_HZ; + + case SYSCLK_SRC_MAINCK_BYPASS: + return OSC_MAINCK_BYPASS_HZ; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLLACK: + return pll_get_default_rate(0); +#endif + +#ifdef CONFIG_PLL1_SOURCE + case SYSCLK_SRC_UPLLCK: + return PLL_UPLL_HZ; +#endif + + default: + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + return 0; + } +} + +/** + * \brief Return the current rate in Hz of the CPU clock + * + * \todo This function assumes that the CPU always runs at the system + * clock frequency. We want to support at least two more scenarios: + * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus + * clock dividers (which may change at run time). Ditto for all the bus + * clocks. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediate value. */ + return sysclk_get_main_hz() / + ((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : + (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))); +} + +/** + * \brief Retrieves the current rate in Hz of the peripheral clocks. + * + * \return Frequency of the peripheral clocks, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediate value. */ + return sysclk_get_main_hz() / + ((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : + (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))); +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_enable_peripheral_clock(uint32_t ul_id) +{ + pmc_enable_periph_clk(ul_id); +} + +/** + * \brief Disable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_disable_peripheral_clock(uint32_t ul_id) +{ + pmc_disable_periph_clk(ul_id); +} + +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +extern void sysclk_set_prescalers(uint32_t ul_pres); +extern void sysclk_set_source(uint32_t ul_src); + +//@} + +extern void sysclk_enable_usb(void); +extern void sysclk_disable_usb(void); + +extern void sysclk_init(void); + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_SYSCLK_H_INCLUDED */ diff --git a/hardware/arduino/sam/libraries/CAN/system_sam3x.h b/hardware/arduino/sam/libraries/CAN/system_sam3x.h new file mode 100644 index 000000000..d9c996e08 --- /dev/null +++ b/hardware/arduino/sam/libraries/CAN/system_sam3x.h @@ -0,0 +1,85 @@ +/** + * \file + * + * \brief Provides the low-level initialization functions that called + * on chip startup. + * + * Copyright (c) 2011-2012 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 + * + */ + +#ifndef SYSTEM_SAM3X_H_INCLUDED +#define SYSTEM_SAM3X_H_INCLUDED + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/* @endcond */ + +#include + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/** + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +void SystemInit(void); + +/** + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void); + +/** + * Initialize flash. + */ +void system_init_flash(uint32_t ul_clk); + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/* @endcond */ + +#endif /* SYSTEM_SAM3X_H_INCLUDED */