diff --git a/bootloaders/zero/Makefile b/bootloaders/zero/Makefile
index fed10e508b82dab2484345766d8ba18992f0a7d7..b02243be798773bf5c2f843fad7379de3eeaab95 100644
--- a/bootloaders/zero/Makefile
+++ b/bootloaders/zero/Makefile
@@ -86,6 +86,7 @@ LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbol
 SOURCES= \
   board_driver_i2c.c \
   board_driver_led.c \
+  board_driver_pmic.c \
   board_driver_serial.c \
   board_driver_usb.c \
   board_init.c \
diff --git a/bootloaders/zero/board_driver_i2c.c b/bootloaders/zero/board_driver_i2c.c
index d58d2b65ca27e4207e9f2c203eacff8fbba08774..e0d192313de21d80aa00364be4e770ce86bf6200 100644
--- a/bootloaders/zero/board_driver_i2c.c
+++ b/bootloaders/zero/board_driver_i2c.c
@@ -28,7 +28,7 @@
 #define I2C_SERCOM_APBCMASK   PM_APBCMASK_SERCOM0
 
 static uint8_t txBuffer[2];
-static uint8_t rxBuffer[1];
+uint8_t rxBuffer[1];
 static uint8_t txBufferLen = 0;
 static uint8_t rxBufferLen = 0;
 static uint8_t txAddress;
@@ -327,7 +327,7 @@ static inline bool sendDataMasterWIRE(uint8_t data)
     return true;
 }
 
