micro code for pen oscilloscope

Dependencies:   BLE_API circular_buffer mbed nRF51822

Fork of BLENano_SimpleControls by RedBearLab

main.cpp

Committer:
aadavids
Date:
2015-03-24
Revision:
7:7a3b7d1c8393
Parent:
6:e19c2a022a95

File content as of revision 7:7a3b7d1c8393:

#include "mbed.h"
#include "BLEDevice.h"
#include "circular_buffer.h"
// Constants
#define BLE_UUID_TXRX_SERVICE            0x0000 /**< The UUID of the Nordic UART Service. */
#define BLE_UUID_TX_CHARACTERISTIC       0x0002 /**< The UUID of the TX Characteristic. */
#define BLE_UUIDS_RX_CHARACTERISTIC      0x0003 /**< The UUID of the RX Characteristic. */

#define TXRX_BUF_LEN                     20

//#define DIGITAL_OUT_PIN                  P0_9       //TXD
//#define DIGITAL_IN_PIN                   P0_10      //CTS
//#define ANALOG_IN_PIN                    P0_4       //P04

#define AC_EN_PIN   P0_19 //FIXFIXFIXTHIS back // P0_4
#define DC_EN_PIN   P0_5
#define PAIRING_LED_PIN P0_7
#define BYPASS_ADC_PIN P0_6
#define PAIRING_BUTTON_PIN P0_15
#define POS_OFFSET_EN_PIN P0_29
#define NEG_OFFSET_EN_PIN P0_28
#define STATUS_LED_PIN P0_11
#define RESET_PIN P0_9

#define COUPLING_SETTING 0x1
#define OFFSET_SETTING 0x2
#define OFFSET_DIR_SETTING 0x9
#define TRIGGER_DIR_SETTING 0x3
#define TRIGGER_VALUE_SETTING 0x4
#define AVERAGING_SETTING 0x5
#define VOLTAGE_RANGE_SETTING 0x6
#define TIME_SHIFT_SETTING 0x7
#define TIME_RANGE_SETTING 0x8

#define AC_COUPLING 0
#define DC_COUPLING 1
#define FALLING_EDGE 0
#define RISING_EDGE 1
#define NEG_OFFSET 0
#define POS_OFFSET 1

// Global Settings
bool coupling_type = 1;  // 0 is AC, 1 is DC
uint8_t offset_value = 0;
bool trigger_dir = 1; // 0 is negative, 1 is positive
bool offset_dir = 1; // 0 is negative, 1 is positive
uint8_t trigger_level = 127;
uint8_t voltage_range = 1;
uint8_t averaging_amount = 1;
uint8_t time_shift_value = 0;
uint8_t time_range_value = 0;

BLEDevice  ble;

// Pins declaration
DigitalOut      AC_EN(AC_EN_PIN);
DigitalOut      DC_EN(DC_EN_PIN);
DigitalOut      PAIRING_LED(PAIRING_LED_PIN);
AnalogIn        ANALOG(BYPASS_ADC_PIN);
DigitalIn       PARING_BUTTON(PAIRING_BUTTON_PIN);
DigitalOut      NEG_OFFSET_EN(NEG_OFFSET_EN_PIN);
DigitalOut      POS_OFFSET_EN(POS_OFFSET_EN_PIN);
DigitalOut      STATUS_LED(STATUS_LED_PIN);

//Serial pc(USBTX, USBRX);

// The Nordic UART Service
static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_rx_uuid[]   = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};


uint8_t txPayload[TXRX_BUF_LEN] = {0,};
uint8_t rxPayload[TXRX_BUF_LEN] = {0,};

//static uint8_t rx_buf[TXRX_BUF_LEN];
//static uint8_t rx_len=0;


GattCharacteristic  txCharacteristic (uart_tx_uuid, txPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);

GattCharacteristic  rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);

GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};

GattService         uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));


void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
    //pc.printf("Disconnected \r\n");
    //pc.printf("Restart advertising \r\n");
    ble.startAdvertising();
}

