diff --git a/include/adc_dma.h b/include/adc_dma.h
index c593122317b670ccb1c49b6f0233d0665732f972..085346b7abcebecd9964b0290b93dc87a9737aea 100755
--- a/include/adc_dma.h
+++ b/include/adc_dma.h
@@ -6,15 +6,29 @@ extern "C" {
 #endif
 
 #include "stm32f1xx.h"
-#include "adc_dma_registers.h"
 #include "memory.h"
+#include "scheduler.h"
 
 #define      ADC_NUM_CHANNELS      12
 
 typedef enum {ADC_CH1=0,ADC_CH2=1,ADC_CH3=2,ADC_CH4=3,ADC_CH5=4,ADC_CH6=5,ADC_CH7=6,ADC_CH8=7,
               ADC_CH9=8,ADC_CH10=9,ADC_CH12=10} adc_ch_t;
 
-uint8_t adc_init(TMemory *memory);
+typedef struct
+{
+  ADC_HandleTypeDef handle1;
+  ADC_HandleTypeDef handle2;
+  DMA_HandleTypeDef dma_handle;
+  TScheduler *scheduler;
+  /* memory module */
+  TMemory *memory;
+  TMemModule mem_module;
+  unsigned short int ram_base_address;
+  unsigned short int eeprom_base_address;
+  uint32_t data[6];// temporal buffer to store ADC data before conversion
+}TADC;
+
+uint8_t adc_init(TMemory *memory,TScheduler *scheduler,unsigned short int eeprom_base_address,unsigned short int ram_base_address);
 void adc_start(void);
 void adc_set_period(uint8_t period_ms);
 uint8_t adc_get_period(void);
diff --git a/include/adc_dma_registers.h b/include/adc_dma_registers.h
index a0a63669cf3fdf56043a96788aa992cdcca6876d..a4f6048a08b5017fb7b502700ac8f360c90dc4de 100644
--- a/include/adc_dma_registers.h
+++ b/include/adc_dma_registers.h
@@ -1,30 +1,34 @@
 #ifndef _ADC_DMA_REGISTERS_H
 #define _ADC_DMA_REGISTERS_H
 
-#ifndef RAM_ADC_DMA_BASE_ADDRESS
-  #define RAM_ADC_DMA_BASE_ADDRESS            ((unsigned short int)0x0000)
-#endif
+#define EEPROM_ADC_DMA_LENGTH                 1
+
+#define ADC_PERIOD_OFFSET                     0
+
+#define adc_eeprom_data(name,section_name,base_address,DEFAULT_PERIOD) \
+unsigned short int name##_eeprom_data[] __attribute__ ((section (section_name))) __attribute__ ((aligned (4)))={ \
+  DEFAULT_PERIOD&0x00FF,base_address+ADC_PERIOD_OFFSET \
+};
 
-#define RAM_ADC_DMA_LENGTH                    26
+#define RAM_ADC_DMA_LENGTH                    25
 
-#define ADC_CNTRL                             RAM_ADC_DMA_BASE_ADDRESS// bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0
-                                                                      //       |       |       |       |       |       |       | Enable
-#define ADC_PERIOD                            (RAM_ADC_DMA_BASE_ADDRESS+1)
-#define ADC_CH1_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+2)
-#define ADC_CH2_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+4)
-#define ADC_CH3_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+6)
-#define ADC_CH4_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+8)
-#define ADC_CH5_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+10)
-#define ADC_CH6_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+12)
-#define ADC_CH7_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+14)
-#define ADC_CH8_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+16)
-#define ADC_CH9_VOLTAGE                       (RAM_ADC_DMA_BASE_ADDRESS+18)
-#define ADC_CH10_VOLTAGE                      (RAM_ADC_DMA_BASE_ADDRESS+20)
-#define ADC_TEMP                              (RAM_ADC_DMA_BASE_ADDRESS+22)
-#define ADC_CH12_VOLTAGE                      (RAM_ADC_DMA_BASE_ADDRESS+24)
+#define ADC_CONTROL_OFFSET                    0// bit 7 | bit 6 | bit 5 |  bit 4  | bit 3 | bit 2 | bit 1 | bit 0
+                                               //       |       |       | running |       |       | stop  | start 
 
 #define ADC_START                             0x01
 #define ADC_STOP                              0x02
 #define ADC_RUNNING                           0x10