-static inline void i2c_init(uint32_t baud) {
+void i2c_init(uint32_t baud) {
   //Master Mode
   initMasterWIRE(baud);
   enableWIRE();
@@ -336,7 +336,7 @@ static inline void i2c_init(uint32_t baud) {
   pin_set_peripheral_function(PINMUX_PA09C_SERCOM0_PAD1);
 }
 
-static inline void i2c_end() {
+void i2c_end() {
   disableWIRE();
 }
 
@@ -425,219 +425,4 @@ uint8_t i2c_write(uint8_t ucData)
   return 1 ;
 }
 
-uint8_t readRegister(uint8_t reg) {
-  i2c_beginTransmission(PMIC_ADDRESS);
-  i2c_write(reg);
-  i2c_endTransmission(true);
-
-  i2c_requestFrom(PMIC_ADDRESS, 1, true);
-  return rxBuffer[0];
-}
-
-uint8_t writeRegister(uint8_t reg, uint8_t data) {
-  i2c_beginTransmission(PMIC_ADDRESS);
-  i2c_write(reg);
-  i2c_write(data);
-  i2c_endTransmission(true);
-
-  return 2;
-}
-
-bool disableWatchdog(void) {
-
-    uint8_t DATA = readRegister(CHARGE_TIMER_CONTROL_REGISTER);
-    writeRegister(CHARGE_TIMER_CONTROL_REGISTER, (DATA & 0b11001110));
-    return 1;
-}
-
-bool setInputVoltageLimit(uint16_t voltage) {
-
-    uint8_t DATA = readRegister(INPUT_SOURCE_REGISTER);
-    uint8_t mask = DATA & 0b10000111;
-
-    switch(voltage) {
-
-        case 3880:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000000));
-        break;
-
-        case 3960:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00001000));
-        break;
-
-        case 4040:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00010000));
-        break;
-
-        case 4120:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00011000));
-        break;
-
-        case 4200:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00100000));
-        break;
-
-        case 4280:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00101000));
-        break;
-
-        case 4360:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00110000));
-        break;
-
-        case 4440:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00111000));
-        break;
-
-        case 4520:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01000000));
-        break;
-
-        case 4600:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01001000));
-        break;
-
-        case 4680:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01010000));
-        break;
-
-        case 4760:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01011000));
-        break;
-
-        case 4840:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01100000));
-        break;
-
-        case 4920:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01101000));
-        break;
-
-        case 5000:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01110000));
-        break;
-
-        case 5080:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01111000));
-        break;
-
-        default:
-        return 0; // return error since the value passed didn't match
-    }
-
-    return 1; // value was written successfully
-}
-
-bool setInputCurrentLimit(uint16_t current) {
-
-
-    uint8_t DATA = readRegister(INPUT_SOURCE_REGISTER);
-    uint8_t mask = DATA & 0b11111000;
-
-    switch (current) {
-
-        case 100:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000000));
-        break;
-
-        case 150:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000001));
-        break;
-
-        case 500:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000010));
-        break;
-
-        case 900:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000011));
-        break;
-
-        case 1200:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000100));
-        break;
-
-        case 1500:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000101));
-        break;
-
-        case 2000:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000110));
-        break;
-
-        case 3000:
-        writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000111));
-        break;
-
-        default:
-        return 0; // return error since the value passed didn't match
-    }
-
-    return 1; // value was written successfully
-}
-
-bool setChargeCurrent(bool bit7, bool bit6, bool bit5, bool bit4, bool bit3, bool bit2) {
-
-    uint8_t current = 0;
-    if (bit7) current = current | 0b10000000;
-    if (bit6) current = current | 0b01000000;
-    if (bit5) current = current | 0b00100000;
-    if (bit4) current = current | 0b00010000;
-    if (bit3) current = current | 0b00001000;
-    if (bit2) current = current | 0b00000100;
-
-    uint8_t DATA = readRegister(CHARGE_CURRENT_CONTROL_REGISTER);
-    uint8_t mask = DATA & 0b00000001;
-    writeRegister(CHARGE_CURRENT_CONTROL_REGISTER, current | mask);
-    return 1;
-}
-
-bool setChargeVoltage(uint16_t voltage) {
-
-    uint8_t DATA = readRegister(CHARGE_VOLTAGE_CONTROL_REGISTER);
-    uint8_t mask = DATA & 0b000000011;
-
-    switch (voltage) {
-
-        case 4112:
-        writeRegister(CHARGE_VOLTAGE_CONTROL_REGISTER, (mask | 0b10011000));
-        break;
-
-        case 4208:
-        writeRegister(CHARGE_VOLTAGE_CONTROL_REGISTER, (mask | 0b10110000));
-        break;
-
-        default:
-        return 0; // return error since the value passed didn't match
-    }
-
-    return 1; // value was written successfully
-}
-
-bool disableCharge()
-{
-  uint8_t DATA = readRegister(POWERON_CONFIG_REGISTER);
-  uint8_t mask = DATA & 0b11001111;
-
-  writeRegister(POWERON_CONFIG_REGISTER, mask);
-
-  return 1;
-}
-
-void apply_pmic_newdefaults()
-{
-  disableWatchdog();
-
-  //disableDPDM();
-  disableCharge();
-  setInputVoltageLimit(4360); // default
-  setInputCurrentLimit(900);     // 900mA
-  setChargeCurrent(0,0,0,0,0,0); // 512mA
-  setChargeVoltage(4112);        // 4.112V termination voltage
-}
-
-void configure_pmic() {
-  i2c_init(100000);
-  apply_pmic_newdefaults();
-}
-
-#endif
\ No newline at end of file
+#endif
diff --git a/bootloaders/zero/board_driver_i2c.h b/bootloaders/zero/board_driver_i2c.h
index b18698cbd2028bf9b500735a3d33882277c17333..f6b206fcce1c99c67d4c2b158b3ffdb17b03cbf2 100644
--- a/bootloaders/zero/board_driver_i2c.h
+++ b/bootloaders/zero/board_driver_i2c.h
@@ -24,22 +24,12 @@
 #include <stdbool.h>
 #include "board_definitions.h"
 
