Seeed / Grove_Node

Dependencies:   BLE_API color_pixels mbed-src-nrf51822 nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Files at this revision

API Documentation at this revision

Comitter:
yihui
Date:
Thu Nov 06 02:22:01 2014 +0000
Parent:
8:5818566e1e8a
Child:
10:f34ff4e47741
Commit message:
Grove Node initial

Changed in this revision

battery.h Show annotated file Show diff for this revision Revisions of this file
color_pixels.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-src.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
node.cpp Show annotated file Show diff for this revision Revisions of this file
power.c Show annotated file Show diff for this revision Revisions of this file
unified_driver/analog_sensor.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/analog_thermometer.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/color_led_strip.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/led.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/switch.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/time_sensor.cpp Show annotated file Show diff for this revision Revisions of this file
unified_driver/unified_driver.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/battery.h	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,43 @@
+
+
+#ifndef __BATTERY_H__
+#define __BATTERY_H__
+
+#include "mbed.h"
+
+class Battery {
+public:
+    Battery(PinName pin) {
+        uint32_t n = (uint32_t) pin;
+        channel = 1 << (1 + n);
+    }
+    
+    float read() {
+        uint32_t pre_enable_register = NRF_ADC->ENABLE;
+        uint32_t pre_config_register = NRF_ADC->CONFIG;
+        
+        
+        NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
+        NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+                          (ADC_CONFIG_INPSEL_AnalogInputNoPrescaling << ADC_CONFIG_INPSEL_Pos) |
+                          (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+                          (channel << ADC_CONFIG_PSEL_Pos) |
+                          (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
+                          
+        NRF_ADC->TASKS_START = 1;
+        while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
+        } 
+        
+        uint16_t value = NRF_ADC->RESULT;
+        
+        NRF_ADC->ENABLE = pre_enable_register;
+        NRF_ADC->CONFIG = pre_config_register;
+        
+        return (float)value * (1.0f / (float)0x3FF) * 1.2 * 12.2 / 2.2;    
+    }
+    
+private:
+    uint32_t channel;
+};
+
+#endif // __BATTERY_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/color_pixels.lib	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Seeed/code/color_pixels/#91af7b451005
--- a/main.cpp	Tue Sep 30 02:20:59 2014 +0000
+++ b/main.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -16,27 +16,60 @@
 
 #include "mbed.h"
 #include "BLEDevice.h"
-
+#include "DFUService.h"
 #include "UARTService.h"
+#include "nrf_delay.h"
+#include "battery.h"
 
-#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
-                               * it will have an impact on code-size and power consumption. */
+#define DEBUG   0
+
+#if DEBUG       // for Arch BLE
+#define LOG(...)        { printf(__VA_ARGS__); }
+#define BUTTON_DOWN     1
+#define LED_ON          1
+#define LED_OFF         0
 
-#if NEED_CONSOLE_OUTPUT
-#define DEBUG(...) { printf(__VA_ARGS__); }
-#else
-#define DEBUG(...) /* nothing */
-#endif /* #if NEED_CONSOLE_OUTPUT */
+DigitalOut  blue(p30);
+DigitalOut  green(p17);
+InterruptIn button(p5);
+#else           // for Grove Node BLE
+#define LOG(...)
+#define BUTTON_DOWN     0
+#define LED_ON          0
+#define LED_OFF         1
+
+DigitalOut  blue(p18);
+DigitalOut  green(p17);
+InterruptIn button(p30);
+#endif
+
+Battery battery(p5);
 
 BLEDevice  ble;
-DigitalOut led1(LED1);
+UARTService *uartServicePtr;
+Ticker ticker;
+
+volatile bool button_event = false;
+
+const int MAX_ARGS = 8;
+char *argv[MAX_ARGS];
 
-UARTService *uartServicePtr;
+static const uint8_t SIZEOF_TX_RX_BUFFER = 32;
+uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,};
+
+extern "C" void power_on();
+extern "C" void power_off();
+
+extern void node_init();
+extern void node_tick();
+extern void node_parse(int argc, char *argv[]);
+
+int button_detect();
 
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
 {
-    DEBUG("Disconnected!\n\r");
-    DEBUG("Restarting the advertising process\n\r");
+    LOG("Disconnected!\n");
+    LOG("Restarting the advertising process\n");
     ble.startAdvertising();
 }
 
