mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
390 lines
10 KiB
C
390 lines
10 KiB
C
/*
|
|
* Copyright (C) 2015-2017 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup cpu_efm32
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief CPU specific definitions for internal peripheral handling
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
|
*/
|
|
|
|
#ifndef PERIPH_CPU_H
|
|
#define PERIPH_CPU_H
|
|
|
|
#include "mutex.h"
|
|
|
|
#include "cpu_conf.h"
|
|
|
|
#include "em_adc.h"
|
|
#include "em_cmu.h"
|
|
#include "em_device.h"
|
|
#include "em_gpio.h"
|
|
#include "em_timer.h"
|
|
#include "em_usart.h"
|
|
#ifdef _SILICON_LABS_32B_SERIES_0
|
|
#include "em_dac.h"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Enable support for Low-power peripherals (if supported by CPU).
|
|
* @{
|
|
*/
|
|
#ifndef LOW_POWER_ENABLED
|
|
#define LOW_POWER_ENABLED (1)
|
|
#endif
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Internal macro for combining ADC resolution (x) with number of
|
|
* shifts (y).
|
|
*/
|
|
#define ADC_MODE(x, y) ((y << 4) | x)
|
|
|
|
/**
|
|
* @brief Internal define to note that resolution is not supported.
|
|
*/
|
|
#define ADC_MODE_UNDEF(x) (ADC_MODE(x, 15))
|
|
|
|
#ifndef DOXYGEN
|
|
/**
|
|
* @brief Possible ADC resolution settings
|
|
* @{
|
|
*/
|
|
#define HAVE_ADC_RES_T
|
|
typedef enum {
|
|
ADC_RES_6BIT = ADC_MODE(adcRes6Bit, 0), /**< ADC resolution: 6 bit */
|
|
ADC_RES_8BIT = ADC_MODE(adcRes8Bit, 0), /**< ADC resolution: 8 bit */
|
|
ADC_RES_10BIT = ADC_MODE(adcRes12Bit, 2), /**< ADC resolution: 10 bit (shifted from 12 bit) */
|
|
ADC_RES_12BIT = ADC_MODE(adcRes12Bit, 0), /**< ADC resolution: 12 bit */
|
|
ADC_RES_14BIT = ADC_MODE_UNDEF(0), /**< ADC resolution: 14 bit (unsupported) */
|
|
ADC_RES_16BIT = ADC_MODE_UNDEF(1), /**< ADC resolution: 16 bit (unsupported) */
|
|
} adc_res_t;
|
|
/** @} */
|
|
#endif /* ndef DOXYGEN */
|
|
|
|
/**
|
|
* @brief ADC device configuration
|
|
*/
|
|
typedef struct {
|
|
ADC_TypeDef *dev; /**< ADC device used */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
} adc_conf_t;
|
|
|
|
/**
|
|
* @brief ADC channel configuration
|
|
*/
|
|
typedef struct {
|
|
uint8_t dev; /**< device index */
|
|
#ifdef _SILICON_LABS_32B_SERIES_0
|
|
ADC_SingleInput_TypeDef input; /**< input channel */
|
|
#else
|
|
ADC_PosSel_TypeDef input; /**< input channel */
|
|
#endif
|
|
ADC_Ref_TypeDef reference; /**< channel voltage reference */
|
|
ADC_AcqTime_TypeDef acq_time; /**< channel acquisition time */
|
|
} adc_chan_conf_t;
|
|
|
|
/**
|
|
* @brief Length of CPU ID in octets.
|
|
*/
|
|
#define CPUID_LEN (8U)
|
|
|
|
#if defined(DAC_COUNT) && DAC_COUNT > 0
|
|
/**
|
|
* @brief DAC device configuration
|
|
*/
|
|
typedef struct {
|
|
DAC_TypeDef *dev; /**< DAC device used */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
} dac_conf_t;
|
|
|
|
/**
|
|
* @brief DAC channel configuration
|
|
*/
|
|
typedef struct {
|
|
uint8_t dev; /**< device index */
|
|
uint8_t index; /**< channel index */
|
|
DAC_Ref_TypeDef ref; /**< channel voltage reference */
|
|
} dac_chan_conf_t;
|
|
#endif
|
|
|
|
/**
|
|
* @brief Define a custom type for GPIO pins.
|
|
* @{
|
|
*/
|
|
#define HAVE_GPIO_T
|
|
typedef uint32_t gpio_t;
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Definition of a fitting UNDEF value.
|
|
*/
|
|
#define GPIO_UNDEF (0xffffffff)
|
|
|
|
/**
|
|
* @brief Mandatory function for defining a GPIO pins.
|
|
*/
|
|
#define GPIO_PIN(x, y) ((gpio_t) ((x << 4) | y))
|
|
|
|
/**
|
|
* @brief Internal macro for combining pin mode (x) and pull-up/down (y).
|
|
*/
|
|
#define GPIO_MODE(x, y) ((x << 1) | y)
|
|
|
|
/**
|
|
* @brief Available ports on the EFM32.
|
|
*/
|
|
enum {
|
|
#if (_GPIO_PORT_A_PIN_COUNT > 0)
|
|
PA = gpioPortA, /**< port A */
|
|
#endif
|
|
#if (_GPIO_PORT_B_PIN_COUNT > 0)
|
|
PB = gpioPortB, /**< port B */
|
|
#endif
|
|
#if (_GPIO_PORT_C_PIN_COUNT > 0)
|
|
PC = gpioPortC, /**< port C */
|
|
#endif
|
|
#if (_GPIO_PORT_D_PIN_COUNT > 0)
|
|
PD = gpioPortD, /**< port D */
|
|
#endif
|
|
#if (_GPIO_PORT_E_PIN_COUNT > 0)
|
|
PE = gpioPortE, /**< port E */
|
|
#endif
|
|
#if (_GPIO_PORT_F_PIN_COUNT > 0)
|
|
PF = gpioPortF, /**< port F */
|
|
#endif
|
|
#if (_GPIO_PORT_G_PIN_COUNT > 0)
|
|
PG = gpioPortG, /**< port G */
|
|
#endif
|
|
#if (_GPIO_PORT_H_PIN_COUNT > 0)
|
|
PH = gpioPortH, /**< port H */
|
|
#endif
|
|
#if (_GPIO_PORT_I_PIN_COUNT > 0)
|
|
PI = gpioPortI, /**< port I */
|
|
#endif
|
|
#if (_GPIO_PORT_J_PIN_COUNT > 0)
|
|
PJ = gpioPortJ, /**< port J */
|
|
#endif
|
|
#if (_GPIO_PORT_K_PIN_COUNT > 0)
|
|
PK = gpioPortK /**< port K */
|
|
#endif
|
|
};
|
|
|
|
#ifndef DOXYGEN
|
|
/**
|
|
* @brief Override direction values.
|
|
* @{
|
|
*/
|
|
#define HAVE_GPIO_MODE_T
|
|
typedef enum {
|
|
GPIO_IN = GPIO_MODE(gpioModeInput, 0), /**< pin as input */
|
|
GPIO_IN_PD = GPIO_MODE(gpioModeInputPull, 0), /**< pin as input with pull-down */
|
|
GPIO_IN_PU = GPIO_MODE(gpioModeInputPull, 1), /**< pin as input with pull-up */
|
|
GPIO_OUT = GPIO_MODE(gpioModePushPull, 0), /**< pin as output */
|
|
GPIO_OD = GPIO_MODE(gpioModeWiredAnd, 1), /**< pin as open-drain */
|
|
GPIO_OD_PU = GPIO_MODE(gpioModeWiredAndPullUp, 1), /**< pin as open-drain with pull-up */
|
|
} gpio_mode_t;
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Override active flank configuration values.
|
|
* @{
|
|
*/
|
|
#define HAVE_GPIO_FLANK_T
|
|
typedef enum {
|
|
GPIO_FALLING = 2, /**< emit interrupt on falling flank */
|
|
GPIO_RISING = 1, /**< emit interrupt on rising flank */
|
|
GPIO_BOTH = 3 /**< emit interrupt on both flanks */
|
|
} gpio_flank_t;
|
|
/** @} */
|
|
#endif /* ndef DOXYGEN */
|
|
|
|
/**
|
|
* @brief Override hardware crypto supported methods.
|
|
* @{
|
|
*/
|
|
#define HAVE_HWCRYPTO_AES128
|
|
#ifdef AES_CTRL_AES256
|
|
#define HAVE_HWCRYPTO_AES256
|
|
#endif
|
|
#ifdef _SILICON_LABS_32B_SERIES_1
|
|
#define HAVE_HWCRYPTO_SHA1
|
|
#define HAVE_HWCRYPTO_SHA256
|
|
#endif
|
|
/** @} */
|
|
|
|
#ifndef DOXYGEN
|
|
/**
|
|
* @brief Override I2C speed values.
|
|
* @{
|
|
*/
|
|
#define HAVE_I2C_SPEED_T
|
|
typedef enum {
|
|
I2C_SPEED_LOW = 10000, /**< low speed mode: ~10kbit/s */
|
|
I2C_SPEED_NORMAL = 100000, /**< normal mode: ~100kbit/s */
|
|
I2C_SPEED_FAST = 400000, /**< fast mode: ~400kbit/sj */
|
|
I2C_SPEED_FAST_PLUS = 1000000, /**< fast plus mode: ~1Mbit/s */
|
|
I2C_SPEED_HIGH = 3400000, /**< high speed mode: ~3.4Mbit/s */
|
|
} i2c_speed_t;
|
|
/** @} */
|
|
#endif /* ndef DOXYGEN */
|
|
|
|
/**
|
|
* @brief I2C device configuration.
|
|
*/
|
|
typedef struct {
|
|
I2C_TypeDef *dev; /**< USART device used */
|
|
gpio_t sda_pin; /**< pin used for SDA */
|
|
gpio_t scl_pin; /**< pin used for SCL */
|
|
uint32_t loc; /**< location of I2C pins */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
IRQn_Type irq; /**< the devices base IRQ channel */
|
|
} i2c_conf_t;
|
|
|
|
#ifndef DOXYGEN
|
|
/**
|
|
* @brief Override PWM mode values.
|
|
* @{
|
|
*/
|
|
#define HAVE_PWM_MODE_T
|
|
typedef enum {
|
|
PWM_LEFT = timerModeUp, /*< use left aligned PWM */
|
|
PWM_RIGHT = timerModeDown, /*< use right aligned PWM */
|
|
PWM_CENTER = timerModeUp /*< not supported, use left aligned */
|
|
} pwm_mode_t;
|
|
/** @} */
|
|
#endif /* ndef DOXYGEN */
|
|
|
|
/**
|
|
* @brief PWM channel configuration.
|
|
*/
|
|
typedef struct {
|
|
uint8_t index; /**< TIMER channel to use */
|
|
gpio_t pin; /**< pin used for pwm */
|
|
uint32_t loc; /**< location of the pin */
|
|
} pwm_chan_conf_t;
|
|
|
|
/**
|
|
* @brief PWM device configuration.
|
|
*/
|
|
typedef struct {
|
|
TIMER_TypeDef *dev; /**< TIMER device used */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
IRQn_Type irq; /**< the devices base IRQ channel */
|
|
uint8_t channels; /**< the number of available channels */
|
|
const pwm_chan_conf_t* channel; /**< pointer to first channel config */
|
|
} pwm_conf_t;
|
|
|
|
#ifndef DOXYGEN
|
|
/**
|
|
* @brief Override SPI clocks.
|
|
* @{
|
|
*/
|
|
#define HAVE_SPI_MODE_T
|
|
typedef enum {
|
|
SPI_MODE_0 = usartClockMode0,
|
|
SPI_MODE_1 = usartClockMode1,
|
|
SPI_MODE_2 = usartClockMode2,
|
|
SPI_MODE_3 = usartClockMode3
|
|
} spi_mode_t;
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Define a set of pre-defined SPI clock speeds.
|
|
* @{
|
|
*/
|
|
#define HAVE_SPI_CLK_T
|
|
typedef enum {
|
|
SPI_CLK_100KHZ = 100000, /**< drive the SPI bus with 100KHz */
|
|
SPI_CLK_400KHZ = 400000, /**< drive the SPI bus with 400KHz */
|
|
SPI_CLK_1MHZ = 1000000, /**< drive the SPI bus with 1MHz */
|
|
SPI_CLK_5MHZ = 5000000, /**< drive the SPI bus with 5MHz */
|
|
SPI_CLK_10MHZ = 10000000 /**< drive the SPI bus with 10MHz */
|
|
} spi_clk_t;
|
|
/** @} */
|
|
#endif /* ndef DOXYGEN */
|
|
|
|
/**
|
|
* @brief SPI device configuration.
|
|
*/
|
|
typedef struct {
|
|
USART_TypeDef *dev; /**< USART device used */
|
|
gpio_t mosi_pin; /**< pin used for MOSI */
|
|
gpio_t miso_pin; /**< pin used for MISO */
|
|
gpio_t clk_pin; /**< pin used for CLK */
|
|
uint32_t loc; /**< location of USART pins */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
IRQn_Type irq; /**< the devices base IRQ channel */
|
|
} spi_dev_t;
|
|
|
|
/**
|
|
* @brief Declare needed generic SPI functions.
|
|
* @{
|
|
*/
|
|
#define PERIPH_SPI_NEEDS_INIT_CS
|
|
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
|
|
#define PERIPH_SPI_NEEDS_TRANSFER_REG
|
|
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief Define timer configuration values
|
|
*
|
|
* @note The two timers must be adjacent to each other (e.g. TIMER0 and
|
|
* TIMER1, or TIMER2 and TIMER3, etc.).
|
|
* @{
|
|
*/
|
|
typedef struct {
|
|
TIMER_TypeDef *dev; /**< Timer device used */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
} timer_dev_t;
|
|
|
|
typedef struct {
|
|
timer_dev_t prescaler; /**< the lower numbered neighboring timer */
|
|
timer_dev_t timer; /**< the higher numbered timer */
|
|
IRQn_Type irq; /**< number of the higher timer IRQ channel */
|
|
} timer_conf_t;
|
|
/** @} */
|
|
|
|
/**
|
|
* @brief UART device configuration.
|
|
*/
|
|
typedef struct {
|
|
void *dev; /**< UART, USART or LEUART device used */
|
|
gpio_t rx_pin; /**< pin used for RX */
|
|
gpio_t tx_pin; /**< pin used for TX */
|
|
uint32_t loc; /**< location of USART pins */
|
|
CMU_Clock_TypeDef cmu; /**< the device CMU channel */
|
|
IRQn_Type irq; /**< the devices base IRQ channel */
|
|
} uart_conf_t;
|
|
|
|
/**
|
|
* @brief CPU provides own pm_off() function
|
|
*/
|
|
#define PROVIDES_PM_LAYERED_OFF
|
|
|
|
/**
|
|
* @brief Number of usable power modes.
|
|
*/
|
|
#define PM_NUM_MODES (2U)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PERIPH_CPU_H */
|
|
/** @} */
|