diff --git a/Makefile b/Makefile
index c448792639103ebb9b6d61828c9f1ce867092dce..b40c7b58328c9719c15036efcb108742f6729c8e 100755
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,13 @@ TARGET_FILES+=src/imu.c
 TARGET_FILES+=src/darwin_dyn_slave.c
 TARGET_FILES+=src/darwin_dyn_master.c
 TARGET_FILES+=src/stm32f1xx_hal_msp.c
+TARGET_FILES+=src/motion_manager.c
+TARGET_FILES+=src/action.c
+TARGET_FILES+=src/motion_pages.c
+TARGET_FILES+=src/walking.c
+TARGET_FILES+=src/darwin_math.c
+TARGET_FILES+=src/darwin_kinematics.c
+
 TARGET_PROCESSOR=STM32F103RE
 
 HAL_PATH=../../STM32_processor/hal/f1
@@ -95,7 +102,7 @@ $(BUILD_PATH)/%.o: $(USART_PATH)/src/%.c
 	$(CC) -c $(CFLAGS) -o $@ $<
 
 $(MAIN_OUT_ELF): mkdir_build $(DARWIN_OBJS) $(BUID_PATH)/$(STARTUP_FILE:.s=.o) 
-	$(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(EXT_LIB) --output $@
+	$(LD) $(LDFLAGS) $(DARWIN_OBJS) $(BUILD_PATH)/$(STARTUP_FILE:.s=.o) $(EXT_LIB) -lm --output $@
 
 $(MAIN_OUT_HEX): $(MAIN_OUT_ELF)	
 	$(OBJCP) $(OBJCPFLAGS_HEX) $< $@
diff --git a/include/action.h b/include/action.h
index afaa86108ce32495aee2d520c819f092ff71221e..98626f1bbc5bd44544809bb9a1e6b935ecdd1e55 100755
--- a/include/action.h
+++ b/include/action.h
@@ -1,18 +1,34 @@
 #ifndef _ACTION_H
 #define _ACTION_H
 
-#include "stm32f10x.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
+#include "motion_pages.h"
 
 // public functions
-void action_init(uint16_t period);
-inline void action_set_period(uint16_t period);
+void action_init(uint16_t period_us);
+inline void action_set_period(uint16_t period_us);
 inline uint16_t action_get_period(void);
 uint8_t action_load_page(uint8_t page_id);
 void action_start_page(void);
 void action_stop_page(void);
 uint8_t action_is_running(void);
-
+uint8_t action_get_current_page(void);
+uint8_t action_get_current_step(void);
+void action_enable_int(void);
+void action_disable_int(void);
+uint8_t action_is_int_enabled(void);
+// operation functions
+uint8_t action_in_range(unsigned short int address, unsigned short int length);
+void action_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data);
 // motion manager interface
 void action_process(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/include/action_id.h b/include/action_id.h
new file mode 100644
index 0000000000000000000000000000000000000000..10c36280ec7962672eb397fab14b03b0e67b370f
--- /dev/null
+++ b/include/action_id.h
@@ -0,0 +1,148 @@
+#ifndef _ACTION_ID_H
+#define _ACTION_ID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define     BOW               1
+#define     BRAVO             2
+#define     RAP_CHEST         5
+#define     SCRATCH_HEAD      8
+#define     HAND_STANDING     11
+#define     R_BLOCKING        14
+#define     L_BLOCKING        16
+#define     L_KICK            18
+#define     R_KICK            19
+#define     R_ATTACK          20
+#define     L_ATTACK          21
+#define     F_ATTACK          22
+#define     DEFENCE           23
+#define     SIT_DOWN          25
+#define     STAND_UP          26
+#define     F_GET_UP          27
+#define     B_GET_UP          28
+#define     CLAP_READY        29
+#define     CLAPPING          30
+#define     WALK_READY        31
+/* forward step */
+#define     F_S_L             32
+#define     F_S_R             34
+#define     F_M_L             36
+#define     F_M_R             38
+#define     F_E_L             40
+#define     F_E_R             42
+/* backward step */
+#define     B_S_L             44
+#define     B_S_R             46
+#define     B_M_L             48
+#define     B_M_R             50
+#define     B_E_L             52
+#define     B_E_R             54
+/* left turn step */
+#define     LT_S_L            56
+#define     LT_S_R            58
+#define     LT_M_L            60
+#define     LT_M_R            62
+#define     LT_E_L            64
+#define     LT_E_R            66
+/* right turn step */
+#define     RT_S_L            68
+#define     RT_S_R            70
+#define     RT_M_L            72
+#define     RT_M_R            74
+#define     RT_E_L            76
+#define     RT_E_R            78
+/* left step */
+#define     L_S_L             80
+#define     L_S_R             82
+#define     L_M_L             84
+#define     L_M_R             86
+#define     L_E_L             88
+#define     L_E_R             90
+/* right step */
+#define     R_S_L             92
+#define     R_S_R             94
+#define     R_M_L             96
+#define     R_M_R             98
+#define     R_E_L             100
+#define     R_E_R             102
+/* forward left turn step */
+#define     FLT_S_L           104
+#define     FLT_S_R           106
+#define     FLT_M_L           108
+#define     FLT_M_R           110
+#define     FLT_E_L           112
+#define     FLT_E_R           114
+/* forward right turn step */
+#define     FRT_S_L           116
+#define     FRT_S_R           118
+#define     FRT_M_L           120
+#define     FRT_M_R           122
+#define     FRT_E_L           124
+#define     FRT_E_R           126
+/* backward left turn step */
+#define     BLT_S_L           128
+#define     BLT_S_R           130
+#define     BLT_M_L           132
+#define     BLT_M_R           134
+#define     BLT_E_L           136
+#define     BLT_E_R           138
+/* backward right turn step */
+#define     BRT_S_L           140
+#define     BRT_S_R           142
+#define     BRT_M_L           144
+#define     BRT_M_R           146
+#define     BRT_E_L           148
+#define     BRT_E_R           150
+/* left turn A??? step */
+#define     LTA_S_L           152
+#define     LTA_S_R           154
+#define     LTA_M_L           156
+#define     LTA_M_R           158
+#define     LTA_E_L           160
+#define     LTA_E_R           162
+/* right turn A?? step */
+#define     RTA_S_L           164
+#define     RTA_S_R           166
+#define     RTA_M_L           168
+#define     RTA_M_R           170
+#define     RTA_E_L           172
+#define     RTA_E_R           174
+/* forward left step */
+#define     FL_S_L            176
+#define     FL_S_R            178
+#define     FL_M_L            180
+#define     FL_M_R            182
+#define     FL_E_L            184
+#define     FL_E_R            186
+/* forward right step */
+#define     FR_S_L            188
+#define     FR_S_R            190
+#define     FR_M_L            192
+#define     FR_M_R            194
+#define     FR_E_L            196
+#define     FR_E_R            198
+/* backward left step */
+#define     BL_S_L            200
+#define     BL_S_R            202
+#define     BL_M_L            204
+#define     BL_M_R            206
+#define     BL_E_L            208
+#define     BL_E_R            210
+/* backward right step */
+#define     BR_S_L            212
+#define     BR_S_R            214
+#define     BR_M_L            216
+#define     BR_M_R            218
+#define     BR_E_L            220
+#define     BR_E_R            222
+
+#define     BALANCE           224
+#define     CLAP_END          225
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
diff --git a/include/darwin_dyn_master.h b/include/darwin_dyn_master.h
index 47f387a0fc9f10f2c926cdb6d3fc5ab8f1b43ddf..8031f12a3c6a3b3ec81f4cea5d40c54a19bdcfab 100644
--- a/include/darwin_dyn_master.h
+++ b/include/darwin_dyn_master.h
@@ -1,8 +1,11 @@
 #ifndef _DARWIN_DYN_MASTER_H
 #define _DARWIN_DYN_MASTER_H
 
-#include "stm32f1xx_hal.h"
-#include "stm32_time.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
 #include "comm.h"
 #include "dynamixel_master.h"
 
@@ -12,5 +15,9 @@ void darwin_dyn_master_init(void);
 inline void darwin_dyn_master_enable_power(void);
 inline void darwin_dyn_master_disable_power(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 
diff --git a/include/darwin_kinematics.h b/include/darwin_kinematics.h
index 40c2dabe808bff6ce3ddb4b82f591f49488d8b7d..7f67ffa092131a028b2f3ca17c120f1c7bb24d2e 100755
--- a/include/darwin_kinematics.h
+++ b/include/darwin_kinematics.h
@@ -1,15 +1,25 @@
 #ifndef _DARWIN_KINEMATICS_H
 #define _DARWIN_KINEMATICS_H
 
-#include "stm32f10x.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
 
-extern const float LEG_SIDE_OFFSET; //mm
-extern const float THIGH_LENGTH; //mm
-extern const float CALF_LENGTH; //mm
-extern const float ANKLE_LENGTH; //mm
-extern const float LEG_LENGTH; //mm (THIGH_LENGTH + CALF_LENGTH + ANKLE_LENGTH)
+#define DARWIN_PELVIS_LENGTH               29.0 //mm
+#define DARWIN_LEG_SIDE_OFFSET             37.0 //mm
+#define DARWIN_THIGH_LENGTH                93.0 //mm
+#define DARWIN_CALF_LENGTH                 93.0 //mm
+#define DARWIN_PITCH_OFFSET                0.1910 //rad
+#define DARWIN_ANKLE_LENGTH                33.5 //mm
+#define DARWIN_LEG_LENGTH                  (DARWIN_THIGH_LENGTH + DARWIN_CALF_LENGTH + DARWIN_ANKLE_LENGTH) //mm (THIGH_LENGTH + CALF_LENGTH + ANKLE_LENGTH)
 
 // public functions
-uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float c);
+uint8_t darwin_leg_ik(float *out, float x, float y, float z, float a, float b, float c);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/include/darwin_math.h b/include/darwin_math.h
index 6fd0f81afa2ad7ff0a408fcb4b8c2d41537c965d..82ef927c3d8c6a225cfe6c18086c37e10ea5d4a6 100755
--- a/include/darwin_math.h
+++ b/include/darwin_math.h
@@ -1,8 +1,11 @@
 #ifndef _DARWIN_MATH_H
 #define _DARWIN_MATH_H
 
-#include "stm32f10x.h"
-#include <math.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
 
 #define   PI    3.14159
 
@@ -60,4 +63,8 @@ uint8_t matrix3d_inverse(TMatrix3D *org, TMatrix3D *inv);
 void matrix3d_set_transform(TMatrix3D *matrix, TPoint3D *point, TVector3D *vector);
 void matrix3d_mult(TMatrix3D *dst,TMatrix3D *a,TMatrix3D *b);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/include/darwin_registers.h b/include/darwin_registers.h
index 3a579afe35a99f43d5dc7118db5ec11027c3fc1f..a9b994e3cd5ba18ac01f6612fffebf927098724e 100644
--- a/include/darwin_registers.h
+++ b/include/darwin_registers.h
@@ -331,22 +331,14 @@ typedef enum {
   DARWIN_MM_SERVO31_CUR_POS_L      = 0x0178, // angle in fixed point format 9|7
   DARWIN_MM_SERVO31_CUR_POS_H      = 0x0179,
   DARWIN_ACTION_PAGE               = 0x017A,
-  DARWIN_ACTION_CNTRL              = 0x017B, // bit 7 | bit 6 | bit 5 |     bit 4    |     bit 3      |       bit 2      |   bit 1   |   bit 0
-                                             //       |       |       | page running | interrupt flag | enable interrupt | stop page | start page
-  DARWIN_GYRO_CNTRL                = 0x017C, // bit 7 | bit 6 | bit 5 | bit 4 |     bit 3       |       bit 2     |         bit 1        |   bit 0
-                                             //       |       |       |       | enable fall int | enable fall det | enable calibrate int | calibrate
-  DARWIN_GYRO_STATUS               = 0x017D, // bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
-                                             // 
-  DARWIN_GYRO_FWD_FALL_THD         = 0x017E,
-  DARWIN_GYRO_BWD_FALL_THD         = 0x017F,
-  DARWIN_GYRO_LEFT_FALL_THD        = 0x0180,
-  DARWIN_GYRO_RIGHT_FALL_THD       = 0x0181,
-  DARWIN_WALK_CNTRL                = 0x0182, // bit 7 | bit 6 | bit 5 |  bit 4  | bit 3 | bit 2 |     bit 1    |    bit 0
+  DARWIN_ACTION_CNTRL              = 0x017B, // bit 7 | bit 6 | bit 5 |     bit 4    | bit 3 | bit 2 |   bit 1   |   bit 0
+                                             //       |       |       | page running |       |       | stop page | start page
+  DARWIN_WALK_CNTRL                = 0x017C, // bit 7 | bit 6 | bit 5 |  bit 4  | bit 3 | bit 2 |     bit 1    |    bit 0
                                              // current phase           walking                   stop walking   start walking
-  DARWIN_WALK_STEP_FW_BW           = 0x0183,
-  DARWIN_WALK_STEP_LEFT_RIGHT      = 0x0184,
-  DARWIN_WALK_STEP_DIRECTION       = 0x0185
-} bioloid_registers;
+  DARWIN_WALK_STEP_FW_BW           = 0x017D,
+  DARWIN_WALK_STEP_LEFT_RIGHT      = 0x017E,
+  DARWIN_WALK_STEP_DIRECTION       = 0x017F
+} darwin_registers;
 
 #define      GPIO_BASE_ADDRESS       0x0100
 #define      GPIO_MEM_LENGTH         23
diff --git a/include/motion_manager.h b/include/motion_manager.h
index 0d6c86fee6bc0b32ac3de4635d26007d11063a61..04caa19e1c496f5fe60de50f61349fdbeec819ce 100755
--- a/include/motion_manager.h
+++ b/include/motion_manager.h
@@ -1,19 +1,13 @@
 #ifndef _MOTION_MANAGER_H
 #define _MOTION_MANAGER_H
 
-#include "stm32f10x.h"
-
-#define         MANAGER_MAX_NUM_SERVOS          31
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-typedef enum{MM_NONE          = 0,
-             MM_ACTION        = 1,
-             MM_WALKING       = 2,
-             MM_JOINTS        = 3,
-             MM_HEAD          = 4,
-             MM_GRIPPER       = 5} TModules;
+#include "stm32f1xx.h"
 
