1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #1997 from Troels51/samr21-transceiver-port

samr21: implemention of transceiver via spi
This commit is contained in:
Thomas Eichinger 2014-12-17 11:56:37 +01:00
commit 5689a7d218
9 changed files with 596 additions and 118 deletions

View File

@ -0,0 +1,6 @@
ifneq (,$(filter defaulttransceiver,$(USEMODULE)))
USEMODULE += at86rf231
ifeq (,$(filter netdev_base,$(USEMODULE)))
USEMODULE += transceiver
endif
endif

View File

@ -1 +1 @@
FEATURES_PROVIDED += periph_gpio cpp periph_uart periph_timer periph_i2c
FEATURES_PROVIDED += transceiver periph_gpio periph_spi cpp periph_timer periph_uart periph_i2c cpp

View File

@ -41,4 +41,5 @@ export LINKFLAGS += -specs=nano.specs -lc -lnosys
endif
# export board specific includes to the global includes-listing
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include/
include $(RIOTBOARD)/$(BOARD)/Makefile.dep

View File

@ -37,6 +37,18 @@ extern "C" {
*/
#define HW_TIMER TIMER_0
/**
* @name AT86RF231 config
* @{
*/
#define AT86RF231_SPI SPI_0
#define AT86RF231_CS GPIO_4
#define AT86RF231_INT GPIO_5
#define AT86RF231_RESET GPIO_6
#define AT86RF231_SLEEP GPIO_7
#define AT86RF231_SPI_SPEED SPI_SPEED_1MHZ
/** @}*/
/**
* @name Define UART device and baudrate for stdio
* @{
@ -51,7 +63,7 @@ extern "C" {
* @{
*/
#define LED_PORT PORT->Group[0]
#define LED_PIN PORT_PA19
#define LED_PIN (19)
/** @} */
/**
@ -74,6 +86,11 @@ extern "C" {
#define LED_RED_TOGGLE LED_TOGGLE
/** @} */
/**
* @brief Define the type for the radio packet length for the transceiver
*/
typedef uint8_t radio_packet_length_t;
/**
* @brief Initialize board specific hardware, including clock, LEDs and std-IO
*/

View File

@ -69,8 +69,8 @@ extern "C" {
#define UART_0_ISR isr_sercom0
/* UART 0 pin configuration */
#define UART_0_PORT (PORT->Group[0])
#define UART_0_TX_PIN PIN_PA04
#define UART_0_RX_PIN PIN_PA05
#define UART_0_TX_PIN (4)
#define UART_0_RX_PIN (5)
#define UART_0_PINS (PORT_PA04 | PORT_PA05)
#define UART_0_REF_F (8000000UL)
@ -84,6 +84,48 @@ extern "C" {
#define UART_1_PINS
/** @} */
/**
* @name SPI configuration
* @{
*/
#define SPI_NUMOF (2)
#define SPI_0_EN 1
#define SPI_1_EN 1
/* SPI0 */
#define SPI_0_DEV SERCOM4->SPI
#define SPI_IRQ_0 SERCOM4_IRQn
#define SPI_0_DOPO (1)
#define SPI_0_DIPO (0)
#define SPI_0_F_REF (8000000UL)
#define SPI_0_SCLK_DEV PORT->Group[2]
#define SPI_0_SCLK_PIN (18)
#define SPI_0_MISO_DEV PORT->Group[2]
#define SPI_0_MISO_PIN (19)
#define SPI_0_MOSI_DEV PORT->Group[1]
#define SPI_0_MOSI_PIN (30)
/* SPI1 */
#define SPI_1_DEV SERCOM5->SPI
#define SPI_IRQ_1 SERCOM5_IRQn
#define SPI_1_DOPO (1)
#define SPI_1_DIPO (2)
#define SPI_1_F_REF (8000000UL)
#define SPI_1_SCLK_DEV PORT->Group[1]
#define SPI_1_SCLK_PIN (23)
#define SPI_1_MISO_DEV PORT->Group[1]
#define SPI_1_MISO_PIN (02)
#define SPI_1_MOSI_DEV PORT->Group[1]
#define SPI_1_MOSI_PIN (22)
/** @} */
/**
* @name I2C configuration
* @{
@ -110,36 +152,96 @@ extern "C" {
* @name Random Number Generator configuration
* @{
*/
#define RANDOM_NUMOF (0U)
#define RANDOM_NUMOF (0U)
/** @} */
/**
* @name GPIO configuration
* @{
*/
#define GPIO_NUMOF (4U)
#define GPIO_0_EN 1
#define GPIO_1_EN 1
#define GPIO_2_EN 1
#define GPIO_3_EN 1
#define GPIO_NUMOF (9U)
#define GPIO_0_EN 1
#define GPIO_1_EN 1
#define GPIO_2_EN 1
#define GPIO_3_EN 1
/*4-7 -> internal */
#define GPIO_4_EN 1
#define GPIO_5_EN 1
#define GPIO_6_EN 1
#define GPIO_7_EN 1
#define GPIO_8_EN 1
#define GPIO_9_EN 0
#define GPIO_10_EN 0
#define GPIO_11_EN 0
#define GPIO_12_EN 0
#define GPIO_13_EN 0
#define GPIO_14_EN 0
#define GPIO_15_EN 0
#define GPIO_NO_EXTINT (18)
/* GPIO channel 0 config */
#define GPIO_0_DEV PORT->Group[0]
#define GPIO_0_PIN PIN_PA13
#define GPIO_0_EXTINT 13
#define GPIO_0_DEV PORT->Group[0]
#define GPIO_0_PIN (13)
#define GPIO_0_EXTINT (13)
/* GPIO channel 1 config */
/* SW0 Button, configure w/ GPIO_PULLUP and GPIO_FALLING */
#define GPIO_1_DEV PORT->Group[0]
#define GPIO_1_PIN PIN_PA28
#define GPIO_1_EXTINT 8
#define GPIO_1_DEV PORT->Group[0]
#define GPIO_1_PIN (28)
#define GPIO_1_EXTINT (8)
/* GPIO channel 2 config */
#define GPIO_2_DEV PORT->Group[0]
#define GPIO_2_PIN PIN_PA15
#define GPIO_2_EXTINT 15
#define GPIO_2_DEV PORT->Group[0]
#define GPIO_2_PIN (15)
#define GPIO_2_EXTINT (15)
/* GPIO channel 3 config */
#define GPIO_3_DEV PORT->Group[0]
#define GPIO_3_PIN PIN_PA19
#define GPIO_3_EXTINT 3
#define GPIO_3_DEV PORT->Group[0]
#define GPIO_3_PIN (19)
#define GPIO_3_EXTINT (3)
/* GPIO 4-7 Internal radio pins*/
/* GPIO channel 4 config radio CS*/
#define GPIO_4_DEV PORT->Group[1]
#define GPIO_4_PIN (31)
#define GPIO_4_EXTINT GPIO_NO_EXTINT
/* GPIO channel 5 config radio IRQ0*/
#define GPIO_5_DEV PORT->Group[1]
#define GPIO_5_PIN (0)
#define GPIO_5_EXTINT (0)
/* GPIO channel 6 config radio reset*/
#define GPIO_6_DEV PORT->Group[1]
#define GPIO_6_PIN (15)
#define GPIO_6_EXTINT GPIO_NO_EXTINT
/* GPIO channel 7 config radio sleep*/
#define GPIO_7_DEV PORT->Group[0]
#define GPIO_7_PIN (20)
#define GPIO_7_EXTINT GPIO_NO_EXTINT
/* GPIO channel 8 config */
#define GPIO_8_DEV PORT->Group[0]
#define GPIO_8_PIN (27)
#define GPIO_8_EXTINT GPIO_NO_EXTINT
/* GPIO channel 9 config */
#define GPIO_9_DEV
#define GPIO_9_PIN
#define GPIO_9_EXTINT
/* GPIO channel 10 config */
#define GPIO_10_DEV
#define GPIO_10_PIN
#define GPIO_10_EXTINT
/* GPIO channel 11 config */
#define GPIO_11_DEV
#define GPIO_11_PIN
#define GPIO_11_EXTINT
/* GPIO channel 12 config */
#define GPIO_12_PIN
#define GPIO_12_EXTINT
/* GPIO channel 13 config */
#define GPIO_13_PIN
#define GPIO_13_EXTINT
/* GPIO channel 14 config */
#define GPIO_14_PIN
#define GPIO_14_EXTINT
/* GPIO channel 15 config */
#define GPIO_15_PIN
#define GPIO_15_EXTINT
/** @} */
#ifdef __cplusplus

View File

@ -50,6 +50,7 @@ extern "C" {
#endif
/** @} */
#define TRANSCEIVER_BUFFER_SIZE (3)
#ifdef __cplusplus
}
#endif

View File

@ -25,6 +25,8 @@
#include "sched.h"
#include "thread.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/* guard file in case no GPIO devices are defined */
#if GPIO_NUMOF
@ -34,7 +36,7 @@ typedef struct {
void *arg; /**< argument passed to the callback */
} gpio_state_t;
static gpio_state_t gpio_config[16];
static gpio_state_t gpio_config[GPIO_NUMOF];
int gpio_init_out(gpio_t dev, gpio_pp_t pushpull)
{
@ -146,17 +148,17 @@ int gpio_init_out(gpio_t dev, gpio_pp_t pushpull)
}
/* configure as output */
port->DIRSET.reg = (1<<(pin%32));
port->DIRSET.reg = 1 << pin;
/* configure the pin's pull resistor state */
switch (pushpull) {
case GPIO_PULLDOWN:
return -1;
case GPIO_PULLUP:
port->PINCFG[pin % 32].bit.PULLEN = true;
port->PINCFG[pin].bit.PULLEN = true;
break;
case GPIO_NOPULL:
port->PINCFG[pin % 32].bit.PULLEN = false;
port->PINCFG[pin].bit.PULLEN = false;
break;
}
@ -273,22 +275,22 @@ int gpio_init_in(gpio_t dev, gpio_pp_t pushpull)
}
/* configure as input */
port->DIRCLR.reg = (1<<(pin%32));
port->DIRCLR.reg = 1 << pin;
/* buffer input value */
port->PINCFG[pin%32].bit.INEN = true;
port->PINCFG[pin].bit.INEN = true;
/* configure the pin's pull resistor state */
switch (pushpull) {
case GPIO_PULLDOWN:
port->OUTCLR.reg = (1 << (pin % 32));
port->PINCFG[pin % 32].bit.PULLEN = true;
port->OUTCLR.reg = 1 << pin;
port->PINCFG[pin].bit.PULLEN = true;
break;
case GPIO_PULLUP:
port->OUTSET.reg = (1 << (pin % 32));
port->PINCFG[pin % 32].bit.PULLEN = true;
port->OUTSET.reg = 1 << pin;
port->PINCFG[pin].bit.PULLEN = true;
break;
case GPIO_NOPULL:
port->PINCFG[pin % 32].bit.PULLEN = false;
port->PINCFG[pin].bit.PULLEN = false;
break;
}
@ -423,18 +425,14 @@ int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb
return -1;
}
/* configure pin as input */
res = gpio_init_in(dev, pullup);
if (res < 0) {
return res;
}
if (pin<16) {
if (pin < 16) {
port->WRCONFIG.reg = PORT_WRCONFIG_WRPINCFG \
| PORT_WRCONFIG_WRPMUX \
| PORT_WRCONFIG_PMUX(0x0) \
| PORT_WRCONFIG_PMUXEN \
| (1<<pin);
| (1 << pin);
}
else {
port->WRCONFIG.reg = PORT_WRCONFIG_HWSEL \
@ -442,20 +440,27 @@ int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb
| PORT_WRCONFIG_WRPMUX \
| PORT_WRCONFIG_PMUX(0x0) \
| PORT_WRCONFIG_PMUXEN \
| (1<<(pin-16));
| ((1 << pin) >> 16);
}
/* configure pin as input */
res = gpio_init_in(dev, pullup);
if (res < 0) {
return res;
}
/* Turn on APB clock */
PM->APBAMASK.reg |= PM_APBAMASK_EIC;
GCLK->CLKCTRL = (GCLK_CLKCTRL_Type){
.bit.ID = EIC_GCLK_ID,
.bit.GEN = 0, //Generator 0
.bit.GEN = 0,
.bit.CLKEN = 1,
.bit.WRTLOCK = 0
};
/* Setup interrupt */
NVIC_SetPriority(EIC_IRQn, 10); //TODO: Come up with a sensible prio, now highest
NVIC_SetPriority(EIC_IRQn, 10);
NVIC_EnableIRQ(EIC_IRQn);
/* save callback */
@ -463,8 +468,9 @@ int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb
gpio_config[extint].arg = arg;
/*Enable pin interrupt */
EIC->INTENSET.reg = (1 << (extint));
EIC->WAKEUP.reg |= (1 << (extint));
EIC->INTFLAG.reg |= (1 << extint);
EIC->INTENSET.reg = 1 << extint;
EIC->WAKEUP.reg |= 1 << extint;
/*Set config */
uint8_t config_pos = (4 * (extint % 8));
@ -473,15 +479,15 @@ int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb
switch (flank) {
case GPIO_FALLING:
EIC->CONFIG[config_reg].reg
|= (EIC_CONFIG_SENSE0_FALL_Val << (config_pos));
|= (EIC_CONFIG_SENSE0_FALL_Val << config_pos);
break;
case GPIO_RISING:
EIC->CONFIG[config_reg].reg
|= (EIC_CONFIG_SENSE0_RISE_Val << (config_pos));
|= (EIC_CONFIG_SENSE0_RISE_Val << config_pos);
break;
case GPIO_BOTH:
EIC->CONFIG[config_reg].reg
|= (EIC_CONFIG_SENSE0_BOTH_Val << (config_pos));
|= (EIC_CONFIG_SENSE0_BOTH_Val << config_pos);
break;
}
@ -495,82 +501,82 @@ void gpio_irq_enable(gpio_t dev)
switch (dev) {
#if GPIO_0_EN
case GPIO_0:
EIC->INTENSET.reg = (1 << GPIO_0_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_0_EXTINT;
break;
#endif
#if GPIO_1_EN
case GPIO_1:
EIC->INTENSET.reg = (1 << GPIO_1_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_1_EXTINT;
break;
#endif
#if GPIO_2_EN
case GPIO_2:
EIC->INTENSET.reg = (1 << GPIO_2_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_2_EXTINT;
break;
#endif
#if GPIO_3_EN
case GPIO_3:
EIC->INTENSET.reg = (1 << GPIO_3_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_3_EXTINT;
break;
#endif
#if GPIO_4_EN
case GPIO_4:
EIC->INTENSET.reg = (1 << GPIO_4_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_4_EXTINT;
break;
#endif
#if GPIO_5_EN
case GPIO_5:
EIC->INTENSET.reg = (1 << GPIO_5_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_5_EXTINT;
break;
#endif
#if GPIO_6_EN
case GPIO_6:
EIC->INTENSET.reg = (1 << GPIO_6_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_6_EXTINT;
break;
#endif
#if GPIO_7_EN
case GPIO_7:
EIC->INTENSET.reg = (1 << GPIO_7_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_7_EXTINT;
break;
#endif
#if GPIO_8_EN
case GPIO_8:
EIC->INTENSET.reg = (1 << GPIO_8_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_8_EXTINT;
break;
#endif
#if GPIO_9_EN
case GPIO_9:
EIC->INTENSET.reg = (1 << GPIO_9_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_9_EXTINT;
break;
#endif
#if GPIO_10_EN
case GPIO_10:
EIC->INTENSET.reg = (1 << GPIO_10_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_10_EXTINT;
break;
#endif
#if GPIO_11_EN
case GPIO_11:
EIC->INTENSET.reg = (1 << GPIO_11_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_11_EXTINT;
break;
#endif
#if GPIO_12_EN
case GPIO_12:
EIC->INTENSET.reg = (1 << GPIO_12_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_12_EXTINT;
break;
#endif
#if GPIO_13_EN
case GPIO_13:
EIC->INTENSET.reg = (1 << GPIO_13_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_13_EXTINT;
break;
#endif
#if GPIO_14_EN
case GPIO_14:
EIC->INTENSET.reg = (1 << GPIO_14_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_14_EXTINT;
break;
#endif
#if GPIO_15_EN
case GPIO_15:
EIC->INTENSET.reg = (1 << GPIO_15_EXTINT);
EIC->INTENSET.reg = 1 << GPIO_15_EXTINT;
break;
#endif
}
@ -581,82 +587,82 @@ void gpio_irq_disable(gpio_t dev)
switch (dev) {
#if GPIO_0_EN
case GPIO_0:
EIC->INTENCLR.reg = (1 << GPIO_0_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_0_EXTINT;
break;
#endif
#if GPIO_1_EN
case GPIO_1:
EIC->INTENCLR.reg = (1 << GPIO_1_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_1_EXTINT;
break;
#endif
#if GPIO_2_EN
case GPIO_2:
EIC->INTENCLR.reg = (1 << GPIO_2_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_2_EXTINT;
break;
#endif
#if GPIO_3_EN
case GPIO_3:
EIC->INTENCLR.reg = (1 << GPIO_3_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_3_EXTINT;
break;
#endif
#if GPIO_4_EN
case GPIO_4:
EIC->INTENCLR.reg = (1 << GPIO_4_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_4_EXTINT;
break;
#endif
#if GPIO_5_EN
case GPIO_5:
EIC->INTENCLR.reg = (1 << GPIO_5_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_5_EXTINT;
break;
#endif
#if GPIO_6_EN
case GPIO_6:
EIC->INTENCLR.reg = (1 << GPIO_6_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_6_EXTINT;
break;
#endif
#if GPIO_7_EN
case GPIO_7:
EIC->INTENCLR.reg = (1 << GPIO_7_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_7_EXTINT;
break;
#endif
#if GPIO_8_EN
case GPIO_8:
EIC->INTENCLR.reg = (1 << GPIO_8_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_8_EXTINT;
break;
#endif
#if GPIO_9_EN
case GPIO_9:
EIC->INTENCLR.reg = (1 << GPIO_9_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_9_EXTINT;
break;
#endif
#if GPIO_10_EN
case GPIO_10:
EIC->INTENCLR.reg = (1 << GPIO_10_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_10_EXTINT;
break;
#endif
#if GPIO_11_EN
case GPIO_11:
EIC->INTENCLR.reg = (1 << GPIO_11_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_11_EXTINT;
break;
#endif
#if GPIO_12_EN
case GPIO_12:
EIC->INTENCLR.reg = (1 << GPIO_12_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_12_EXTINT;
break;
#endif
#if GPIO_13_EN
case GPIO_13:
EIC->INTENCLR.reg = (1 << GPIO_13_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_13_EXTINT;
break;
#endif
#if GPIO_14_EN
case GPIO_14:
EIC->INTENCLR.reg = (1 << GPIO_14_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_14_EXTINT;
break;
#endif
#if GPIO_15_EN
case GPIO_15:
EIC->INTENCLR.reg = (1 << GPIO_15_EXTINT);
EIC->INTENCLR.reg = 1 << GPIO_15_EXTINT;
break;
#endif
}
@ -670,66 +676,82 @@ int gpio_read(gpio_t dev)
#if GPIO_0_EN
case GPIO_0:
res = (&GPIO_0_DEV)->IN.reg & (1 << GPIO_0_PIN);
break;
#endif
#if GPIO_1_EN
case GPIO_1:
res = (&GPIO_1_DEV)->IN.reg & (1 << GPIO_1_PIN);
break;
#endif
#if GPIO_2_EN
case GPIO_2:
res = (&GPIO_2_DEV)->IN.reg & (1 << GPIO_2_PIN);
break;
#endif
#if GPIO_3_EN
case GPIO_3:
res = (&GPIO_3_DEV)->IN.reg & (1 << GPIO_3_PIN);
break;
#endif
#if GPIO_4_EN
case GPIO_4:
res = (&GPIO_4_DEV)->IN.reg & (1 << GPIO_4_PIN);
break;
#endif
#if GPIO_5_EN
case GPIO_5:
res = (&GPIO_5_DEV)->IN.reg & (1 << GPIO_5_PIN);
break;
#endif
#if GPIO_6_EN
case GPIO_6:
res = (&GPIO_6_DEV)->IN.reg & (1 << GPIO_6_PIN);
break;
#endif
#if GPIO_7_EN
case GPIO_7:
res = (&GPIO_7_DEV)->IN.reg & (1 << GPIO_7_PIN);
break;
#endif
#if GPIO_8_EN
case GPIO_8:
res = (&GPIO_8_DEV)->IN.reg & (1 << GPIO_8_PIN);
break;
#endif
#if GPIO_9_EN
case GPIO_9:
res = (&GPIO_9_DEV)->IN.reg & (1 << GPIO_9_PIN);
break;
#endif
#if GPIO_10_EN
case GPIO_10:
res = (&GPIO_10_DEV)->IN.reg & (1 << GPIO_10_PIN);
break;
#endif
#if GPIO_11_EN
case GPIO_11:
res = (&GPIO_11_DEV)->IN.reg & (1 << GPIO_11_PIN);
break;
#endif
#if GPIO_12_EN
case GPIO_12:
res = (&GPIO_12_DEV)->IN.reg & (1 << GPIO_12_PIN);
break;
#endif
#if GPIO_13_EN
case GPIO_13:
res = (&GPIO_13_DEV)->IN.reg & (1 << GPIO_13_PIN);
break;
#endif
#if GPIO_14_EN
case GPIO_14:
res = (&GPIO_14_DEV)->IN.reg & (1 << GPIO_14_PIN);
break;
#endif
#if GPIO_15_EN
case GPIO_15:
res = (&GPIO_15_DEV)->IN.reg & (1 << GPIO_15_PIN);
break;
#endif
}
@ -746,67 +768,83 @@ void gpio_set(gpio_t dev)
switch (dev) {
#if GPIO_0_EN
case GPIO_0:
(&GPIO_0_DEV)->OUTSET.reg = (1 << GPIO_3_PIN);
(&GPIO_0_DEV)->OUTSET.reg = 1 << GPIO_0_PIN;
break;
#endif
#if GPIO_1_EN
case GPIO_1:
(&GPIO_1_DEV)->OUTSET.reg = (1 << GPIO_3_PIN);
(&GPIO_1_DEV)->OUTSET.reg = 1 << GPIO_1_PIN;
break;
#endif
#if GPIO_2_EN
case GPIO_2:
(&GPIO_2_DEV)->OUTSET.reg = (1 << GPIO_3_PIN);
(&GPIO_2_DEV)->OUTSET.reg = 1 << GPIO_2_PIN;
break;
#endif
#if GPIO_3_EN
case GPIO_3:
(&GPIO_3_DEV)->OUTSET.reg = (1 << GPIO_3_PIN);
(&GPIO_3_DEV)->OUTSET.reg = 1 << GPIO_3_PIN;
break;
#endif
#if GPIO_4_EN
case GPIO_4:
(&GPIO_4_DEV)->OUTSET.reg = (1 << GPIO_4_PIN);
(&GPIO_4_DEV)->OUTSET.reg = 1 << GPIO_4_PIN;
break;
#endif
#if GPIO_5_EN
case GPIO_5:
(&GPIO_5_DEV)->OUTSET.reg = (1 << GPIO_5_PIN);
(&GPIO_5_DEV)->OUTSET.reg = 1 << GPIO_5_PIN;
break;
#endif
#if GPIO_6_EN
case GPIO_6:
(&GPIO_6_DEV)->OUTSET.reg = (1 << GPIO_6_PIN);
(&GPIO_6_DEV)->OUTSET.reg = 1 << GPIO_6_PIN;
break;
#endif
#if GPIO_7_EN
case GPIO_7:
(&GPIO_7_DEV)->OUTSET.reg = (1 << GPIO_7_PIN);
(&GPIO_7_DEV)->OUTSET.reg = 1 << GPIO_7_PIN;
break;
#endif
#if GPIO_8_EN
case GPIO_8:
(&GPIO_8_DEV)->OUTSET.reg = (1 << GPIO_8_PIN);
(&GPIO_8_DEV)->OUTSET.reg = 1 << GPIO_8_PIN;
break;
#endif
#if GPIO_9_EN
case GPIO_9:
(&GPIO_9_DEV)->OUTSET.reg = (1 << GPIO_9_PIN);
(&GPIO_9_DEV)->OUTSET.reg = 1 << GPIO_9_PIN;
break;
#endif
#if GPIO_10_EN
case GPIO_10:
(&GPIO_10_DEV)->OUTSET.reg = (1 << GPIO_10_PIN);
(&GPIO_10_DEV)->OUTSET.reg = 1 << GPIO_10_PIN;
break;
#endif
#if GPIO_11_EN
case GPIO_11:
(&GPIO_11_DEV)->OUTSET.reg = (1 << GPIO_11_PIN);
(&GPIO_11_DEV)->OUTSET.reg = 1 << GPIO_11_PIN;
break;
#endif
#if GPIO_12_EN
case GPIO_12:
(&GPIO_12_DEV)->OUTSET.reg = (1 << GPIO_12_PIN);
(&GPIO_12_DEV)->OUTSET.reg = 1 << GPIO_12_PIN;
break;
#endif
#if GPIO_13_EN
case GPIO_13:
(&GPIO_13_DEV)->OUTSET.reg = (1 << GPIO_13_PIN);
(&GPIO_13_DEV)->OUTSET.reg = 1 << GPIO_13_PIN;
break;
#endif
#if GPIO_14_EN
case GPIO_14:
(&GPIO_14_DEV)->OUTSET.reg = (1 << GPIO_14_PIN);
(&GPIO_14_DEV)->OUTSET.reg = 1 << GPIO_14_PIN;
break;
#endif
#if GPIO_15_EN
case GPIO_15:
(&GPIO_15_DEV)->OUTSET.reg = (1 << GPIO_15_PIN);
(&GPIO_15_DEV)->OUTSET.reg = 1 << GPIO_15_PIN;
break;
#endif
}
}
@ -816,67 +854,84 @@ void gpio_clear(gpio_t dev)
switch (dev) {
#if GPIO_0_EN
case GPIO_0:
(&GPIO_0_DEV)->OUTCLR.reg = (1 << GPIO_3_PIN);
(&GPIO_0_DEV)->OUTCLR.reg = 1 << GPIO_0_PIN;
break;
#endif
#if GPIO_1_EN
case GPIO_1:
(&GPIO_1_DEV)->OUTCLR.reg = (1 << GPIO_3_PIN);
(&GPIO_1_DEV)->OUTCLR.reg = 1 << GPIO_1_PIN;
break;
#endif
#if GPIO_2_EN
case GPIO_2:
(&GPIO_2_DEV)->OUTCLR.reg = (1 << GPIO_3_PIN);
(&GPIO_2_DEV)->OUTCLR.reg = 1 << GPIO_2_PIN;
break;
#endif
#if GPIO_3_EN
case GPIO_3:
(&GPIO_3_DEV)->OUTCLR.reg = (1 << GPIO_3_PIN);
(&GPIO_3_DEV)->OUTCLR.reg = 1 << GPIO_3_PIN;
break;
#endif
#if GPIO_4_EN
case GPIO_4:
(&GPIO_4_DEV)->OUTCLR.reg = (1 << GPIO_4_PIN);
(&GPIO_4_DEV)->OUTCLR.reg = 1 << GPIO_4_PIN;
break;
#endif
#if GPIO_5_EN
case GPIO_5:
(&GPIO_5_DEV)->OUTCLR.reg = (1 << GPIO_5_PIN);
(&GPIO_5_DEV)->OUTCLR.reg = 1 << GPIO_5_PIN;
break;
#endif
#if GPIO_6_EN
case GPIO_6:
(&GPIO_6_DEV)->OUTCLR.reg = (1 << GPIO_6_PIN);
(&GPIO_6_DEV)->OUTCLR.reg = 1 << GPIO_6_PIN;
break;
#endif
#if GPIO_7_EN
case GPIO_7:
(&GPIO_7_DEV)->OUTCLR.reg = (1 << GPIO_7_PIN);
(&GPIO_7_DEV)->OUTCLR.reg = 1 << GPIO_7_PIN;
break;
#endif
#if GPIO_8_EN
case GPIO_8:
(&GPIO_8_DEV)->OUTCLR.reg = (1 << GPIO_8_PIN);
(&GPIO_8_DEV)->OUTCLR.reg = 1 << GPIO_8_PIN;
break;
#endif
#if GPIO_9_EN
case GPIO_9:
(&GPIO_9_DEV)->OUTCLR.reg = (1 << GPIO_9_PIN);
(&GPIO_9_DEV)->OUTCLR.reg = 1 << GPIO_9_PIN;
break;
#endif
#if GPIO_10_EN
case GPIO_10:
(&GPIO_10_DEV)->OUTCLR.reg = (1 << GPIO_10_PIN);
(&GPIO_10_DEV)->OUTCLR.reg = 1 << GPIO_10_PIN;
break;
#endif
#if GPIO_11_EN
case GPIO_11:
(&GPIO_11_DEV)->OUTCLR.reg = (1 << GPIO_11_PIN);
(&GPIO_11_DEV)->OUTCLR.reg = 1 << GPIO_11_PIN;
break;
#endif
#if GPIO_12_EN
case GPIO_12:
(&GPIO_12_DEV)->OUTCLR.reg = (1 << GPIO_12_PIN);
(&GPIO_12_DEV)->OUTCLR.reg = 1 << GPIO_12_PIN;
break;
#endif
#if GPIO_13_EN
case GPIO_13:
(&GPIO_13_DEV)->OUTCLR.reg = (1 << GPIO_13_PIN);
(&GPIO_13_DEV)->OUTCLR.reg = 1 << GPIO_13_PIN;
break;
#endif
#if GPIO_14_EN
case GPIO_14:
(&GPIO_14_DEV)->OUTCLR.reg = (1 << GPIO_14_PIN);
(&GPIO_14_DEV)->OUTCLR.reg = 1 << GPIO_14_PIN;
break;
#endif
#if GPIO_15_EN
case GPIO_15:
(&GPIO_15_DEV)->OUTCLR.reg = (1 << GPIO_15_PIN);
(&GPIO_15_DEV)->OUTCLR.reg = 1 << GPIO_15_PIN;
break;
#endif
}
}

291
cpu/samd21/periph/spi.c Normal file
View File

@ -0,0 +1,291 @@
/*
* Copyright (C) 2014 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_samd21
* @{
*
* @file spi.c
* @brief Low-level SPI driver implementation
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
* Troels Hoffmeyer <troels.d.hoffmeyer@gmail.com>
*
* @}
*/
#include "cpu.h"
#include "periph/gpio.h"
#include "periph/spi.h"
#include "periph_conf.h"
#include "board.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#if SPI_0_EN || SPI_1_EN
int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
{
SercomSpi* spi_dev = 0;
uint8_t dopo = 0;
uint8_t dipo = 0;
uint8_t cpha = 0;
uint8_t cpol = 0;
uint32_t f_baud = 0;
switch(speed)
{
case SPI_SPEED_100KHZ:
f_baud = 100000;
break;
case SPI_SPEED_400KHZ:
f_baud = 400000;
break;
case SPI_SPEED_1MHZ:
f_baud = 1000000;
break;
case SPI_SPEED_5MHZ:
return -1;
case SPI_SPEED_10MHZ:
return -1;
}
switch(conf)
{
case SPI_CONF_FIRST_RISING: /**< first data bit is transacted on the first rising SCK edge */
cpha = 0;
cpol = 0;
break;
case SPI_CONF_SECOND_RISING:/**< first data bit is transacted on the second rising SCK edge */
cpha = 1;
cpol = 0;
break;
case SPI_CONF_FIRST_FALLING:/**< first data bit is transacted on the first falling SCK edge */
cpha = 0;
cpol = 1;
break;
case SPI_CONF_SECOND_FALLING:/**< first data bit is transacted on the second falling SCK edge */
cpha = 1;
cpol = 1;
break;
}
switch(dev)
{
#ifdef SPI_0_EN
case SPI_0:
spi_dev = &SPI_0_DEV;
/* Enable sercom4 in power manager */
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM4;
GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN_GCLK0
| (SERCOM4_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));
/* Setup clock */
while (GCLK->STATUS.bit.SYNCBUSY);
/* Mux enable*/
SPI_0_SCLK_DEV.PINCFG[ SPI_0_SCLK_PIN ].bit.PMUXEN = 1;
SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.PMUXEN = 1;
SPI_0_MOSI_DEV.PINCFG[ SPI_0_MOSI_PIN ].bit.PMUXEN = 1;
/*Set mux function to spi. seperate registers, for even or odd pins */
SPI_0_SCLK_DEV.PMUX[ SPI_0_SCLK_PIN / 2].bit.PMUXE = 5;
SPI_0_MISO_DEV.PMUX[ SPI_0_MISO_PIN / 2].bit.PMUXO = 5;
SPI_0_MOSI_DEV.PMUX[ SPI_0_MOSI_PIN / 2].bit.PMUXE = 5;
/* SCLK+MOSI */
SPI_0_SCLK_DEV.DIRSET.reg = 1 << SPI_0_SCLK_PIN;
SPI_0_MOSI_DEV.DIRSET.reg = 1 << SPI_0_MOSI_PIN;
/* MISO = input */
/* configure as input */
SPI_0_MISO_DEV.DIRCLR.reg = 1 << SPI_0_MISO_PIN;
SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.INEN = true;
SPI_0_MISO_DEV.OUTCLR.reg = 1 << SPI_0_MISO_PIN;
SPI_0_MISO_DEV.PINCFG[ SPI_0_MISO_PIN ].bit.PULLEN = true;
dopo = SPI_0_DOPO;
dipo = SPI_0_DIPO;
break;
#endif
#ifdef SPI_1_EN
case SPI_1:
spi_dev = &SPI_1_DEV;
/* Enable sercom5 in power manager */
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;
/* Setup clock */ /* configure GCLK0 to feed sercom5 */;
GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN
| GCLK_CLKCTRL_GEN_GCLK0
| (SERCOM5_GCLK_ID_CORE << GCLK_CLKCTRL_ID_Pos)));
/* Mux enable*/
SPI_1_SCLK_DEV.PINCFG[ SPI_1_SCLK_PIN ].bit.PMUXEN = 1;
SPI_1_MISO_DEV.PINCFG[ SPI_1_MISO_PIN ].bit.PMUXEN = 1;
SPI_1_MOSI_DEV.PINCFG[ SPI_1_MOSI_PIN ].bit.PMUXEN = 1;
/*Set mux function to spi. seperate registers, for even or odd pins */
SPI_1_SCLK_DEV.PMUX[ SPI_1_SCLK_PIN / 2].bit.PMUXO = 3;
SPI_1_MISO_DEV.PMUX[ SPI_1_MISO_PIN / 2].bit.PMUXE = 3;
SPI_1_MOSI_DEV.PMUX[ SPI_1_MOSI_PIN / 2].bit.PMUXE = 3;
/* SCLK+MOSI */
SPI_1_SCLK_DEV.DIRSET.reg = 1 << SPI_1_SCLK_PIN;
SPI_1_MOSI_DEV.DIRSET.reg = 1 << SPI_1_MOSI_PIN;
/* MISO = input */
/* configure as input */
SPI_1_MISO_DEV.DIRCLR.reg = 1 << SPI_1_MISO_PIN;
SPI_1_MISO_DEV.PINCFG[ SPI_1_MISO_PIN ].bit.INEN = true;
SPI_1_MISO_DEV.OUTCLR.reg = 1 << SPI_1_MISO_PIN;
SPI_1_MISO_DEV.PINCFG[SPI_1_MISO_PIN].bit.PULLEN = true;
dopo = SPI_1_DOPO;
dipo = SPI_1_DIPO;
break;
#endif
default:
return -1;
}
spi_dev->CTRLA.bit.ENABLE = 0; /* Disable spi to write confs */
while (spi_dev->SYNCBUSY.reg);
spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
while (spi_dev->SYNCBUSY.reg);
spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t) SPI_0_F_REF) / (2 * f_baud) - 1); /* Syncronous mode*/
spi_dev->CTRLA.reg |= (SERCOM_SPI_CTRLA_DOPO(dopo))
| (SERCOM_SPI_CTRLA_DIPO(dipo))
| (cpha << SERCOM_SPI_CTRLA_CPHA_Pos)
| (cpol << SERCOM_SPI_CTRLA_CPOL_Pos);
while (spi_dev->SYNCBUSY.reg);
spi_dev->CTRLB.reg = (SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN);
while(spi_dev->SYNCBUSY.reg);
spi_poweron(dev);
return 0;
}
int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char))
{
/* TODO */
return 0;
}
void spi_transmission_begin(spi_t dev, char reset_val)
{
/* TODO*/
}
int spi_transfer_byte(spi_t dev, char out, char *in)
{
SercomSpi* spi_dev = 0;
int transfered = 0;
switch(dev)
{
#ifdef SPI_0_EN
case SPI_0:
spi_dev = &(SPI_0_DEV);
break;
#endif
#ifdef SPI_1_EN
case SPI_1:
spi_dev = &(SPI_1_DEV);
break;
#endif
}
while (!spi_dev->INTFLAG.bit.DRE); /* while data register is not empty*/
spi_dev->DATA.bit.DATA = out;
transfered++;
if (in != NULL)
{
while (!spi_dev->INTFLAG.bit.RXC); /* while receive is not complete*/
*in = spi_dev->DATA.bit.DATA;
transfered++;
}
else
{
spi_dev->DATA.reg;
}
return transfered;
}
int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
{
int transfered = 0;
if (out != NULL) {
DEBUG("out*: %p out: %x length: %x\n", out, *out, length);
while (length--) {
int ret = spi_transfer_byte(dev, *(out)++, 0);
if (ret < 0) {
return ret;
}
transfered += ret;
}
}
if (in != NULL) {
while (length--) {
int ret = spi_transfer_byte(dev, 0, in++);
if (ret < 0) {
return ret;
}
transfered += ret;
}
DEBUG("in*: %p in: %x transfered: %x\n", in, *(in-transfered), transfered);
}
DEBUG("sent %x byte(s)\n", transfered);
return transfered;
}
int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
{
spi_transfer_byte(dev, reg, NULL);
return spi_transfer_byte(dev, out, in);
}
int spi_transfer_regs(spi_t dev, uint8_t reg, char *out, char *in, unsigned int length)
{
spi_transfer_byte(dev, reg, NULL);
return spi_transfer_bytes(dev, out, in, length);
}
void spi_poweron(spi_t dev)
{
switch(dev) {
#ifdef SPI_0_EN
case SPI_0:
SPI_0_DEV.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
while(SPI_0_DEV.SYNCBUSY.bit.ENABLE);
break;
#endif
#ifdef SPI_1_EN
case SPI_1:
SPI_1_DEV.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
while(SPI_1_DEV.SYNCBUSY.bit.ENABLE);
break;
#endif
}
}
void spi_poweroff(spi_t dev)
{
switch(dev) {
#ifdef SPI_0_EN
case SPI_0:
SPI_0_DEV.CTRLA.bit.ENABLE = 0; /*Disable spi*/
while(SPI_0_DEV.SYNCBUSY.bit.ENABLE);
break;
#endif
#ifdef SPI_1_EN
case SPI_1:
SPI_1_DEV.CTRLA.bit.ENABLE = 0; /*Disable spi*/
while(SPI_1_DEV.SYNCBUSY.bit.ENABLE);
break;
#endif
}
}
#endif /* SPI_0_EN || SPI_1_EN */

View File

@ -31,6 +31,12 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
#ifndef AT86RF231_SPI_SPEED
#define SPI_SPEED SPI_SPEED_5MHZ
#else
#define SPI_SPEED AT86RF231_SPI_SPEED
#endif
#define _MAX_RETRIES (100)
static uint16_t radio_pan;
@ -396,7 +402,7 @@ int at86rf231_get_monitor(void)
void at86rf231_gpio_spi_interrupts_init(void)
{
/* SPI init */
spi_init_master(AT86RF231_SPI, SPI_CONF_FIRST_RISING, SPI_SPEED_5MHZ);
spi_init_master(AT86RF231_SPI, SPI_CONF_FIRST_RISING, SPI_SPEED);
/* IRQ0 */
gpio_init_int(AT86RF231_INT, GPIO_NOPULL, GPIO_RISING, (gpio_cb_t)at86rf231_rx_irq, NULL);
/* CS */
@ -417,9 +423,8 @@ void at86rf231_reset(void)
gpio_clear(AT86RF231_SLEEP);
/* additional waiting to comply to min rst pulse width */
uint8_t delay = 50;
while (delay--){}
uint8_t volatile delay = 50; /* volatile to ensure it isn't optimized away */
while (--delay);
gpio_set(AT86RF231_RESET);
}