+#define ADC_CH1_VOLTAGE_OFFSET                1
+#define ADC_CH2_VOLTAGE_OFFSET                3
+#define ADC_CH3_VOLTAGE_OFFSET                5
+#define ADC_CH4_VOLTAGE_OFFSET                7
+#define ADC_CH5_VOLTAGE_OFFSET                9
+#define ADC_CH6_VOLTAGE_OFFSET                11
+#define ADC_CH7_VOLTAGE_OFFSET                13
+#define ADC_CH8_VOLTAGE_OFFSET                15
+#define ADC_CH9_VOLTAGE_OFFSET                17
+#define ADC_CH10_VOLTAGE_OFFSET               19
+#define ADC_TEMP_OFFSET                       21
+#define ADC_CH12_VOLTAGE_OFFSET               23
 
 #endif
diff --git a/include/darwin_conf.h b/include/darwin_conf.h
index b3af0df0b573fffb92a813faa7ba0d71aba194ce..ea4ab3783c4891f69f5108a6a20a66afde638a71 100644
--- a/include/darwin_conf.h
+++ b/include/darwin_conf.h
@@ -56,6 +56,10 @@
 /* IMU */
 #define RAM_IMU_MM_BASE_ADDRESS                ((unsigned short int)0x0188)
 
+/* ADC */
+#define RAM_ADC_DMA_BASE_ADDRESS               ((unsigned short int)0x0193)
+#define EEPROM_ADC_DMA_BASE_ADDRESS            ((unsigned short int)0x0007)
+
 /* EEPROM default values */
 /* Dynamixel slave */
 #define DARWIN_DEVICE_MODEL                    0x7300
@@ -123,5 +127,6 @@
 #define DEFAULT_WALK_L_ANKLE_ROLL_SERVO_ID     0x0012
 #define DEFAULT_WALK_L_SHOULDER_PITCH_SERVO_ID 0x0002
 
+#define DEFAULT_ADC_PERIOD                     0x000A
 
 #endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5b017b947933eda74a3dea822fc8396220db873a..4217ec39947bd93fd9289e717f38fc93d12a6aac 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,8 +2,9 @@ SET(sources ${CMAKE_CURRENT_SOURCE_DIR}/cm730_fw.c
             ${CMAKE_CURRENT_SOURCE_DIR}/system_stm32f1xx.c
             #${CMAKE_CURRENT_SOURCE_DIR}/gpio.c
             ${CMAKE_CURRENT_SOURCE_DIR}/darwin_sch.c
+            ${CMAKE_CURRENT_SOURCE_DIR}/darwin_sch2.c
             ${CMAKE_CURRENT_SOURCE_DIR}/darwin_time.c
-            #${CMAKE_CURRENT_SOURCE_DIR}/adc_dma.c
+            ${CMAKE_CURRENT_SOURCE_DIR}/adc_dma.c
             ${CMAKE_CURRENT_SOURCE_DIR}/darwin_imu.c
             ${CMAKE_CURRENT_SOURCE_DIR}/darwin_dyn_slave.c
             ${CMAKE_CURRENT_SOURCE_DIR}/darwin_dyn_master.c
diff --git a/src/adc_dma.c b/src/adc_dma.c
index cebb7a93f7e6d133e49aeec4b93edf75c18e2828..f1799eeb9a5c5903796c12a1cd8f75ab2e4b0e90 100755
--- a/src/adc_dma.c
+++ b/src/adc_dma.c
@@ -1,5 +1,7 @@
 #include "adc_dma.h"
+#include "adc_dma_registers.h"
 #include "ram.h"
+#include "eeprom.h"
  
 #define ADC1_CH1                  ADC_CHANNEL_0
 #define ADC1_CH2                  ADC_CHANNEL_5
@@ -60,28 +62,15 @@
 #define ADC_DMA_IRQn              DMA1_Channel1_IRQn
 #define ADC_DMA_IRQHandler        DMA1_Channel1_IRQHandler
 
-#define ADC_TIMER                 TIM1
-#define ENABLE_ADC_TIMER_CLK      __HAL_RCC_TIM1_CLK_ENABLE()
-#define ADC_TIMER_IRQn            TIM1_CC_IRQn
-#define ADC_TIMER_IRQHandler      TIM1_CC_IRQHandler
-
 // temperature conversion functions
 #define TEMP_V25                  1.43// ADC voltage at 25 degrees in V
 #define TEMP_INV_SLOPE            232.558// ADC slope in degree/mV
 // general voltage conversion
 #define VOLTAGE_DELTA             0.000805664
 