-// default joint identifiers
-enum{
+typedef enum {
   R_SHOULDER_PITCH     = 1,
   L_SHOULDER_PITCH     = 2,
   R_SHOULDER_ROLL      = 3,
@@ -32,13 +26,23 @@ enum{
   L_ANKLE_PITCH        = 16,
   R_ANKLE_ROLL         = 17,
   L_ANKLE_ROLL         = 18,
-  HEAD_PAN             = 19,
-  HEAD_TILT            = 20,
-  R_WRIST              = 23,
-  L_WRIST              = 22,
-  R_GRIPPER            = 21,
-  L_GRIPPER            = 24
-};
+  L_PAN                = 19,
+  L_TILT               = 20} servo_id_t;
+
+
+typedef enum {MM_NONE          = 0,
+              MM_ACTION        = 1,
+              MM_WALKING       = 2,
+              MM_JOINTS        = 3} TModules;
+
+typedef struct
+{
+  void (*process_fnct)(void);
+  void (*init_fnct)(void);
+  uint8_t name[16];
+}TMotionModule;
+
+#define MAX_MOTION_MODULES              8
 
 // servo information structure
 typedef struct{
@@ -50,6 +54,8 @@ typedef struct{
   uint16_t center_angle;
   uint16_t max_speed;
   int16_t current_angle;
+  uint8_t cw_comp;
+  uint8_t ccw_comp;
   uint16_t current_value;
   TModules module;
   uint8_t enabled;
@@ -58,12 +64,16 @@ typedef struct{
   uint8_t dyn_version;
 }TServoInfo;
 
+#define MANAGER_MAX_NUM_SERVOS          31
+
 // public variables
-extern int64_t current_angles[MANAGER_MAX_NUM_SERVOS];
+extern int64_t manager_current_angles[MANAGER_MAX_NUM_SERVOS];
+extern int8_t manager_current_slopes[MANAGER_MAX_NUM_SERVOS];
 
 // public functions
 void manager_init(uint16_t period_us);
 inline uint16_t manager_get_period(void);
+inline uint16_t manager_get_period_us(void);
 inline void manager_set_period(uint16_t period_us);
 inline void manager_enable(void);
 inline void manager_disable(void);
@@ -71,18 +81,21 @@ inline uint8_t manager_is_enabled(void);
 void manager_enable_balance(void);
 void manager_disable_balance(void);
 inline uint8_t manager_get_num_servos(void);
-inline void manager_set_module(uint8_t servo_id,TModules module);
+void manager_set_module(uint8_t servo_id,TModules module);
 inline TModules manager_get_module(uint8_t servo_id);
 inline void manager_enable_servo(uint8_t servo_id);
 inline void manager_disable_servo(uint8_t servo_id);
-void manager_disable_servos(void);
 inline uint8_t manager_is_servo_enabled(uint8_t servo_id);
+void manager_set_offset(uint8_t servo_id,int8_t offset);
 inline int16_t manager_get_cw_angle_limit(uint8_t servo_id);
 inline int16_t manager_get_ccw_angle_limit(uint8_t servo_id);
-void manager_set_knee_gain(uint8_t gain);
-void manager_set_ankle_pitch_gain(uint8_t gain);
-void manager_set_hip_roll_gain(uint8_t gain);
-void manager_set_ankle_roll_gain(uint8_t gain);
-uint8_t manager_get_dyn_version(uint8_t servo_id);
+// motion modules handling
+// operation functions
+uint8_t manager_in_range(unsigned short int address, unsigned short int length);
+void manager_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/include/motion_pages.h b/include/motion_pages.h
index 5d3f3fea6f051266bda506fceefd68c115963d88..b4530de6acd85223c6c8763ca0786b75338b113a 100755
--- a/include/motion_pages.h
+++ b/include/motion_pages.h
@@ -1,7 +1,11 @@
 #ifndef _MOTION_PAGES_H
 #define _MOTION_PAGES_H
 
-#include "stm32f10x.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
 
 #define MAX_PAGES                     256 
 #define PAGE_MAX_NUM_SERVOS           31
@@ -48,4 +52,8 @@ uint8_t pages_check_checksum(TPage *page);
 void pages_clear_page(TPage *page);
 void pages_copy_page(TPage *src,TPage *dst);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/include/walking.h b/include/walking.h
index da933a5efbd30306b01a35ca7e868b4c01d75b6d..4e0975562df333d8a93448f32ea4aadc18299535 100755
--- a/include/walking.h
+++ b/include/walking.h
@@ -1,18 +1,30 @@
 #ifndef _WALKING_H
 #define _WALKING_H
 
-#include "stm32f10x.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "stm32f1xx.h"
+#include "motion_manager.h"
 
 // public functions
-void walking_init(uint16_t period);
-inline void walking_set_period(uint16_t period);
+void walking_init(uint16_t period_us);
+inline void walking_set_period(uint16_t period_us);
 inline uint16_t walking_get_period(void);
-void walking_set_param(uint8_t param_id,int8_t param_value);
 void walking_start(void);
 void walking_stop(void);
 uint8_t is_walking(void);
 
+// operation functions
+uint8_t walking_in_range(unsigned short int address, unsigned short int length);
+void walking_process_read_cmd(unsigned short int address,unsigned short int length,unsigned char *data);
+void walking_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data);
 // motion manager interface functions
 void walking_process(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/src/action.c b/src/action.c
index 67ff5ba94832bf05191203d3cb5495eec66b18f2..b7e2c653799b90a2cfccf940a0b62fa5d7514705 100755
--- a/src/action.c
+++ b/src/action.c
@@ -12,6 +12,7 @@ typedef enum {ACTION_PRE,ACTION_MAIN,ACTION_POST,ACTION_PAUSE} action_states;
 TPage action_next_page;
 TPage action_current_page;
 uint8_t action_current_step_index;
+uint8_t action_current_page_index;
 // angle variables
 int64_t action_moving_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
 int64_t action_start_angles[PAGE_MAX_NUM_SERVOS];// fixed point 48|16 format
@@ -32,12 +33,12 @@ int64_t action_pause_time;// fixed point 48|16 format
 int64_t action_current_time;// fixed point 48|16 format
 int64_t action_section_time;// fixed point 48|16 format
 int64_t action_period;
+int16_t action_period_us;
 
 // private functions
 void action_load_next_step(void)
 {
   // page and step information
-  static uint8_t current_index=0;
   static int8_t num_repetitions=0;
   // angle variables
   int16_t next_angle;// information from the flash memory (fixed point 9|7 format)
@@ -68,7 +69,7 @@ void action_load_next_step(void)
       {
         num_repetitions--;
         if(num_repetitions>0)
-          action_next_index=current_index;
+          action_next_index=action_current_page_index;
         else
           action_next_index=action_current_page.header.next;
       }
@@ -76,9 +77,10 @@ void action_load_next_step(void)
         action_end=0x01;
       else
       {
-        if(action_next_index!=current_index)
+        if(action_next_index!=action_current_page_index)
         {
           pages_get_page(action_next_index,&action_next_page);
+          ram_data[DARWIN_ACTION_PAGE]=action_next_index;
           if(!pages_check_checksum(&action_next_page))
             action_end=0x01;
         }
@@ -87,10 +89,10 @@ void action_load_next_step(void)
       }
     }
     pages_copy_page(&action_next_page,&action_current_page);// make the next page active
-    if(current_index!=action_next_index)
+    if(action_current_page_index!=action_next_index)
       num_repetitions=action_current_page.header.repeat;
     action_current_step_index=0;
-    current_index=action_next_index;
+    action_current_page_index=action_next_index;
   }
   else if(action_current_step_index==action_current_page.header.stepnum-1)// it is the last step
   {
@@ -100,7 +102,7 @@ void action_load_next_step(void)
     {
       num_repetitions--;
       if(num_repetitions>0)
-        action_next_index=current_index;
+        action_next_index=action_current_page_index;
       else
         action_next_index=action_current_page.header.next;
     }
@@ -108,9 +110,10 @@ void action_load_next_step(void)
       action_end=0x01;
     else
     {
-      if(action_next_index!=current_index)
+      if(action_next_index!=action_current_page_index)
       {
         pages_get_page(action_next_index,&action_next_page);
+        ram_data[DARWIN_ACTION_PAGE]=action_next_index;
         if(!pages_check_checksum(&action_next_page))
           action_end=0x01;
       }
@@ -119,8 +122,10 @@ void action_load_next_step(void)
     }
   }
   // compute trajectory
-  action_pause_time=((action_current_page.steps[action_current_step_index].pause<<14)/action_current_page.header.speed);
-  action_step_time=((action_current_page.steps[action_current_step_index].time<<14)/action_current_page.header.speed);
+  action_pause_time=(action_current_page.steps[action_current_step_index].pause*action_current_page.header.speed)>>5;
+  action_pause_time=action_pause_time<<9;
+  action_step_time=(action_current_page.steps[action_current_step_index].time*action_current_page.header.speed)>>5;
+  action_step_time=action_step_time<<9;
   if(action_step_time<action_period)
     action_step_time=action_period;// 0.078 in 16|16 format
   max_angle=0;
@@ -130,10 +135,10 @@ void action_load_next_step(void)
     {
       angle=action_current_page.steps[action_current_step_index].position[i];
       if(angle==0x5A00)// bigger than 180
-        target_angles=current_angles[i];
+        target_angles=manager_current_angles[i];
       else
         target_angles=angle<<9;
-      action_moving_angles[i]=target_angles-current_angles[i];
+      action_moving_angles[i]=target_angles-manager_current_angles[i];
       if(action_end)
         next_angles=target_angles;
       else
@@ -148,8 +153,8 @@ void action_load_next_step(void)
           next_angles=next_angle<<9;
       }
       // check changes in direction
-      if(((current_angles[i] < target_angles) && (target_angles < next_angles)) ||
-         ((current_angles[i] > target_angles) && (target_angles > next_angles)))
+      if(((manager_current_angles[i] < target_angles) && (target_angles < next_angles)) ||
+         ((manager_current_angles[i] > target_angles) && (target_angles > next_angles)))
         dir_change=0x00;
       else
         dir_change=0x01;
@@ -169,6 +174,7 @@ void action_load_next_step(void)
         if(tmp_angle>max_angle)
           max_angle=tmp_angle;
       }
+      manager_current_slopes[i]=action_current_page.header.slope[i];
     }
   }
   if(action_current_page.header.schedule==SPEED_BASE_SCHEDULE)
@@ -213,17 +219,29 @@ void action_load_next_step(void)
   }
 }
 
+void action_finish(void)
+{
+  // set the internal state machine to the idle state
+  action_end=0x00;
+  // clear the status falg for the action module
+  ram_data[DARWIN_ACTION_CNTRL]&=(~ACTION_STATUS);
+  // set the interrupt falg for the action module
+  ram_data[DARWIN_ACTION_CNTRL]|=ACTION_INT_FLAG;
+  // change the internal state 
+  action_running=0x00;
+}
+
 // public functions
-void action_init(uint16_t period)
+void action_init(uint16_t period_us)
 {
   unsigned char i;
 
-  // init current_angles with the current position of the servos
+  // init manager_current_angles with the current position of the servos
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
   {
     // angle variables
     action_moving_angles[i]=0;// fixed point 48|16 format
-    action_start_angles[i]=current_angles[i];
+    action_start_angles[i]=manager_current_angles[i];
     // speed variables
     action_start_speed[i]=0;// fixed point 48|16 format
     action_main_speed[i]=0;// fixed point 48|16 format
@@ -233,6 +251,8 @@ void action_init(uint16_t period)
   // clear the contents of the next page
   pages_clear_page(&action_next_page);
   pages_clear_page(&action_current_page);
+  action_current_page_index=0;
+  action_current_step_index=-1;
   // control variables
   action_end=0x00;
   action_stop=0x00;
@@ -247,17 +267,19 @@ void action_init(uint16_t period)
   action_current_time=0;// fixed point 48|16 format
   action_section_time=0;// fixed point 48|16 format
 
-  action_period=period;
+  action_period=(period_us<<16)/1000000;
+  action_period_us=period_us;
 }
 
-inline void action_set_period(uint16_t period)
+inline void action_set_period(uint16_t period_us)
 {
-  action_period=period;
+  action_period=(period_us<<16)/1000000;
+  action_period_us=period_us;
 }
 
 inline uint16_t action_get_period(void)
 {
-  return action_period;
+  return action_period_us;
 }
 
 uint8_t action_load_page(uint8_t page_id)
@@ -271,7 +293,7 @@ uint8_t action_load_page(uint8_t page_id)
     return 0x00;
   if(!pages_check_checksum(&action_next_page))
     return 0x00;
-  ram_write_byte(DARWIN_ACTION_PAGE,page_id);
+  ram_data[DARWIN_ACTION_PAGE]=page_id;
 
   return 0x01;
 }
@@ -281,20 +303,20 @@ void action_start_page(void)
   uint8_t i;
 
   for(i=0;i<PAGE_MAX_NUM_SERVOS;i++)
-    action_start_angles[i]=current_angles[i];
+    action_start_angles[i]=manager_current_angles[i];
   action_stop=0x00;
   action_current_time=0;
   action_section_time=0; 
   action_current_step_index=-1;
-  ram_set_bit(DARWIN_ACTION_STATUS,0);
+  ram_data[DARWIN_ACTION_CNTRL]|=ACTION_STATUS;
+  /* clear the interrupt flag */
+  ram_data[DARWIN_ACTION_CNTRL]&=(~ACTION_INT_FLAG);
   action_running=0x01;
-  ram_set_bit(DARWIN_ACTION_CONTROL,0); 
 }
 
 void action_stop_page(void)
 {
   action_stop=0x01;
-  ram_set_bit(DARWIN_ACTION_CONTROL,1); 
 }
 
 uint8_t action_is_running(void)
@@ -302,6 +324,34 @@ uint8_t action_is_running(void)
   return action_running;
 }
 
+uint8_t action_get_current_page(void)
+{
+  return action_current_page_index;
+}
+
+uint8_t action_get_current_step(void)
+{
+  return action_current_step_index;
+}
+
+void action_enable_int(void)
+{
+  ram_data[DARWIN_ACTION_CNTRL]|=ACTION_INT_EN;
+}
+
+void action_disable_int(void)
+{
+  ram_data[DARWIN_ACTION_CNTRL]&=(~ACTION_INT_EN);
+}
+
+uint8_t action_is_int_enabled(void)
+{
+  if(ram_data[DARWIN_ACTION_CNTRL]&ACTION_INT_EN)
+    return 0x01;
+  else
+    return 0x00;
+}
+
 // motion manager interface
 void action_process(void)
 {
@@ -330,7 +380,7 @@ void action_process(void)
                              delta_speed=(action_main_speed[i]-action_start_speed[i]);
                              current_speed[i]=action_start_speed[i]+delta_speed;
                              accel_angles[i]=(action_start_speed[i]*action_section_time+((delta_speed*action_section_time)>>1))>>16;
-                             current_angles[i]=action_start_angles[i]+accel_angles[i];
+                             manager_current_angles[i]=action_start_angles[i]+accel_angles[i];
                              /* update of the state */
                              if(!action_zero_speed_finish[i])
                              {
@@ -338,15 +388,15 @@ void action_process(void)
                                  main_angles[i]=0;
                                else
                                  main_angles[i]=((action_moving_angles[i]-accel_angles[i])*(action_step_time-(action_pre_time<<1)))/(action_step_time-action_pre_time);
-                               action_start_angles[i]=current_angles[i];
+                               action_start_angles[i]=manager_current_angles[i];
                              }
                              else
                              {
                                main_angles[i]=action_moving_angles[i]-accel_angles[i]-(((action_main_speed[i]*action_pre_time)>>1)>>16);
-                               action_start_angles[i]=current_angles[i];
+                               action_start_angles[i]=manager_current_angles[i];
                              }
                              /* the first step of the main section */
-                             current_angles[i]=action_start_angles[i]+(main_angles[i]*(action_current_time-action_section_time))/(action_step_time-(action_pre_time<<1));
+                             manager_current_angles[i]=action_start_angles[i]+(main_angles[i]*(action_current_time-action_section_time))/(action_step_time-(action_pre_time<<1));
                              current_speed[i]=action_main_speed[i];
                            }
                          }
@@ -363,7 +413,7 @@ void action_process(void)
                              delta_speed=((action_main_speed[i]-action_start_speed[i])*action_current_time)/action_section_time;
                              current_speed[i]=action_start_speed[i]+delta_speed;
                              accel_angles[i]=((action_start_speed[i]*action_current_time)+((delta_speed*action_current_time)>>1))>>16;
-                             current_angles[i]=action_start_angles[i]+accel_angles[i];
+                             manager_current_angles[i]=action_start_angles[i]+accel_angles[i];
                            }
                          }
                          state=ACTION_PRE;
@@ -376,21 +426,21 @@ void action_process(void)
                             if(manager_get_module(i)==MM_ACTION)
                             {
                               /* last segment of the main section */
-                              current_angles[i]=action_start_angles[i]+main_angles[i];
+                              manager_current_angles[i]=action_start_angles[i]+main_angles[i];
                               current_speed[i]=action_main_speed[i];
                               /* update state */
-                              action_start_angles[i]=current_angles[i];
+                              action_start_angles[i]=manager_current_angles[i];
                               main_angles[i]=action_moving_angles[i]-main_angles[i]-accel_angles[i];
                               /* first segment of the post section */
                               if(action_zero_speed_finish[i])
                               {
                                 delta_speed=((0.0-action_main_speed[i])*(action_current_time-action_section_time))/action_pre_time;
                                 current_speed[i]=action_main_speed[i]+delta_speed;
-                                current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
+                                manager_current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
                               }
                               else
                               {
-                                current_angles[i]=action_start_angles[i]+((main_angles[i]*(action_current_time-action_section_time))/action_pre_time);
+                                manager_current_angles[i]=action_start_angles[i]+((main_angles[i]*(action_current_time-action_section_time))/action_pre_time);
                                 current_speed[i]=action_main_speed[i];
                               }
                             }
@@ -405,7 +455,7 @@ void action_process(void)
                           {
                             if(manager_get_module(i)==MM_ACTION)
                             {
-                              current_angles[i]=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
+                              manager_current_angles[i]=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
                               current_speed[i]=action_main_speed[i];
                             }
                           }
