diff --git a/include/darwin_registers.h b/include/darwin_registers.h
index 4ed272219dcbf6ba48627d0819c094e06e040c92..c91a8321d5c29ef6ede370b25527631cfc9128af 100644
--- a/include/darwin_registers.h
+++ b/include/darwin_registers.h
@@ -272,8 +272,8 @@ typedef enum {
   DARWIN_IMU_ACCEL_Z_H             = 0x0149,
 
   DARWIN_MM_NUM_SERVOS             = 0x014A,
-  DARWIN_MM_CNTRL                  = 0x014B, //   bit 7  | bit 6 | bit 5 | bit 4 | bit 3 |     bit 2    |      bit 1      |    bit 0
-                                             // scanning |       |       |       |       | Enable power | Enable balance  | Enable manager
+  DARWIN_MM_CNTRL                  = 0x014B, //   bit 7  |   bit 6  |   bit 5  | bit 4 | bit 3 |     bit 2    |      bit 1      |    bit 0
+                                             // scanning | fwd fall | bwd fall |       |       | Enable power | Enable balance  | Enable manager
   DARWIN_MM_MODULE_EN0             = 0x014C, //      bit 7      | bit 6 | bit 5 | bit 4 |      bit 3      | bit 2 | bit 1 | bit 0i
                                              // Enable servo 0  |   assigned module     | Enable servo 1  |   assigned module
                                              //                 |     000 -> none       |
@@ -627,6 +627,8 @@ typedef enum {
 #define      MANAGER_EN_BAL          0x02
 #define      MANAGER_EN_PWR          0x04
 #define      MANAGER_SCANNING        0x80
+#define      MANAGER_FWD_FALL        0x40
+#define      MANAGER_BWD_FALL        0x20
 #define      MANAGER_EVEN_SER_EN     0x80
 #define      MANAGER_EVEN_SER_MOD    0x70
 #define      MANAGER_ODD_SER_EN      0x08
diff --git a/include/imu.h b/include/imu.h
index 079304bf1b235660acb081ab1186a926366633c0..f3e1c3d203ca0ebe27e7a82ba3c569d4d5cddb11 100755
--- a/include/imu.h
+++ b/include/imu.h
@@ -14,6 +14,7 @@ void imu_stop(void);
 void imu_set_calibration_samples(uint16_t num_samples);
 void imu_start_gyro_cal(void);
 void imu_get_gyro_data(int32_t *x, int32_t *y, int32_t *z);
+void imu_get_accel_data(int32_t *x, int32_t *y, int32_t *z);
 uint8_t imu_is_gyro_calibrated(void);
 // operation functions
 uint8_t imu_in_range(unsigned short int address,unsigned short int length);
diff --git a/include/motion_manager.h b/include/motion_manager.h
index 10f053f73afb1aeef86c1b705e4e2f68b0feb327..641c39d8debe1b66a42cb213e7f7faff44104e63 100755
--- a/include/motion_manager.h
+++ b/include/motion_manager.h
@@ -38,6 +38,10 @@ typedef enum {MM_NONE          = 0,
               MM_JOINTS        = 3,
               MM_HEAD          = 4} TModules;
 
+typedef enum {MM_FWD_FALL      =0,
+              MM_BWD_FALL      =1, 
+              MM_STANDING      =2} TFall;
+
 typedef struct
 {
   void (*process_fnct)(void);
@@ -86,6 +90,8 @@ inline void manager_disable(void);
 inline uint8_t manager_is_enabled(void);
 void manager_enable_balance(void);
 void manager_disable_balance(void);
+inline uint8_t manager_has_fallen(void);
+TFall manager_get_fallen_position(void);
 inline uint8_t manager_get_num_servos(void);
 void manager_set_module(uint8_t servo_id,TModules module);
 inline TModules manager_get_module(uint8_t servo_id);
diff --git a/src/imu.c b/src/imu.c
index 3d3f0478946591baac10d9cfa0017ce762f82be9..e7925854577a476426157709ec5289cfbf2d830c 100755
--- a/src/imu.c
+++ b/src/imu.c
@@ -31,11 +31,11 @@
 // accelerometer registers
 #define        ACCEL_ID               0x32
 #define        ACCEL_WHO_AM_I         0x0F
-#define        ACCEL_CNTRL_REG1        0x20
-#define        ACCEL_CNTRL_REG2        0x21
-#define        ACCEL_CNTRL_REG3        0x22
-#define        ACCEL_CNTRL_REG4        0x23
-#define        ACCEL_CNTRL_REG5        0x24
+#define        ACCEL_CNTRL_REG1       0x20
+#define        ACCEL_CNTRL_REG2       0x21
+#define        ACCEL_CNTRL_REG3       0x22
+#define        ACCEL_CNTRL_REG4       0x23
+#define        ACCEL_CNTRL_REG5       0x24
 #define        ACCEL_HP_FILTER_RESET  0x25
 #define        ACCEL_REFERENCE        0x26
 #define        ACCEL_STATUS_REG       0x27
@@ -58,11 +58,11 @@
 // gyroscope registers
 #define        GYRO_ID                0xD3
 #define        GYRO_WHO_AM_I          0x0F
-#define        GYRO_CNTRL_REG1         0x20
-#define        GYRO_CNTRL_REG2         0x21
-#define        GYRO_CNTRL_REG3         0x22
-#define        GYRO_CNTRL_REG4         0x23
-#define        GYRO_CNTRL_REG5         0x24
+#define        GYRO_CNTRL_REG1        0x20
+#define        GYRO_CNTRL_REG2        0x21
+#define        GYRO_CNTRL_REG3        0x22
+#define        GYRO_CNTRL_REG4        0x23
+#define        GYRO_CNTRL_REG5        0x24
 #define        GYRO_REFERENCE         0x25
 #define        GYRO_OUT_TEMP          0x26
 #define        GYRO_STATUS_REG        0x27
@@ -72,7 +72,7 @@
 #define        GYRO_OUT_Y_H           0x2B
 #define        GYRO_OUT_Z_L           0x2C
 #define        GYRO_OUT_Z_H           0x2D
-#define        GYRO_FIFO_CNTRL_REG     0x2E
+#define        GYRO_FIFO_CNTRL_REG    0x2E
 #define        GYRO_FIFO_SRC_REG      0x2F
 #define        GYRO_INT1_CFG          0x30
 #define        GYRO_INT1_SRC          0x31
@@ -110,6 +110,7 @@ uint16_t gyro_calibration_num_samples;
 const uint8_t accel_conf_reg=ACCEL_CNTRL_REG1;
 const uint8_t accel_conf_len=5;
 uint8_t accel_conf_data[5];
+int32_t accel_data[3];
 const uint8_t accel_data_reg=ACCEL_OUT_X_L;
 const uint8_t accel_data_len=6;
 
@@ -254,13 +255,12 @@ void imu_accel_get_data(void)
 void imu_accel_convert_data(uint8_t *data_in,uint8_t *data_out)
 {
   uint8_t i;
-  int16_t value;
 
   for(i=0;i<3;i++)
   {
-    value=(data_in[i*2]+(data_in[i*2+1]<<8));
-    data_out[i*2]=value%256;
-    data_out[i*2+1]=value/256;
+    accel_data[i]=(data_in[i*2]+(data_in[i*2+1]<<8));
+    data_out[i*2]=accel_data[i]%256;
+    data_out[i*2+1]=accel_data[i]/256;
   }
 }
 
@@ -603,6 +603,13 @@ void imu_get_gyro_data(int32_t *x, int32_t *y, int32_t *z)
   *z=gyro_data[2];
 }
 
+void imu_get_accel_data(int32_t *x, int32_t *y, int32_t *z)
+{
+  *x=accel_data[0];
+  *y=accel_data[1];
+  *z=accel_data[2];
+}
+
 // operation functions
 uint8_t imu_in_range(unsigned short int address,unsigned short int length)
 {
diff --git a/src/motion_manager.c b/src/motion_manager.c
index 6e7768ab975482d88278925b992ee9e3de973a64..b6bb218c0f2ca6f328eddaa2d5a5401b8bcd01d5 100755
--- a/src/motion_manager.c
+++ b/src/motion_manager.c
@@ -12,6 +12,7 @@
 #include "smart_charger.h"
 #include "dyn_battery.h"
 #include "gpio.h"
+#include <stdlib.h>
 
 #define MANAGER_TIMER                   TIM5
 #define ENABLE_MANAGER_TIMER_CLK        __HAL_RCC_TIM5_CLK_ENABLE()
@@ -132,6 +133,7 @@ void manager_balance(void)
 {
   uint32_t knee_gain,ankle_roll_gain,ankle_pitch_gain,hip_roll_gain;
   int32_t gyro_x,gyro_y,gyro_z;
+  int32_t accel_x,accel_y,accel_z;
 
   if(manager_balance_enabled==0x01)// balance is enabled
   {
@@ -152,6 +154,26 @@ void manager_balance(void)
     manager_balance_offset[R_ANKLE_ROLL]=((((int64_t)gyro_x*(int64_t)ankle_roll_gain)/12000)>>9);
     manager_balance_offset[L_ANKLE_ROLL]=((((int64_t)gyro_x*(int64_t)ankle_roll_gain)/12000)>>9);
   }
+  // fall detection (using accelerometer)
+  imu_get_accel_data(&accel_x,&accel_y,&accel_z);
+  if(abs(accel_y)>abs(accel_z))
+  {
+    if(accel_y>0)
+    {
+      ram_data[DARWIN_MM_CNTRL]&=~(MANAGER_FWD_FALL);
+      ram_data[DARWIN_MM_CNTRL]|=MANAGER_BWD_FALL;
+    }
+    else
+    {
+      ram_data[DARWIN_MM_CNTRL]&=~(MANAGER_BWD_FALL);
+      ram_data[DARWIN_MM_CNTRL]|=MANAGER_FWD_FALL;
+    }
+  }
+  else
+  {
+    ram_data[DARWIN_MM_CNTRL]&=~(MANAGER_FWD_FALL);
+    ram_data[DARWIN_MM_CNTRL]&=~(MANAGER_BWD_FALL);
+  }
 }
 
 // interrupt handlers
@@ -509,6 +531,24 @@ void manager_disable_balance(void)
   ram_data[DARWIN_MM_CNTRL]&=(~MANAGER_EN_BAL);
 }
 
+uint8_t manager_has_fallen(void)
+{
+  if(ram_data[DARWIN_MM_CNTRL]&(MANAGER_FWD_FALL|MANAGER_BWD_FALL))
+    return 0x01;
+  else
+    return 0x00;
+}
+
+TFall manager_get_fallen_position(void)
+{
+  if(ram_data[DARWIN_MM_CNTRL]&MANAGER_FWD_FALL)
+    return MM_FWD_FALL;
+  else if(ram_data[DARWIN_MM_CNTRL]&MANAGER_BWD_FALL)
+    return MM_BWD_FALL;
+  else
+    return MM_STANDING;
+}
+
 inline uint8_t manager_get_num_servos(void)
 {
   return manager_num_servos;