-// private variables
-ADC_HandleTypeDef hadc1;
-ADC_HandleTypeDef hadc2;
-DMA_HandleTypeDef hdma_adc1; 
-TIM_HandleTypeDef ADC_TIM_Handle;
-
-/* memory module */
-TMemModule adc_mem_module;
+TADC darwin_adc;
 
-uint32_t adc_data[6];// temporal buffer to store ADC data before conversion
-uint16_t adc_period_ms;
+adc_eeprom_data(adc_dma,".eeprom",EEPROM_ADC_DMA_BASE_ADDRESS,DEFAULT_ADC_PERIOD);
 
 // private functions
 uint16_t adc_convert_temperature(uint16_t value)
@@ -104,107 +93,73 @@ uint16_t adc_convert_voltage(uint16_t value)
 
 void adc_write_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
 {
-  if(ram_in_range(ADC_CNTRL,address,length))
+  TADC *adc=(TADC *)module;
+  unsigned short int eeprom_offset,ram_offset;
+
+  eeprom_offset=address-adc->eeprom_base_address;
+  if(ram_in_window(adc->eeprom_base_address+ADC_PERIOD_OFFSET,1,address,length))
+    adc_set_period(data[ADC_PERIOD_OFFSET-eeprom_offset]);
+
+  ram_offset=address-adc->ram_base_address;
+  if(ram_in_range(adc->ram_base_address+ADC_CONTROL_OFFSET,address,length))
   {
-    if(data[ADC_CNTRL-address]&ADC_START)
+    if(data[ADC_CONTROL_OFFSET-ram_offset]&ADC_START)
       adc_start();
-    else if(data[ADC_CNTRL-address]&ADC_STOP)
+    if(data[ADC_CONTROL_OFFSET-ram_offset]&ADC_STOP)
       adc_stop();
   }
-  if(ram_in_range(ADC_PERIOD,address,length))
-    adc_set_period(data[ADC_PERIOD-address]);
 }
 
 void adc_read_cmd(void *module,unsigned short int address,unsigned short int length,unsigned char *data)
 {
-  ram_read_table(address,length,data);
+  ram_read_table(module,address,length,data);
 }
 
 // interrupt handlers
-void ADC_TIMER_IRQHandler(void)
-{
-  uint32_t capture;
-
-  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_CC1) != RESET)
-  {
-    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_CC1) !=RESET)
-    {
-      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_CC1);
-      capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_1);
-      __HAL_TIM_SET_COMPARE(&ADC_TIM_Handle, TIM_CHANNEL_1, (capture + adc_period_ms));
-    }
-  }
-  /* TIM Update event */
-  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_UPDATE) != RESET)
-    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_UPDATE) !=RESET)
-      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_UPDATE);
-  /* TIM Break input event */
-  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_BREAK) != RESET)
-    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_BREAK) !=RESET)
-      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_BREAK);
-  /* TIM Trigger detection event */
-  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_TRIGGER) != RESET)
-    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_TRIGGER) !=RESET)
-      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_IT_TRIGGER);
-  /* TIM commutation event */
-  if(__HAL_TIM_GET_FLAG(&ADC_TIM_Handle, TIM_FLAG_COM) != RESET)
-    if(__HAL_TIM_GET_IT_SOURCE(&ADC_TIM_Handle, TIM_IT_COM) !=RESET)
-      __HAL_TIM_CLEAR_IT(&ADC_TIM_Handle, TIM_FLAG_COM);
-}
-
 void ADC_DMA_IRQHandler(void)
 {
   uint16_t value,i;
 
   /* Transfer Error Interrupt management ***************************************/
-  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1)) != RESET)
-    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TE) != RESET)
-      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_adc1));
+  if(__HAL_DMA_GET_FLAG(&(darwin_adc.dma_handle), __HAL_DMA_GET_TE_FLAG_INDEX(&darwin_adc.dma_handle)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&darwin_adc.dma_handle, DMA_IT_TE) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&darwin_adc.dma_handle, __HAL_DMA_GET_TE_FLAG_INDEX(&darwin_adc.dma_handle));
   /* Half Transfer Complete Interrupt management ******************************/
-  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1)) != RESET)
-    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_HT) != RESET)
-      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1));
+  if(__HAL_DMA_GET_FLAG(&darwin_adc.dma_handle, __HAL_DMA_GET_HT_FLAG_INDEX(&darwin_adc.dma_handle)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&darwin_adc.dma_handle, DMA_IT_HT) != RESET)
+      __HAL_DMA_CLEAR_FLAG(&darwin_adc.dma_handle, __HAL_DMA_GET_HT_FLAG_INDEX(&darwin_adc.dma_handle));
   /* Transfer Complete Interrupt management ***********************************/
