test

Dependencies:   BLE_API nRF51822 mbed

Fork of KS7 by masaaki makabe

main.cpp

Committer:
akita11
Date:
2015-12-04
Revision:
10:95c1e5a218d5
Parent:
9:a7bd5ae66d6d
Child:
11:be439189e3f7

File content as of revision 10:95c1e5a218d5:

#include "mbed.h"
#include "io.h"
#include "BLEDevice.h"
#include "common.h"

// BLE
#define INTERVAL_500MSEC        (500UL)
#define CONNTIMEOUT_3000MSEC    (3000UL)
#define ADV_TIMEOUT             (0)
#define DEVICE_NAME "Kitchen Scale"
#define BLE_TXPOWER_4DBM        (4)

// Device Information Service (DIS) (20 character limit)
// https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml
#define MANUFACTURER_NAME_STRING        "Hacarus" // Manufacturer Name String - shall represent the name of the manufacturer of the device.
#define MODEL_NUMBER_STRING             "0001" // Model Number String - shall represent the model number that is assigned by the device vendor.
#define SERIAL_NUMBER_STRING            "000780c0ffeef00d"  // Serial Number String - shall represent the serial number for a particular instance of the device.
#define FIRMWARE_REVISION_STRING        "v1.00.002@rev0009" // Firmware Revision String - shall represent the firmware revision for the firmware within the device.

// Weight Scale Service (Original)
#define UUID_WEIGHT_SCALE_SERVICE       (0x181D)

// JoyStick
#define PUSH_MINTHRESHOLD       (0.2)
#define PUSH_MAXTHRESHOLD       (0.6)
#define PUSH_COUNT              (15)

// Mode
#define MODE_OFF    (0) // LED OFF
#define MODE_START  (1) // LED OFF -> ON
#define MODE_ON     (2) // LED ON
#define MODE_END    (3) // LED ON -> OFF

// Led
#define LED_INTERVAL_NSEC   (100000)
#define BRIGHTNESS_ADDVALUE (0.1)
#define BRIGHTNESS_MINVALUE (0.0)
#define BRIGHTNESS_MAXVALUE (1.0)

// Properties
io io;
Ticker tk;
uint32_t weight_data;
float32_t weight = 0.0;
uint32_t scale = 0;
int update_counter = 0;
int push_counter = 0;
int led_mode = MODE_OFF;
float led_brightness = BRIGHTNESS_MINVALUE;

// UART for debug

#ifdef UART_DEBUG
Serial pc(P0_9, P0_8);// TX=P0_9
#define UART_BAUD_RATE   (9600UL)
#define DEBUG(...)              { pc.printf(__VA_ARGS__); }
#else
#define DEBUG(...) {}
#endif

// BLE 
BLEDevice ble;
Gap::ConnectionParams_t connectionParams;

/* Complete list of 16-bit Service IDs */
uint16_t    uuid16_list[] = {GattService::UUID_DEVICE_INFORMATION_SERVICE};

/* Weight Scale Service */
static const uint8_t UUID_HACARUS_WEIGHT_CHAR[] = {0x00, 0x00, 0x2A, 0x9D, 0x00, 0x01, 0x00, 0x01, 0x00, 'H','a', 'c', 'a', 'r','u', 's'};
GattCharacteristic  WeightMeasurement (UUID(UUID_HACARUS_WEIGHT_CHAR), (uint8_t *)&weight_data, sizeof(weight_data), sizeof(weight_data),
        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);
