diff --git a/boards/samr21-xpro/include/periph_conf.h b/boards/samr21-xpro/include/periph_conf.h
index 65b0bc72275f7d70042ac595a5e5eaf471ffd291..acfccece08139c2b5b7b961119e9a8e5738cf662 100644
--- a/boards/samr21-xpro/include/periph_conf.h
+++ b/boards/samr21-xpro/include/periph_conf.h
@@ -160,34 +160,32 @@ static const pwm_conf_t pwm_config[] = {
 #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_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)
+#define SPI_0_DEV           SERCOM4->SPI
+#define SPI_IRQ_0           SERCOM4_IRQn
+#define SPI_0_GCLK_ID       SERCOM4_GCLK_ID_CORE
+/* SPI 0 pin configuration */
+#define SPI_0_SCLK          GPIO_PIN(PC, 18)
+#define SPI_0_SCLK_MUX      GPIO_MUX_F
+#define SPI_0_MISO          GPIO_PIN(PC, 19)
+#define SPI_0_MISO_MUX      GPIO_MUX_F
+#define SPI_0_MISO_PAD      SERCOM_RX_PAD_0
+#define SPI_0_MOSI          GPIO_PIN(PB, 30)
+#define SPI_0_MOSI_MUX      GPIO_MUX_F
+#define SPI_0_MOSI_PAD      SPI_PAD_2_SCK_3
 
 /*      SPI1             */
-#define SPI_1_DEV          SERCOM5->SPI
-#define SPI_IRQ_1          SERCOM5_IRQn
-#define SPI_1_DOPO         (1)
-#define SPI_1_DIPO         (0)
-
-#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)
+#define SPI_1_DEV           SERCOM5->SPI
+#define SPI_IRQ_1           SERCOM5_IRQn
+#define SPI_1_GCLK_ID       SERCOM5_GCLK_ID_CORE
+/* SPI 1 pin configuration */
+#define SPI_1_SCLK          GPIO_PIN(PB, 23)
+#define SPI_1_SCLK_MUX      GPIO_MUX_D
+#define SPI_1_MISO          GPIO_PIN(PB, 02)
+#define SPI_1_MISO_MUX      GPIO_MUX_D
+#define SPI_1_MISO_PAD      SERCOM_RX_PAD_0
+#define SPI_1_MOSI          GPIO_PIN(PB, 22)
+#define SPI_1_MOSI_MUX      GPIO_MUX_D
+#define SPI_1_MOSI_PAD      SPI_PAD_2_SCK_3
 /** @} */
 
 /**
diff --git a/cpu/samd21/periph/spi.c b/cpu/samd21/periph/spi.c
index a58dcc9d7f63314aa48ea00fb6077b772ed14340..f5f0b90a642a01a40d93c5fd1866207442edd8f7 100644
--- a/cpu/samd21/periph/spi.c
+++ b/cpu/samd21/periph/spi.c
@@ -60,10 +60,17 @@ static mutex_t locks[] =  {
 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;
+    uint8_t sercom_gclk_id = 0;
+    gpio_t pin_sclk = 0;
+    gpio_t pin_miso = 0;
+    gpio_t pin_mosi = 0;
+    gpio_mux_t mux_sclk = 0;
+    gpio_mux_t mux_miso = 0;
+    gpio_mux_t mux_mosi = 0;
+    sercom_spi_txpad_t  dopo = 0;
+    sercom_rxpad_t      dipo = 0;
+    uint32_t   cpha = 0;
+    uint32_t   cpol = 0;
     uint32_t   f_baud = 0;
     switch (speed)
     {
@@ -93,21 +100,21 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
     }
     switch (conf)
     {
-    case SPI_CONF_FIRST_RISING: /**< first data bit is transacted on the first rising SCK edge */
+    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;
+    case SPI_CONF_SECOND_RISING:        /**< first data bit is transacted on the second rising SCK edge */
+        cpha = SERCOM_SPI_CTRLA_CPHA;
         cpol = 0;
         break;
-    case SPI_CONF_FIRST_FALLING:/**< first data bit is transacted on the first falling SCK edge */
+    case SPI_CONF_FIRST_FALLING:        /**< first data bit is transacted on the first falling SCK edge */
         cpha = 0;
-        cpol = 1;
+        cpol = SERCOM_SPI_CTRLA_CPOL;
         break;
-    case SPI_CONF_SECOND_FALLING:/**< first data bit is transacted on the second falling SCK edge */
-        cpha = 1;
-        cpol = 1;
+    case SPI_CONF_SECOND_FALLING:       /**< first data bit is transacted on the second falling SCK edge */
+        cpha = SERCOM_SPI_CTRLA_CPHA;
+        cpol = SERCOM_SPI_CTRLA_CPOL;
         break;
     }
     switch (dev)