@@ -423,15 +473,15 @@ void action_process(void)
                               {
                                 delta_speed=-action_main_speed[i];
                                 current_speed[i]=action_main_speed[i]+delta_speed;
-                                current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*action_section_time)+((delta_speed*action_section_time)>>1))>>16);
+                                manager_current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*action_section_time)+((delta_speed*action_section_time)>>1))>>16);
                               }
                               else
                               {
-                                current_angles[i]=action_start_angles[i]+main_angles[i];
+                                manager_current_angles[i]=action_start_angles[i]+main_angles[i];
                                 current_speed[i]=action_main_speed[i];
                               }
                               /* update state */
-                              action_start_angles[i]=current_angles[i];
+                              action_start_angles[i]=manager_current_angles[i];
                               action_start_speed[i]=current_speed[i];
                             }
                           }
@@ -440,11 +490,8 @@ void action_process(void)
                           {
                             if(action_end)
                             {
-                              action_load_next_step();
                               state=ACTION_PAUSE;
-                              action_end=0x00;
-                              ram_clear_bit(DARWIN_ACTION_STATUS,0);
-                              action_running=0x00;
+                              action_finish();
                             }
                             else
                             {
@@ -457,7 +504,7 @@ void action_process(void)
                                   delta_speed=((action_main_speed[i]-action_start_speed[i])*(action_current_time-action_section_time))/action_pre_time;
                                   current_speed[i]=action_start_speed[i]+delta_speed;
                                   accel_angles[i]=(((action_start_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
-                                  current_angles[i]=action_start_angles[i]+accel_angles[i];
+                                  manager_current_angles[i]=action_start_angles[i]+accel_angles[i];
                                 }
                               }
                               action_current_time=action_current_time-action_section_time;
@@ -482,11 +529,11 @@ void action_process(void)
                               {
                                 delta_speed=((0.0-action_main_speed[i])*action_current_time)/action_section_time;
                                 current_speed[i]=action_main_speed[i]+delta_speed;
-                                current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*action_current_time)+((delta_speed*action_current_time)>>1))>>16);
+                                manager_current_angles[i]=action_start_angles[i]+(((action_main_speed[i]*action_current_time)+((delta_speed*action_current_time)>>1))>>16);
                               }
                               else
                               {
-                                current_angles[i]=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
+                                manager_current_angles[i]=action_start_angles[i]+(main_angles[i]*action_current_time)/action_section_time;
                                 current_speed[i]=action_main_speed[i];
                               }
                             }
@@ -498,12 +545,8 @@ void action_process(void)
                          {
                            if(action_end)
                            {
-                             // find next page to execute
-                             action_load_next_step();
                              state=ACTION_PAUSE;
-                             action_end=0x00;
-                             ram_clear_bit(DARWIN_ACTION_STATUS,0);
-                             action_running=0x00;
+                             action_finish();
                            }
                            else
                            {
@@ -515,7 +558,7 @@ void action_process(void)
                                delta_speed=((action_main_speed[i]-action_start_speed[i])*(action_current_time-action_section_time))/action_pre_time;
                                current_speed[i]=action_start_speed[i]+delta_speed;
                                accel_angles[i]=(((action_start_speed[i]*(action_current_time-action_section_time))+((delta_speed*(action_current_time-action_section_time))>>1))>>16);
-                               current_angles[i]=action_start_angles[i]+accel_angles[i];
+                               manager_current_angles[i]=action_start_angles[i]+accel_angles[i];
                              }
                              action_current_time=action_current_time-action_section_time;
                              action_section_time=action_pre_time;
@@ -523,10 +566,35 @@ void action_process(void)
                            }
                          }
                          else// pause section still active
+                         {
                            state=ACTION_PAUSE;
+                         }
                          break;
       default: break;
     }
   }
 }
 
+// operation functions
+uint8_t action_in_range(unsigned short int address, unsigned short int length)
+{
+  return ram_in_window(ACTION_BASE_ADDRESS,ACTION_MEM_LENGTH,address,length);
+}
+
+void action_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  if(ram_in_range(DARWIN_ACTION_CNTRL,address,length))
+  {
+    if(data[DARWIN_ACTION_CNTRL-address]&ACTION_START)
+      action_start_page();
+    if(data[DARWIN_ACTION_CNTRL-address]&ACTION_STOP)
+      action_stop_page();
+    if(data[DARWIN_ACTION_CNTRL-address]&ACTION_INT_EN)
+      action_enable_int();
+    else
+      action_disable_int();
+  }
+  if(ram_in_range(DARWIN_ACTION_PAGE,address,length))// load the page identifier 
+    action_load_page(data[DARWIN_ACTION_PAGE-address]);
+}
+
diff --git a/src/cm730_fw.c b/src/cm730_fw.c
index aa8df078d76384414ce592bdd32e52b34325b638..5679db03820b8b854ea451224f6aebedf1258039 100755
--- a/src/cm730_fw.c
+++ b/src/cm730_fw.c
@@ -6,10 +6,12 @@
 #include "imu.h"
 #include "darwin_time.h"
 #include "darwin_dyn_slave.h"
-#include "darwin_dyn_master.h"
+#include "motion_manager.h"
 
 int main(void)
 {
+  uint16_t eeprom_data,period;
+
   /* initialize the HAL module */
   HAL_Init();
   /* initialize the GPIO module */
@@ -27,17 +29,12 @@ int main(void)
   /* initialize the dynamixel slave interface */
   darwin_dyn_slave_init();
   darwin_dyn_slave_start();
-  /* initialize the dynamixel master interface */
-  darwin_dyn_master_init();
-
-/*  darwin_dyn_master_enable_power();
-  HAL_Delay(1000);
-  gpio_set_led(LED_3);
-  if(dyn_master_ping(&darwin_dyn_master,0x01)==DYN_SUCCESS)
-    gpio_set_led(LED_2);
-  else
-    gpio_clear_led(LED_2);
-  darwin_dyn_master_disable_power();*/
+  /* initialize motion manager module */
+  EE_ReadVariable(MM_PERIOD_OFFSET,&eeprom_data);
+  period=eeprom_data&0x00FF;
+  EE_ReadVariable(MM_PERIOD_OFFSET+1,&eeprom_data);
+  period+=((eeprom_data&0x00FF)<<8);
+  manager_init(period);
 
   while(1);/* main function does not return */
 }
diff --git a/src/darwin_dyn_master.c b/src/darwin_dyn_master.c
index 13ef77880b64f8a8620fe75d33d5bce350c2b525..d55b13c8a87d614617273bd9aaf3bdad3af9671d 100755
--- a/src/darwin_dyn_master.c
+++ b/src/darwin_dyn_master.c
@@ -85,6 +85,10 @@ void darwin_dyn_master_init(void)
   dyn_master_init(&darwin_dyn_master,&darwin_dyn_master_comm,DYN_VER1);
   darwin_dyn_master.set_rx_mode=darwin_dyn_master_set_rx_mode;
   darwin_dyn_master.set_tx_mode=darwin_dyn_master_set_tx_mode;
+
+  /* configure dynamixel master module */
+  dyn_master_set_rx_timeout(&darwin_dyn_master,50);
+  dyn_master_set_return_level(&darwin_dyn_master,return_all);
 }
 
 inline void darwin_dyn_master_enable_power(void)
diff --git a/src/darwin_dyn_slave.c b/src/darwin_dyn_slave.c
index e00f1952cf84b9a0e1579d0f4e43883c983eb08e..2970d520007dd8c45459d4fa3b01aa7f586e8ffd 100755
--- a/src/darwin_dyn_slave.c
+++ b/src/darwin_dyn_slave.c
@@ -6,6 +6,9 @@
 #include "gpio.h"
 #include "adc_dma.h"
 #include "imu.h"
+#include "motion_manager.h"
+#include "action.h"
+#include "walking.h"
 
 /* timer for the execution of the dynamixel slave loop */
 #define     DYN_SLAVE_TIMER                   TIM7