-  if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1)) != RESET)
-    if(__HAL_DMA_GET_IT_SOURCE(&hdma_adc1, DMA_IT_TC) != RESET)
+  if(__HAL_DMA_GET_FLAG(&darwin_adc.dma_handle, __HAL_DMA_GET_TC_FLAG_INDEX(&darwin_adc.dma_handle)) != RESET)
+    if(__HAL_DMA_GET_IT_SOURCE(&darwin_adc.dma_handle, DMA_IT_TC) != RESET)
     {
-      __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
+      __HAL_DMA_CLEAR_FLAG(&darwin_adc.dma_handle, __HAL_DMA_GET_TC_FLAG_INDEX(&darwin_adc.dma_handle));
       for(i=0;i<6;i++)
       {
         if(i==5)
         {
-          value=adc_convert_temperature(adc_data[i]&0x0000FFFF);
-          ram_data[ADC_TEMP]=value%256;
-          ram_data[ADC_TEMP+1]=value/256;
+          value=adc_convert_temperature(darwin_adc.data[i]&0x0000FFFF);
+          darwin_adc.memory->data[ADC_TEMP_OFFSET]=value%256;
+          darwin_adc.memory->data[ADC_TEMP_OFFSET+1]=value/256;
         }
         else
         {
-          value=adc_convert_voltage(adc_data[i]&0x0000FFFF);
-          ram_data[ADC_CH1_VOLTAGE+i*4]=value%256;
-          ram_data[ADC_CH1_VOLTAGE+1+i*4]=value/256;
+          value=adc_convert_voltage(darwin_adc.data[i]&0x0000FFFF);
+          darwin_adc.memory->data[ADC_CH1_VOLTAGE_OFFSET+i*4]=value%256;
+          darwin_adc.memory->data[ADC_CH1_VOLTAGE_OFFSET+1+i*4]=value/256;
         }
-        value=adc_convert_voltage((adc_data[i]&0xFFFF0000)>>16);
-        ram_data[ADC_CH2_VOLTAGE+i*4]=value%256;
-        ram_data[ADC_CH2_VOLTAGE+1+i*4]=value/256;
+        value=adc_convert_voltage((darwin_adc.data[i]&0xFFFF0000)>>16);
+        darwin_adc.memory->data[ADC_CH2_VOLTAGE_OFFSET+i*4]=value%256;
+        darwin_adc.memory->data[ADC_CH2_VOLTAGE_OFFSET+1+i*4]=value/256;
       }
     }
 }
 
 // public functions
-uint8_t adc_init(TMemory *memory)
+uint8_t adc_init(TMemory *memory,TScheduler *scheduler,unsigned short int eeprom_base_address,unsigned short int ram_base_address)
 {
   GPIO_InitTypeDef GPIO_InitStruct; 	
   ADC_MultiModeTypeDef multimode;
   ADC_ChannelConfTypeDef sConfig;
-  TIM_ClockConfigTypeDef sClockSourceConfig;
-  TIM_MasterConfigTypeDef sMasterConfig;
-  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
-  TIM_OC_InitTypeDef TIM_OCInitStructure;
-  uint32_t capture;
-
-  /* initialize the internal variables */
-  adc_period_ms=360;// equivalent to 10 ms
-  ram_data[ADC_PERIOD]=10;
 
   /* enable clocks */
   ADC1_CH1_ENABLE_PORT_CLK;
@@ -223,43 +178,43 @@ uint8_t adc_init(TMemory *memory)
 
   ADC1_ENABLE_CLK;
   // configure ADC1 
-  hadc1.Instance = ADC1;
-  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
-  hadc1.Init.ContinuousConvMode = DISABLE;
-  hadc1.Init.DiscontinuousConvMode = DISABLE;
-  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
-  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
-  hadc1.Init.NbrOfConversion = 6;
-  HAL_ADC_Init(&hadc1);
+  darwin_adc.handle1.Instance = ADC1;
+  darwin_adc.handle1.Init.ScanConvMode = ADC_SCAN_ENABLE;
+  darwin_adc.handle1.Init.ContinuousConvMode = DISABLE;
+  darwin_adc.handle1.Init.DiscontinuousConvMode = DISABLE;
+  darwin_adc.handle1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
+  darwin_adc.handle1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
+  darwin_adc.handle1.Init.NbrOfConversion = 6;
+  HAL_ADC_Init(&darwin_adc.handle1);
 
   multimode.Mode = ADC_DUALMODE_REGSIMULT;
-  HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
+  HAL_ADCEx_MultiModeConfigChannel(&darwin_adc.handle1, &multimode);
 
   // configure ADC1 channels 
   sConfig.Channel = ADC1_CH1;
   sConfig.Rank = 1;
   sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   sConfig.Channel = ADC1_CH2;
   sConfig.Rank = 2;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   sConfig.Channel = ADC1_CH3;
   sConfig.Rank = 3;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   sConfig.Channel = ADC1_CH4;
   sConfig.Rank = 4;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   sConfig.Channel = ADC1_CH5;
   sConfig.Rank = 5;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   sConfig.Channel = ADC1_CH6;
   sConfig.Rank = 6;
-  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle1, &sConfig);
 
   // configure GPIO 
   GPIO_InitStruct.Pin = ADC1_CH1_PIN|ADC1_CH2_PIN|ADC1_CH3_PIN|ADC1_CH4_PIN;