static const uint8_t UUID_HACARUS_SCALE_CHAR[] = {0x00, 0x00, 0x2A, 0x9E, 0x00, 0x01, 0x00, 0x01, 0x00, 'H','a', 'c', 'a', 'r','u', 's'};
GattCharacteristic  WeightScale (UUID(UUID_HACARUS_SCALE_CHAR), (uint8_t *)&scale, sizeof(scale), sizeof(scale),
        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
GattCharacteristic *Chars[] = {&WeightMeasurement,&WeightScale};
static const uint8_t UUID_HACARUS_WEIGHT_SERVICE[] = {0x00, 0x00, 0x18, 0x1D, 0x00, 0x01, 0x00, 0x01, 0x00, 'H','a', 'c', 'a', 'r','u', 's'};
GattService HWS = GattService(UUID(UUID_HACARUS_WEIGHT_SERVICE), Chars, sizeof(Chars) / sizeof(GattCharacteristic *));

/* Device Information Service */
GattCharacteristic ManuName(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, (uint8_t *)&MANUFACTURER_NAME_STRING, sizeof(MANUFACTURER_NAME_STRING) - 1, sizeof(MANUFACTURER_NAME_STRING) - 1,
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic ModelNum(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, (uint8_t *)&MODEL_NUMBER_STRING, sizeof(MODEL_NUMBER_STRING) - 1, sizeof(MODEL_NUMBER_STRING) - 1,
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic SerialNum(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, (uint8_t *)&SERIAL_NUMBER_STRING, sizeof(SERIAL_NUMBER_STRING) - 1, sizeof(SERIAL_NUMBER_STRING) - 1,
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic FWVersion(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)&FIRMWARE_REVISION_STRING, sizeof(FIRMWARE_REVISION_STRING) - 1, sizeof(FIRMWARE_REVISION_STRING) - 1,
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *DISChars[] = {&ManuName, &ModelNum, &SerialNum, &FWVersion};
GattService        DIS(GattService::UUID_DEVICE_INFORMATION_SERVICE , DISChars, sizeof(DISChars) / sizeof(GattCharacteristic *));

/* to confirm joystick */
bool check_joystick(){
    bool pushing = false;
    float value_x,value_y;
    
//    value_x = io.get_x();
//    value_y = io.get_y();
    
    if(PUSH_MINTHRESHOLD >= value_x || PUSH_MAXTHRESHOLD <= value_x){
        pushing = true;
    }
    else if(PUSH_MINTHRESHOLD >= value_y || PUSH_MAXTHRESHOLD <= value_y){
        pushing = true;
    }
    
    if(pushing){
        if(++push_counter >= PUSH_COUNT){
            push_counter = 0;
            return true;
        }
    }else{
        push_counter = 0;
    }
    
    return false;
}

uint32_t quick_ieee11073_from_float(float data)
{
    uint8_t  exponent = 0xFE; //exponent is -2
    uint32_t mantissa = (uint32_t)(data*100);
    
    return ( ((uint32_t)exponent) << 24) | mantissa;
}

void ticker_callback()
{

//        pc.printf("!!!\r\n");
/*
    while(1){
    adc_dat[0] = 0x01; // config reg.
//    adc_dat[1] = 0xc4 | (ch << 4); // single conv. & FS=+-2.048V & conv.
    adc_dat[1] = 0xc4;
    adc_dat[2] = 0x83; // 8SPS & disable comp.
    pc.printf("adc_dat: %02x %02x\r\n", adc_dat[0], adc_dat[1]);
//    i2c.write(I2C_ADDR_ADS1115, adc_dat, 3);
    adc_dat[0] = 0x00;
//    i2c.write(I2C_ADDR_ADS1115, adc_dat, 1);
//    i2c.read(I2C_ADDR_ADS1115, adc_dat, 2);
    uint8_t dh, dl;
    dh = adc_dat[0];
    dl = adc_dat[1];
        pc.printf("%d %d\r\n", dh, dl);
//    pc.printf("ADC result=%02x %02x\r\n", dh, dl);
    }
*/

    switch(led_mode){
        case MODE_OFF:
            if(check_joystick()){
//                io.display_value = 0;
                led_mode = MODE_START;
            }
        break;
        case MODE_START:
            led_brightness += BRIGHTNESS_ADDVALUE;
//            io.display(led_brightness);
            if(led_brightness >= BRIGHTNESS_MAXVALUE){
                led_mode = MODE_ON;
                ble.startAdvertising();
            }
        break;
        case MODE_ON:
            if(!check_joystick()){
//                io.analog_pow(1); // turn analog power on
//                weight = io.get_weight() * 9999.0;
//                io.display_value = (uint16_t)weight; // dummy display
                if(++update_counter >= 5){
                    weight_data = quick_ieee11073_from_float(weight);
                    ble.updateCharacteristicValue(WeightMeasurement.getValueAttribute().getHandle(),
                                                                    (uint8_t *)&weight_data,
                                                                    sizeof(weight_data));
                    update_counter = 0;
                }  
//                io.analog_pow(0); // turn analog power off 
            }else{
                led_mode = MODE_END;
                if(ble.getGapState().connected){
                    ble.disconnect(Gap::REMOTE_USER_TERMINATED_CONNECTION);
                }else{
                    ble.stopAdvertising();
                }
                update_counter = 0;
            }
        break;
        case MODE_END:
            led_brightness -= BRIGHTNESS_ADDVALUE;
//            io.display(led_brightness);
            if(led_brightness <= BRIGHTNESS_MINVALUE){
                led_mode = MODE_OFF;
            }
        break;
    }
}

/*
 * BLE CallBacks
 */
void BLEConnectionCallback(Gap::Handle_t handle, Gap::addr_type_t type, const Gap::address_t addr,const Gap::ConnectionParams_t *params)
{
    ble.updateConnectionParams(handle, &connectionParams);                       
}

void BLEDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
    if(led_mode == MODE_ON){
        ble.startAdvertising();
    }
}

void BleInitialize(void){
    
    uint8_t advertiseServiceID[16];
    
    // Initialize
    ble.init();
    
    // Event Set
    ble.onConnection(&BLEConnectionCallback);
    ble.onDisconnection(&BLEDisconnectionCallback);
    
    ble.getPreferredConnectionParams(&connectionParams);
    connectionParams.maxConnectionInterval = INTERVAL_500MSEC;
    connectionParams.minConnectionInterval = INTERVAL_500MSEC;
    connectionParams.connectionSupervisionTimeout = CONNTIMEOUT_3000MSEC;
    connectionParams.slaveLatency = 2;
    ble.setPreferredConnectionParams(&connectionParams);
    
    ble.setTxPower(BLE_TXPOWER_4DBM);
    
    for(int i=0; i<16; i++){
        advertiseServiceID[i] = UUID_HACARUS_WEIGHT_SERVICE[16 - 1 - i];
    }

    ble.accumulateAdvertisingPayload((GapAdvertisingData::Flags)(GapAdvertisingData::LE_GENERAL_DISCOVERABLE | GapAdvertisingData::BREDR_NOT_SUPPORTED));
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,
                                        (const uint8_t *)DEVICE_NAME,
                                        strlen(DEVICE_NAME)); 
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                     (const uint8_t *)advertiseServiceID, sizeof(advertiseServiceID));
                                                                   
    ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(INTERVAL_500MSEC));
    ble.setAdvertisingTimeout(ADV_TIMEOUT); /* 0 is disable the advertising timeout. */
    
    ble.addService(HWS);
    ble.addService(DIS);
}