@@ -68,6 +71,15 @@ unsigned char darwin_on_write(unsigned short int address,unsigned short int leng
   // IMU commands
   if(imu_in_range(address,length))
     imu_process_write_cmd(address,length,data);
+  // Manager commands
+  if(manager_in_range(address,length))
+    manager_process_write_cmd(address,length,data);
+  // action commands
+  if(action_in_range(address,length))
+    action_process_write_cmd(address,length,data);
+  // walk commands
+  if(walking_in_range(address,length))
+    walking_process_write_cmd(address,length,data);
   // write eeprom
   for(i=address,j=0;i<LAST_EEPROM_OFFSET && i<(address+length);i++,j++)
     EE_WriteVariable(i,data[j]);
diff --git a/src/darwin_kinematics.c b/src/darwin_kinematics.c
index a7791fb1931fc7c328288863e0e5fdaffab7c2eb..a60ca577c8c7529d72d3d5d012f44eede9e65e10 100755
--- a/src/darwin_kinematics.c
+++ b/src/darwin_kinematics.c
@@ -1,13 +1,8 @@
 #include "darwin_kinematics.h"
 #include "darwin_math.h"
+#include <math.h>
 
-const float LEG_SIDE_OFFSET = 37.0; //mm
-const float THIGH_LENGTH = 93.0; //mm
-const float CALF_LENGTH = 93.0; //mm
-const float ANKLE_LENGTH = 33.5; //mm
-const float LEG_LENGTH = 219.5; //mm (THIGH_LENGTH + CALF_LENGTH + ANKLE_LENGTH)
-
-uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float c)
+uint8_t darwin_leg_ik(float *out, float x, float y, float z, float a, float b, float c)
 {
   TMatrix3D Tad, Tda, Tcd, Tdc, Tac;
   TVector3D vec,orientation;
@@ -15,16 +10,16 @@ uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float
   float _Rac, _Acos, _Atan, _k, _l, _m, _n, _s, _c, _theta;
 
   vector3d_load(&orientation,a * 180.0 / PI, b * 180.0 / PI, c * 180.0 / PI);
-  point3d_load(&position,x, y, z - LEG_LENGTH);
+  point3d_load(&position,x, y, z - DARWIN_LEG_LENGTH);
   matrix3d_set_transform(&Tad,&position,&orientation);
 
-  vec.x = x + Tad.coef[2] * ANKLE_LENGTH;
-  vec.y = y + Tad.coef[6] * ANKLE_LENGTH;
-  vec.z = (z - LEG_LENGTH) + Tad.coef[10] * ANKLE_LENGTH;
+  vec.x = x + Tad.coef[2] * DARWIN_ANKLE_LENGTH;
+  vec.y = y + Tad.coef[6] * DARWIN_ANKLE_LENGTH;
+  vec.z = (z - DARWIN_LEG_LENGTH) + Tad.coef[10] * DARWIN_ANKLE_LENGTH;
 
   // Get Knee
   _Rac = vector3d_length(&vec);
-  _Acos = acos((_Rac * _Rac - THIGH_LENGTH * THIGH_LENGTH - CALF_LENGTH * CALF_LENGTH) / (2 * THIGH_LENGTH * CALF_LENGTH));
+  _Acos = acos((_Rac * _Rac - DARWIN_THIGH_LENGTH * DARWIN_THIGH_LENGTH - DARWIN_CALF_LENGTH * DARWIN_CALF_LENGTH) / (2 * DARWIN_THIGH_LENGTH * DARWIN_CALF_LENGTH));
   if(isnan(_Acos) == 1)
     return 0x00;;
   *(out + 3) = _Acos;
@@ -34,8 +29,8 @@ uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float
   if(matrix3d_inverse(&Tda,&Tda) == 0x00)
     return 0x00;
   _k = sqrt(Tda.coef[7] * Tda.coef[7] + Tda.coef[11] * Tda.coef[11]);
-  _l = sqrt(Tda.coef[7] * Tda.coef[7] + (Tda.coef[11] - ANKLE_LENGTH) * (Tda.coef[11] - ANKLE_LENGTH));
-  _m = (_k * _k - _l * _l - ANKLE_LENGTH * ANKLE_LENGTH) / (2 * _l * ANKLE_LENGTH);
+  _l = sqrt(Tda.coef[7] * Tda.coef[7] + (Tda.coef[11] - DARWIN_ANKLE_LENGTH) * (Tda.coef[11] - DARWIN_ANKLE_LENGTH));
+  _m = (_k * _k - _l * _l - DARWIN_ANKLE_LENGTH * DARWIN_ANKLE_LENGTH) / (2 * _l * DARWIN_ANKLE_LENGTH);
   if(_m > 1.0)
     _m = 1.0;
   else if(_m < -1.0)
@@ -49,7 +44,7 @@ uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float
     *(out + 5) = _Acos;
   // Get Hip Yaw
   vector3d_load(&orientation,*(out + 5) * 180.0 / PI, 0, 0);
-  point3d_load(&position,0, 0, -ANKLE_LENGTH);
+  point3d_load(&position,0, 0, -DARWIN_ANKLE_LENGTH);
   matrix3d_set_transform(&Tcd,&position,&orientation);
   Tdc = Tcd;
   if(matrix3d_inverse(&Tdc,&Tdc) == 0x00)
@@ -71,8 +66,8 @@ uint8_t computeIK(float *out, float x, float y, float z, float a, float b, float
   if(isinf(_Atan) == 1)
     return 0x00;
   _theta = _Atan;
-  _k = sin(*(out + 3)) * CALF_LENGTH;
-  _l = -THIGH_LENGTH - cos(*(out + 3)) * CALF_LENGTH;
+  _k = sin(*(out + 3)) * DARWIN_CALF_LENGTH;
+  _l = -DARWIN_THIGH_LENGTH - cos(*(out + 3)) * DARWIN_CALF_LENGTH;
   _m = cos(*(out)) * vec.x + sin(*(out)) * vec.y;
   _n = cos(*(out + 1)) * vec.z + sin(*(out)) * sin(*(out + 1)) * vec.x - cos(*(out)) * sin(*(out + 1)) * vec.y;
   _s = (_k * _n + _l * _m) / (_k * _k + _l * _l);
diff --git a/src/darwin_math.c b/src/darwin_math.c
index 5a4b80cd4df6e3afd6c6ac3e9835c491c5abc0d4..e76646357603c96cf91e2dc5994c9fea00f1971d 100755
--- a/src/darwin_math.c
+++ b/src/darwin_math.c
@@ -1,5 +1,4 @@
 #include "darwin_math.h"
-
 #include <math.h>
 
 // point functions
diff --git a/src/motion_manager.c b/src/motion_manager.c
index 93323f66eafcc7cf74aae31ea49d693a15c1b348..4857ef925fab6881334dbfbf3eabb408ad5d7c35 100755
--- a/src/motion_manager.c
+++ b/src/motion_manager.c
@@ -1,73 +1,54 @@
+#include "darwin_dyn_master.h"
 #include "motion_manager.h"
-#include "dynamixel_master_uart_dma.h"
-#include "dynamixel_slave_uart_dma.h"
 #include "dyn_servos.h"
 #include "ram.h"
 #include "action.h"
 #include "walking.h"
-#include "joint_motion.h"
-#include "head_tracking.h"
-#include "time.h"
-#include "imu.h"
-#include "gpio.h"
 
-#define      MOTION_TIMER                 TIM5
-#define      MOTION_TIMER_IRQn            TIM5_IRQn
-#define      MOTION_TIMER_IRQHandler      TIM5_IRQHandler
-#define      MOTION_TIMER_CLK             RCC_APB1Periph_TIM5
+#define MANAGER_TIMER                   TIM5
+#define ENABLE_MANAGER_TIMER_CLK        __HAL_RCC_TIM5_CLK_ENABLE()
+#define MANAGER_TIMER_IRQn              TIM5_IRQn
+#define MANAGER_TIMER_IRQHandler        TIM5_IRQHandler
 
 // private variables
-// manager period
-__IO uint16_t manager_motion_period;
-// manager number of servos (both version 1 and 2)
+TIM_HandleTypeDef MANAGER_TIM_Handle;
+
+uint16_t manager_motion_period;
+uint16_t manager_motion_period_us;
 uint8_t manager_num_servos;
-// servo information structures
 TServoInfo manager_servos[MANAGER_MAX_NUM_SERVOS];
 // current angles used for all motion modules
-int64_t current_angles[MANAGER_MAX_NUM_SERVOS];
+int64_t manager_current_angles[MANAGER_MAX_NUM_SERVOS];
+int8_t manager_current_slopes[MANAGER_MAX_NUM_SERVOS];
 // balance values and configuration
-int64_t balance_offset[MANAGER_MAX_NUM_SERVOS];
-uint8_t balance_enabled;
-// package variables
-uint8_t servo_ids[MANAGER_MAX_NUM_SERVOS];
-TWriteData write_data[MANAGER_MAX_NUM_SERVOS];
-uint8_t length[MANAGER_MAX_NUM_SERVOS];
-uint8_t address[MANAGER_MAX_NUM_SERVOS];
-
-// balane variables
-float knee_gain=0.3;
-float ankle_pitch_gain=0.9;
-float hip_roll_gain=0.5;
-float ankle_roll_gain=1.0;
+int64_t manager_balance_offset[MANAGER_MAX_NUM_SERVOS];
+uint8_t manager_balance_enabled;
+// manager offsets
+int16_t manager_offset[MANAGER_MAX_NUM_SERVOS];
 
 // private functions
 void manager_send_motion_command(void)
 {
+  static uint8_t servo_ids[MANAGER_MAX_NUM_SERVOS];
+  static TWriteData write_data[MANAGER_MAX_NUM_SERVOS];
   uint8_t i,num=0;
-  
-  for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
-  {
-    if(manager_servos[i].enabled && manager_servos[i].model!=0x0000 && manager_servos[i].dyn_version==0x02)
-    {
-      servo_ids[num]=manager_servos[i].id;
-      write_data[num].data_addr=(uint8_t *)&(manager_servos[i].current_value);
-      num++;
-    }
-  }
-  if(num>0)
-    dyn2_master_sync_write(num,servo_ids,XL_GOAL_POSITION_L,2,write_data);
-  num=0;
+
   for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
   {
-    if(manager_servos[i].enabled && manager_servos[i].model!=0x0000 && manager_servos[i].dyn_version==0x01)
-    {
-      servo_ids[num]=manager_servos[i].id;
-      write_data[num].data_addr=(uint8_t *)&(manager_servos[i].current_value);
-      num++;
+    if(manager_servos[i].enabled)
+    { 
+      if(manager_servos[i].model==SERVO_MX28)
+      {
+        servo_ids[num]=manager_servos[i].id;
+        manager_servos[i].cw_comp=(1<<(manager_current_slopes[i]&0x0F));
+        manager_servos[i].ccw_comp=(1<<((manager_current_slopes[i]&0xF0)>>4));
+        write_data[num].data_addr=(uint8_t *)&(manager_servos[i].cw_comp);
+        num++;
+      }
     }
   }
   if(num>0)
-    dyn_master_sync_write(num,servo_ids,P_GOAL_POSITION_L,2,write_data);
+    dyn_master_sync_write(&darwin_dyn_master,num,servo_ids,P_CW_COMPLIANCE_SLOPE,4,write_data);
 }
 
 inline uint16_t manager_angle_to_value(uint8_t servo_id,int16_t angle)
@@ -94,38 +75,18 @@ inline uint16_t manager_value_to_speed(uint8_t servo_id,uint16_t value)
 
 void manager_get_current_position(void)
 {
-  uint8_t i,num=0,id;
+  uint8_t i;
 
   for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
   {
-    if((!manager_servos[i].enabled && manager_servos[i].model!=0x0000 && manager_servos[i].dyn_version==0x01) || manager_servos[i].module==MM_HEAD)// servo is disabled
-    {
-      servo_ids[num]=manager_servos[i].id;
-      length[num]=2;
-      address[num]=P_PRESENT_POSITION_L;
-      write_data[num].data_addr=(uint8_t *)&(manager_servos[i].current_value);
-      num++;
-    }
-    else
+    if(!manager_servos[i].enabled && manager_servos[i].model!=0x0000)// servo is not enabled but it is present
     {
+      dyn_master_read_word(&darwin_dyn_master,manager_servos[i].id,P_PRESENT_POSITION_L,&manager_servos[i].current_value);
+      manager_servos[i].current_angle=manager_value_to_angle(i,manager_servos[i].current_value);
       ram_data[DARWIN_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF);
       ram_data[DARWIN_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8);
     }
   }
-  if(num>0)
-  {
-    if(dyn_master_bulk_read(num,servo_ids,address,length,write_data)==DYN_SUCCESS)
-    {
-      for(i=0;i<num;i++)
-      {
-        id=servo_ids[i];
-        manager_servos[id].current_angle=manager_value_to_angle(id,manager_servos[id].current_value);
-        current_angles[id]=manager_servos[id].current_angle<<9;
-        ram_data[DARWIN_MM_SERVO0_CUR_POS_L+id*2]=(manager_servos[id].current_angle&0xFF);
-        ram_data[DARWIN_MM_SERVO0_CUR_POS_H+id*2]=(manager_servos[id].current_angle>>8);
-      }
-    }
-  }
 }
 
 void manager_get_target_position(void)
@@ -134,96 +95,99 @@ void manager_get_target_position(void)
 
   for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
   {
-    if(manager_servos[i].enabled)// servo is enabled
+    if(manager_servos[i].enabled && manager_servos[i].model!=0x0000)// servo is enabled and present
     {
-      manager_servos[i].current_angle=((current_angles[i]+balance_offset[i])>>9);
+      manager_servos[i].current_angle=((manager_current_angles[i]>>9)+manager_balance_offset[i]+manager_offset[i]);
       //>>16 from the action codification, <<7 from the manager codification
       manager_servos[i].current_value=manager_angle_to_value(i,manager_servos[i].current_angle);
+      ram_data[DARWIN_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF);
+      ram_data[DARWIN_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8);
     }
   }
 }
 
 void manager_balance(void)
 {
-  int32_t gyro_x,gyro_y,gyro_z;
- 
-  if(balance_enabled)
+  //adc_ch_t fb_ch,lr_ch;
+  int16_t knee_gain,ankle_roll_gain,ankle_pitch_gain,hip_roll_gain;
+  //uint16_t fb_offset,lr_offset;
+  int16_t fb_value,lr_value;
+
+  if(manager_balance_enabled==0x01)// balance is enabled
   {
-    imu_get_gyro_data(&gyro_x,&gyro_y,&gyro_z);
-    // filter out some noise
-    if(gyro_x>0 && gyro_x<4096)
-      gyro_x=0;
-    else if(gyro_x<0 && gyro_x>-4096)
-      gyro_x=0;
-    if(gyro_y>0 && gyro_y<4096)
-      gyro_y=0;
-    else if(gyro_y<0 && gyro_y>-4096)
-      gyro_y=0;
-
-    balance_offset[R_HIP_ROLL]=(int32_t)(gyro_x*hip_roll_gain*6.428571); // R_HIP_ROLL
-    balance_offset[L_HIP_ROLL]=(int32_t)(gyro_x*hip_roll_gain*6.428571); // L_HIP_ROLL
-    balance_offset[R_KNEE]=(int32_t)(gyro_y*knee_gain*-6.428571); // R_KNEE
-    balance_offset[L_KNEE]=(int32_t)(gyro_y*knee_gain*6.428571); // L_KNEE
-
-    balance_offset[R_ANKLE_PITCH]=(int32_t)(gyro_y*ankle_pitch_gain*6.428571); // R_ANKLE_PITCH
-    balance_offset[L_ANKLE_PITCH]=(int32_t)(gyro_y*ankle_pitch_gain*-6.428571); // L_ANKLE_PITCH        
-    balance_offset[R_ANKLE_ROLL]=(int32_t)(gyro_x*ankle_roll_gain*6.428571); // R_ANKLE_ROLL
-    balance_offset[L_ANKLE_ROLL]=(int32_t)(gyro_x*ankle_roll_gain*6.428571); // L_ANKLE_ROLL
+    //fb_ch=gyro_get_fb_adc_channel();
+    //lr_ch=gyro_get_lr_adc_channel();
+    // get the balance gains
+    knee_gain=ram_data[DARWIN_MM_BAL_KNEE_GAIN_L]+(ram_data[DARWIN_MM_BAL_KNEE_GAIN_H]<<8);
+    ankle_roll_gain=ram_data[DARWIN_MM_BAL_ANKLE_ROLL_GAIN_L]+(ram_data[DARWIN_MM_BAL_ANKLE_ROLL_GAIN_H]<<8);
+    ankle_pitch_gain=ram_data[DARWIN_MM_BAL_ANKLE_PITCH_GAIN_L]+(ram_data[DARWIN_MM_BAL_ANKLE_PITCH_GAIN_H]<<8);
+    hip_roll_gain=ram_data[DARWIN_MM_BAL_HIP_ROLL_GAIN_L]+(ram_data[DARWIN_MM_BAL_HIP_ROLL_GAIN_H]<<8);
+    // get the offsets of the gyroscope calibration
+    //gyro_get_offsets(&fb_offset,&lr_offset);
+    // get the values of the gyroscope
+    //fb_value=adc_get_channel_raw(fb_ch)-fb_offset;
+    //lr_value=adc_get_channel_raw(lr_ch)-lr_offset;
+    fb_value=0;
+    lr_value=0;
+    // compensate the servo angle values
+    manager_balance_offset[R_KNEE]=(((fb_value*manager_servos[R_KNEE].max_angle)/manager_servos[R_KNEE].encoder_resolution)*knee_gain)>>16;
+    manager_balance_offset[R_ANKLE_PITCH]=(((fb_value*manager_servos[R_ANKLE_PITCH].max_angle)/manager_servos[R_ANKLE_PITCH].encoder_resolution)*ankle_pitch_gain)>>16;    
+    manager_balance_offset[L_KNEE]=-(((fb_value*manager_servos[L_KNEE].max_angle)/manager_servos[L_KNEE].encoder_resolution)*knee_gain)>>16;    
+    manager_balance_offset[L_ANKLE_PITCH]=-(((fb_value*manager_servos[L_ANKLE_PITCH].max_angle)/manager_servos[L_ANKLE_PITCH].encoder_resolution)*ankle_pitch_gain)>>16;
+    manager_balance_offset[R_HIP_ROLL]=(((lr_value*manager_servos[R_HIP_ROLL].max_angle)/manager_servos[R_HIP_ROLL].encoder_resolution)*hip_roll_gain)>>16;
+    manager_balance_offset[L_HIP_ROLL]=(((lr_value*manager_servos[L_HIP_ROLL].max_angle)/manager_servos[L_HIP_ROLL].encoder_resolution)*hip_roll_gain)>>16;
+    manager_balance_offset[R_ANKLE_ROLL]=-(((lr_value*manager_servos[R_ANKLE_ROLL].max_angle)/manager_servos[R_ANKLE_ROLL].encoder_resolution)*ankle_roll_gain)>>16;
+    manager_balance_offset[L_ANKLE_ROLL]=-(((lr_value*manager_servos[L_ANKLE_ROLL].max_angle)/manager_servos[L_ANKLE_ROLL].encoder_resolution)*ankle_roll_gain)>>16;
   }
 }
 
 // interrupt handlers
-void MOTION_TIMER_IRQHandler(void)
+void MANAGER_TIMER_IRQHandler(void)
 {
-  uint16_t capture_start,capture_end;
-  int16_t elapsed;
+  uint16_t capture;
 
-  if(TIM_GetITStatus(MOTION_TIMER, TIM_IT_CC1)!=RESET)
+  if(__HAL_TIM_GET_FLAG(&MANAGER_TIM_Handle, TIM_FLAG_CC1) != RESET)
   {
-    TIM_ClearITPendingBit(MOTION_TIMER,TIM_IT_CC1);
-    capture_start = TIM_GetCapture1(MOTION_TIMER);
-    TIM_SetCompare1(MOTION_TIMER, capture_start + manager_motion_period);
-    // get the disabled servos position
-    manager_get_current_position();
-    // call the action process
-    action_process();
-    // call the joint motion process
-    joint_motion_process();
-    // call the walking process
-    walking_process();
-    // head tracking process
-    head_tracking_process();
-    // balance the robot
-    manager_balance();
-    // get the target angles from all modules
-    manager_get_target_position();
-    // send the motion commands to the servos
-    manager_send_motion_command();
-    capture_end = TIM_GetCounter(MOTION_TIMER);
-    elapsed=capture_end-capture_start;
-    if(elapsed<0) elapsed+=0xFFFFF;
-    ram_write_word(DARWIN_MM_CUR_PERIOD,(uint16_t)elapsed);
+    if(__HAL_TIM_GET_IT_SOURCE(&MANAGER_TIM_Handle, TIM_IT_CC1) !=RESET)
+    {
+      __HAL_TIM_CLEAR_IT(&MANAGER_TIM_Handle, TIM_IT_CC1);
+      capture = HAL_TIM_ReadCapturedValue(&MANAGER_TIM_Handle, TIM_CHANNEL_1);
+      __HAL_TIM_SET_COMPARE(&MANAGER_TIM_Handle, TIM_CHANNEL_1, (capture + manager_motion_period_us));
+      // call the action process
+      action_process();
+      // call the joint motion process
+      // joint_motion_process();
+      // call the walking process
+      walking_process();
+      // balance the robot
+      manager_balance();
+      // get the target angles from all modules
+      manager_get_target_position();
+      // send the motion commands to the servos
+      manager_send_motion_command();
+      // get the disabled servos position
+      // manager_get_current_position();
+    }
   }
 }
 
 // public functions
 void manager_init(uint16_t period_us)
 {
-  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
-  TIM_OCInitTypeDef  TIM_OCInitStructure;
-  NVIC_InitTypeDef NVIC_InitStructure;
+  TIM_ClockConfigTypeDef sClockSourceConfig;
+  TIM_MasterConfigTypeDef sMasterConfig;
   uint8_t servo_ids[MANAGER_MAX_NUM_SERVOS];
   uint16_t model,value;
   uint8_t i,num=0;
 
-  RCC_APB1PeriphClockCmd(MOTION_TIMER_CLK,ENABLE);
+  /* initialize the dynamixel master module for the servos */
+  darwin_dyn_master_init();
 
   // enable power to the servos
-  dyn_master_enable_power();
-  delay_ms(1000);
-
+  darwin_dyn_master_enable_power();
+  HAL_Delay(1000);
   // detect the servos connected 
-  dyn_master_scan(&num,servo_ids); 
+  dyn_master_scan(&darwin_dyn_master,&num,servo_ids); 
   ram_data[DARWIN_MM_NUM_SERVOS]=num;
   manager_num_servos=0;
   for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
@@ -231,7 +195,7 @@ void manager_init(uint16_t period_us)
     if(i==servo_ids[manager_num_servos])
     {
       // read the model of the i-th device
-      dyn_master_read_word(servo_ids[manager_num_servos],P_MODEL_NUMBER_L,&model);
+      dyn_master_read_word(&darwin_dyn_master,servo_ids[manager_num_servos],P_MODEL_NUMBER_L,&model);
       switch(model)
       {
         case SERVO_AX12A: manager_servos[i].encoder_resolution=1023;
@@ -300,19 +264,18 @@ void manager_init(uint16_t period_us)
       manager_servos[i].model=model;
       manager_servos[i].module=MM_NONE;
       manager_servos[i].enabled=0x00;
-      manager_servos[i].dyn_version=0x01;
       // get the servo's current position
-      dyn_master_read_word(manager_servos[i].id,P_PRESENT_POSITION_L,&manager_servos[i].current_value);
+      dyn_master_read_word(&darwin_dyn_master,manager_servos[i].id,P_PRESENT_POSITION_L,&manager_servos[i].current_value);
       manager_servos[i].current_angle=manager_value_to_angle(i,manager_servos[i].current_value);
       ram_data[DARWIN_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF);
       ram_data[DARWIN_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8);
       // read the servo limits
-      dyn_master_read_word(manager_servos[i].id,P_CW_ANGLE_LIMIT_L,&value);
+      dyn_master_read_word(&darwin_dyn_master,manager_servos[i].id,P_CW_ANGLE_LIMIT_L,&value);
       manager_servos[i].cw_angle_limit=manager_value_to_angle(i,value);
-      dyn_master_read_word(manager_servos[i].id,P_CCW_ANGLE_LIMIT_L,&value);
+      dyn_master_read_word(&darwin_dyn_master,manager_servos[i].id,P_CCW_ANGLE_LIMIT_L,&value);
       manager_servos[i].ccw_angle_limit=manager_value_to_angle(i,value);
       // set the action current angles
-      current_angles[i]=manager_servos[i].current_angle<<9;
+      manager_current_angles[i]=manager_servos[i].current_angle<<9;
       manager_num_servos++;
     }
     else
@@ -330,92 +293,43 @@ void manager_init(uint16_t period_us)
       manager_servos[i].enabled=0x00;
       manager_servos[i].cw_angle_limit=0;
       manager_servos[i].ccw_angle_limit=0;
-      manager_servos[i].dyn_version=0x00;
     }
   }
-  // scan for version 2 servos
-  dyn2_master_scan(&num,servo_ids);
-  ram_data[DARWIN_MM_NUM_SERVOS]=manager_num_servos;
-  manager_num_servos=0;
+  darwin_dyn_master_disable_power();
+
+  /* configure timer */
+  ENABLE_MANAGER_TIMER_CLK;
+  MANAGER_TIM_Handle.Instance=MANAGER_TIMER;
+  MANAGER_TIM_Handle.Init.Period = 0xFFFF;
+  MANAGER_TIM_Handle.Init.Prescaler = 72;
+  MANAGER_TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  MANAGER_TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
+  HAL_NVIC_SetPriority(MANAGER_TIMER_IRQn, 2, 1);
+  HAL_NVIC_EnableIRQ(MANAGER_TIMER_IRQn);
+  /* use the internal clock */
+  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+  HAL_TIM_ConfigClockSource(&MANAGER_TIM_Handle, &sClockSourceConfig);
+  HAL_TIM_OC_Init(&MANAGER_TIM_Handle);
+  /* disable master/slave mode */
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  HAL_TIMEx_MasterConfigSynchronization(&MANAGER_TIM_Handle, &sMasterConfig);
+  /* configure ouptut counter channel 4 */
+  manager_motion_period=(period_us<<16)/1000000;
+  manager_motion_period_us=period_us;
+
+  /* initialize balance parameters */
+  /* initialize the manager offsets from EEPROM */
   for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
   {
-    if(i==servo_ids[manager_num_servos])
-    {
-      // read the model of the i-th device
-      dyn2_master_read_word(servo_ids[manager_num_servos],XL_MODEL_NUMBER_L,&model);
-      switch(model)
-      {
-        case SERVO_XL320: manager_servos[i].encoder_resolution=1023;
-                          manager_servos[i].gear_ratio=238;
-                          manager_servos[i].max_angle=300<<7;
-                          manager_servos[i].center_angle=150<<7;
-                          manager_servos[i].max_speed=690;
-                          break;
-        default: break;
-      }
-      manager_servos[i].id=servo_ids[manager_num_servos];
-      manager_servos[i].model=model;
-      manager_servos[i].module=MM_NONE;
-      manager_servos[i].enabled=0x00;
-      manager_servos[i].dyn_version=0x02;
-      // get the servo's current position
-      dyn2_master_read_word(manager_servos[i].id,XL_PRESENT_POSITION_L,&manager_servos[i].current_value);
-      manager_servos[i].current_angle=manager_value_to_angle(i,manager_servos[i].current_value);
-      ram_data[DARWIN_MM_SERVO0_CUR_POS_L+i*2]=(manager_servos[i].current_angle&0xFF);
-      ram_data[DARWIN_MM_SERVO0_CUR_POS_H+i*2]=(manager_servos[i].current_angle>>8);
-      // read the servo limits
-      dyn2_master_read_word(manager_servos[i].id,XL_CW_ANGLE_LIMIT_L,&value);
-      manager_servos[i].cw_angle_limit=manager_value_to_angle(i,value);
-      dyn2_master_read_word(manager_servos[i].id,XL_CCW_ANGLE_LIMIT_L,&value);
-      manager_servos[i].ccw_angle_limit=manager_value_to_angle(i,value);
-      // set the action current angles
-      current_angles[i]=manager_servos[i].current_angle<<9;
-      manager_num_servos++;
-    }
+    manager_balance_offset[i]=0;
+    manager_set_offset(i,(signed char)ram_data[DARWIN_MM_SERVO0_OFFSET+i]);
   }
-  dyn_master_disable_power();
-  manager_num_servos=num+ram_data[DARWIN_MM_NUM_SERVOS];
-  ram_data[DARWIN_MM_NUM_SERVOS]=((num&0x07)<<5)+(ram_data[DARWIN_MM_NUM_SERVOS]&0x1F);
-
-  // initialize the timer interrupts
-  NVIC_InitStructure.NVIC_IRQChannel = MOTION_TIMER_IRQn;
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-  NVIC_Init(&NVIC_InitStructure);
-
-  /* motion timer configuration */
-  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
-  TIM_TimeBaseStructure.TIM_Prescaler = 72;
-  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
-  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
-  TIM_TimeBaseInit(MOTION_TIMER,&TIM_TimeBaseStructure);
-
-  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
-  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
-  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
-  manager_motion_period=(period_us*1000000)>>16;
-  TIM_OCInitStructure.TIM_Pulse = manager_motion_period;
-  TIM_OC1Init(MOTION_TIMER, &TIM_OCInitStructure);
-  TIM_OC1PreloadConfig(MOTION_TIMER, TIM_OCPreload_Disable);
-
-  ram_clear_bit(DARWIN_MM_STATUS,0);
-
-  /* initialize motion modules */
-  action_init(period_us);
-  walking_init(manager_motion_period);
-  joint_motion_init(period_us);
-  head_tracking_init(period_us);
-
-  ram_write_byte(DARWIN_MM_KNEE_GAIN,(uint8_t)(knee_gain*64.0));
-  ram_write_byte(DARWIN_MM_ANKLE_PITCH_GAIN,(uint8_t)(ankle_pitch_gain*64.0));
-  ram_write_byte(DARWIN_MM_HIP_ROLL_GAIN,(uint8_t)(hip_roll_gain*64.0));
-  ram_write_byte(DARWIN_MM_ANKLE_ROLL_GAIN,(uint8_t)(ankle_roll_gain*64.0));
+  manager_balance_enabled=0x00;
 
-  for(i=0;i<MANAGER_MAX_NUM_SERVOS;i++)
-    balance_offset[i]=0;
-  balance_enabled=0x01;
-  ram_data[DARWIN_MM_CONTROL]=0x02;
+  /* initialize action module */
+  action_init(period_us);
+  walking_init(period_us);
 }
 
 uint16_t manager_get_period(void)
@@ -423,53 +337,57 @@ uint16_t manager_get_period(void)
   return manager_motion_period;
 }
 