@@ -271,40 +226,40 @@ uint8_t adc_init(TMemory *memory)
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
   ADC2_ENABLE_CLK;
-  hadc2.Instance = ADC2;
-  hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
-  hadc2.Init.ContinuousConvMode = DISABLE;
-  hadc2.Init.DiscontinuousConvMode = DISABLE;
-  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;//ADC_EXTERNALTRIGCONV_T1_CC1;
-  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
-  hadc2.Init.NbrOfConversion = 6;
-  HAL_ADC_Init(&hadc2);
+  darwin_adc.handle2.Instance = ADC2;
+  darwin_adc.handle2.Init.ScanConvMode = ADC_SCAN_ENABLE;
+  darwin_adc.handle2.Init.ContinuousConvMode = DISABLE;
+  darwin_adc.handle2.Init.DiscontinuousConvMode = DISABLE;
+  darwin_adc.handle2.Init.ExternalTrigConv = ADC_SOFTWARE_START;//ADC_EXTERNALTRIGCONV_T1_CC1;
+  darwin_adc.handle2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
+  darwin_adc.handle2.Init.NbrOfConversion = 6;
+  HAL_ADC_Init(&darwin_adc.handle2);
 
   // configure ADC2 channels 
   sConfig.Channel = ADC2_CH1;
   sConfig.Rank = 1;
   sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   sConfig.Channel = ADC2_CH2;
   sConfig.Rank = 2;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   sConfig.Channel = ADC2_CH3;
   sConfig.Rank = 3;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   sConfig.Channel = ADC2_CH4;
   sConfig.Rank = 4;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   sConfig.Channel = ADC2_CH5;
   sConfig.Rank = 5;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   sConfig.Channel = ADC2_CH6;
   sConfig.Rank = 6;
-  HAL_ADC_ConfigChannel(&hadc2, &sConfig);
+  HAL_ADC_ConfigChannel(&darwin_adc.handle2, &sConfig);
 
   // configure GPIO 
   GPIO_InitStruct.Pin = ADC2_CH2_PIN|ADC2_CH3_PIN|ADC2_CH4_PIN|ADC2_CH5_PIN|
@@ -317,103 +272,77 @@ uint8_t adc_init(TMemory *memory)
   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
   //initialize DMA 
-  hdma_adc1.Instance = ADC_DMA_CHANNEL;
-  hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
-  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
-  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
-  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
-  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
-  hdma_adc1.Init.Mode = DMA_CIRCULAR;
-  hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
-  HAL_DMA_Init(&hdma_adc1);
-
-  __HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
+  darwin_adc.dma_handle.Instance = ADC_DMA_CHANNEL;
+  darwin_adc.dma_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
+  darwin_adc.dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;
+  darwin_adc.dma_handle.Init.MemInc = DMA_MINC_ENABLE;
+  darwin_adc.dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+  darwin_adc.dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+  darwin_adc.dma_handle.Init.Mode = DMA_CIRCULAR;
+  darwin_adc.dma_handle.Init.Priority = DMA_PRIORITY_LOW;
+  HAL_DMA_Init(&darwin_adc.dma_handle);
+
+  __HAL_LINKDMA(&darwin_adc.handle1,DMA_Handle,darwin_adc.dma_handle);
 
   HAL_NVIC_SetPriority(ADC_DMA_IRQn, 3, 1);
   HAL_NVIC_EnableIRQ(ADC_DMA_IRQn);
 