-//Default PMIC (BQ24195) I2C address
-#define PMIC_ADDRESS                        0x6B
-
-// Register address definitions
-#define INPUT_SOURCE_REGISTER               0x00
-#define POWERON_CONFIG_REGISTER             0x01
-#define CHARGE_CURRENT_CONTROL_REGISTER     0x02
-#define PRECHARGE_CURRENT_CONTROL_REGISTER  0x03
-#define CHARGE_VOLTAGE_CONTROL_REGISTER     0x04
-#define CHARGE_TIMER_CONTROL_REGISTER       0x05
-#define THERMAL_REG_CONTROL_REGISTER        0x06
-#define MISC_CONTROL_REGISTER               0x07
-#define SYSTEM_STATUS_REGISTER              0x08
-#define FAULT_REGISTER                      0x09
-#define PMIC_VERSION_REGISTER               0x0A
-
-void configure_pmic();
-
-#endif // _BOARD_DRIVER_LED_
+void i2c_init(uint32_t baud);
+void i2c_end();
+uint8_t i2c_requestFrom(uint8_t address, uint8_t quantity, bool stopBit);
+void i2c_beginTransmission(uint8_t address);
+uint8_t i2c_endTransmission(bool stopBit);
+uint8_t i2c_write(uint8_t ucData);
+
+
+#endif // _BOARD_DRIVER_I2C_
diff --git a/bootloaders/zero/board_driver_pmic.c b/bootloaders/zero/board_driver_pmic.c
new file mode 100644
index 0000000000000000000000000000000000000000..ffb8e1fee9ea5a1d2b6b8bd10c6e97885d2ab98c
--- /dev/null
+++ b/bootloaders/zero/board_driver_pmic.c
@@ -0,0 +1,238 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "board_driver_i2c.h"
+#include "board_driver_pmic.h"
+
+#ifdef CONFIGURE_PMIC
+
+extern uint8_t rxBuffer[1];
+
+uint8_t readRegister(uint8_t reg) {
+  i2c_beginTransmission(PMIC_ADDRESS);
+  i2c_write(reg);
+  i2c_endTransmission(true);
+
+  i2c_requestFrom(PMIC_ADDRESS, 1, true);
+  return rxBuffer[0];
+}
+
+uint8_t writeRegister(uint8_t reg, uint8_t data) {
+  i2c_beginTransmission(PMIC_ADDRESS);
+  i2c_write(reg);
+  i2c_write(data);
+  i2c_endTransmission(true);
+
+  return 2;
+}
+
+bool disableWatchdog(void) {
+  uint8_t DATA = readRegister(CHARGE_TIMER_CONTROL_REGISTER);
+  writeRegister(CHARGE_TIMER_CONTROL_REGISTER, (DATA & 0b11001110));
+  return 1;
+}
+
+bool setInputVoltageLimit(uint16_t voltage) {
+
+  uint8_t DATA = readRegister(INPUT_SOURCE_REGISTER);
+  uint8_t mask = DATA & 0b10000111;
+
+  switch(voltage) {
+
+    case 3880:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000000));
+      break;
+
+    case 3960:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00001000));
+      break;
+
+    case 4040:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00010000));
+      break;
+
+    case 4120:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00011000));
+      break;
+
+    case 4200:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00100000));
+      break;
+
+    case 4280:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00101000));
+      break;
+
+    case 4360:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00110000));
+      break;
+
+    case 4440:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00111000));
+      break;
+
+    case 4520:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01000000));
+      break;
+
+    case 4600:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01001000));
+      break;
+
+    case 4680:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01010000));
+      break;
+
+    case 4760:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01011000));
+      break;
+
+    case 4840:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01100000));
+      break;
+
+    case 4920:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01101000));
+      break;
+
+    case 5000:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01110000));
+      break;
+
+    case 5080:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b01111000));
+      break;
+
+    default:
+      return 0; // return error since the value passed didn't match
+  }
+
+  return 1; // value was written successfully
+}
+
+bool setInputCurrentLimit(uint16_t current) {
+  uint8_t DATA = readRegister(INPUT_SOURCE_REGISTER);
+  uint8_t mask = DATA & 0b11111000;
+
+  switch (current) {
+    case 100:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000000));
+      break;
+
+    case 150:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000001));
+      break;
+
+    case 500:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000010));
+      break;
+
+    case 900:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000011));
+      break;
+
+    case 1200:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000100));
+      break;
+
+    case 1500:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000101));
+      break;
+
+    case 2000:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000110));
+      break;
+
+    case 3000:
+      writeRegister(INPUT_SOURCE_REGISTER, (mask | 0b00000111));
+      break;
+
+    default:
+      return 0; // return error since the value passed didn't match
+  }
+
+  return 1; // value was written successfully
+}
+
+bool setChargeCurrent(bool bit7, bool bit6, bool bit5, bool bit4, bool bit3, bool bit2) {
+  uint8_t current = 0;
+  if (bit7) current = current | 0b10000000;
+  if (bit6) current = current | 0b01000000;
+  if (bit5) current = current | 0b00100000;
+  if (bit4) current = current | 0b00010000;
+  if (bit3) current = current | 0b00001000;
+  if (bit2) current = current | 0b00000100;
+
+  uint8_t DATA = readRegister(CHARGE_CURRENT_CONTROL_REGISTER);
+  uint8_t mask = DATA & 0b00000001;
+  writeRegister(CHARGE_CURRENT_CONTROL_REGISTER, current | mask);
+  return 1;
+}
+
+bool setChargeVoltage(uint16_t voltage) {
+
+  uint8_t DATA = readRegister(CHARGE_VOLTAGE_CONTROL_REGISTER);
+  uint8_t mask = DATA & 0b000000011;
+
+  switch (voltage) {
+
+    case 4112:
+      writeRegister(CHARGE_VOLTAGE_CONTROL_REGISTER, (mask | 0b10011000));
+      break;
+
+    case 4208:
+      writeRegister(CHARGE_VOLTAGE_CONTROL_REGISTER, (mask | 0b10110000));
+      break;
+
+    default:
+      return 0; // return error since the value passed didn't match
+  }
+
+  return 1; // value was written successfully
+}
+
+bool disableCharge()
+{
+  uint8_t DATA = readRegister(POWERON_CONFIG_REGISTER);
+  uint8_t mask = DATA & 0b11001111;
+
+  writeRegister(POWERON_CONFIG_REGISTER, mask);
+
+  return 1;
+}
+
+void apply_pmic_newdefaults()
+{
+  disableWatchdog();
+
+  //disableDPDM();
+  disableCharge();
+  setInputVoltageLimit(4360); // default
+  setInputCurrentLimit(900);     // 900mA
+  setChargeCurrent(0,0,0,0,0,0); // 512mA
+  setChargeVoltage(4112);        // 4.112V termination voltage
+}
+
+void configure_pmic()
+{
+  i2c_init(100000);
+  apply_pmic_newdefaults();
+}
+
+#endif
diff --git a/bootloaders/zero/board_driver_pmic.h b/bootloaders/zero/board_driver_pmic.h
new file mode 100644
index 0000000000000000000000000000000000000000..169b64d6a1a22a47d18532ffab3f4cad9d5875d3
--- /dev/null
+++ b/bootloaders/zero/board_driver_pmic.h
@@ -0,0 +1,45 @@
+/*
+  Copyright (c) 2015 Arduino LLC.  All right reserved.
+  Copyright (c) 2015 Atmel Corporation/Thibaut VIARD.  All right reserved.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _BOARD_DRIVER_PMIC_
+#define _BOARD_DRIVER_PMIC_
+
+#include <sam.h>
+#include <stdbool.h>
+#include "board_definitions.h"
+
+//Default PMIC (BQ24195) I2C address
+#define PMIC_ADDRESS                        0x6B
+
+// Register address definitions
+#define INPUT_SOURCE_REGISTER               0x00
+#define POWERON_CONFIG_REGISTER             0x01
+#define CHARGE_CURRENT_CONTROL_REGISTER     0x02
+#define PRECHARGE_CURRENT_CONTROL_REGISTER  0x03
+#define CHARGE_VOLTAGE_CONTROL_REGISTER     0x04
+#define CHARGE_TIMER_CONTROL_REGISTER       0x05
+#define THERMAL_REG_CONTROL_REGISTER        0x06
+#define MISC_CONTROL_REGISTER               0x07
+#define SYSTEM_STATUS_REGISTER              0x08
+#define FAULT_REGISTER                      0x09
+#define PMIC_VERSION_REGISTER               0x0A
+
+void configure_pmic();
+
+#endif // _BOARD_DRIVER_PMIC_