+uint16_t manager_get_period_us(void)
+{
+  return manager_motion_period_us;
+}
+
 void manager_set_period(uint16_t period_us)
 {
-  manager_motion_period=(period_us*1000000)>>16;
-  ram_write_word(DARWIN_MM_PERIOD_H,period_us);
+  manager_motion_period=(period_us<<16)/1000000;
+  manager_motion_period_us=period_us;
+  ram_data[DARWIN_MM_PERIOD_L]=period_us&0x00FF;
+  ram_data[DARWIN_MM_PERIOD_H]=(period_us&0xFF00)>>8;
   action_set_period(period_us);
-  walking_set_period(manager_motion_period);
-  joint_motion_set_period(period_us);
-  head_tracking_set_period(period_us);
+  walking_set_period(period_us);
 }
 
 inline void manager_enable(void)
 {
+  TIM_OC_InitTypeDef TIM_OCInitStructure;
   uint16_t capture;
 
-  capture = TIM_GetCapture1(MOTION_TIMER);
-  TIM_SetCompare1(MOTION_TIMER, capture + manager_motion_period);
-  TIM_Cmd(MOTION_TIMER, ENABLE);
-  TIM_ITConfig(MOTION_TIMER, TIM_IT_CC1, ENABLE);
-  ram_set_bit(DARWIN_MM_STATUS,0);
-  ram_set_bit(DARWIN_MM_CONTROL,0);
+  TIM_OCInitStructure.OCMode = TIM_OCMODE_TIMING;
+  TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
+  TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
+  capture = HAL_TIM_ReadCapturedValue(&MANAGER_TIM_Handle, TIM_CHANNEL_1);
+  TIM_OCInitStructure.Pulse = capture+manager_motion_period_us;
+  HAL_TIM_OC_ConfigChannel(&MANAGER_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_1);
+  HAL_TIM_OC_Start_IT(&MANAGER_TIM_Handle, TIM_CHANNEL_1);
+  ram_data[DARWIN_MM_CNTRL]|=MANAGER_ENABLE;
 }
 
 inline void manager_disable(void)
 {
-  TIM_Cmd(MOTION_TIMER, DISABLE);
-  TIM_ITConfig(MOTION_TIMER, TIM_IT_CC1, DISABLE);
-  ram_clear_bit(DARWIN_MM_STATUS,0);
-  ram_clear_bit(DARWIN_MM_CONTROL,0);
+  HAL_TIM_OC_Stop_IT(&MANAGER_TIM_Handle, TIM_CHANNEL_1);
+  ram_data[DARWIN_MM_CNTRL]&=(~MANAGER_ENABLE);
 }
 
 inline uint8_t manager_is_enabled(void)
 {
-  return ram_data[DARWIN_MM_STATUS]&0x01;
+  return ram_data[DARWIN_MM_CNTRL]&MANAGER_ENABLE;
 }
 
 void manager_enable_balance(void)
 {
-  ram_set_bit(DARWIN_MM_STATUS,1);
-  ram_set_bit(DARWIN_MM_CONTROL,1);
-  balance_enabled=0x01;
+  manager_balance_enabled=0x01;
+  ram_data[DARWIN_MM_CNTRL]|=MANAGER_EN_BAL;
 }
 
 void manager_disable_balance(void)
 {
-  ram_clear_bit(DARWIN_MM_STATUS,1);
-  ram_clear_bit(DARWIN_MM_CONTROL,1);
-  balance_enabled=0x00;
+  manager_balance_enabled=0x00;
+  ram_data[DARWIN_MM_CNTRL]&=(~MANAGER_EN_BAL);
 }
 
 inline uint8_t manager_get_num_servos(void)
@@ -484,12 +402,12 @@ void manager_set_module(uint8_t servo_id,TModules module)
   if(servo_id>=0 && servo_id<MANAGER_MAX_NUM_SERVOS)
   {
     manager_servos[servo_id].module=module;
-    ram_read_byte(DARWIN_MM_MODULE_EN0+servo_id/2,&byte);
-    if(servo_id%2)
-      byte=(byte&0xF8)+((uint8_t)module);
-    else
-      byte=(byte&0x8F)+(((uint8_t)module)<<4);
-    ram_write_byte(DARWIN_MM_MODULE_EN0+servo_id/2,byte);
+    byte=ram_data[DARWIN_MM_MODULE_EN0+servo_id/2];
+    if(servo_id%2)// odd servo
+      byte=(byte&(~MANAGER_ODD_SER_MOD))+((uint8_t)module);
+    else// even servo
+      byte=(byte&(~MANAGER_EVEN_SER_MOD))+(((uint8_t)module)<<4);
+    ram_data[DARWIN_MM_MODULE_EN0+servo_id/2]=byte;
   }
 }
 
@@ -508,12 +426,12 @@ inline void manager_enable_servo(uint8_t servo_id)
   if(servo_id>=0 && servo_id<MANAGER_MAX_NUM_SERVOS)
   {
     manager_servos[servo_id].enabled=0x01;
-    ram_read_byte(DARWIN_MM_MODULE_EN0+servo_id/2,&byte);
-    if(servo_id%2)
-      byte|=0x08;
-    else
-      byte|=0x80;
-    ram_write_byte(DARWIN_MM_MODULE_EN0+servo_id/2,byte);
+    byte=ram_data[DARWIN_MM_MODULE_EN0+servo_id/2];;
+    if(servo_id%2)// odd servo
+      byte|=MANAGER_ODD_SER_EN;
+    else// even servo
+      byte|=MANAGER_EVEN_SER_EN;
+    ram_data[DARWIN_MM_MODULE_EN0+servo_id/2]=byte;
   }
 }
 
@@ -524,32 +442,15 @@ inline void manager_disable_servo(uint8_t servo_id)
   if(servo_id>=0 && servo_id<MANAGER_MAX_NUM_SERVOS)
   {
     manager_servos[servo_id].enabled=0x00;
-    ram_read_byte(DARWIN_MM_MODULE_EN0+servo_id/2,&byte);
+    byte=ram_data[DARWIN_MM_MODULE_EN0+servo_id/2];
     if(servo_id%2)
-      byte&=0xF7;
+      byte&=(~MANAGER_ODD_SER_EN);
     else
-      byte&=0x7F;
-    ram_write_byte(DARWIN_MM_MODULE_EN0+servo_id/2,byte);
+      byte&=(~MANAGER_EVEN_SER_EN);
+    ram_data[DARWIN_MM_MODULE_EN0+servo_id/2]=byte;
   }
 }
 
-void manager_disable_servos(void)
-{
-  uint8_t i,num=0,data=0x00;
-
-  for(i=0;i<manager_num_servos;i++)
-  {
-    if(!manager_servos[i].enabled && manager_servos[i].dyn_version==0x01)
-    {
-      servo_ids[num]=manager_servos[i].id;
-      write_data[num].data_addr=&data;
-      num++;
-    }
-  }
-  if(num>0)
-    dyn_master_sync_write(num,servo_ids,P_TORQUE_ENABLE,1,write_data);
-}
-
 inline uint8_t manager_is_servo_enabled(uint8_t servo_id)
 {
   if(servo_id>=0 && servo_id<MANAGER_MAX_NUM_SERVOS)
@@ -558,6 +459,15 @@ inline uint8_t manager_is_servo_enabled(uint8_t servo_id)
     return 0x00;
 }
 
+void manager_set_offset(uint8_t servo_id, int8_t offset)
+{
+  if(servo_id>=0 && servo_id<MANAGER_MAX_NUM_SERVOS)
+  {
+    manager_offset[servo_id]=(int16_t)(offset*8);
+    ram_data[DARWIN_MM_SERVO0_OFFSET+servo_id]=offset;
+  }
+}
+
 inline int16_t manager_get_cw_angle_limit(uint8_t servo_id)
 {
   return manager_servos[servo_id].cw_angle_limit;
@@ -568,32 +478,64 @@ inline int16_t manager_get_ccw_angle_limit(uint8_t servo_id)
   return manager_servos[servo_id].ccw_angle_limit;
 }
 
-void manager_set_knee_gain(uint8_t gain)
+// operation functions
+uint8_t manager_in_range(unsigned short int address, unsigned short int length)
 {
-  ram_data[DARWIN_MM_KNEE_GAIN]=gain;
-  knee_gain=gain/64.0;
-}
-
-void manager_set_ankle_pitch_gain(uint8_t gain)
-{
-  ram_data[DARWIN_MM_ANKLE_PITCH_GAIN]=gain;
-  ankle_pitch_gain=gain/64.0;
-}
-
-void manager_set_hip_roll_gain(uint8_t gain)
-{
-  ram_data[DARWIN_MM_HIP_ROLL_GAIN]=gain;
-  hip_roll_gain=gain/64.0;
+  if(ram_in_window(MANAGER_BASE_ADDRESS,MANAGER_MEM_LENGTH,address,length) ||
+     ram_in_window(MANAGER_EEPROM_BASE1,MANAGER_EEPROM_LENGTH1,address,length) ||
+     ram_in_window(MANAGER_EEPROM_BASE2,MANAGER_EEPROM_LENGTH2,address,length))
+    return 0x01;
+  else
+    return 0x00;
 }
 
-void manager_set_ankle_roll_gain(uint8_t gain)
+void manager_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data)
 {
-  ram_data[DARWIN_MM_ANKLE_ROLL_GAIN]=gain;
-  ankle_roll_gain=gain/64.0;
-}
+  uint16_t word_value,i,j;
+  uint8_t byte_value,module;
 