-  /* initialize timer */
-  ENABLE_ADC_TIMER_CLK;
-  ADC_TIM_Handle.Instance = ADC_TIMER;
-  ADC_TIM_Handle.Init.Prescaler = 1000;
-  ADC_TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
-  ADC_TIM_Handle.Init.Period = 0xFFFF;
-  ADC_TIM_Handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-  ADC_TIM_Handle.Init.RepetitionCounter = 0;
-  HAL_NVIC_SetPriority(ADC_TIMER_IRQn, 3, 1);
-  HAL_NVIC_EnableIRQ(ADC_TIMER_IRQn);
-  HAL_TIM_OC_Init(&ADC_TIM_Handle);
-  /* use the internal clock */
-  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
-  HAL_TIM_ConfigClockSource(&ADC_TIM_Handle, &sClockSourceConfig);
-  /* disable master/slave mode */
-  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
-  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
-  HAL_TIMEx_MasterConfigSynchronization(&ADC_TIM_Handle, &sMasterConfig);
-  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
-  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
-  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
-  sBreakDeadTimeConfig.DeadTime = 0;
-  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
-  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
-  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
-  HAL_TIMEx_ConfigBreakDeadTime(&ADC_TIM_Handle, &sBreakDeadTimeConfig);
-  TIM_OCInitStructure.OCMode = TIM_OCMODE_TOGGLE;
-  TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
-  TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;
-  TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
-  capture = HAL_TIM_ReadCapturedValue(&ADC_TIM_Handle, TIM_CHANNEL_1);
-  TIM_OCInitStructure.Pulse = capture+adc_period_ms;
-  TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_RESET;
-  TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
-  HAL_TIM_OC_ConfigChannel(&ADC_TIM_Handle, &TIM_OCInitStructure,TIM_CHANNEL_1);
-
   /* calibrate ADC1 */
-  HAL_ADCEx_Calibration_Start(&hadc1);
-  HAL_ADCEx_Calibration_Start(&hadc2);
+  HAL_ADCEx_Calibration_Start(&darwin_adc.handle1);
+  HAL_ADCEx_Calibration_Start(&darwin_adc.handle2);
 
-  HAL_ADC_Start(&hadc2);
-  HAL_ADCEx_MultiModeStart_DMA(&hadc1,adc_data,6);
+  HAL_ADC_Start(&darwin_adc.handle2);
+  HAL_ADCEx_MultiModeStart_DMA(&darwin_adc.handle1,darwin_adc.data,6);
+
+  scheduler_set_channel(scheduler,SCHED_CH1,0x00000000,10,&darwin_adc);
+  darwin_adc.scheduler=scheduler;
 
   /* initialize memory module */
-  mem_module_init(&adc_mem_module);
-  adc_mem_module.write_cmd=adc_write_cmd;
-  adc_mem_module.read_cmd=adc_read_cmd;
-  if(!mem_module_add_ram_segment(&adc_mem_module,RAM_ADC_DMA_BASE_ADDRESS,RAM_ADC_DMA_LENGTH))
+  mem_module_init(&darwin_adc.mem_module);
+  darwin_adc.mem_module.data=&darwin_adc;
+  darwin_adc.mem_module.write_cmd=adc_write_cmd;
+  darwin_adc.mem_module.read_cmd=adc_read_cmd;
+  if(!mem_module_add_ram_segment(&darwin_adc.mem_module,ram_base_address,RAM_ADC_DMA_LENGTH))
+    return 0x00;
+  if(!mem_module_add_eeprom_segment(&darwin_adc.mem_module,eeprom_base_address,EEPROM_ADC_DMA_LENGTH))
     return 0x00;
-  if(!mem_add_module(memory,&adc_mem_module))
+  if(!mem_add_module(memory,&darwin_adc.mem_module))
     return 0x00;
