Example of BLE scan/connect/service discovery
Fork of BLE_LEDBlinker by
Revision 14:92bb9a8ccd0b, committed 2017-04-20
- Comitter:
- tsungta
- Date:
- Thu Apr 20 06:54:25 2017 +0000
- Parent:
- 13:75f95a5cf9c1
- Commit message:
- Update mbed-os to support Delta DFCM-NNN50 platform
Changed in this revision
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b main.cpp --- a/main.cpp Fri Dec 09 10:10:14 2016 +0000 +++ b/main.cpp Thu Apr 20 06:54:25 2017 +0000 @@ -21,12 +21,6 @@ DigitalOut alivenessLED(LED1, 1); -#if defined(TARGET_DELTA_DFCM_NNN40) -Serial uart(p17, p16);//temp use for NNN50 -#else -Serial uart(USBTX, USBRX); -#endif - bool triggerLedCharacteristic = false; DiscoveredCharacteristic ledCharacteristic; @@ -40,7 +34,7 @@ if (params->peerAddr[0] != 0xF9) { /* !ALERT! Alter this filter to suit your device. */ return; } - uart.printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", + printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type); @@ -48,43 +42,43 @@ } void serviceDiscoveryCallback(const DiscoveredService *service) { - uart.printf("serviceDiscoveryCallback\n"); + printf("serviceDiscoveryCallback\n"); if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { - uart.printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); + printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); } else { - uart.printf("S UUID-"); + printf("S UUID-"); const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { - uart.printf("%02x", longUUIDBytes[i]); + printf("%02x", longUUIDBytes[i]); } - uart.printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); + printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); } } void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { if (characteristicP->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { - uart.printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); if (characteristicP->getUUID().getShortUUID() == 0x2a19) { /* !ALERT! Alter this filter to suit your device. */ ledCharacteristic = *characteristicP; triggerLedCharacteristic = true; } } else { - uart.printf(" C UUID-"); + printf(" C UUID-"); const uint8_t *longUUIDBytes = characteristicP->getUUID().getBaseUUID(); for (unsigned i = (UUID::LENGTH_OF_LONG_UUID) - 1; i < UUID::LENGTH_OF_LONG_UUID; i--) { - uart.printf("%02x ", longUUIDBytes[i]); + printf("%02x ", longUUIDBytes[i]); } - uart.printf(" valueAttr[%u] props[%x]\r\n", characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + printf(" valueAttr[%u] props[%x]\r\n", characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); } } void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { - uart.printf("terminated SD for handle %u\r\n", connectionHandle); + printf("terminated SD for handle %u\r\n", connectionHandle); } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { - uart.printf("connectionCallback\n"); + printf("connectionCallback\n"); if (params->role == Gap::CENTRAL) { BLE::Instance().gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); BLE::Instance().gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback); @@ -94,11 +88,11 @@ void triggerToggledWrite(const GattReadCallbackParams *response) { if (response->handle == ledCharacteristic.getValueHandle()) { #if DUMP_READ_DATA - uart.printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); + printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); for (unsigned index = 0; index < response->len; index++) { - uart.printf("%c[%02x]", response->data[index], response->data[index]); + printf("%c[%02x]", response->data[index], response->data[index]); } - uart.printf("\r\n"); + printf("\r\n"); #endif uint8_t toggledValue = response->data[0] ^ 0x1; @@ -113,7 +107,7 @@ } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { - uart.printf("disconnected\r\n"); + printf("disconnected\r\n"); } /** @@ -154,7 +148,7 @@ } int main(void) { - uart.printf("APPLICATION START\r\n"); + printf("APPLICATION START\r\n"); ticker.attach(periodicCallback, 1); BLE &ble = BLE::Instance(); @@ -163,7 +157,7 @@ /* SpinWait for initialization to complete. This is necessary because the * BLE object is used in the main loop below. */ while (ble.hasInitialized() == false) { /* spin loop */ } - uart.printf("init DONE\r\n"); + printf("init DONE\r\n"); while (true) { if (triggerLedCharacteristic && !ble.gattClient().isServiceDiscoveryActive()) { triggerLedCharacteristic = false;
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/EventLoop.cpp --- a/mbed-events/EventLoop.cpp Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -#ifdef MBED_CONF_RTOS_PRESENT -#include "EventLoop.h" - -#include "events.h" -#include "rtos.h" -#include "mbed.h" - - -EventLoop::EventLoop( - osPriority priority, - unsigned event_size, - unsigned char *event_pointer, - uint32_t stack_size, - unsigned char *stack_pointer) - : EventQueue(event_size, event_pointer) - , _thread(priority, stack_size, stack_pointer) - , _running(false) { -} - -EventLoop::~EventLoop() { - stop(); -} - -static void run(EventLoop *loop) { - loop->dispatch(); -} - -osStatus EventLoop::start() { - if (_running) { - return osOK; - } - - osStatus status = _thread.start(this, run); - _running = (status == osOK); - return status; -} - -osStatus EventLoop::stop() { - if (!_running) { - return osOK; - } - - break_(); - osStatus status = _thread.join(); - _running = false; - return status; -} - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/EventLoop.h --- a/mbed-events/EventLoop.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* events - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifdef MBED_CONF_RTOS_PRESENT -#ifndef EVENT_LOOP_H -#define EVENT_LOOP_H - -#include "EventQueue.h" -#include "Thread.h" - -namespace events { - - -/** EventLoop - * - * An event queue wrapped in a thread - */ -class EventLoop : public EventQueue { -public: - /** Create an event loop - * - * @param priority Initial priority of the thread - * (default: osPriorityNormal) - * @param queue_size Size of buffer to use for events - * (default: DEFAULT_QUEUE_SIZE) - * @param queue_pointer Pointer to memory region to use for events - * (default: NULL) - * @param stack_size Stack size (in bytes) requirements for the thread - * (default: DEFAULT_STACK_SIZE) - * @param stack_pointer Pointer to stack area to be used by the thread - * (default: NULL) - */ - EventLoop(osPriority priority=osPriorityNormal, - unsigned event_size=DEFAULT_QUEUE_SIZE, - unsigned char *event_pointer=NULL, - uint32_t stack_size=DEFAULT_STACK_SIZE, - unsigned char *stack_pointer=NULL); - - /** Clean up event loop - */ - ~EventLoop(); - - /** Starts an event loop running in a dedicated thread - * @return status code that indicates the execution status of the function. - */ - osStatus start(); - - /** Stops an event loop cleanly, waiting for any currently executing events - * @return status code that indicates the execution status of the function. - */ - osStatus stop(); - -private: - rtos::Thread _thread; - bool _running; -}; - - -} - -#endif -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/EventQueue.cpp --- a/mbed-events/EventQueue.cpp Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#include "EventQueue.h" - -#include "events-c/events.h" -#include "events.h" -#include "mbed.h" - - -EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) { - if (!event_pointer) { - equeue_create(&_equeue, event_size); - } else { - equeue_create_inplace(&_equeue, event_size, event_pointer); - } -} - -EventQueue::~EventQueue() { - equeue_destroy(&_equeue); -} - -void EventQueue::dispatch(int ms) { - return equeue_dispatch(&_equeue, ms); -} - -void EventQueue::break_() { - return equeue_break(&_equeue); -} - -unsigned EventQueue::get_tick() { - return events_tick(); -} - -void EventQueue::cancel(int id) { - return event_cancel(&_equeue, id); -} - -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/EventQueue.h --- a/mbed-events/EventQueue.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -/* events - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef EVENT_QUEUE_H -#define EVENT_QUEUE_H - -#include "events-c/events.h" -#include "Callback.h" -#include <cstddef> -#include <new> - -namespace events { - - -/** DEFAULT_QUEUE_SIZE - * default size of buffer for events - */ -#define DEFAULT_QUEUE_SIZE \ - (32*(sizeof(struct event) + sizeof(mbed::Callback<void()>))) - - -/** EventQueue - * - * Flexible event queue - */ -class EventQueue { -public: - /** Create an event queue - * - * @param queue_size Size of buffer to use for events - * (default: DEFAULT_QUEUE_SIZE) - * @param queue_pointer Pointer to memory region to use for events - * (default: NULL) - */ - EventQueue(unsigned queue_size=DEFAULT_QUEUE_SIZE, - unsigned char *queue_pointer=NULL); - - /** Destroy an event queue - */ - ~EventQueue(); - - /** Dispatch pending events - * @param ms Time to wait for events in milliseconds, 0 will return - * immediately if no events are pending, a negative - * value will dispatch events forever - * (default: -1) - */ - void dispatch(int ms=-1); - - /* Monotonic counter for the event queue - * @return A monotonically incrementing counter in milliseconds - * this count intentionally overflows to 0 after 2^32-1 - */ - unsigned get_tick(); - - /** Cancel events that are in flight - * - * If event has already been dispatched or does not exist, no error occurs. - * - * @param id Event id to cancel - * @note This can not stop a currently executing event - */ - void cancel(int id); - - /** Post an event to the queue - * - * @param f Function to call on event dispatch - * @param a0..a4 Arguments to pass to the callback - * @return A positive id representing the event in the queue, - * or 0 on failure - */ - template <typename F> - int post(F f) { - void *p = event_alloc(&_equeue, sizeof(F)); - if (!p) { - return 0; - } - - F *e = new (p) F(f); - event_dtor(e, &EventQueue::dtor<F>); - return event_post(&_equeue, &EventQueue::call<F>, e); - } - - template <typename F, typename A0> - int post(F f, A0 a0) { - return post(Context1<F,A0>(f,a0)); - } - - template <typename F, typename A0, typename A1> - int post(F f, A0 a0, A1 a1) { - return post(Context2<F,A0,A1>(f,a0,a1)); - } - - template <typename F, typename A0, typename A1, typename A2> - int post(F f, A0 a0, A1 a1, A2 a2) { - return post(Context3<F,A0,A1,A2>(f,a0,a1,a2)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3> - int post(F f, A0 a0, A1 a1, A2 a2, A3 a3) { - return post(Context4<F,A0,A1,A2,A3>(f,a0,a1,a2,a3)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> - int post(F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { - return post(Context5<F,A0,A1,A2,A3,A4>(f,a0,a1,a2,a3,a4)); - } - - /** Post an event to the queue after a specified delay - * - * @param f Function to call on event dispatch - * @param a0..a4 Arguments to pass to the callback - * @param ms Time to delay in milliseconds - * @return A positive id representing the event in the queue, - * or 0 on failure - */ - template <typename F> - int post_in(int ms, F f) { - void *p = event_alloc(&_equeue, sizeof(F)); - if (!p) { - return 0; - } - - F *e = new (p) F(f); - event_delay(e, ms); - event_dtor(e, &EventQueue::dtor<F>); - return event_post(&_equeue, &EventQueue::call<F>, e); - } - - template <typename F, typename A0> - int post_in(int ms, F f, A0 a0) { - return post_in(ms, Context1<F,A0>(f,a0)); - } - - template <typename F, typename A0, typename A1> - int post_in(int ms, F f, A0 a0, A1 a1) { - return post_in(ms, Context2<F,A0,A1>(f,a0,a1)); - } - - template <typename F, typename A0, typename A1, typename A2> - int post_in(int ms, F f, A0 a0, A1 a1, A2 a2) { - return post_in(ms, Context3<F,A0,A1,A2>(f,a0,a1,a2)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3> - int post_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { - return post_in(ms, Context4<F,A0,A1,A2,A3>(f,a0,a1,a2,a3)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> - int post_in(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { - return post_in(ms, Context5<F,A0,A1,A2,A3,A4>(f,a0,a1,a2,a3,a4)); - } - - /** Post an event to the queue periodically - * - * @param f Function to call on event dispatch - * @param a0..a4 Arguments to pass to the callback - * @param ms Period of the event in milliseconds - * @return A positive id representing the event in the queue, - * or 0 on failure - */ - template <typename F> - int post_every(int ms, F f) { - void *p = event_alloc(&_equeue, sizeof(F)); - if (!p) { - return 0; - } - - F *e = new (p) F(f); - event_delay(e, ms); - event_period(e, ms); - event_dtor(e, &EventQueue::dtor<F>); - return event_post(&_equeue, &EventQueue::call<F>, e); - } - - template <typename F, typename A0> - int post_every(int ms, F f, A0 a0) { - return post_every(ms, Context1<F,A0>(f,a0)); - } - - template <typename F, typename A0, typename A1> - int post_every(int ms, F f, A0 a0, A1 a1) { - return post_every(ms, Context2<F,A0,A1>(f,a0,a1)); - } - - template <typename F, typename A0, typename A1, typename A2> - int post_every(int ms, F f, A0 a0, A1 a1, A2 a2) { - return post_every(ms, Context3<F,A0,A1,A2>(f,a0,a1,a2)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3> - int post_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3) { - return post_every(ms, Context4<F,A0,A1,A2,A3>(f,a0,a1,a2,a3)); - } - - template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> - int post_every(int ms, F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { - return post_every(ms, Context5<F,A0,A1,A2,A3,A4>(f,a0,a1,a2,a3,a4)); - } - -protected: - void break_(); - - struct equeue _equeue; - - template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> - struct Context5 { - F f; A0 a0; A1 a1; A2 a2; A3 a3; A4 a4; - - Context5(F f, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) - : f(f), a0(a0), a1(a1), a2(a2), a3(a3), a4(a4) {} - - void operator()() { - f(a0, a1, a2, a3, a4); - } - }; - - template <typename F, typename A0, typename A1, typename A2, typename A3> - struct Context4 { - F f; A0 a0; A1 a1; A2 a2; A3 a3; - - Context4(F f, A0 a0, A1 a1, A2 a2, A3 a3) - : f(f), a0(a0), a1(a1), a2(a2), a3(a3) {} - - void operator()() { - f(a0, a1, a2, a3); - } - }; - - template <typename F, typename A0, typename A1, typename A2> - struct Context3 { - F f; A0 a0; A1 a1; A2 a2; - - Context3(F f, A0 a0, A1 a1, A2 a2) - : f(f), a0(a0), a1(a1), a2(a2) {} - - void operator()() { - f(a0, a1, a2); - } - }; - - template <typename F, typename A0, typename A1> - struct Context2 { - F f; A0 a0; A1 a1; - - Context2(F f, A0 a0, A1 a1) - : f(f), a0(a0), a1(a1) {} - - void operator()() { - f(a0, a1); - } - }; - - template <typename F, typename A0> - struct Context1 { - F f; A0 a0; - - Context1(F f, A0 a0) - : f(f), a0(a0) {} - - void operator()() { - f(a0); - } - }; - - template <typename T> - static void call(void *p) { - (*static_cast<T*>(p))(); - } - - template <typename T> - static void dtor(void *p) { - static_cast<T*>(p)->~T(); - } -}; - - -} - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events.c --- a/mbed-events/events-c/events.c Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +0,0 @@ -#include "events.h" - -#include <stdlib.h> -#include <string.h> - - -int equeue_create(equeue_t *q, unsigned size) { - void *buffer = malloc(size); - if (!buffer) { - return -1; - } - - int err = equeue_create_inplace(q, size, buffer); - q->buffer = buffer; - return err; -} - -int equeue_create_inplace(equeue_t *q, unsigned size, void *buffer) { - q->slab.size = size; - q->slab.data = buffer; - q->chunks = 0; - q->buffer = 0; - - q->queue = 0; - q->next_id = 42; - q->break_ = (struct event){ - .id = 0, - .period = -1, - }; - - int err; - err = events_sema_create(&q->eventsema); - if (err < 0) { - return err; - } - - err = events_mutex_create(&q->queuelock); - if (err < 0) { - return err; - } - - err = events_mutex_create(&q->freelock); - if (err < 0) { - return err; - } - - return 0; -} - -void equeue_destroy(equeue_t *q) { - while (q->queue) { - struct event *e = q->queue; - q->queue = e->next; - event_dealloc(q, e+1); - } - - events_mutex_destroy(&q->freelock); - events_mutex_destroy(&q->queuelock); - events_sema_destroy(&q->eventsema); - free(q->buffer); -} - -// equeue allocation functions -static void *equeue_alloc(equeue_t *q, unsigned size) { - size = size + sizeof(unsigned); - size = (size + sizeof(unsigned)-1) & ~(sizeof(unsigned)-1); - if (size < sizeof(struct equeue_chunk)) { - size = sizeof(struct equeue_chunk); - } - - events_mutex_lock(&q->freelock); - - for (struct equeue_chunk **p = &q->chunks; *p; p = &(*p)->nchunk) { - if ((*p)->size >= size) { - struct equeue_chunk *c = *p; - if (c->next) { - *p = c->next; - (*p)->nchunk = c->nchunk; - } else { - *p = c->nchunk; - } - events_mutex_unlock(&q->freelock); - return (unsigned *)c + 1; - } - } - - if (q->slab.size >= size) { - struct equeue_chunk *c = (struct equeue_chunk *)q->slab.data; - q->slab.data += size; - q->slab.size -= size; - c->size = size; - events_mutex_unlock(&q->freelock); - return (unsigned *)c + 1; - } - - events_mutex_unlock(&q->freelock); - return 0; -} - -static void equeue_dealloc(equeue_t *q, void *e) { - struct equeue_chunk *c = (struct equeue_chunk *)((unsigned *)e - 1); - - events_mutex_lock(&q->freelock); - - struct equeue_chunk **p = &q->chunks; - while (*p && (*p)->size < c->size) { - p = &(*p)->nchunk; - } - - if (*p && (*p)->size == c->size) { - c->next = *p; - c->nchunk = (*p)->nchunk; - } else { - c->next = 0; - c->nchunk = *p; - } - *p = c; - - events_mutex_unlock(&q->freelock); -} - -// event allocation functions -static inline int event_next_id(equeue_t *q) { - int id = q->next_id++; - if (q->next_id < 0) { - q->next_id = 42; - } - return id; -} - -void *event_alloc(equeue_t *q, unsigned size) { - struct event *e = equeue_alloc(q, sizeof(struct event) + size); - if (!e) { - return 0; - } - - e->id = event_next_id(q); - e->target = 0; - e->period = -1; - e->dtor = 0; - - return e + 1; -} - -void event_dealloc(equeue_t *q, void *p) { - struct event *e = (struct event*)p - 1; - - if (e->dtor) { - e->dtor(e+1); - } - - equeue_dealloc(q, e); -} - -// equeue scheduling functions -static inline int equeue_tickdiff(unsigned a, unsigned b) { - return (int)(a - b); -} - -static void equeue_enqueue(equeue_t *q, struct event *e, unsigned ms) { - e->target = events_tick() + ms; - - struct event **p = &q->queue; - while (*p && equeue_tickdiff((*p)->target, e->target) <= 0) { - p = &(*p)->next; - } - - e->next = *p; - *p = e; -} - -static struct event *equeue_dequeue(equeue_t *q, int id) { - for (struct event **p = &q->queue; *p; p = &(*p)->next) { - if ((*p)->id == id) { - struct event *e = *p; - *p = (*p)->next; - return e; - } - } - - return 0; -} - -static int equeue_post(equeue_t *q, struct event *e, int ms) { - int id = e->id; - if (ms < 0) { - event_dealloc(q, e+1); - return id; - } - - events_mutex_lock(&q->queuelock); - equeue_enqueue(q, e, ms); - events_mutex_unlock(&q->queuelock); - - events_sema_release(&q->eventsema); - return id; -} - -static void equeue_cancel(equeue_t *q, int id) { - events_mutex_lock(&q->queuelock); - struct event *e = equeue_dequeue(q, id); - events_mutex_unlock(&q->queuelock); - - if (e) { - event_dealloc(q, e+1); - } -} - -void equeue_break(equeue_t *q) { - equeue_post(q, &q->break_, 0); -} - -void equeue_dispatch(equeue_t *q, int ms) { - if (ms >= 0) { - equeue_post(q, &q->break_, ms); - } - - while (1) { - int deadline = -1; - - while (q->queue) { - deadline = -1; - - events_mutex_lock(&q->queuelock); - if (!q->queue) { - events_mutex_unlock(&q->queuelock); - break; - } - - deadline = equeue_tickdiff(q->queue->target, events_tick()); - if (deadline > 0) { - events_mutex_unlock(&q->queuelock); - break; - } - - struct event *e = q->queue; - q->queue = e->next; - - if (e->period >= 0) { - // requeue periodic tasks to avoid race conditions - // in event_cancel - equeue_enqueue(q, e, e->period); - } - events_mutex_unlock(&q->queuelock); - - if (e == &q->break_) { - return; - } - - // actually dispatch the callback - e->cb(e + 1); - - if (e->period < 0) { - event_dealloc(q, e+1); - } - } - - events_sema_wait(&q->eventsema, deadline); - } -} - -// event functions -void event_delay(void *p, int ms) { - struct event *e = (struct event*)p - 1; - e->target = ms; -} - -void event_period(void *p, int ms) { - struct event *e = (struct event*)p - 1; - e->period = ms; -} - -void event_dtor(void *p, void (*dtor)(void *)) { - struct event *e = (struct event*)p - 1; - e->dtor = dtor; -} - -// event operations -int event_post(equeue_t *q, void (*cb)(void*), void *p) { - struct event *e = (struct event*)p - 1; - e->cb = cb; - int id = equeue_post(q, e, e->target); - return id; -} - -void event_cancel(equeue_t *q, int id) { - equeue_cancel(q, id); -} - -// simple callbacks -struct ecallback { - void (*cb)(void*); - void *data; -}; - -static void ecallback_dispatch(void *p) { - struct ecallback *e = (struct ecallback*)p; - e->cb(e->data); -} - -int event_call(equeue_t *q, void (*cb)(void*), void *data) { - struct ecallback *e = event_alloc(q, sizeof(struct ecallback)); - if (!e) { - return 0; - } - - e->cb = cb; - e->data = data; - return event_post(q, ecallback_dispatch, e); -} - -int event_call_in(equeue_t *q, int ms, void (*cb)(void*), void *data) { - struct ecallback *e = event_alloc(q, sizeof(struct ecallback)); - if (!e) { - return 0; - } - - event_delay(e, ms); - e->cb = cb; - e->data = data; - return event_post(q, ecallback_dispatch, e); -} - -int event_call_every(equeue_t *q, int ms, void (*cb)(void*), void *data) { - struct ecallback *e = event_alloc(q, sizeof(struct ecallback)); - if (!e) { - return 0; - } - - event_delay(e, ms); - event_period(e, ms); - e->cb = cb; - e->data = data; - return event_post(q, ecallback_dispatch, e); -} -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events.h --- a/mbed-events/events-c/events.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * Flexible event queue for dispatching events - */ -#ifndef EVENTS_H -#define EVENTS_H - -#ifdef __cplusplus -extern "C" { -#endif - -// System specific files -#include "events_tick.h" -#include "events_mutex.h" -#include "events_sema.h" - - -// Event/queue structures -struct event { - struct event *next; - int id; - unsigned target; - int period; - void (*dtor)(void *); - - void (*cb)(void *); - // data follows -}; - -typedef struct equeue { - struct event *queue; - int next_id; - - void *buffer; - struct equeue_chunk { - unsigned size; - struct equeue_chunk *next; - struct equeue_chunk *nchunk; - } *chunks; - struct equeue_slab { - unsigned size; - unsigned char *data; - } slab; - - struct event break_; - - events_sema_t eventsema; - events_mutex_t queuelock; - events_mutex_t freelock; -} equeue_t; - -// Queue operations -// -// Creation results in negative value on failure. -int equeue_create(equeue_t *queue, unsigned size); -int equeue_create_inplace(equeue_t *queue, unsigned size, void *buffer); -void equeue_destroy(equeue_t *queue); - -// Dispatch events -// -// Executes any callbacks enqueued for the specified time in milliseconds, -// or forever if ms is negative -void equeue_dispatch(equeue_t *queue, int ms); - -// Break a running event loop -// -// Shuts down an unbounded event loop. Already pending events may finish -// executing, but the queue will not continue looping indefinitely. -void equeue_break(equeue_t *queue); - -// Simple event calls -// -// Passed callback will be executed in the associated equeue's -// dispatch call with the data pointer passed unmodified -// -// event_call - Immediately post an event to the queue -// event_call_in - Post an event after a specified time in milliseconds -// event_call_every - Post an event periodically in milliseconds -// -// These calls will result in 0 if no memory is available, otherwise they -// will result in a unique identifier that can be passed to event_cancel. -int event_call(equeue_t *queue, void (*cb)(void *), void *data); -int event_call_in(equeue_t *queue, int ms, void (*cb)(void *), void *data); -int event_call_every(equeue_t *queue, int ms, void (*cb)(void *), void *data); - -// Events with queue handled blocks of memory -// -// Argument to event_post must point to a result of a event_alloc call -// and the associated memory is automatically freed after the event -// is dispatched. -// -// event_alloc will result in null if no memory is available -// or the requested size is less than the size passed to equeue_create. -void *event_alloc(equeue_t *queue, unsigned size); -void event_dealloc(equeue_t *queue, void *event); - -// Configure an allocated event -// -// event_delay - Specify a millisecond delay before posting an event -// event_period - Specify a millisecond period to repeatedly post an event -// event_dtor - Specify a destructor to run before the memory is deallocated -void event_delay(void *event, int ms); -void event_period(void *event, int ms); -void event_dtor(void *event, void (*dtor)(void *)); - -// Post an allocted event to the event queue -// -// Argument to event_post must point to a result of a event_alloc call -// and the associated memory is automatically freed after the event -// is dispatched. -// -// This call results in an unique identifier that can be passed to -// event_cancel. -int event_post(equeue_t *queue, void (*cb)(void *), void *event); - -// Cancel events that are in flight -// -// Every event_call function returns a non-negative identifier on success -// that can be used to cancel an in-flight event. If the event has already -// been dispatched or does not exist, no error occurs. Note, this can not -// stop a currently executing event -void event_cancel(equeue_t *queue, int event); - - -#ifdef __cplusplus -} -#endif - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events_mbed.cpp --- a/mbed-events/events-c/events_mbed.cpp Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -#if defined(__MBED__) - -#include "events_tick.h" -#include "events_sema.h" -#include "events_mutex.h" - -#include <stdbool.h> -#include "mbed.h" -#ifdef MBED_CONF_RTOS_PRESENT -#include "rtos.h" -#endif - - -// Ticker operations -static class GlobalTicker { -public: - GlobalTicker() { - _tick = 0; - _timer.start(); - _ticker.attach_us(this, &GlobalTicker::step, (1 << 16) * 1000); - }; - - void step() { - _timer.reset(); - _tick += 1 << 16; - } - - unsigned tick() { - return _tick + (unsigned)_timer.read_ms(); - } - -private: - unsigned _tick; - Timer _timer; - Ticker _ticker; -} gticker; - -unsigned events_tick() { - return gticker.tick(); -} - - -// Mutex operations -int events_mutex_create(events_mutex_t *m) { return 0; } -void events_mutex_destroy(events_mutex_t *m) { } - -void events_mutex_lock(events_mutex_t *m) { - *m = __get_PRIMASK(); - __disable_irq(); -} - -void events_mutex_unlock(events_mutex_t *m) { - __set_PRIMASK(*m); -} - - -// Semaphore operations -#ifdef MBED_CONF_RTOS_PRESENT - -static inline Semaphore *sema(events_sema_t *s) { - return static_cast<Semaphore*>(*s); -} - -int events_sema_create(events_sema_t *s) { - *s = new Semaphore(0); - return sema(s) ? 0 : -1; -} - -void events_sema_destroy(events_sema_t *s) { - delete sema(s); -} - -void events_sema_release(events_sema_t *s) { - sema(s)->release(); -} - -bool events_sema_wait(events_sema_t *s, int ms) { - int t = sema(s)->wait(ms < 0 ? osWaitForever : ms); - return t > 0; -} - -#else - -// Semaphore operations -int events_sema_create(events_sema_t *s) { return 0; } -void events_sema_destroy(events_sema_t *s) {} -void events_sema_release(events_sema_t *s) {} - -static void events_sema_wakeup() {} - -bool events_sema_wait(events_sema_t *s, int ms) { - Timeout timeout; - timeout.attach_us(events_sema_wakeup, ms*1000); - - __WFI(); - - return true; -} - -#endif - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events_mutex.h --- a/mbed-events/events-c/events_mutex.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * System specific mutex implementation - */ -#ifndef EVENTS_MUTEX_H -#define EVENTS_MUTEX_H - -#ifdef __cplusplus -extern "C" { -#endif - - -// Mutex type -// -// If this type is safe in interrupt contexts, then -// the associated event queue will also be safe in -// interrupt contexts. -#if defined(__unix__) -#include <pthread.h> -typedef pthread_mutex_t events_mutex_t; -#elif defined(__MBED__) -typedef unsigned events_mutex_t; -#endif - - -// Mutex operations -int events_mutex_create(events_mutex_t *mutex); -void events_mutex_destroy(events_mutex_t *mutex); -void events_mutex_lock(events_mutex_t *mutex); -void events_mutex_unlock(events_mutex_t *mutex); - - -#ifdef __cplusplus -} -#endif - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events_posix.c --- a/mbed-events/events-c/events_posix.c Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -#if defined(__unix__) - -#include "events_tick.h" -#include "events_sema.h" -#include "events_mutex.h" - -#include <time.h> - - -// Tick operations -#ifdef _POSIX_TIMERS - -unsigned events_tick(void) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (unsigned)(ts.tv_sec*1000 + ts.tv_nsec/1000000); -} - -#else -#include <sys/time.h> - -unsigned events_tick(void) { - struct timeval tv; - gettimeofday(&tv, 0); - return (unsigned)(tv.tv_sec*1000 + tv.tv_usec/1000); -} - -#endif - - -// Mutex operations -int events_mutex_create(events_mutex_t *m) { - return pthread_mutex_init(m, 0); -} - -void events_mutex_destroy(events_mutex_t *m) { - pthread_mutex_destroy(m); -} - -void events_mutex_lock(events_mutex_t *m) { - pthread_mutex_lock(m); -} - -void events_mutex_unlock(events_mutex_t *m) { - pthread_mutex_unlock(m); -} - - -int events_sema_create(events_sema_t *s) { - int err = pthread_mutex_init(&s->mutex, 0); - if (err) { - return err; - } - - err = pthread_cond_init(&s->cond, 0); - if (err) { - return err; - } - - return 0; -} - -void events_sema_destroy(events_sema_t *s) { - pthread_mutex_destroy(&s->mutex); - pthread_cond_destroy(&s->cond); -} - -void events_sema_release(events_sema_t *s) { - pthread_cond_signal(&s->cond); -} - -bool events_sema_wait(events_sema_t *s, int ms) { - int err; - pthread_mutex_lock(&s->mutex); - - if (ms < 0) { - err = pthread_cond_wait(&s->cond, &s->mutex); - } else { - ms += events_tick(); - struct timespec ts = { - .tv_sec = ms/1000, - .tv_nsec = ms*1000000, - }; - err = pthread_cond_timedwait(&s->cond, &s->mutex, &ts); - } - - pthread_mutex_unlock(&s->mutex); - return !err; -} - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events_sema.h --- a/mbed-events/events-c/events_sema.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * System specific semaphore implementation - */ -#ifndef EVENTS_SEMA_H -#define EVENTS_SEMA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdbool.h> - - -// Semaphore type -// -// Optimal implementation is a binary semaphore, -// however a regular semaphore is sufficient. -#if defined(__unix__) -#include <pthread.h> -typedef struct { - pthread_mutex_t mutex; - pthread_cond_t cond; -} events_sema_t; -#elif defined(__MBED__) -#ifdef MBED_CONF_RTOS_PRESENT -typedef void *events_sema_t; -#else -typedef struct {} events_sema_t; -#endif -#endif - - -// Semaphore operations -int events_sema_create(events_sema_t *sema); -void events_sema_destroy(events_sema_t *sema); -void events_sema_release(events_sema_t *sema); -bool events_sema_wait(events_sema_t *sema, int ms); - - -#ifdef __cplusplus -} -#endif - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events-c/events_tick.h --- a/mbed-events/events-c/events_tick.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * System specific tick implementation - */ -#ifndef EVENTS_TICK_H -#define EVENTS_TICK_H - -#ifdef __cplusplus -extern "C" { -#endif - - -// Monotonic tick -// -// Returns a tick that is incremented every millisecond, -// must intentionally overflow to 0 after 2^32-1 -unsigned events_tick(void); - - -#ifdef __cplusplus -} -#endif - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-events/events.h --- a/mbed-events/events.h Fri Dec 09 10:10:14 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* events - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef EVENTS_CPP_H -#define EVENTS_CPP_H - -#include "EventQueue.h" -#include "EventLoop.h" - -using namespace events; - -#endif -
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed-os.lib --- a/mbed-os.lib Fri Dec 09 10:10:14 2016 +0000 +++ b/mbed-os.lib Thu Apr 20 06:54:25 2017 +0000 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#a6f3fd1a60d5df59246d7caf3f108c4d34e1808e +https://github.com/ARMmbed/mbed-os/#50b3418e45484ebf442b88cd935a2d5355402d7d
diff -r 75f95a5cf9c1 -r 92bb9a8ccd0b mbed_app.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_app.json Thu Apr 20 06:54:25 2017 +0000 @@ -0,0 +1,17 @@ +{ + "config": { + "lf_clock_rc_calib_timer_interval": { + "value": 16, + "macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL" + }, + "lf_clock_rc_calib_mode_config": { + "value": 0, + "macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG" + }, + "uart_hwfc": { + "help": "Value: 1 for enable, 0 for disable", + "value": 0, + "macro_name": "MBED_CONF_NORDIC_UART_HWFC" + } + } +} \ No newline at end of file