-uint8_t manager_get_dyn_version(uint8_t servo_id)
-{
-  return manager_servos[servo_id].dyn_version;
+  if(ram_in_range(DARWIN_MM_PERIOD_L,address,length) && ram_in_range(DARWIN_MM_PERIOD_H,address,length))
+  {
+    word_value=data[DARWIN_MM_PERIOD_L-address]+(data[DARWIN_MM_PERIOD_H-address]<<8);
+    manager_set_period(word_value);
+  }
+  for(i=DARWIN_MM_SERVO0_OFFSET,j=0;i<=DARWIN_MM_SERVO31_OFFSET;i++,j++)
+  {
+    if(ram_in_range(i,address,length))
+      manager_set_offset(j,(signed char)(data[i-address]));
+  }
+  for(i=DARWIN_MM_MODULE_EN0,j=0;i<=DARWIN_MM_MODULE_EN15;i++,j+=2)
+  {
+    if(ram_in_range(i,address,length))
+    {
+      byte_value=data[i-address];
+      if(byte_value&MANAGER_EVEN_SER_EN) manager_enable_servo(j);
+      else manager_disable_servo(j);
+      module=(byte_value&MANAGER_EVEN_SER_MOD)>>4;
+      manager_set_module(j,module);
+      if(byte_value&MANAGER_ODD_SER_EN) manager_enable_servo(j+1);
+      else manager_disable_servo(j+1);
+      module=byte_value&MANAGER_ODD_SER_MOD;
+      manager_set_module(j+1,module);
+    }
+  }
+  if(ram_in_range(DARWIN_MM_CNTRL,address,length))
+  {
+    if(data[DARWIN_MM_CNTRL-address]&MANAGER_ENABLE)
+      manager_enable();
+    else
+      manager_disable();
+    if(data[DARWIN_MM_CNTRL-address]&MANAGER_EN_BAL)
+      manager_enable_balance();
+    else
+      manager_disable_balance();
+    if(data[DARWIN_MM_CNTRL-address]&MANAGER_EN_PWR)
+      darwin_dyn_master_enable_power();
+    else
+      darwin_dyn_master_disable_power();
+  }
+  // balance gains
+  for(i=MM_BAL_KNEE_GAIN_OFFSET;i<=MM_BAL_HIP_ROLL_GAIN_OFFSET+1;i++)
+    if(ram_in_range(i,address,length))
+      ram_data[i]=data[i-address];
 }
-
diff --git a/src/walking.c b/src/walking.c
index 13d03c12bb971f658d568c638f3fe2de9ccd2fac..192efbdad77bc1766f0469ad5fdd15fefb575182 100755
--- a/src/walking.c
+++ b/src/walking.c
@@ -1,79 +1,15 @@
 #include "walking.h"
-#include "motion_manager.h"
-#include "ram.h"
 #include "darwin_kinematics.h"
 #include "darwin_math.h"
-#include "time.h"
-
-enum {PHASE0 = 0,PHASE1 = 1,PHASE2 = 2, PHASE3 = 3};
-
-// leg kinematics
-const uint8_t servo_seq[14]={R_HIP_YAW,R_HIP_ROLL,R_HIP_PITCH,R_KNEE,R_ANKLE_PITCH,R_ANKLE_ROLL,L_HIP_YAW,L_HIP_ROLL,L_HIP_PITCH,L_KNEE,L_ANKLE_PITCH,L_ANKLE_ROLL,R_SHOULDER_PITCH,L_SHOULDER_PITCH};
-
-const int8_t dir[14]={-1,-1,1,1,-1,1,-1,-1,-1,-1,1,1,1,-1};
-
-// walking configuration variables
-float Y_SWAP_AMPLITUDE=20.0;//mm
-float Z_SWAP_AMPLITUDE=5;//mm
-float ARM_SWING_GAIN=1.5;
-float PELVIS_OFFSET=3.0;//degrees
-float HIP_PITCH_OFFSET=0;//23.0;//degrees
-
-uint8_t P_GAIN=32;
-uint8_t I_GAIN=0;
-uint8_t D_GAIN=0;
+#include "ram.h"
+#include <math.h>
 
-// Walking initial pose
-float X_OFFSET=-10;//mm
-float Y_OFFSET=5;//mm
-float Z_OFFSET=20;//mm
-float A_OFFSET=0;
-float P_OFFSET=0;
-float R_OFFSET=0;
+enum {PHASE0=0x00,PHASE1=0x40,PHASE2=0x80,PHASE3=0xC0};
 
 // Walking control
-float PERIOD_TIME=600;//milliseconds
-float DSP_RATIO=0.1;
-float STEP_FB_RATIO=0.3;
-float X_MOVE_AMPLITUDE=0;//mm
-float current_x_amplitude=0;
-float Y_MOVE_AMPLITUDE=0;//mm
-float current_y_amplitude=0;
-float Z_MOVE_AMPLITUDE=40;//mm
-float A_MOVE_AMPLITUDE=0;//degrees
-float current_a_amplitude=0;
 uint8_t A_MOVE_AIM_ON=0x00;
 
-float max_acceleration=0.02;// m/s/s
-float max_rot_accel=0.02;// rad/s/s
-
-// private variables
-float m_PeriodTime;
-float m_DSP_Ratio;
-float m_SSP_Ratio;
-float m_X_Swap_PeriodTime;
-float m_X_Move_PeriodTime;
-float m_Y_Swap_PeriodTime;
-float m_Y_Move_PeriodTime;
-float m_Z_Swap_PeriodTime;
-float m_Z_Move_PeriodTime;
-float m_A_Move_PeriodTime;
-float m_SSP_Time;
-float m_SSP_Time_Start_L;
-float m_SSP_Time_End_L;
-float m_SSP_Time_Start_R;
-float m_SSP_Time_End_R;
-float m_Phase_Time1;
-float m_Phase_Time2;
-float m_Phase_Time3;
-
-float m_X_Offset;
-float m_Y_Offset;
-float m_Z_Offset;
-float m_R_Offset;
-float m_P_Offset;
-float m_A_Offset;
-
+// internal motion variables
 float m_X_Swap_Phase_Shift;
 float m_X_Swap_Amplitude;
 float m_X_Swap_Amplitude_Shift;
@@ -96,170 +32,179 @@ float m_A_Move_Phase_Shift;
 float m_A_Move_Amplitude;
 float m_A_Move_Amplitude_Shift;
 
+// internal offset variables
+float m_Hip_Pitch_Offset;
 float m_Pelvis_Offset;
 float m_Pelvis_Swing;
-float m_Hip_Pitch_Offset;
 float m_Arm_Swing_Gain;
+float m_X_Offset;
+float m_Y_Offset;
+float m_Z_Offset;
+float m_R_Offset;
+float m_P_Offset;
+float m_A_Offset;
 
-volatile uint8_t m_Ctrl_Running;
+// internal time variables
 float m_Time;
-float walking_period;
+float m_PeriodTime;
+float m_X_Swap_PeriodTime;
+float m_X_Move_PeriodTime;
+float m_Y_Swap_PeriodTime;
+float m_Y_Move_PeriodTime;
+float m_Z_Swap_PeriodTime;
+float m_Z_Move_PeriodTime;
+float m_A_Move_PeriodTime;
+float m_SSP_Time_Start_L;
+float m_SSP_Time_End_L;
+float m_SSP_Time_Start_R;
+float m_SSP_Time_End_R;
+float m_Phase_Time1;
+float m_Phase_Time2;
+float m_Phase_Time3;
 
-uint8_t m_Phase;
-float m_Body_Swing_Y;
-float m_Body_Swing_Z;
+// control variables
+uint8_t m_Ctrl_Running;
+float walking_period;
 
 // private functions
 inline float wsin(float time, float period, float period_shift, float mag, float mag_shift)
 {
-  return mag * sin(((2.0*PI*time)/period)-period_shift) + mag_shift;
+  return mag*sin(((2.0*PI*time)/period)-period_shift)+mag_shift;
 }
 
 void update_param_time()
 {
-  m_PeriodTime = PERIOD_TIME;
-  m_DSP_Ratio = DSP_RATIO;
-  m_SSP_Ratio = 1 - DSP_RATIO;
+  float m_SSP_Ratio;
+  float m_SSP_Time;
 
-  m_SSP_Time = m_PeriodTime * m_SSP_Ratio;
+  m_PeriodTime=((float)((int16_t)(ram_data[DARWIN_WALK_PERIOD_TIME_L]+(ram_data[DARWIN_WALK_PERIOD_TIME_H]<<8))));
+  m_SSP_Ratio=1.0-((float)ram_data[DARWIN_WALK_DSP_RATIO])/256.0;
 
-  m_X_Swap_PeriodTime = m_PeriodTime / 2.0;
-  m_X_Move_PeriodTime = m_SSP_Time;
-  m_Y_Swap_PeriodTime = m_PeriodTime;
-  m_Y_Move_PeriodTime = m_SSP_Time;
-  m_Z_Swap_PeriodTime = m_PeriodTime / 2.0;
-  m_Z_Move_PeriodTime = m_SSP_Time / 2.0;
-  m_A_Move_PeriodTime = m_SSP_Time;
+  m_SSP_Time=m_PeriodTime*m_SSP_Ratio;
 
-  m_SSP_Time_Start_L = (1 - m_SSP_Ratio) * m_PeriodTime / 4.0;
-  m_SSP_Time_End_L = (1 + m_SSP_Ratio) * m_PeriodTime / 4.0;
-  m_SSP_Time_Start_R = (3 - m_SSP_Ratio) * m_PeriodTime / 4.0;
-  m_SSP_Time_End_R = (3 + m_SSP_Ratio) * m_PeriodTime / 4.0;
+  m_X_Swap_PeriodTime=m_PeriodTime/2.0;
+  m_X_Move_PeriodTime=m_SSP_Time;
+  m_Y_Swap_PeriodTime=m_PeriodTime;
+  m_Y_Move_PeriodTime=m_SSP_Time;
+  m_Z_Swap_PeriodTime=m_PeriodTime/2.0;
+  m_Z_Move_PeriodTime=m_SSP_Time/2.0;
+  m_A_Move_PeriodTime=m_SSP_Time;
 
-  m_Phase_Time1 = (m_SSP_Time_End_L + m_SSP_Time_Start_L) / 2.0;
-  m_Phase_Time2 = (m_SSP_Time_Start_R + m_SSP_Time_End_L) / 2.0;
-  m_Phase_Time3 = (m_SSP_Time_End_R + m_SSP_Time_Start_R) / 2.0;
+  m_SSP_Time_Start_L=(1-m_SSP_Ratio)*m_PeriodTime/4.0;
+  m_SSP_Time_End_L=(1+m_SSP_Ratio)*m_PeriodTime/4.0;
+  m_SSP_Time_Start_R=(3-m_SSP_Ratio)*m_PeriodTime/4.0;
+  m_SSP_Time_End_R=(3+m_SSP_Ratio)*m_PeriodTime/4.0;
+
+  m_Phase_Time1=(m_SSP_Time_End_L+m_SSP_Time_Start_L)/2.0;
+  m_Phase_Time2=(m_SSP_Time_Start_R+m_SSP_Time_End_L)/2.0;
+  m_Phase_Time3=(m_SSP_Time_End_R+m_SSP_Time_Start_R)/2.0;
 
   // m_pelvis_offset and m_pelvis_Swing in degrees
-  m_Pelvis_Offset = PELVIS_OFFSET;
-  m_Pelvis_Swing = m_Pelvis_Offset * 0.35;
-  m_Arm_Swing_Gain = ARM_SWING_GAIN;
+  m_Pelvis_Offset=((float)ram_data[DARWIN_WALK_PELVIS_OFFSET])*PI/1440.0;
+  m_Pelvis_Swing=m_Pelvis_Offset*0.35;
+  m_Arm_Swing_Gain=((float)ram_data[DARWIN_WALK_ARM_SWING_GAIN])/32.0;
 }
 
 void update_param_move()
 {
+  float target_x_amplitude;
+  float target_y_amplitude;
+  float target_a_amplitude;
+  static float current_x_amplitude=0;
+  static float current_y_amplitude=0;
+  static float current_a_amplitude=0;
+
+  target_x_amplitude=((float)((int8_t)ram_data[DARWIN_WALK_STEP_FW_BW]));
   // change longitudinal and transversal velocities to get to the target ones
-  if(current_x_amplitude<X_MOVE_AMPLITUDE)
+  if(current_x_amplitude<target_x_amplitude)
   {
-    current_x_amplitude+=max_acceleration*PERIOD_TIME;
-    if(current_x_amplitude>X_MOVE_AMPLITUDE)
-      current_x_amplitude=X_MOVE_AMPLITUDE;
+    current_x_amplitude+=(((float)ram_data[DARWIN_WALK_MAX_VEL])*m_PeriodTime)/1000.0;
+    if(current_x_amplitude>target_x_amplitude)
+      current_x_amplitude=target_x_amplitude;
   }
-  else if(current_x_amplitude>X_MOVE_AMPLITUDE)
+  else if(current_x_amplitude>target_x_amplitude)
   {
-    current_x_amplitude-=max_acceleration*PERIOD_TIME;
-    if(current_x_amplitude<X_MOVE_AMPLITUDE)
-      current_x_amplitude=X_MOVE_AMPLITUDE;
+    current_x_amplitude-=(((float)ram_data[DARWIN_WALK_MAX_VEL])*m_PeriodTime)/1000.0;
+    if(current_x_amplitude<target_x_amplitude)
+      current_x_amplitude=target_x_amplitude;
   }
-  m_X_Move_Amplitude = current_x_amplitude;
-  m_X_Swap_Amplitude = current_x_amplitude * STEP_FB_RATIO;
+  m_X_Move_Amplitude=current_x_amplitude;
+  m_X_Swap_Amplitude=current_x_amplitude*((float)ram_data[DARWIN_WALK_STEP_FW_BW_RATIO])/256.0;
 
   // Right/Left
-  if(current_y_amplitude<Y_MOVE_AMPLITUDE)
+  target_y_amplitude=((float)((int8_t)ram_data[DARWIN_WALK_STEP_LEFT_RIGHT]));
+  if(current_y_amplitude<target_y_amplitude)
   {
-    current_y_amplitude+=max_acceleration*PERIOD_TIME;
-    if(current_y_amplitude>Y_MOVE_AMPLITUDE)
-      current_y_amplitude=Y_MOVE_AMPLITUDE;
+    current_y_amplitude+=(((float)ram_data[DARWIN_WALK_MAX_VEL])*m_PeriodTime)/1000.0;
+    if(current_y_amplitude>target_y_amplitude)
+      current_y_amplitude=target_y_amplitude;
   }
-  else if(current_y_amplitude>Y_MOVE_AMPLITUDE)
+  else if(current_y_amplitude>target_y_amplitude)
   {
-    current_y_amplitude-=max_acceleration*PERIOD_TIME;
-    if(current_y_amplitude<Y_MOVE_AMPLITUDE)
-      current_y_amplitude=Y_MOVE_AMPLITUDE;
+    current_y_amplitude-=(((float)ram_data[DARWIN_WALK_MAX_VEL])*m_PeriodTime)/1000.0;
+    if(current_y_amplitude<target_y_amplitude)
+      current_y_amplitude=target_y_amplitude;
   }
-  m_Y_Move_Amplitude = current_y_amplitude / 2.0;
-  if(m_Y_Move_Amplitude > 0)
-    m_Y_Move_Amplitude_Shift = m_Y_Move_Amplitude;
+  m_Y_Move_Amplitude=current_y_amplitude/2.0;
+  if(m_Y_Move_Amplitude>0)
+    m_Y_Move_Amplitude_Shift=m_Y_Move_Amplitude;
   else
-    m_Y_Move_Amplitude_Shift = -m_Y_Move_Amplitude;
-  m_Y_Swap_Amplitude = Y_SWAP_AMPLITUDE + m_Y_Move_Amplitude_Shift * 0.04;
+    m_Y_Move_Amplitude_Shift=-m_Y_Move_Amplitude;
+  m_Y_Swap_Amplitude=((float)ram_data[DARWIN_WALK_SWING_RIGHT_LEFT])+m_Y_Move_Amplitude_Shift*0.04;
 
-  m_Z_Move_Amplitude = Z_MOVE_AMPLITUDE / 2.0;
-  m_Z_Move_Amplitude_Shift = m_Z_Move_Amplitude / 2.0;
-  m_Z_Swap_Amplitude = Z_SWAP_AMPLITUDE;
-  m_Z_Swap_Amplitude_Shift = m_Z_Swap_Amplitude;
+  m_Z_Move_Amplitude=((float)ram_data[DARWIN_WALK_FOOT_HEIGHT])/2.0;
+  m_Z_Move_Amplitude_Shift=m_Z_Move_Amplitude / 2.0;
+  m_Z_Swap_Amplitude=((float)ram_data[DARWIN_WALK_SWING_TOP_DOWN]);
+  m_Z_Swap_Amplitude_Shift=m_Z_Swap_Amplitude;
 
   // Direction
-  if(current_a_amplitude<A_MOVE_AMPLITUDE)
+  target_a_amplitude=((float)((int8_t)ram_data[DARWIN_WALK_STEP_DIRECTION]))/8.0;
+  if(current_a_amplitude<target_a_amplitude)
   {
-    current_a_amplitude+=max_acceleration*PERIOD_TIME;
-    if(current_a_amplitude>A_MOVE_AMPLITUDE)
-      current_a_amplitude=A_MOVE_AMPLITUDE;
+    current_a_amplitude+=(((float)ram_data[DARWIN_WALK_MAX_ROT_VEL])*m_PeriodTime)/8000.0;
+    if(current_a_amplitude>target_a_amplitude)
+      current_a_amplitude=target_a_amplitude;
   }
-  else if(current_a_amplitude>A_MOVE_AMPLITUDE)
+  else if(current_a_amplitude>target_a_amplitude)
   {
-    current_a_amplitude-=max_acceleration*PERIOD_TIME;
-    if(current_a_amplitude<A_MOVE_AMPLITUDE)
-      current_a_amplitude=A_MOVE_AMPLITUDE;
+    current_a_amplitude-=(((float)ram_data[DARWIN_WALK_MAX_ROT_VEL])*m_PeriodTime)/8000.0;
+    if(current_a_amplitude<target_a_amplitude)
+      current_a_amplitude=target_a_amplitude;
   }
 
-  if(A_MOVE_AIM_ON == 0x00)
+  if(A_MOVE_AIM_ON==0x00)
   {
-    m_A_Move_Amplitude = A_MOVE_AMPLITUDE * PI / 180.0 / 2.0;
-    if(m_A_Move_Amplitude > 0)
-      m_A_Move_Amplitude_Shift = m_A_Move_Amplitude;
+    m_A_Move_Amplitude=current_a_amplitude*PI/180.0/2.0;
+    if(m_A_Move_Amplitude>0)
+      m_A_Move_Amplitude_Shift=m_A_Move_Amplitude;
     else
-      m_A_Move_Amplitude_Shift = -m_A_Move_Amplitude;
+      m_A_Move_Amplitude_Shift=-m_A_Move_Amplitude;
   }
   else
   {
-    m_A_Move_Amplitude = -A_MOVE_AMPLITUDE * PI / 180.0 / 2.0;
-    if(m_A_Move_Amplitude > 0)
-      m_A_Move_Amplitude_Shift = -m_A_Move_Amplitude;
+    m_A_Move_Amplitude=-current_a_amplitude*PI/180.0/2.0;
+    if(m_A_Move_Amplitude>0)
+      m_A_Move_Amplitude_Shift=-m_A_Move_Amplitude;
     else
-      m_A_Move_Amplitude_Shift = m_A_Move_Amplitude;
+      m_A_Move_Amplitude_Shift=m_A_Move_Amplitude;
   }
 }
 
 void update_param_balance()
 {
-  m_X_Offset = X_OFFSET;
-  m_Y_Offset = Y_OFFSET;
-  m_Z_Offset = Z_OFFSET;
-  m_R_Offset = R_OFFSET * PI / 180.0;
-  m_P_Offset = P_OFFSET * PI / 180.0;
-  m_A_Offset = A_OFFSET * PI / 180.0;
-  m_Hip_Pitch_Offset = HIP_PITCH_OFFSET;
+  m_X_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_X_OFFSET]));
+  m_Y_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_Y_OFFSET]));
+  m_Z_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_Z_OFFSET]));
+  m_R_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_ROLL_OFFSET]))*PI/1440.0;// (r_offset/8)*(pi/180)
+  m_P_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_PITCH_OFFSET]))*PI/1440.0;// (p_offset/8)*(pi/180)
+  m_A_Offset = ((float)((int8_t)ram_data[DARWIN_WALK_YAW_OFFSET]))*PI/1440.0;// (a_offset/8)*(pi/180)
+  m_Hip_Pitch_Offset = ((float)((int16_t)(ram_data[DARWIN_WALK_HIP_PITCH_OFF_L]+(ram_data[DARWIN_WALK_HIP_PITCH_OFF_H]<<8))))/1024.0;
 }
 
 // public functions