+  darwin_adc.eeprom_base_address=eeprom_base_address;
+  darwin_adc.ram_base_address=ram_base_address;
+  darwin_adc.memory=memory;
+  EE_update_num_variables(EEPROM_ADC_DMA_LENGTH);
 
   return 0x01;
 }
 
 void adc_start(void)
 {
-  if((ram_data[ADC_CNTRL]&ADC_RUNNING)==0x00)
+  if((darwin_adc.memory->data[ADC_CONTROL_OFFSET]&ADC_RUNNING)==0x00)
   {
-    ram_data[ADC_CNTRL]|=ADC_RUNNING;
-    HAL_TIM_OC_Start_IT(&ADC_TIM_Handle, TIM_CHANNEL_1);
+    darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CONTROL_OFFSET]|=ADC_RUNNING;
+    scheduler_enable_channel(darwin_adc.scheduler,SCHED_CH1);
   }
 }
 
 void adc_stop(void)
 {
-  if(ram_data[ADC_CNTRL]&ADC_RUNNING)
+  if(darwin_adc.memory->data[ADC_CONTROL_OFFSET]&ADC_RUNNING)
   {
-    ram_data[ADC_CNTRL]&=(~ADC_RUNNING);
-    HAL_TIM_OC_Stop_IT(&ADC_TIM_Handle, TIM_CHANNEL_1);
+    darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CONTROL_OFFSET]&=(~ADC_RUNNING);
+    scheduler_disable_channel(darwin_adc.scheduler,SCHED_CH1);
   }
 }
 
 void adc_set_period(uint8_t period_ms)
 {
-  adc_period_ms=period_ms*36;
-  ram_data[ADC_PERIOD]=period_ms;
+  scheduler_change_period(darwin_adc.scheduler,SCHED_CH1,period_ms);
+  darwin_adc.memory->data[darwin_adc.eeprom_base_address+ADC_PERIOD_OFFSET]=period_ms;
 }
 
 uint8_t adc_get_period(void)
 {
-  return ram_data[ADC_PERIOD];
+  return darwin_adc.memory->data[darwin_adc.eeprom_base_address+ADC_PERIOD_OFFSET];
 }
 
 uint16_t adc_get_channel(adc_ch_t channel)
@@ -422,27 +351,27 @@ uint16_t adc_get_channel(adc_ch_t channel)
 
   switch(channel)
   {
-    case ADC_CH1: value=ram_data[ADC_CH1_VOLTAGE]+ram_data[ADC_CH1_VOLTAGE+1]*256;
+    case ADC_CH1: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH1_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH1_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH2: value=ram_data[ADC_CH2_VOLTAGE]+ram_data[ADC_CH2_VOLTAGE+1]*256;
+    case ADC_CH2: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH2_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH2_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH3: value=ram_data[ADC_CH3_VOLTAGE]+ram_data[ADC_CH3_VOLTAGE+1]*256;
+    case ADC_CH3: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH3_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH3_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH4: value=ram_data[ADC_CH4_VOLTAGE]+ram_data[ADC_CH4_VOLTAGE+1]*256;
+    case ADC_CH4: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH4_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH4_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH5: value=ram_data[ADC_CH5_VOLTAGE]+ram_data[ADC_CH5_VOLTAGE+1]*256;
+    case ADC_CH5: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH5_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH5_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH6: value=ram_data[ADC_CH6_VOLTAGE]+ram_data[ADC_CH6_VOLTAGE+1]*256;
+    case ADC_CH6: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH6_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH6_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH7: value=ram_data[ADC_CH7_VOLTAGE]+ram_data[ADC_CH7_VOLTAGE+1]*256;
+    case ADC_CH7: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH7_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH7_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH8: value=ram_data[ADC_CH8_VOLTAGE]+ram_data[ADC_CH8_VOLTAGE+1]*256;
+    case ADC_CH8: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH8_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH8_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH9: value=ram_data[ADC_CH9_VOLTAGE]+ram_data[ADC_CH9_VOLTAGE+1]*256;
+    case ADC_CH9: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH9_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH9_VOLTAGE_OFFSET+1]*256;
                   break;
-    case ADC_CH10: value=ram_data[ADC_CH10_VOLTAGE]+ram_data[ADC_CH10_VOLTAGE+1]*256;
+    case ADC_CH10: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH10_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH10_VOLTAGE_OFFSET+1]*256;
                    break;
-    case ADC_CH12: value=ram_data[ADC_CH12_VOLTAGE]+ram_data[ADC_CH12_VOLTAGE+1]*256;
+    case ADC_CH12: value=darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH12_VOLTAGE_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_CH12_VOLTAGE_OFFSET+1]*256;
                    break;
     default: value=0x0000;
   }
