diff --git a/cpu/sam3/Makefile.include b/cpu/sam3/Makefile.include
index 99de28dcc7b1d26e43979d1aa7b539cc4dc573d6..d96ea6726ec0003c5fb78155f71ddbba8f7fd17c 100644
--- a/cpu/sam3/Makefile.include
+++ b/cpu/sam3/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m3
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# include common SPI functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/sam3/include/periph_cpu.h b/cpu/sam3/include/periph_cpu.h
index ebb7b6aad31d2af435ff11d9f4eb8dd244d14925..1fdce3836e65833403d9d0f81a54d2e696c6f2ed 100644
--- a/cpu/sam3/include/periph_cpu.h
+++ b/cpu/sam3/include/periph_cpu.h
@@ -25,7 +25,14 @@
 extern "C" {
 #endif
 
-/* nothing defined here so far... */
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/cpu/sam3/periph/spi.c b/cpu/sam3/periph/spi.c
index 206443db550ff3a02af50ac9414381c2a9b9026a..845bce1038b0b561ae1d049bcb775a76fb535cd0 100644
--- a/cpu/sam3/periph/spi.c
+++ b/cpu/sam3/periph/spi.c
@@ -335,76 +335,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    int trans_ret, trans_bytes = 0;
-    char in_temp;
-
-    for (int i = 0; i < length; i++) {
-
-        if (out) {
-            trans_ret = spi_transfer_byte(dev, out[i], &in_temp);
-        }
-        else {
-            trans_ret = spi_transfer_byte(dev, 0, &in_temp);
-        }
-
-        if (trans_ret < 0) {
-            return -1;
-        }
-
-        if (in) {
-            in[i] = in_temp;
-        }
-
-        trans_bytes++;
-    }
-
-    return trans_bytes++;
-}
-
-
-int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    trans_ret = spi_transfer_byte(dev, out, in);
-
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return 1;
-}
-
-
-int spi_transfer_regs(spi_t dev, uint8_t reg, char *out, char *in, unsigned int length)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    trans_ret = spi_transfer_bytes(dev, out, in, length);
-
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return trans_ret;
-}
-
-
 void spi_transmission_begin(spi_t dev, char reset_val)
 {
     switch (dev) {
diff --git a/cpu/samd21/Makefile.include b/cpu/samd21/Makefile.include
index ab5f80f11d4c49451a77578132e7c3c9cd8dc891..9e534e08384ecbb75d5e5061af7b2b5d42dd6554 100644
--- a/cpu/samd21/Makefile.include
+++ b/cpu/samd21/Makefile.include
@@ -6,4 +6,7 @@ export CFLAGS += -DDONT_USE_CMSIS_INIT
 # use the hwtimer compatibility layer
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/samd21/include/periph_cpu.h b/cpu/samd21/include/periph_cpu.h
index 8e743a050d1b090097fb4afed75b9c499a71ea0d..69ca15fcb0e77621602ba1cb1f4056f91204d541 100644
--- a/cpu/samd21/include/periph_cpu.h
+++ b/cpu/samd21/include/periph_cpu.h
@@ -88,6 +88,15 @@ typedef enum {
  */
 int gpio_init_mux(gpio_t dev, gpio_mux_t mux);
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/samd21/periph/spi.c b/cpu/samd21/periph/spi.c
index 7b41029713213be201dfeed36f466fed4347f7f9..1193de8e1c7706a16d1b037ee8f807bb924254ba 100644
--- a/cpu/samd21/periph/spi.c
+++ b/cpu/samd21/periph/spi.c
@@ -258,47 +258,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-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) {
diff --git a/cpu/saml21/Makefile.include b/cpu/saml21/Makefile.include
index 389ec9f25b856171863dbd8b3d4e3a4be2d14946..8967988c8db2d30fae89ae4f19698b5f6eb19329 100644
--- a/cpu/saml21/Makefile.include
+++ b/cpu/saml21/Makefile.include
@@ -6,4 +6,7 @@ export CFLAGS += -DDONT_USE_CMSIS_INIT
 # use the hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/saml21/include/periph_cpu.h b/cpu/saml21/include/periph_cpu.h
index 2e2788f0c552eaa492cbc716c94c8c5e480c22ed..1c6dc5eae25a5e9ead08424881c6ecbc8aa70bc9 100644
--- a/cpu/saml21/include/periph_cpu.h
+++ b/cpu/saml21/include/periph_cpu.h
@@ -87,6 +87,15 @@ typedef enum {
  */
 void gpio_init_mux(gpio_t dev, gpio_mux_t mux);
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/saml21/periph/spi.c b/cpu/saml21/periph/spi.c
index 846a818ac0f45f056732f3b382c369320e1e532c..0f9e7f73780d117ab2e1418d147d4ec8904393f0 100644
--- a/cpu/saml21/periph/spi.c
+++ b/cpu/saml21/periph/spi.c
@@ -219,41 +219,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    int transfered = 0;
-    int ret = 0;
-
-    DEBUG("out*: %p out: %x length: %x\n", out, *out, length);
-    while (length--) {
-        if ((ret = spi_transfer_byte(dev, *out, in)) <  0) {
-            return ret;
-        }
-
-        transfered += ret;
-
-        if (out) {
-            out++;
-        }
-        if (in) {
-            in++;
-        }
-    }
-    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)
 {
     SercomSpi* spi_dev = spi[dev].dev;
diff --git a/cpu/stm32f0/Makefile.include b/cpu/stm32f0/Makefile.include
index da01dcdf4f2f9654beee0e4a3e026cc4cbcade06..9ff29fdc7d15a63709aea86487f61cd423cf10f1 100644
--- a/cpu/stm32f0/Makefile.include
+++ b/cpu/stm32f0/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m0
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/stm32f0/include/periph_cpu.h b/cpu/stm32f0/include/periph_cpu.h
index f4d650441c521680892d1471764cb6d53a099e06..1cff6e2cca413bd54f0c59bfb56a51cc130cd0b1 100644
--- a/cpu/stm32f0/include/periph_cpu.h
+++ b/cpu/stm32f0/include/periph_cpu.h
@@ -25,7 +25,14 @@
 extern "C" {
 #endif
 
-/* nothing to do here, yet */
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/cpu/stm32f0/periph/spi.c b/cpu/stm32f0/periph/spi.c
index 8d5929139ea7ca8e7b44311be218b33fe256e29b..66ad5b459850c320fa8f9f510ed41ed34851ab91 100644
--- a/cpu/stm32f0/periph/spi.c
+++ b/cpu/stm32f0/periph/spi.c
@@ -213,38 +213,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    char res;
-    int count = 0;
-
-    for (int i = 0; i < length; i++) {
-        if (out) {
-            count += spi_transfer_byte(dev, out[i], &res);
-        }
-        else {
-            count += spi_transfer_byte(dev, 0, &res);
-        }
-        if (in) {
-            in[i] = res;
-        }
-    }
-
-    return count;
-}
-
-int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
-{
-    spi_transfer_byte(dev, reg, 0);
-    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, 0);
-    return spi_transfer_bytes(dev, out, in, length);
-}
-
 void spi_transmission_begin(spi_t dev, char reset_val)
 {
     /* slave mode is not (yet) supported */
diff --git a/cpu/stm32f1/Makefile.include b/cpu/stm32f1/Makefile.include
index 99de28dcc7b1d26e43979d1aa7b539cc4dc573d6..14626ee605f76a221e505a6cc48e2902c1ee4fb0 100644
--- a/cpu/stm32f1/Makefile.include
+++ b/cpu/stm32f1/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m3
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/stm32f1/include/periph_cpu.h b/cpu/stm32f1/include/periph_cpu.h
index 1ded7c7065066f3a5a3cf2eb17c7230407ea0dd9..f883b03b691bce35001700ab7d2c03fd3e2c832d 100644
--- a/cpu/stm32f1/include/periph_cpu.h
+++ b/cpu/stm32f1/include/periph_cpu.h
@@ -102,6 +102,15 @@ typedef enum {
  */
 void gpio_init_af(gpio_t pin, gpio_af_out_t af);
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/stm32f1/periph/spi.c b/cpu/stm32f1/periph/spi.c
index c605a9528636c8431948306004c861431f6ec086..2cbaa187075dac74a23c47e6d1c4896845f574ab 100644
--- a/cpu/stm32f1/periph/spi.c
+++ b/cpu/stm32f1/periph/spi.c
@@ -190,47 +190,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return transferred;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    int transferred = 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;
-            }
-            transferred += ret;
-        }
-    }
-    if (in != NULL) {
-        while (length--) {
-            int ret = spi_transfer_byte(dev, 0, in++);
-            if (ret <  0) {
-                return ret;
-            }
-            transferred += ret;
-        }
-        DEBUG("in*: %p in: %x transferred: %x\n", in, *(in-transferred), transferred);
-    }
-
-    DEBUG("sent %x byte(s)\n", transferred);
-    return transferred;
-}
-
-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_transmission_begin(spi_t dev, char reset_val)
 {
     /* slave mode not implemented, yet */
diff --git a/cpu/stm32f3/Makefile.include b/cpu/stm32f3/Makefile.include
index ed4584a4859caf21773544aee08bd6c9e6692952..a47fb55833ef6e267721207d981c4dc9c07941bf 100644
--- a/cpu/stm32f3/Makefile.include
+++ b/cpu/stm32f3/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m4f
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# includ common periph module
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/stm32f3/include/periph_cpu.h b/cpu/stm32f3/include/periph_cpu.h
index 6c456a3d33ebbeca9c741ea373a81ac8ad2ebefd..8e86ebac7c9dc202c959b60ab6b04e0a898c861b 100644
--- a/cpu/stm32f3/include/periph_cpu.h
+++ b/cpu/stm32f3/include/periph_cpu.h
@@ -79,6 +79,15 @@ typedef enum {
     GPIO_AF15               /**< use alternate function 14 */
 } gpio_af_t;
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/stm32f3/periph/spi.c b/cpu/stm32f3/periph/spi.c
index 1631998a13348e17c21b16b740325baa5c539efe..160f5f348bcde6d65dc2a47c9d4903bf9fa2c93a 100644
--- a/cpu/stm32f3/periph/spi.c
+++ b/cpu/stm32f3/periph/spi.c
@@ -334,62 +334,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    int i, trans_ret, trans_bytes = 0;
-    char in_temp;
-
-    for (i = 0; i < length; i++) {
-        if (out != NULL) {
-            trans_ret = spi_transfer_byte(dev, out[i], &in_temp);
-        }
-        else {
-            trans_ret = spi_transfer_byte(dev, 0, &in_temp);
-        }
-        if (trans_ret < 0) {
-            return -1;
-        }
-        if (in != NULL) {
-            in[i] = in_temp;
-        }
-        trans_bytes++;
-    }
-
-    return trans_bytes++;
-}
-
-int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-    trans_ret = spi_transfer_byte(dev, out, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return 1;
-}
-
-int spi_transfer_regs(spi_t dev, uint8_t reg, char *out, char *in, unsigned int length)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-    trans_ret = spi_transfer_bytes(dev, out, in, length);
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return trans_ret;
-}
-
 void spi_transmission_begin(spi_t dev, char reset_val)
 {
     if (dev < SPI_NUMOF) {
diff --git a/cpu/stm32f4/Makefile.include b/cpu/stm32f4/Makefile.include
index ed4584a4859caf21773544aee08bd6c9e6692952..329c4fe9e51b181d9eecde510d8f71ed8287ddd8 100644
--- a/cpu/stm32f4/Makefile.include
+++ b/cpu/stm32f4/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m4f
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/stm32f4/include/periph_cpu.h b/cpu/stm32f4/include/periph_cpu.h
index 609fc51f1817333ecc9d41d022f2e90eee2ff2c2..aead4e9a083b4e86f3f470b143b0a5da8e3399da 100644
--- a/cpu/stm32f4/include/periph_cpu.h
+++ b/cpu/stm32f4/include/periph_cpu.h
@@ -90,6 +90,14 @@ typedef enum {
  */
 void gpio_init_af(gpio_t pin, gpio_af_t af);
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
 
 #ifdef __cplusplus
 }
diff --git a/cpu/stm32f4/periph/spi.c b/cpu/stm32f4/periph/spi.c
index 1d59d630b71056fadf1d9f72cf48001bd8173648..2f7eb492675799f27ac5bc158abe18743506f4a4 100644
--- a/cpu/stm32f4/periph/spi.c
+++ b/cpu/stm32f4/periph/spi.c
@@ -350,66 +350,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    int trans_bytes = 0;
-
-    for (unsigned int i = 0; i < length; i++) {
-        char in_temp;
-        int trans_ret;
-
-        if (out) {
-            trans_ret = spi_transfer_byte(dev, out[i], &in_temp);
-        }
-        else {
-            trans_ret = spi_transfer_byte(dev, 0, &in_temp);
-        }
-
-        if (trans_ret < 0) {
-            return -1;
-        }
-
-        if (in != NULL) {
-            in[i] = in_temp;
-        }
-        trans_bytes++;
-    }
-
-    return trans_bytes++;
-}
-
-int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-    trans_ret = spi_transfer_byte(dev, out, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return 1;
-}
-
-int spi_transfer_regs(spi_t dev, uint8_t reg, char *out, char *in, unsigned int length)
-{
-    int trans_ret;
-
-    trans_ret = spi_transfer_byte(dev, reg, in);
-    if (trans_ret < 0) {
-        return -1;
-    }
-    trans_ret = spi_transfer_bytes(dev, out, in, length);
-    if (trans_ret < 0) {
-        return -1;
-    }
-
-    return trans_ret;
-}
-
 void spi_transmission_begin(spi_t dev, char reset_val)
 {
 
diff --git a/cpu/stm32l1/Makefile.include b/cpu/stm32l1/Makefile.include
index 99de28dcc7b1d26e43979d1aa7b539cc4dc573d6..14626ee605f76a221e505a6cc48e2902c1ee4fb0 100644
--- a/cpu/stm32l1/Makefile.include
+++ b/cpu/stm32l1/Makefile.include
@@ -3,4 +3,7 @@ export CPU_ARCH = cortex-m3
 # use hwtimer compatibility module
 USEMODULE += hwtimer_compat
 
+# use common periph functions
+USEMODULE += periph_common
+
 include $(RIOTCPU)/Makefile.include.cortexm_common
diff --git a/cpu/stm32l1/include/periph_cpu.h b/cpu/stm32l1/include/periph_cpu.h
index 218f1312f0fefc150fb6ffa5c77b2dffbdfedc9d..2d6e0a2c57396e5c2b985106efcbb611dc720e67 100644
--- a/cpu/stm32l1/include/periph_cpu.h
+++ b/cpu/stm32l1/include/periph_cpu.h
@@ -81,6 +81,15 @@ typedef enum {
     GPIO_AF14               /**< use alternate function 14 */
 } gpio_af_t;
 
+/**
+ * @brief declare needed generic SPI functions
+ * @{
+ */
+#define PERIPH_SPI_NEEDS_TRANSFER_BYTES
+#define PERIPH_SPI_NEEDS_TRANSFER_REG
+#define PERIPH_SPI_NEEDS_TRANSFER_REGS
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/stm32l1/periph/spi.c b/cpu/stm32l1/periph/spi.c
index f2544ec4be892e12257d46ae67aee720338d81fd..d767c0fbf1b070273df8d9f9d4a81273568b3a9f 100644
--- a/cpu/stm32l1/periph/spi.c
+++ b/cpu/stm32l1/periph/spi.c
@@ -218,38 +218,6 @@ int spi_transfer_byte(spi_t dev, char out, char *in)
     return 1;
 }
 
-int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
-{
-    char res;
-    int count = 0;
-
-    for (int i = 0; i < length; i++) {
-        if (out) {
-            count += spi_transfer_byte(dev, out[i], &res);
-        }
-        else {
-            count += spi_transfer_byte(dev, 0, &res);
-        }
-        if (in) {
-            in[i] = res;
-        }
-    }
-
-    return count;
-}
-
-int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
-{
-    spi_transfer_byte(dev, reg, 0);
-    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, 0);
-    return spi_transfer_bytes(dev, out, in, length);
-}
-
 void spi_transmission_begin(spi_t dev, char reset_val)
 {
     /* slave mode is not (yet) supported */
diff --git a/drivers/periph_common/Makefile b/drivers/periph_common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2
--- /dev/null
+++ b/drivers/periph_common/Makefile
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/drivers/periph_common/spi.c b/drivers/periph_common/spi.c
new file mode 100644
index 0000000000000000000000000000000000000000..88e9de5510bb6d2fb25ee26e6564f2860052cafd
--- /dev/null
+++ b/drivers/periph_common/spi.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * 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 drivers
+ * @{
+ *
+ * @file
+ * @brief       common SPI function fallback implementations
+ *
+ * @author      Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ * @}
+ */
+#include <stddef.h>
+
+#include "board.h"
+#include "cpu.h"
+#include "periph/spi.h"
+#include "periph_cpu.h"
+
+#if SPI_NUMOF
+
+#ifdef PERIPH_SPI_NEEDS_TRANSFER_BYTES
+int spi_transfer_bytes(spi_t dev, char *out, char *in, unsigned int length)
+{
+    int i, trans_ret, trans_bytes = 0;
+    char in_temp;
+
+    for (i = 0; i < length; i++) {
+        if (out != NULL) {
+            trans_ret = spi_transfer_byte(dev, out[i], &in_temp);
+        }
+        else {
+            trans_ret = spi_transfer_byte(dev, 0, &in_temp);
+        }
+        if (trans_ret < 0) {
+            return -1;
+        }
+        if (in != NULL) {
+            in[i] = in_temp;
+        }
+        trans_bytes++;
+    }
+
+    return trans_bytes++;
+}
+#endif
+
+#ifdef PERIPH_SPI_NEEDS_TRANSFER_REG
+int spi_transfer_reg(spi_t dev, uint8_t reg, char out, char *in)
+{
+    int trans_ret;
+
+    trans_ret = spi_transfer_byte(dev, reg, in);
+    if (trans_ret < 0) {
+        return -1;
+    }
+    trans_ret = spi_transfer_byte(dev, out, in);
+    if (trans_ret < 0) {
+        return -1;
+    }
+
+    return 1;
+}
+#endif
+
+#ifdef PERIPH_SPI_NEEDS_TRANSFER_REGS
+int spi_transfer_regs(spi_t dev, uint8_t reg, char *out, char *in, unsigned int length)
+{
+    int trans_ret;
+
+    trans_ret = spi_transfer_byte(dev, reg, in);
+    if (trans_ret < 0) {
+        return -1;
+    }
+    trans_ret = spi_transfer_bytes(dev, out, in, length);
+    if (trans_ret < 0) {
+        return -1;
+    }
+
+    return trans_ret;
+}
+#endif
+
+#endif /* SPI_NUMOF */