void WrittenHandler(const GattCharacteristicWriteCBParams *Handler)
{
    uint8_t buf[TXRX_BUF_LEN];
    uint16_t bytesRead;

    if (Handler->charHandle == txCharacteristic.getValueAttribute().getHandle()) {
        ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
        memset(txPayload, 0, TXRX_BUF_LEN);
        memcpy(txPayload, buf, TXRX_BUF_LEN);

        //for(index=0; index<bytesRead; index++)
        //pc.putc(buf[index]);

        if(buf[0] == COUPLING_SETTING) {
            coupling_type = buf[1];
            if (coupling_type == AC_COUPLING) {
                AC_EN = 1;
                DC_EN = 0;
            } else // DC coupling
                AC_EN = 0;
            DC_EN = 1;
        }
    } else if(buf[0] == TRIGGER_DIR_SETTING) {
        trigger_dir = buf[1];
    } else if(buf[0] == AVERAGING_SETTING) {
        averaging_amount = buf[0];
    } else if(buf[0] == TIME_SHIFT_SETTING) {
        time_shift_value = buf[1];
    } else if(buf[0] == TIME_RANGE_SETTING) {
        time_range_value = buf[1];
    } else if(buf[0] == OFFSET_SETTING) {
        offset_value = buf[1];
        if (offset_dir == POS_OFFSET) { // postitive offset
            NEG_OFFSET_EN = 0;
            POS_OFFSET_EN = 1;
        } else { // negative offset
            NEG_OFFSET_EN = 1;
            POS_OFFSET_EN = 0;
        }
    } else if(buf[0] == TRIGGER_VALUE_SETTING) {
        trigger_level = buf[1];
    }
}

bool is_rising_edge (uint8_t current_sample, uint8_t previous_sample)
{
    return (current_sample > trigger_level && previous_sample < trigger_level);
}

bool is_falling_edge (uint8_t current_sample, uint8_t previous_sample)
{
    return (current_sample > trigger_level && previous_sample < trigger_level);
}

bool is_triggered (uint8_t current_sample, uint8_t previous_sample, bool dir) {
    if (dir == RISING_EDGE) {
        return is_rising_edge (current_sample, previous_sample);
    } else {
        return is_falling_edge (current_sample, previous_sample);
    }
}

#define VOLTAGE_BUFFER_SIZE 1024
circular_buffer<uint8_t> voltage_buffer(VOLTAGE_BUFFER_SIZE);
uint8_t out_buf[VOLTAGE_BUFFER_SIZE];
void m_status_check_handle(void)
{
    static bool is_shifting = false;
    static uint8_t time_shift = 0;
    static uint8_t prev_sample = 0;
    // Read and send out
    float s = ANALOG;
    uint8_t sample = s*255;
    voltage_buffer.push_back(sample);

    if ((is_shifting) || (voltage_buffer.get_size() == VOLTAGE_BUFFER_SIZE) && (is_triggered(sample, prev_sample, trigger_dir))) {
        if (is_rising_edge(sample, prev_sample) || is_falling_edge(sample, prev_sample))  {
            if (time_shift < time_shift_value) {
                is_shifting = true;
                time_shift++;
            } else {
                is_shifting = false;
                time_shift = 0;
                for (int i = 0; i < VOLTAGE_BUFFER_SIZE; i++) {
                    out_buf[i] = voltage_buffer.front();
                    voltage_buffer.pop_front();
                }
                ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), out_buf, VOLTAGE_BUFFER_SIZE);
            }
        }
        prev_sample = sample;
    }
    }

    int main(void) {
        Ticker ticker;
        ticker.attach_us(m_status_check_handle, 1000);

        ble.init();
        ble.onDisconnection(disconnectionCallback);
        ble.onDataWritten(WrittenHandler);

        //pc.baud(9600);
        //pc.printf("SimpleChat Init \r\n");

        //pc.attach( uartCB , pc.RxIrq);

        // setup advertising
        //ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
        ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
        ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                         (const uint8_t *)"Serqet", sizeof("Serqet") - 1);
        ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                         (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
        // 100ms; in multiples of 0.625ms.
        ble.setAdvertisingInterval(160);

        ble.addService(uartService);

        ble.startAdvertising();

        //pc.printf("Advertising Start \r\n");

        while(1) {
            ble.waitForEvent();
        }
    }