@@ -44,23 +77,53 @@
 {
     if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
         uint16_t bytesRead = params->len;
-        DEBUG("received %u bytes\n\r", bytesRead);
-        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
+        LOG("received %u bytes\n\r", bytesRead);
+        if (bytesRead < sizeof(rxPayload)) {
+            memcpy(rxPayload, params->data, bytesRead);
+            rxPayload[bytesRead] = '\0';
+        }
+        
+        LOG("%s\n", (char *)rxPayload);
+
+        char *piece = strtok((char *)rxPayload, " ");
+        int argc = 0;
+        while (piece && argc < MAX_ARGS) {
+            argv[argc++] = piece;
+            piece = strtok(0, " ");
+        }
+        
+        if (argc > 0) {
+           node_parse(argc, argv);
+        }
+        
     }
 }
 
-void periodicCallback(void)
+void tick(void)
 {
-    led1 = !led1;
+    node_tick();
+}
+
+void button_down(void)
+{
+    button_event = true;
 }
 
 int main(void)
 {
-    led1 = 1;
-    Ticker ticker;
-    ticker.attach(periodicCallback, 1);
+    power_on();
+    blue = LED_ON;
+    green = LED_ON;
+    
+#if BUTTON_DOWN
+    button.mode(PullDown);
+    button.rise(button_down);
+#else
+    button.mode(PullUp);
+    button.fall(button_down);
+#endif
 
-    DEBUG("Initialising the nRF51822\n\r");
+    LOG("Initialising the nRF51822\n");
     ble.init();
     ble.onDisconnection(disconnectionCallback);
     ble.onDataWritten(onDataWritten);
@@ -69,17 +132,97 @@
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
-                                     (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
+                                     (const uint8_t *)"NODE", sizeof("NODE"));
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
 
-    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
-    ble.startAdvertising();
+    DFUService dfu(ble);
 
     UARTService uartService(ble);
     uartServicePtr = &uartService;
+    
+    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
+    ble.startAdvertising();
+    
+    node_init();
+    ticker.attach(tick, 1);
 
+    blue = LED_OFF;
+    green = LED_OFF;
+    
     while (true) {
-        ble.waitForEvent();
+        if (button_event) {
+            int click;
+            
+            green = LED_ON;
+            click = button_detect();
+            green = LED_OFF;
+            LOG("click type: %d\n\r", click);
+            
+            button_event = false;
+            
+            if (1 == click) {
+            } else if (2 == click) {
+                //green = LED_ON;
+            } else if (-1 == click) {
+                green = LED_OFF;
+                blue = LED_OFF;
+                while (BUTTON_DOWN == button.read()) {
+                    
+                }
+                nrf_delay_us(3000);
+                
+                power_off();
+            } else {
+                continue;
+            }
+
+        } else {
+            ble.waitForEvent();
+        }
     }
 }