@@ -115,92 +122,79 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
 #if 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;
+        sercom_gclk_id = SPI_0_GCLK_ID;
+        pin_sclk = SPI_0_SCLK;
+        mux_sclk = SPI_0_SCLK_MUX;
+        pin_miso = SPI_0_MISO;
+        mux_miso = SPI_0_MISO_MUX;
+        pin_mosi = SPI_0_MOSI;
+        mux_mosi = SPI_0_MOSI_MUX;
+        dopo = SPI_0_MOSI_PAD;
+        dipo = SPI_0_MISO_PAD;
         break;
 #endif
 #if 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;
+        sercom_gclk_id = SPI_1_GCLK_ID;
+        pin_sclk = SPI_1_SCLK;
+        mux_sclk = SPI_1_SCLK_MUX;
+        pin_miso = SPI_1_MISO;
+        mux_miso = SPI_1_MISO_MUX;
+        pin_mosi = SPI_1_MOSI;
+        mux_mosi = SPI_1_MOSI_MUX;
+        dopo = SPI_1_MOSI_PAD;
+        dipo = SPI_1_MISO_PAD;
         break;
 #endif
     default:
         return -1;
     }
 
+    /* Use the same sequence as ArduinoCore
+     *  - setup pins
+     *  - disable SPI
+     *  - init SPI (reset, init clock NVIC, CTRLA, CTRLB)
+     *  - init cpha/cpol, BAUD.reg
+     *  - enable SPI
+     */
+
+    gpio_init_sercom(pin_sclk, mux_sclk);
+    gpio_init_sercom(pin_miso, mux_miso);
+    gpio_init_sercom(pin_mosi, mux_mosi);
+
     /* Disable spi to write confs */
     _spi_poweroff(spi_dev);
 
+    /* reset */
+    // Setting the Software Reset bit to 1
+    spi_dev->CTRLA.bit.SWRST = 1;
+
+    // Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
+    while (spi_dev->CTRLA.bit.SWRST || spi_dev->SYNCBUSY.bit.SWRST) {}
+
+    /* Turn on power manager for sercom */
+    PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << (sercom_gclk_id - GCLK_CLKCTRL_ID_SERCOM0_CORE_Val));
+
+    /* Setup clock */
+    /* SPI using CLK GEN 0 */
+    GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
+                         GCLK_CLKCTRL_GEN_GCLK0 |
+                         GCLK_CLKCTRL_ID(sercom_gclk_id));
+    while (GCLK->STATUS.bit.SYNCBUSY) {}
+
+    /* ???? init NVIC. Maybe not needed in master mode. */
+
+    /* Master mode */
     spi_dev->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER;
-    while (spi_dev->SYNCBUSY.reg) {}	// ???? not needed
+    while (spi_dev->SYNCBUSY.reg) {}// ???? not needed
 
     spi_dev->BAUD.bit.BAUD = (uint8_t) (((uint32_t)CLOCK_CORECLOCK) / (2 * f_baud) - 1); /* Synchronous 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);
+                       |  cpha
+                       |  cpol;
     while (spi_dev->SYNCBUSY.reg) {}	// ???? not needed
 
     /* datasize 0 => 8 bits */
@@ -263,7 +257,7 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     while (!spi_dev->INTFLAG.bit.DRE) {} /* while data register is not empty*/
     spi_dev->DATA.bit.DATA = out;
 
-    while (!spi_dev->INTFLAG.bit.RXC) {} /* while receive is not complete*/
+    while (!spi_dev->INTFLAG.bit.DRE || !spi_dev->INTFLAG.bit.RXC) {} /* while receive is not complete*/
     tmp = (char)spi_dev->DATA.bit.DATA;
 
     if (in != NULL)