@@ -456,27 +385,27 @@ uint16_t adc_get_channel_raw(adc_ch_t channel)
 
   switch(channel)
   {
-    case ADC_CH1: value=adc_data[0]&0x0000FFFF;
+    case ADC_CH1: value=darwin_adc.data[0]&0x0000FFFF;
                   break;
-    case ADC_CH2: value=(adc_data[0]&0xFFFF0000)>>16;
+    case ADC_CH2: value=(darwin_adc.data[0]&0xFFFF0000)>>16;
                   break;
-    case ADC_CH3: value=adc_data[1]&0x0000FFFF;
+    case ADC_CH3: value=darwin_adc.data[1]&0x0000FFFF;
                   break;
-    case ADC_CH4: value=(adc_data[1]&0xFFFF0000)>>16;
+    case ADC_CH4: value=(darwin_adc.data[1]&0xFFFF0000)>>16;
                   break;
-    case ADC_CH5: value=adc_data[2]&0x0000FFFF;
+    case ADC_CH5: value=darwin_adc.data[2]&0x0000FFFF;
                   break;
-    case ADC_CH6: value=(adc_data[2]&0xFFFF0000)>>16;
+    case ADC_CH6: value=(darwin_adc.data[2]&0xFFFF0000)>>16;
                   break;
-    case ADC_CH7: value=adc_data[3]&0x0000FFFF;
+    case ADC_CH7: value=darwin_adc.data[3]&0x0000FFFF;
                   break;
-    case ADC_CH8: value=(adc_data[3]&0xFFFF0000)>>16;
+    case ADC_CH8: value=(darwin_adc.data[3]&0xFFFF0000)>>16;
                   break;
-    case ADC_CH9: value=adc_data[4]&0x0000FFFF;
+    case ADC_CH9: value=darwin_adc.data[4]&0x0000FFFF;
                   break;
-    case ADC_CH10: value=(adc_data[4]&0xFFFF0000)>>16;
+    case ADC_CH10: value=(darwin_adc.data[4]&0xFFFF0000)>>16;
                    break;
-    case ADC_CH12: value=(adc_data[5]&0xFFFF0000)>>16;
+    case ADC_CH12: value=(darwin_adc.data[5]&0xFFFF0000)>>16;
                    break;
     default: value=0x0000;
   }
@@ -486,6 +415,6 @@ uint16_t adc_get_channel_raw(adc_ch_t channel)
 
 uint16_t adc_get_temperature(void)
 {
-  return ram_data[ADC_TEMP]+ram_data[ADC_TEMP+1]*256;
+  return darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_TEMP_OFFSET]+darwin_adc.memory->data[darwin_adc.ram_base_address+ADC_TEMP_OFFSET+1]*256;
 }
 
diff --git a/src/cm730_fw.c b/src/cm730_fw.c
index b1c17b782fd46a3f4cdc91c66b87964a791e3dcf..a4a761a03171d4f196fe6dc12cce978ba91f1cfc 100755
--- a/src/cm730_fw.c
+++ b/src/cm730_fw.c
@@ -2,6 +2,7 @@
 #include "darwin_conf.h"
 #include "memory.h"
 #include "darwin_sch.h"
+#include "darwin_sch2.h"
 #include "darwin_dyn_slave.h"
 #include "darwin_time.h"
 #include "eeprom.h"
@@ -9,10 +10,12 @@
 #include "darwin_motion.h"
 #include "darwin_imu.h"
 #include "darwin_balance.h"
+#include "adc_dma.h"
 
 TMemory *darwin_memory;
 TDynamixelMaster *dyn_master;
-TScheduler *scheduler;
+TScheduler *scheduler_low_priority;
+TScheduler *scheduler_high_priority;
 
 int main(void)
 {
@@ -25,22 +28,24 @@ int main(void)
   // initialize time module
   darwin_time_init();
   /* initialize the scheduler */
-  scheduler=darwin_sch_init();
+  scheduler_low_priority=darwin_sch_init();
+  scheduler_high_priority=darwin_sch2_init();
   /* initialize the GPIO module */
 //  gpio_init(&darwin_memory);
   // initialize adc
-//  adc_init(&darwin_memory);
+  adc_init(darwin_memory,scheduler_low_priority,EEPROM_ADC_DMA_BASE_ADDRESS,RAM_ADC_DMA_BASE_ADDRESS);
   /* initialize the dynamixel slave interface */
-  darwin_dyn_slave_init(&darwin_memory,scheduler);
+  darwin_dyn_slave_init(&darwin_memory,scheduler_high_priority);
   // initialize imu
   imu_init(darwin_memory,RAM_IMU_MM_BASE_ADDRESS);
   // initialize motion manager
-  darwin_mm_init(scheduler,darwin_memory);
+  darwin_mm_init(scheduler_low_priority,darwin_memory);
   /* initialize the ram module */
   ram_init(darwin_memory);
 
   darwin_dyn_slave_start();
 
-  while(1);/* main function does not return */
+  while(1)/* main function does not return */
+    HAL_Delay(1000);
 }