-void walking_init(uint16_t period)
+void walking_init(uint16_t period_us)
 {
-  // initialize RAM
-  ram_write_byte(DARWIN_X_OFFSET,(uint8_t)X_OFFSET);//mm
-  ram_write_byte(DARWIN_Y_OFFSET,(uint8_t)Y_OFFSET);//mm
-  ram_write_byte(DARWIN_Z_OFFSET,(uint8_t)Z_OFFSET);//mm
-  ram_write_byte(DARWIN_ROLL,(uint8_t)(A_OFFSET*8));//degrees format 5|3
-  ram_write_byte(DARWIN_PITCH,(uint8_t)(P_OFFSET*8));//degrees format 5|3
-  ram_write_byte(DARWIN_YAW,(uint8_t)(R_OFFSET*8));//degrees  format 5|3
-  ram_write_word(DARWIN_HIP_PITCH_OFF_L,(uint16_t)(HIP_PITCH_OFFSET*1024));//degrees format 6|10
-  ram_write_word(DARWIN_PERIOD_TIME_L,(uint16_t)PERIOD_TIME);// milliseconds
-  ram_write_byte(DARWIN_DSP_RATIO,(uint8_t)(DSP_RATIO*128));//ratio [0,1] format 1|7
-  ram_write_byte(DARWIN_STEP_FW_BW_RATIO,(uint8_t)(STEP_FB_RATIO*128));//ratio [0,1] format 1|7
-  ram_write_byte(DARWIN_STEP_FW_BW,(uint8_t)(X_MOVE_AMPLITUDE));//mm
-  ram_write_byte(DARWIN_STEP_LEFT_RIGHT,(uint8_t)(Y_MOVE_AMPLITUDE));//mm
-  ram_write_byte(DARWIN_STEP_DIRECTION,(uint8_t)(A_MOVE_AMPLITUDE*8));//degrees 5|3
-  ram_write_byte(DARWIN_FOOT_HEIGHT,(uint8_t)(Z_MOVE_AMPLITUDE));//mm
-  ram_write_byte(DARWIN_SWING_RIGHT_LEFT,(uint8_t)(Y_SWAP_AMPLITUDE));//mm
-  ram_write_byte(DARWIN_SWING_TOP_DOWN,(uint8_t)(Z_SWAP_AMPLITUDE));//mm
-  ram_write_byte(DARWIN_PELVIS_OFFSET,(uint8_t)(PELVIS_OFFSET*8));//degrees 5|3
-  ram_write_byte(DARWIN_ARM_SWING_GAIN,(uint8_t)(ARM_SWING_GAIN*32));// gain 3|5
-  ram_write_byte(DARWIN_P_GAIN,(uint8_t)(P_GAIN));// servo gain
-  ram_write_byte(DARWIN_I_GAIN,(uint8_t)(I_GAIN));// servo gain
-  ram_write_byte(DARWIN_D_GAIN,(uint8_t)(D_GAIN));// servo gain
-  ram_write_byte(DARWIN_MAX_ACC,(uint8_t)(max_acceleration*1024));// maximum linear acceleration
-  ram_write_byte(DARWIN_MAX_ROT_ACC,(uint8_t)(max_rot_accel*1024));// maximum rotational acceleration
-  // initialize the internal variables
+  // initialize the internal motion variables
   m_X_Swap_Phase_Shift=PI;
   m_X_Swap_Amplitude_Shift=0.0;
   m_X_Move_Phase_Shift=PI/2.0;
@@ -272,12 +217,9 @@ void walking_init(uint16_t period)
   m_Z_Move_Phase_Shift=PI/2.0;
   m_A_Move_Phase_Shift=PI/2.0;
 
+  // initialize internal control variables
   m_Time=0;
-  walking_period=((double)period)/1000.0;
-
-  m_Body_Swing_Y=0.0;
-  m_Body_Swing_Z=0.0;
-
+  walking_period=((float)period_us)/1000.0;
   m_Ctrl_Running=0x00;
 
   update_param_time();
@@ -286,9 +228,9 @@ void walking_init(uint16_t period)
   walking_process();
 }
 
-inline void walking_set_period(uint16_t period)
+inline void walking_set_period(uint16_t period_us)
 {
-  walking_period=((double)period)/1000.0;
+  walking_period=((float)period_us)/1000.0;
 }
 
 inline uint16_t walking_get_period(void)
@@ -296,166 +238,92 @@ inline uint16_t walking_get_period(void)
   return (uint16_t)(walking_period*1000);
 }
 
-void walking_set_param(uint8_t param_id,int8_t param_value)
-{
-  uint16_t value;
-
-  switch(param_id)
-  {
-    case DARWIN_X_OFFSET: X_OFFSET=param_value;
-                          break;
-    case DARWIN_Y_OFFSET: Y_OFFSET=param_value;
-                          break;
-    case DARWIN_Z_OFFSET: Z_OFFSET=param_value;
-                          break;
-    case DARWIN_ROLL: A_OFFSET=((float)param_value)/8.0;
-                      break;
-    case DARWIN_PITCH: P_OFFSET=((float)param_value)/8.0;
-                       break;
-    case DARWIN_YAW: R_OFFSET=((float)param_value)/8.0;
-                     break;
-    case DARWIN_HIP_PITCH_OFF_L: value=(uint16_t)(HIP_PITCH_OFFSET*1024);
-                                 value&=0xFF00;
-                                 value+=param_value;
-                                 HIP_PITCH_OFFSET=((float)value)/1024.0;
-                                 break;
-    case DARWIN_HIP_PITCH_OFF_H: value=(uint16_t)(HIP_PITCH_OFFSET*1024);
-                                 value&=0x00FF;
-                                 value+=param_value*256;
-                                 HIP_PITCH_OFFSET=((float)value)/1024.0;
-                                 break;
-    case DARWIN_PERIOD_TIME_L: value=(uint16_t)PERIOD_TIME;
-                               value&=0xFF00;
-                               value+=param_value;
-                               PERIOD_TIME=value;
-                               break;
-    case DARWIN_PERIOD_TIME_H: value=(uint16_t)PERIOD_TIME;
-                               value&=0x00FF;
-                               value+=param_value*256;
-                               PERIOD_TIME=value;
-                               break;
-    case DARWIN_DSP_RATIO: DSP_RATIO=((float)param_value)/128.0;
-                           break;
-    case DARWIN_STEP_FW_BW_RATIO: STEP_FB_RATIO=((float)param_value)/128.0;
-                                  break;
-    case DARWIN_STEP_FW_BW: X_MOVE_AMPLITUDE=param_value;
-                            break;
-    case DARWIN_STEP_LEFT_RIGHT: Y_MOVE_AMPLITUDE=param_value;
-                                 break;
-    case DARWIN_STEP_DIRECTION: A_MOVE_AMPLITUDE=((float)param_value)/8.0;
-                                break;
-    case DARWIN_FOOT_HEIGHT: Z_MOVE_AMPLITUDE=param_value;
-                             break;
-    case DARWIN_SWING_RIGHT_LEFT: Y_SWAP_AMPLITUDE=param_value;
-                                  break;
-    case DARWIN_SWING_TOP_DOWN: Z_SWAP_AMPLITUDE=param_value;
-                                break;
-    case DARWIN_PELVIS_OFFSET: PELVIS_OFFSET=((float)param_value)/8.0;
-                               break;
-    case DARWIN_ARM_SWING_GAIN: ARM_SWING_GAIN=((float)param_value)/32.0;
-                                break;
-    case DARWIN_P_GAIN: P_GAIN=param_value;
-                        break;
-    case DARWIN_I_GAIN: I_GAIN=param_value;
-                        break;
-    case DARWIN_D_GAIN: D_GAIN=param_value;
-                        break;
-    case DARWIN_MAX_ACC: max_acceleration=param_value/1024.0;
-                         break;
-    case DARWIN_MAX_ROT_ACC: max_rot_accel=param_value/1024.0;
-                             break;
-  }  
-  ram_write_byte(param_id,param_value);
-}
-
 void walking_start(void)
 {
-  ram_set_bit(DARWIN_WALK_STATUS,0);
-  ram_set_bit(DARWIN_WALK_CONTROL,0);
+  ram_data[DARWIN_WALK_CNTRL]|=WALK_STATUS;
   m_Ctrl_Running=0x01;
 }
 
 void walking_stop(void)
 {
-  ram_set_bit(DARWIN_WALK_CONTROL,1);
   m_Ctrl_Running=0x00;
 }
 
 uint8_t is_walking(void)
 {
-  uint8_t walking;
-
-  ram_read_byte(DARWIN_WALK_STATUS,&walking);
-
-  return walking;
+  if(ram_data[DARWIN_WALK_CNTRL]&WALK_STATUS)
+    return 0x01;
+  else 
+    return 0x00;
 }
 
 // motion manager interface functions
 void walking_process(void)
 {
-  float x_swap, y_swap, z_swap, a_swap, b_swap, c_swap;
-  float x_move_r, y_move_r, z_move_r, a_move_r, b_move_r, c_move_r;
-  float x_move_l, y_move_l, z_move_l, a_move_l, b_move_l, c_move_l;
-  float pelvis_offset_r, pelvis_offset_l;
-  float angle[14], ep[12];
-  uint8_t walking,i;
-
-  //R_HIP_YAW, R_HIP_ROLL, R_HIP_PITCH, R_KNEE, R_ANKLE_PITCH, R_ANKLE_ROLL, L_HIP_YAW, L_HIP_ROLL, L_HIP_PITCH, L_KNEE, L_ANKLE_PITCH, L_ANKLE_ROLL, R_ARM_SWING, L_ARM_SWING
-  float initAngle[14] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-48.345,41.313};
-
-  if(m_Time == 0)
+  float x_swap,y_swap,z_swap,a_swap,b_swap,c_swap;
+  float x_move_r,y_move_r,z_move_r,a_move_r,b_move_r,c_move_r;
+  float x_move_l,y_move_l,z_move_l,a_move_l,b_move_l,c_move_l;
+  float pelvis_offset_r,pelvis_offset_l;
+//  float m_Body_Swing_Y,m_Body_Swing_Z;
+  float angle[14],ep[12];
+
+  if(m_Time==0)
   {
     update_param_time();
-    m_Phase = PHASE0;
-    if(m_Ctrl_Running == 0x00)
+    ram_data[DARWIN_WALK_CNTRL]&=(~WALK_PHASE);
+    ram_data[DARWIN_WALK_CNTRL]|=PHASE0;
+    if(m_Ctrl_Running==0x00)
     {
-      if(m_X_Move_Amplitude == 0 && m_Y_Move_Amplitude == 0 && m_A_Move_Amplitude == 0)
-        ram_write_byte(DARWIN_WALK_STATUS,0x00);
+      if(m_X_Move_Amplitude==0 && m_Y_Move_Amplitude==0 && m_A_Move_Amplitude==0)
+        ram_data[DARWIN_WALK_CNTRL]&=(~WALK_STATUS);
       else
       {
-        X_MOVE_AMPLITUDE = 0;
-        Y_MOVE_AMPLITUDE = 0;
-        A_MOVE_AMPLITUDE = 0;
+        ram_data[DARWIN_WALK_STEP_FW_BW]=0.0;
+        ram_data[DARWIN_WALK_STEP_LEFT_RIGHT]=0.0;
+        ram_data[DARWIN_WALK_STEP_DIRECTION]=0.0;
       }
     }
   }
-  else if(m_Time >= (m_Phase_Time1 - walking_period/2.0) && m_Time < (m_Phase_Time1 + walking_period/2.0))
+  else if(m_Time>=(m_Phase_Time1-walking_period/2.0) && m_Time<(m_Phase_Time1+walking_period/2.0))
   {
     update_param_move();
-    m_Phase = PHASE1;
+    ram_data[DARWIN_WALK_CNTRL]&=(~WALK_PHASE);
+    ram_data[DARWIN_WALK_CNTRL]|=PHASE1;
   }