+
+int button_detect(void)
+{
+    int t = 0;
+    
+    while (1) {
+        if (button.read() != BUTTON_DOWN) {
+            if (t < 30) {
+                return 0;     // for anti shake
+            } else {
+                break;
+            }
+        }
+        
+        if (t > 30000) {        // More than 3 seconds
+            return -1;          // long click
+        }
+        
+        t++;
+        nrf_delay_us(100);
+    }
+    
+    if (t > 4000) {             // More than 0.4 seconds
+        return 1;               // single click
+    }
+    
+    while (true) {
+        if (button.read() == BUTTON_DOWN) {
+            nrf_delay_us(1000);
+            if (button.read() == BUTTON_DOWN) {
+                return 2;      // double click
+            }
+            
+            t += 10;
+        }
+        
+        if (t > 4000) {
+            return 1;          // The interval of double click should less than 0.4 seconds, so it's single click
+        }
+        
+        t++;
+        nrf_delay_us(100);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src.lib	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/yihui/code/mbed-src-nrf51822/#700cadd8b708
--- a/mbed.bld	Tue Sep 30 02:20:59 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/node.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,229 @@
+
+
+#include "unified_driver.h"
+#include "mbed.h"
+#include "UARTService.h"
+
+#define LOG(...)      //  { printf(__VA_ARGS__); }
+
+extern UARTService *uartServicePtr;
+
+
+extern "C" driver_t analog_sensor_driver;
+extern "C" driver_t analog_thermometer_driver;
+extern "C" driver_t time_sensor_driver;
+
+driver_t *sensor_list[] =
+{
+    &analog_sensor_driver,
+    &analog_thermometer_driver,
+    &time_sensor_driver,
+};
+
+
+extern "C" driver_t switch_driver;
+extern "C" driver_t led_driver;
+extern "C" driver_t color_led_strip_driver;
+
+driver_t *actuator_list[] = 
+{
+    &switch_driver,
+    &led_driver,
+    &color_led_strip_driver
+};
+
+
+equation_t equation_list[8] = 
+{
+    {0, '>', 0.50},
+    {0, '<', 0.49},
+};
+
+int equation_number = 2;
+
+driver_t *sensor;
+driver_t *actuator;
+int sensor_id = 0;
+int actuator_id = 0;
+void *sensor_object;
+void *actuator_object;
+float sensor_data[16] = {0,};
+float actuator_data[8] = {0,};
+
+float action_list[8][8] = 
+{
+    {1, },
+    {0.0, },
+    {0.5, 1.0},
+};
+
+uint8_t action_number = 2;
+
+uint32_t sensor_init_data[8] = {0, };
+uint32_t actuator_init_data[8] = {0, };
+
+int8_t event_to_action_map[8] = {0, 2, };
+
+
+void node_init()
+{
+    sensor_id = 0;
+    sensor = sensor_list[0];
+    sensor_init_data[0] = p3;
+    sensor_init_data[1] = p4;
+    sensor->init(&sensor_object, sensor_init_data);
+    
+    actuator = actuator_list[0];
+    actuator_init_data[0] = p1;
+    actuator_init_data[1] = p2;
+    actuator->init(&actuator_object, actuator_init_data);
+}
+
+void node_tick()
+{
+    sensor->read(&sensor_object, sensor_data);
+    
+    for (int d = 0; d < sensor->d; d++) {
+        float value = sensor_data[d];
+        
+        uartServicePtr->printf("i %d %f\n", d, value);
+        
+        for (int e = 0; e < equation_number; e++) {
+            equation_t *equation = equation_list + e;
+            
+            bool result;
+            if (equation->d == d) {
+                if ('>' == equation->op) {
+                    result = value > equation->value;
+                } else if ('<' == equation->op) {
+                    result = value < equation->value;
+                } else if ('=' == equation->op) {
+                    result = value == equation->value;
+                }
+            }
+            
+            if (result) {
+                LOG("event [%d] occured\n", e);
+                
+                int a = event_to_action_map[e];
+                if (a != -1) {
+                    actuator->write(&actuator_object, action_list[a]);
+                    
+                    LOG("execute action [%d]\n", a);
+                }
+            }
+
+        }
+    }
+}
+
+void node_parse(int argc, char *argv[])
+{
+    if (2 == argc) {
+        int param1 = atoi(argv[1]);
+        if (0 == strcmp(argv[0], "s")) {
+            if (param1 != sensor_id) {
+                sensor_id = param1;
+                sensor->fini(&sensor_object);
+                sensor = sensor_list[param1];
+                sensor->init(&sensor_object, sensor_init_data);
+                
+                equation_number = 0; 
+            }
+            
+            LOG("select sensor [%d]\n", sensor_id); 
+        } else if (0 == strcmp(argv[0], "a")) {
+            if (param1 != actuator_id) {
+                actuator_id = param1;
+                actuator->fini(&actuator_object);
+                actuator = actuator_list[param1];
+                actuator->init(&actuator_object, actuator_init_data);  
+                
+                action_number = 0;
+            }
+                
+            LOG("select sensor [%d]\n", sensor_id);
+        } 
+
+        memset(event_to_action_map, -1, sizeof(event_to_action_map));
+    } else if (5 == argc && 0 == strcmp(argv[0], "e")) {
+        uint8_t event_id = atoi(argv[1]);
+        if (event_id > equation_number) {
+            return;
+        }
+        uint8_t dimention = atoi(argv[2]);
+        uint8_t symbol = argv[3][0];
+        float   value = atof(argv[4]);
+        
+        equation_t *equation = equation_list + event_id;
+        equation->d = dimention;
+        equation->op = symbol;
+        equation->value     = value;
+        
+        LOG("set event [%d]: %d %c %f\n", event_id, dimention, symbol, value);
+        
+        
+        if (event_id == equation_number) {
+            equation_number++;
+        }
+    } else if (3 == argc && 0 == strcmp(argv[0], "m")) {
+        uint8_t event_id = atoi(argv[1]);
+        uint8_t action_id = atoi(argv[2]);
+        
+        event_to_action_map[event_id] = action_id;
+        
+        LOG("map event [%d] -> action [%d]\n", event_id, action_id);
+    }
+    
+    if (0 == strcmp(argv[0], "f")) {
+        uint8_t action_id = atoi(argv[1]);
+        if (action_id > action_number) {
+            return;
+        } else if (action_id == action_number) {
+            action_number++;
+        }
+        
+        int n = argc - 2;
+        if (n > 8) {
+            n = 8;
+        }
+        
+        LOG("set action [%d]:", action_id);
+        for (int i = 0; i < 8; i++) {
+            if (i < n) {
+                float value = atof(argv[i + 2]);
+                action_list[action_id][i] = value;
+                LOG(" %f", value);
+            } else {
+                action_list[action_id][i] = 0;
+            }
+        }
+        
+        LOG("\n");
+        
+ //       actuator->write(&actuator_object, action_list[action_id]);
+    } else if (0 == strcmp(argv[0], "o")) {
+
+        int n = argc - 1;
+        if (n > 8) {
+            n = 8;
+        }
+        
+        
+        LOG("set output:");
+        for (int i = 0; i < 8; i++) {
+            if (i < n) {
+                float value = atof(argv[i + 1]);
+                actuator_data[i] = value;
+                LOG(" %f", value);
+            } else {
+                actuator_data[i] = 0;
+            }
+        }
+        
+        LOG("\n");
+        
+        actuator->write(&actuator_object, actuator_data);
+    }
+     
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/power.c	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,24 @@
+
+#include "nrf51.h"
+#include "nrf51_bitfields.h"
+
+#define POWER_PIN   8
+
+void power_on()
+{
+    NRF_GPIO->PIN_CNF[POWER_PIN] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                            | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                            | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                            | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                            | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+    NRF_GPIO->OUTSET = (1UL << POWER_PIN);
+}
+
+
+void power_off()
+{
+    NRF_GPIO->OUTCLR = (1UL << POWER_PIN);
+    
+    // Enter system OFF. After wakeup the chip will be reset, and the MCU will run from the top 
+    NRF_POWER->SYSTEMOFF = 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/analog_sensor.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,45 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+
+int analog_sensor_init(void *obj, void *params)
+{
+    int pin = *(int *)params;
+    AnalogIn *probe = new AnalogIn((PinName)pin);
+    *((AnalogIn **)obj) = probe;
+    
+    return 0;
+}
+    
+
+int analog_sensor_read(void *obj, void *data)
+{
+    AnalogIn *probe = *(AnalogIn **)obj;
+    
+    *(float *)data = probe->read() * 100;
+    
+    return 0;
+}
+
+int analog_sensor_write(void *obj, void *data)
+{
+    return 0;
+}
+
+int analog_sensor_fini(void *obj)
+{
+    AnalogIn *ptr = *(AnalogIn **)obj;
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t analog_sensor_driver = 
+{
+    "analog sensor",
+    1,
+    analog_sensor_init,
+    analog_sensor_read,
+    analog_sensor_write,
+    analog_sensor_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/analog_thermometer.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,56 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+
+int analog_thermometer_init(void *obj, void *params)
+{
+    int pin = *(int *)params;
+    *(AnalogIn **)obj = new AnalogIn((PinName)pin);
+    
+    return 0;
+}
+    
+
+int analog_thermometer_read(void *obj, void *data)
+{
+    const uint32_t beta = 3975;
+    float a;
+    float temperature;
+    float resistance;
+    AnalogIn *probe = *(AnalogIn **)obj;
+    
+    a = probe->read();
+    
+    /* Calculate the resistance of the thermistor from analog votage read. */
+    resistance = (float) 10000.0 * ((1 / a) - 1);
+    
+    /* Convert the resistance to temperature using Steinhart's Hart equation */
+    temperature = (1/((log(resistance/10000.0)/beta) + (1.0/298.15)))-273.15; 
+    
+    *(float *)data = temperature;
+    
+    return 0;
+}
+
+int analog_thermometer_write(void *obj, void *data)
+{
+    return 0;
+}
+
+int analog_thermometer_fini(void *obj)
+{
+    AnalogIn *ptr = *(AnalogIn **)obj;
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t analog_thermometer_driver = 
+{
+    "analog thermometer",
+    1,
+    analog_thermometer_init,
+    analog_thermometer_read,
+    analog_thermometer_write,
+    analog_thermometer_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/color_led_strip.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,56 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+#include "color_pixels.h"
+
+int color_led_strip_init(void *obj, void *params)
+{
+    int pin = *(int *)params;
+    int num = *((int *)params + 2);
+    if (num == 0) {
+        num = 30;
+    }
+    ColorPixels *ptr = new ColorPixels(pin, num);
+    *((ColorPixels **)obj) = ptr;
+    
+    ptr->rainbow();
+    
+    return 0;
+}
+    
+
+int color_led_strip_read(void *obj, void *data)
+{
+    return 0;
+}
+
+int color_led_strip_write(void *obj, void *data)
+{
+    ColorPixels *pixels = *(ColorPixels **)obj;
+    float *params = (float *)data;
+    uint8_t red = params[0];
+    uint8_t green = params[1];
+    uint8_t blue = params[2];
+    
+    pixels->rainbow(red, green, blue);
+    
+    return 0;
+}
+
+int color_led_strip_fini(void *obj)
+{
+    ColorPixels *ptr = *(ColorPixels **)obj;
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t color_led_strip_driver = 
+{
+    "color led strip",
+    4,
+    color_led_strip_init,
+    color_led_strip_read,
+    color_led_strip_write,
+    color_led_strip_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/led.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,53 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+
+int led_init(void *obj, void *params)
+{
+    int pin = *(int *)params;
+    *((PwmOut **)obj) = new PwmOut((PinName)pin);
+    
+    return 0;
+}
+    
+
+int led_read(void *obj, void *data)
+{
+    PwmOut *output = *(PwmOut **)obj;
+    
+    *(float *)data = output->read();
+    
+    return 0;
+}
+
+int led_write(void *obj, void *data)
+{
+    PwmOut *pwm = *(PwmOut **)obj;
+    float pulse_width = *(float *)data;
+    float period   = *((float *)data + 1);
+    
+    pwm->write(pulse_width);
+    if (0 != period) {
+        pwm->period(period);
+    }
+    
+    return 0;
+}
+
+int led_fini(void *obj)
+{
+    PwmOut *ptr = *(PwmOut **)obj;
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t led_driver = 
+{
+    "led",
+    1,
+    led_init,
+    led_read,
+    led_write,
+    led_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/switch.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,53 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+
+int switch_init(void *obj, void *params)
+{
+    int pin = *(int *)params;
+    DigitalInOut *ptr = new DigitalInOut((PinName)pin);
+    *((DigitalInOut **)obj) = ptr;
+    ptr->input();
+    
+    return 0;
+}
+    
+
+int switch_read(void *obj, void *data)
+{
+    DigitalInOut *in = *(DigitalInOut **)obj;
+    
+    in->input();
+    int value = in->read();
+    *(float *)data = value;
+    
+    return 0;
+}
+
+int switch_write(void *obj, void *data)
+{
+    DigitalInOut *out = *(DigitalInOut **)obj;
+    uint32_t value = *(float *)data;
+    out->output();
+    out->write(value);
+    
+    return 0;
+}
+
+int switch_fini(void *obj)
+{
+    DigitalInOut *ptr = *(DigitalInOut **)obj;
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t switch_driver = 
+{
+    "switch",
+    1,
+    switch_init,
+    switch_read,
+    switch_write,
+    switch_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/time_sensor.cpp	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,56 @@
+
+#include "unified_driver.h"
+#include "mbed.h"
+
+uint8_t time_sensor_second = 0;
+
+
+void time_sensor_tick(void)
+{
+    time_sensor_second++;
+    if (time_sensor_second >= 60) {
+        time_sensor_second = 0;
+    }
+}
+
+int time_sensor_init(void *obj, void *params)
+{
+    Ticker *ticker = new Ticker();
+    *((Ticker **)obj) = probe;
+    
+    ticker->attach(time_sensor_tick, 1);
+    
+    return 0;
+}
+    
+
+int time_sensor_read(void *obj, void *data)
+{
+    *(float *)data = time_sensor_second;
+    
+    return 0;
+}
+
+int time_sensor_write(void *obj, void *data)
+{
+    return 0;
+}
+
+int time_sensor_fini(void *obj)
+{
+    Ticker *ptr = *(Ticker **)obj;
+    ptr->detach();
+    delete ptr;
+    
+    return 0;
+}
+
+driver_t time_sensor_driver = 
+{
+    "time sensor",
+    1,
+    time_sensor_init,
+    time_sensor_read,
+    time_sensor_write,
+    time_sensor_fini,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unified_driver/unified_driver.h	Thu Nov 06 02:22:01 2014 +0000
@@ -0,0 +1,26 @@
+
+#ifndef __UNIFIED_DRIVER_H__
+#define __UNIFIED_DRIVER_H__
+
+#include <stdint.h>
+
+typedef struct _driver_t        driver_t;
+typedef struct _equation_t      equation_t;
+
+struct _driver_t {
+    char    *name;
+    uint8_t  d;     // dimention
+    int     (*init)(void *obj, void *params);
+    int     (*read)(void *obj, void *data);
+    int     (*write)(void *obj, void *data);
+    int     (*fini)(void *obj);
+};
+
+struct _equation_t {
+    uint8_t     d;      // dimention
+    uint8_t     op;     // operator
+    float       value;
+};
+    
+
+#endif // __UNIFIED_DRIVER_H__