int main()
{
#ifdef UART_DEBUG
    pc.baud(UART_BAUD_RATE);
#endif
#ifndef PCB_VER1
    // set XTAL=32MHz for TaiyoYuden's module
    DEBUG("Initializing XTALFREQ\n\r");
    SystemCoreClock = 32000000;
    DEBUG("UICR->XTALFREQ=%x\r\n", NRF_UICR->XTALFREQ);
    if (NRF_UICR->XTALFREQ == 0xffffffff){
        DEBUG("updating UICR->XTALFREQ...");
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; 
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 
        *(uint32_t *)0x10001008 = 0xFFFFFF00; 
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; 
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} 
        DEBUG("done");
        NVIC_SystemReset();
    } 
    DEBUG("UICR->XTALFREQ=%x\r\n", NRF_UICR->XTALFREQ);
#endif

    BleInitialize();
    
    tk.attach_us(&ticker_callback, LED_INTERVAL_NSEC);
/*
    io.display(0.5);
    io.display_value = 1111;    
    for (int i = 0; i < 10; i++){
        wait(0.1);
        io.display_value += 1111;
    }
*/
    while(1){
/*
        int ch;
        ch = 0; pc.printf("%02x\r\n", 0xc4 | (ch << 4));
        ch = 1; pc.printf("%02x\r\n", 0xc4 | (ch << 4));
        ch = 2; pc.printf("%02x\r\n", 0xc4 | (ch << 4));
*/
//        DEBUG("%f %f %f\r\n", io._get_adc(0), io._get_adc(1), io._get_adc(2));
        DEBUG("%x %x %x\r\n", io._get_adc(0), io._get_adc(1), io._get_adc(2));
    }
    for (;; ) {
        ble.waitForEvent();
    }
}