-  else if(m_Time >= (m_Phase_Time2 - walking_period/2.0) && m_Time < (m_Phase_Time2 + walking_period/2.0))
+  else if(m_Time>=(m_Phase_Time2-walking_period/2.0) && m_Time<(m_Phase_Time2+walking_period/2.0))
   {
     update_param_time();
-    m_Time = m_Phase_Time2;
-    m_Phase = PHASE2;
-    if(m_Ctrl_Running == 0x00)
+    m_Time=m_Phase_Time2;
+    ram_data[DARWIN_WALK_CNTRL]&=(~WALK_PHASE);
+    ram_data[DARWIN_WALK_CNTRL]|=PHASE2;
+    if(m_Ctrl_Running==0x00)
     {
-      if(m_X_Move_Amplitude == 0 && m_Y_Move_Amplitude == 0 && m_A_Move_Amplitude == 0)
-        ram_write_byte(DARWIN_WALK_STATUS,0x00);
+      if(m_X_Move_Amplitude==0 && m_Y_Move_Amplitude==0 && m_A_Move_Amplitude==0)
+        ram_data[DARWIN_WALK_CNTRL]&=~WALK_STATUS;
       else
       {
-        X_MOVE_AMPLITUDE = 0;
-        Y_MOVE_AMPLITUDE = 0;
-        A_MOVE_AMPLITUDE = 0;
+        ram_data[DARWIN_WALK_STEP_FW_BW]=0.0;
+        ram_data[DARWIN_WALK_STEP_LEFT_RIGHT]=0.0;
+        ram_data[DARWIN_WALK_STEP_DIRECTION]=0.0;
       }
     }
   }
-  else if(m_Time >= (m_Phase_Time3 - walking_period/2.0) && m_Time < (m_Phase_Time3 + walking_period/2.0))
+  else if(m_Time>=(m_Phase_Time3-walking_period/2.0) && m_Time<(m_Phase_Time3+walking_period/2.0))
   {
     update_param_move();
-    m_Phase = PHASE3;
+    ram_data[DARWIN_WALK_CNTRL]&=(~WALK_PHASE);
+    ram_data[DARWIN_WALK_CNTRL]|=PHASE3;
   }
   update_param_balance();
 
   // Compute endpoints
-  x_swap = wsin(m_Time, m_X_Swap_PeriodTime, m_X_Swap_Phase_Shift, m_X_Swap_Amplitude, m_X_Swap_Amplitude_Shift);
-  y_swap = wsin(m_Time, m_Y_Swap_PeriodTime, m_Y_Swap_Phase_Shift, m_Y_Swap_Amplitude, m_Y_Swap_Amplitude_Shift);
-  z_swap = wsin(m_Time, m_Z_Swap_PeriodTime, m_Z_Swap_Phase_Shift, m_Z_Swap_Amplitude, m_Z_Swap_Amplitude_Shift);
-  a_swap = 0;
-  b_swap = 0;
-  c_swap = 0;
-  if(m_Time <= m_SSP_Time_Start_L)
+  x_swap=wsin(m_Time,m_X_Swap_PeriodTime,m_X_Swap_Phase_Shift,m_X_Swap_Amplitude,m_X_Swap_Amplitude_Shift);
+  y_swap=wsin(m_Time,m_Y_Swap_PeriodTime,m_Y_Swap_Phase_Shift,m_Y_Swap_Amplitude,m_Y_Swap_Amplitude_Shift);
+  z_swap=wsin(m_Time,m_Z_Swap_PeriodTime,m_Z_Swap_Phase_Shift,m_Z_Swap_Amplitude,m_Z_Swap_Amplitude_Shift);
+  a_swap=0;
+  b_swap=0;
+  c_swap=0;
+  if(m_Time<=m_SSP_Time_Start_L)
   {
     x_move_l=wsin(m_SSP_Time_Start_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift);
     y_move_l=wsin(m_SSP_Time_Start_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift);
@@ -465,10 +333,10 @@ void walking_process(void)
     y_move_r=wsin(m_SSP_Time_Start_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift);
     z_move_r=wsin(m_SSP_Time_Start_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift);
     c_move_r=wsin(m_SSP_Time_Start_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift);
-    pelvis_offset_l = 0;
-    pelvis_offset_r = 0;
+    pelvis_offset_l=0;
+    pelvis_offset_r=0;
   }
-  else if(m_Time <= m_SSP_Time_End_L)
+  else if(m_Time<=m_SSP_Time_End_L)
   {
     x_move_l=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift);
     y_move_l=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift);
@@ -481,7 +349,7 @@ void walking_process(void)
     pelvis_offset_l=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,m_Pelvis_Swing/2.0,m_Pelvis_Swing/2.0);
     pelvis_offset_r=wsin(m_Time,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_L,-m_Pelvis_Offset/2.0,-m_Pelvis_Offset/2.0);
   }
-  else if(m_Time <= m_SSP_Time_Start_R)
+  else if(m_Time<=m_SSP_Time_Start_R)
   {
     x_move_l=wsin(m_SSP_Time_End_L,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_L,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift);
     y_move_l=wsin(m_SSP_Time_End_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift);
@@ -491,10 +359,10 @@ void walking_process(void)
     y_move_r=wsin(m_SSP_Time_End_L,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_L,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift);
     z_move_r=wsin(m_SSP_Time_Start_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift);
     c_move_r=wsin(m_SSP_Time_End_L,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_L,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift);
-    pelvis_offset_l = 0;
-    pelvis_offset_r = 0;
+    pelvis_offset_l=0.0;
+    pelvis_offset_r=0.0;
   }
-  else if(m_Time <= m_SSP_Time_End_R)
+  else if(m_Time<=m_SSP_Time_End_R)
   {
     x_move_l=wsin(m_Time,m_X_Move_PeriodTime,m_X_Move_Phase_Shift+2.0*PI/m_X_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_X_Move_Amplitude,m_X_Move_Amplitude_Shift);
     y_move_l=wsin(m_Time,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,m_Y_Move_Amplitude,m_Y_Move_Amplitude_Shift);
@@ -517,81 +385,125 @@ void walking_process(void)
     y_move_r=wsin(m_SSP_Time_End_R,m_Y_Move_PeriodTime,m_Y_Move_Phase_Shift+2.0*PI/m_Y_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_Y_Move_Amplitude,-m_Y_Move_Amplitude_Shift);
     z_move_r=wsin(m_SSP_Time_End_R,m_Z_Move_PeriodTime,m_Z_Move_Phase_Shift+2.0*PI/m_Z_Move_PeriodTime*m_SSP_Time_Start_R,m_Z_Move_Amplitude,m_Z_Move_Amplitude_Shift);
     c_move_r=wsin(m_SSP_Time_End_R,m_A_Move_PeriodTime,m_A_Move_Phase_Shift+2.0*PI/m_A_Move_PeriodTime*m_SSP_Time_Start_R+PI,-m_A_Move_Amplitude,-m_A_Move_Amplitude_Shift);
-    pelvis_offset_l = 0;
-    pelvis_offset_r = 0;
+    pelvis_offset_l=0.0;
+    pelvis_offset_r=0.0;
   }
-  a_move_l = 0;
-  b_move_l = 0;
-  a_move_r = 0;
-  b_move_r = 0;
-
-  ep[0] = x_swap + x_move_r + m_X_Offset;
-  ep[1] = y_swap + y_move_r - m_Y_Offset / 2.0;
-  ep[2] = z_swap + z_move_r + m_Z_Offset;
-  ep[3] = a_swap + a_move_r - m_R_Offset / 2.0;
-  ep[4] = b_swap + b_move_r + m_P_Offset;
-  ep[5] = c_swap + c_move_r - m_A_Offset / 2.0;
-  ep[6] = x_swap + x_move_l + m_X_Offset;
-  ep[7] = y_swap + y_move_l + m_Y_Offset / 2.0;
-  ep[8] = z_swap + z_move_l + m_Z_Offset;
-  ep[9] = a_swap + a_move_l + m_R_Offset / 2.0;
-  ep[10] = b_swap + b_move_l + m_P_Offset;
-  ep[11] = c_swap + c_move_l + m_A_Offset / 2.0;
+  a_move_l=0.0;
+  b_move_l=0.0;
+  a_move_r=0.0;
+  b_move_r=0.0;
+
+  ep[0]=x_swap+x_move_r+m_X_Offset;
+  ep[1]=y_swap+y_move_r-m_Y_Offset / 2.0;
+  ep[2]=z_swap+z_move_r+m_Z_Offset;
+  ep[3]=a_swap+a_move_r-m_R_Offset / 2.0;
+  ep[4]=b_swap+b_move_r+m_P_Offset;
+  ep[5]=c_swap+c_move_r-m_A_Offset / 2.0;
+  ep[6]=x_swap+x_move_l+m_X_Offset;
+  ep[7]=y_swap+y_move_l+m_Y_Offset / 2.0;
+  ep[8]=z_swap+z_move_l+m_Z_Offset;
+  ep[9]=a_swap+a_move_l+m_R_Offset / 2.0;
+  ep[10]=b_swap+b_move_l+m_P_Offset;
+  ep[11]=c_swap+c_move_l+m_A_Offset / 2.0;
+
   // Compute body swing
-  if(m_Time <= m_SSP_Time_End_L)
+/*  if(m_Time<=m_SSP_Time_End_L)
   {
-    m_Body_Swing_Y = -ep[7];
-    m_Body_Swing_Z = ep[8];
+    m_Body_Swing_Y=-ep[7];
+    m_Body_Swing_Z=ep[8];
   }
   else
   {
-    m_Body_Swing_Y = -ep[1];
-    m_Body_Swing_Z = ep[2];
+    m_Body_Swing_Y=-ep[1];
+    m_Body_Swing_Z=ep[2];
   }
-  m_Body_Swing_Z -= LEG_LENGTH;
+  m_Body_Swing_Z-=DARWIN_LEG_LENGTH;*/
 
   // Compute arm swing
-  if(m_X_Move_Amplitude == 0)
+  if(m_X_Move_Amplitude==0)
   {
-    angle[12] = 0; // Right
-    angle[13] = 0; // Left
+    angle[12]=0; // Right
+    angle[13]=0; // Left
   }
   else
   {
-    angle[12] = wsin(m_Time, m_PeriodTime, PI * 1.5, -m_X_Move_Amplitude * m_Arm_Swing_Gain, 0);
-    angle[13] = wsin(m_Time, m_PeriodTime, PI * 1.5, m_X_Move_Amplitude * m_Arm_Swing_Gain, 0);
+    angle[12]=wsin(m_Time,m_PeriodTime,0.0,-m_X_Move_Amplitude*m_Arm_Swing_Gain,0.0);
+    angle[13]=wsin(m_Time,m_PeriodTime,0.0,m_X_Move_Amplitude*m_Arm_Swing_Gain,0.0);
   }
-  ram_read_byte(DARWIN_WALK_STATUS,&walking);
-  if(walking == 0x01)
+
+  if(ram_data[DARWIN_WALK_CNTRL]&WALK_STATUS)
   {
     m_Time += walking_period;
     if(m_Time >= m_PeriodTime)
       m_Time = 0;
   }
-  // Compute angles
-  if((computeIK(&angle[0], ep[0], ep[1], ep[2], ep[3], ep[4], ep[5]) == 1)
-      && (computeIK(&angle[6], ep[6], ep[7], ep[8], ep[9], ep[10], ep[11]) == 1))
-  {
-    for(i=0; i<12; i++)
-      angle[i] *= 180.0 / PI;
-  }
-  else
-    return;// Do not use angle;
+
+  // Compute angles with the inverse kinematics
+  if((darwin_leg_ik(&angle[0],ep[0],ep[1],ep[2],ep[3],ep[4],ep[5])!=1) || 
+     (darwin_leg_ik(&angle[6],ep[6],ep[7],ep[8],ep[9],ep[10],ep[11])!=1))
+    return;// Do not use angles
 
   // Compute motor value
-  for(i=0; i<14; i++)
+  if(manager_get_module(R_HIP_YAW)==MM_WALKING)
+    manager_current_angles[R_HIP_YAW]=((180.0*(angle[0]-PI/4.0))/PI)*65536.0;
+  if(manager_get_module(R_HIP_ROLL)==MM_WALKING)
+    manager_current_angles[R_HIP_ROLL]=((180.0*(angle[1]+pelvis_offset_r))/PI)*65536.0;
+  if(manager_get_module(R_HIP_PITCH)==MM_WALKING)
+    manager_current_angles[R_HIP_PITCH]=((180.0*(angle[2]-DARWIN_PITCH_OFFSET))/PI-m_Hip_Pitch_Offset)*65536.0;
+  if(manager_get_module(R_KNEE)==MM_WALKING)
+    manager_current_angles[R_KNEE]=((-180.0*angle[3])/PI)*65536.0;
+  if(manager_get_module(R_ANKLE_PITCH)==MM_WALKING)
+    manager_current_angles[R_ANKLE_PITCH]=((-180.0*(angle[4]+DARWIN_PITCH_OFFSET))/PI)*65536.0;
+  if(manager_get_module(R_ANKLE_ROLL)==MM_WALKING)
+    manager_current_angles[R_ANKLE_ROLL]=((-180.0*angle[5])/PI)*65536.0;
+  if(manager_get_module(L_HIP_YAW)==MM_WALKING)
+    manager_current_angles[L_HIP_YAW]=((180.0*(angle[6]+PI/4.0))/PI)*65536.0;
+  if(manager_get_module(L_HIP_ROLL)==MM_WALKING)
+    manager_current_angles[L_HIP_ROLL]=((180.0*(angle[7]+pelvis_offset_l))/PI)*65536.0;
+  if(manager_get_module(L_HIP_PITCH)==MM_WALKING)
+    manager_current_angles[L_HIP_PITCH]=((-180.0*(angle[8]-DARWIN_PITCH_OFFSET))/PI+m_Hip_Pitch_Offset)*65536.0;
+  if(manager_get_module(L_KNEE)==MM_WALKING)
+    manager_current_angles[L_KNEE]=((180.0*angle[9])/PI)*65536.0;
+  if(manager_get_module(L_ANKLE_PITCH)==MM_WALKING)
+    manager_current_angles[L_ANKLE_PITCH]=((180.0*(angle[10]+DARWIN_PITCH_OFFSET))/PI)*65536.0;
+  if(manager_get_module(L_ANKLE_ROLL)==MM_WALKING)
+    manager_current_angles[L_ANKLE_ROLL]=((-180.0*angle[11])/PI)*65536.0;
+  if(manager_get_module(R_SHOULDER_PITCH)==MM_WALKING)
+    manager_current_angles[R_SHOULDER_PITCH]=(angle[12]-90.0)*65536.0;
+  if(manager_get_module(L_SHOULDER_PITCH)==MM_WALKING)
+    manager_current_angles[L_SHOULDER_PITCH]=(-angle[13]+90.0)*65536.0;
+}
+
+// operation functions
+uint8_t walking_in_range(unsigned short int address, unsigned short int length)
+{
+  if(ram_in_window(WALK_BASE_ADDRESS,WALK_MEM_LENGTH,address,length) ||
+     ram_in_window(WALK_EEPROM_ADDRESS,WALK_EEPROM_LENGTH,address,length))
+    return 0x01;
+  else
+    return 0x00;
+}
+
+void walking_process_read_cmd(unsigned short int address,unsigned short int length,unsigned char *data)
+{
+
+}
+
+void walking_process_write_cmd(unsigned short int address,unsigned short int length,unsigned char *data)
+{
+  uint16_t i;
+
+  // walk control
+  if(ram_in_range(DARWIN_WALK_CNTRL,address,length))
   {
-    if(manager_get_module(i)==MM_WALKING)
-    {
-      if(i==1)
-        current_angles[servo_seq[i]]=(initAngle[i]+(float)dir[i]*(angle[i] + pelvis_offset_r))*65536;// format 9|7
-      else if(i==7)
-        current_angles[servo_seq[i]]=(initAngle[i]+(float)dir[i]*(angle[i] + pelvis_offset_l))*65536;// format 9|7
-      else if(i==2 || i==8)
-        current_angles[servo_seq[i]]=(initAngle[i]+(float)dir[i]*(angle[i] - HIP_PITCH_OFFSET))*65536;// format 9|7
-      else
-        current_angles[servo_seq[i]]=(initAngle[i]+(float)dir[i] * angle[i])*65536;//format 9|7
-    }
+    if(data[DARWIN_WALK_CNTRL-address]&WALK_START)
+      walking_start();
+    if(data[DARWIN_WALK_CNTRL-address]&WALK_STOP)
+      walking_stop();
   }
+  // walk parameters
+  for(i=WALK_EEPROM_ADDRESS;i<=WALK_EEPROM_ADDRESS+WALK_EEPROM_LENGTH;i++)
+    if(ram_in_range(i,address,length))
+      ram_data[i]=data[i-address];
 }