Added NRF52_adc Tutorial
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/5095a8d2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/5095a8d2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/5095a8d2 Branch: refs/heads/develop Commit: 5095a8d208e77d22a01feeeca551990b802b1a38 Parents: c870a0f Author: David G. Simmons <[email protected]> Authored: Tue Dec 6 17:21:51 2016 -0500 Committer: David G. Simmons <[email protected]> Committed: Tue Dec 20 10:41:51 2016 -0500 ---------------------------------------------------------------------- apps/nrf52_adc/pkg.yml | 41 ++++ apps/nrf52_adc/src/bleadc.h | 74 ++++++ apps/nrf52_adc/src/gatt_svr.c | 318 ++++++++++++++++++++++++++ apps/nrf52_adc/src/main.c | 451 +++++++++++++++++++++++++++++++++++++ apps/nrf52_adc/src/misc.c | 43 ++++ apps/nrf52_adc/syscfg.yml | 50 ++++ hw/bsp/nrf52dk/src/hal_bsp.c | 22 +- hw/bsp/nrf52dk/syscfg.yml | 15 +- 8 files changed, 1011 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/pkg.yml b/apps/nrf52_adc/pkg.yml new file mode 100644 index 0000000..a1a4ebb --- /dev/null +++ b/apps/nrf52_adc/pkg.yml @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# +pkg.name: apps/nrf52_adc +pkg.type: app +pkg.description: Simple ADC peripheral application. +pkg.author: "Apache Mynewt <[email protected]>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - kernel/os + - sys/log + - mgmt/newtmgr + - mgmt/newtmgr/transport/ble + - net/nimble/controller + - net/nimble/host + - net/nimble/host/services/gap + - net/nimble/host/services/gatt + - net/nimble/host/store/ram + - net/nimble/transport/ram + - sys/console/full + - sys/shell + - libc/baselibc + - sys/sysinit + - sys/id + - "@mynewt_nordic/hw/drivers/adc/adc_nrf52" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/src/bleadc.h ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/src/bleadc.h b/apps/nrf52_adc/src/bleadc.h new file mode 100644 index 0000000..6c9ac81 --- /dev/null +++ b/apps/nrf52_adc/src/bleadc.h @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 H_BLEADC_ +#define H_BLEADC_ + +#include "log/log.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +extern struct log bleadc_log; + +/* bleadc uses the first "peruser" log module. */ +#define BLEADC_LOG_MODULE (LOG_MODULE_PERUSER + 0) + +/* Convenience macro for logging to the bleadc module. */ +#define BLEADC_LOG(lvl, ...) \ + LOG_ ## lvl(&bleadc_log, BLEADC_LOG_MODULE, __VA_ARGS__) + +/** GATT server. */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +/* Sensor Data */ +/* e761d2af-1c15-4fa7-af80-b5729002b340 */ +static const uint8_t gatt_svr_svc_sns_uuid[16] = { + 0x40, 0xb3, 0x20, 0x90, 0x72, 0xb5, 0x80, 0xaf, + 0xa7, 0x4f, 0x15, 0x1c, 0xaf, 0xd2, 0x61, 0xe7 }; +#define ADC_SNS_TYPE 0xDEAD +#define ADC_SNS_STRING "eTape Water Level Sensor" +#define ADC_SNS_VAL 0xBEEF +#define SPI_SNS_TYPE 0xDE48 +#define SPI_SNS_STRING "SPI Sensor" +#define SPI_SNS_VAL 0xBE48 + +uint16_t gatt_adc_val; +uint8_t gatt_spi_val; + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/src/gatt_svr.c ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/src/gatt_svr.c b/apps/nrf52_adc/src/gatt_svr.c new file mode 100644 index 0000000..740817c --- /dev/null +++ b/apps/nrf52_adc/src/gatt_svr.c @@ -0,0 +1,318 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include "bsp/bsp.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "bleadc.h" +#include "console/console.h" + +static int +gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static int +gatt_svr_sns_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static uint16_t gatt_adc_val_len; +static uint16_t gatt_spi_val_len; + +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /*** Alert Notification Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid128 = BLE_UUID16(GATT_SVR_SVC_ALERT_UUID), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid128 = BLE_UUID16(GATT_SVR_CHR_NEW_ALERT), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid128 = BLE_UUID16(GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid128 = BLE_UUID16(GATT_SVR_CHR_UNR_ALERT_STAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid128 = BLE_UUID16(GATT_SVR_CHR_ALERT_NOT_CTRL_PT), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_WRITE, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + { + /*** Water Level Notification Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid128 = gatt_svr_svc_sns_uuid, + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid128 = BLE_UUID16(ADC_SNS_TYPE), + .access_cb = gatt_svr_sns_access, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid128 = BLE_UUID16(ADC_SNS_VAL), + .access_cb = gatt_svr_sns_access, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid128 = BLE_UUID16(SPI_SNS_TYPE), + .access_cb = gatt_svr_sns_access, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid128 = BLE_UUID16(SPI_SNS_VAL), + .access_cb = gatt_svr_sns_access, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + { + 0, /* No more services. */ + }, +}; + +static int +gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +#define GATT_SVR_NEW_ALERT_VAL_MAX_LEN 64 + +static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */ +static uint8_t gatt_svr_new_alert_val[GATT_SVR_NEW_ALERT_VAL_MAX_LEN]; +static uint16_t gatt_svr_new_alert_val_len; +static const uint8_t gatt_svr_unr_alert_cat = 0x01; /* Simple alert. */ +static uint16_t gatt_svr_unr_alert_stat; +static uint16_t gatt_svr_alert_not_ctrl_pt; + +static int +gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + uint16_t uuid16; + int rc; + + uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128); + assert(uuid16 != 0); + + switch (uuid16) { + case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat, + sizeof gatt_svr_new_alert_cat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case GATT_SVR_CHR_NEW_ALERT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 0, + sizeof gatt_svr_new_alert_val, + gatt_svr_new_alert_val, + &gatt_svr_new_alert_val_len); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_val, + sizeof gatt_svr_new_alert_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_cat, + sizeof gatt_svr_unr_alert_cat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case GATT_SVR_CHR_UNR_ALERT_STAT_UUID: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 2, 2, &gatt_svr_unr_alert_stat, + NULL); + return rc; + } else { + rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_stat, + sizeof gatt_svr_unr_alert_stat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case GATT_SVR_CHR_ALERT_NOT_CTRL_PT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 2, 2, + &gatt_svr_alert_not_ctrl_pt, NULL); + } else { + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + +} + +static int +gatt_svr_sns_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + uint16_t uuid16; + int rc; + + uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128); + assert(uuid16 != 0); + + switch (uuid16) { + case ADC_SNS_TYPE: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, ADC_SNS_STRING, sizeof ADC_SNS_STRING); + BLEADC_LOG(INFO, "ADC SENSOR TYPE READ: %s\n", ADC_SNS_STRING); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case SPI_SNS_TYPE: + BLEADC_LOG(INFO, "SPI SENSOR TYPE READ: %s\n", SPI_SNS_STRING); + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, SPI_SNS_STRING, sizeof SPI_SNS_STRING); + + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case ADC_SNS_VAL: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 0, + sizeof gatt_adc_val, + &gatt_adc_val, + &gatt_adc_val_len); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_adc_val, + sizeof gatt_adc_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + case SPI_SNS_VAL: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 0, + sizeof gatt_spi_val, + &gatt_spi_val, + &gatt_spi_val_len); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_spi_val, + sizeof gatt_spi_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} +static char * +gatt_svr_uuid_to_s(const void *uuid128, char *dst) +{ + const uint8_t *u8p; + uint16_t uuid16; + + uuid16 = ble_uuid_128_to_16(uuid128); + if (uuid16 != 0) { + sprintf(dst, "0x%04x", uuid16); + return dst; + } + + u8p = uuid128; + + sprintf(dst, "%02x%02x%02x%02x-", u8p[15], u8p[14], u8p[13], u8p[12]); + sprintf(dst + 9, "%02x%02x-%02x%02x-", u8p[11], u8p[10], u8p[9], u8p[8]); + sprintf(dst + 19, "%02x%02x%02x%02x%02x%02x%02x%02x", + u8p[7], u8p[6], u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); + + return dst; +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[40]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + BLEADC_LOG(DEBUG, "registered service %s with handle=%d\n", + gatt_svr_uuid_to_s(ctxt->svc.svc_def->uuid128, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + BLEADC_LOG(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + gatt_svr_uuid_to_s(ctxt->chr.chr_def->uuid128, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + BLEADC_LOG(DEBUG, "registering descriptor %s with handle=%d\n", + gatt_svr_uuid_to_s(ctxt->dsc.dsc_def->uuid128, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +gatt_svr_init(void) +{ + int rc; + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/src/main.c ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/src/main.c b/apps/nrf52_adc/src/main.c new file mode 100755 index 0000000..751f6c3 --- /dev/null +++ b/apps/nrf52_adc/src/main.c @@ -0,0 +1,451 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include "sysinit/sysinit.h" +#include "bsp/bsp.h" +#include "os/os.h" +#include "bsp/bsp.h" +#include "hal/hal_gpio.h" +#include "console/console.h" + +/* BLE */ +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "services/gap/ble_svc_gap.h" + +/* ADC */ +#include "nrf.h" +#include "app_util_platform.h" +#include "app_error.h" +#include <adc/adc.h> +#include <adc_nrf52/adc_nrf52.h> +#include <adc_nrf52/adc_nrf52.h> +#include "nrf_drv_saadc.h" + +nrf_drv_saadc_config_t adc_config = NRF_DRV_SAADC_DEFAULT_CONFIG; + +/* Application-specified header. */ +#include "bleadc.h" + +/** Log data. */ +struct log bleadc_log; + +/** bleadc task settings. */ +#define BLEADC_TASK_PRIO 1 +#define BLEADC_STACK_SIZE (OS_STACK_ALIGN(336)) + +/* ADC Task settings */ +#define ADC_TASK_PRIO 5 +#define ADC_STACK_SIZE (OS_STACK_ALIGN(336)) +struct os_task adc_task; +bssnz_t os_stack_t adc_stack[ADC_STACK_SIZE]; + +/* SPI Task settings */ +#define SPI_TASK_PRIO 5 +#define SPI_STACK_SIZE (OS_STACK_ALIGN(336)) +struct os_task spi_task; +bssnz_t os_stack_t spi_stack[SPI_STACK_SIZE]; + +struct os_eventq bleadc_evq; +struct os_task bleadc_task; +bssnz_t os_stack_t bleadc_stack[BLEADC_STACK_SIZE]; + +static int bleadc_gap_event(struct ble_gap_event *event, void *arg); + +#define ADC_NUMBER_SAMPLES (2) +#define ADC_NUMBER_CHANNELS (1) + +uint8_t *sample_buffer1; +uint8_t *sample_buffer2; + + + + + + +/** + * Logs information about a connection to the console. + */ +static void +bleadc_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + BLEADC_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr_type); + print_addr(desc->our_ota_addr); + BLEADC_LOG(INFO, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr_type); + print_addr(desc->our_id_addr); + BLEADC_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr_type); + print_addr(desc->peer_ota_addr); + BLEADC_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr_type); + print_addr(desc->peer_id_addr); + BLEADC_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d\n", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +bleadc_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + const char *name; + int rc; + + /** + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info). + * o Advertising tx power. + * o Device name. + * o 16-bit service UUIDs (alert notifications). + */ + + memset(&fields, 0, sizeof fields); + + /* Indicate that the flags field should be included; specify a value of 0 + * to instruct the stack to fill the value in for us. + */ + fields.flags_is_present = 1; + fields.flags = 0; + + /* Indicate that the TX power level field should be included; have the + * stack fill this one automatically as well. This is done by assiging the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + name = ble_svc_gap_device_name(); + fields.name = (uint8_t *)name; + fields.name_len = strlen(name); + fields.name_is_complete = 1; + uint16_t ble16 = ble_uuid_128_to_16(gatt_svr_svc_sns_uuid); + fields.uuids16 = (uint16_t[]){ ble16}; + fields.num_uuids16 = 1; + fields.uuids16_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + BLEADC_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising. */ + memset(&adv_params, 0, sizeof adv_params); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(BLE_ADDR_TYPE_PUBLIC, 0, NULL, BLE_HS_FOREVER, + &adv_params, bleadc_gap_event, NULL); + if (rc != 0) { + BLEADC_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that forms. + * bleadc uses the same callback for all connections. + * + * @param event The type of event being signalled. + * @param ctxt Various information pertaining to the event. + * @param arg Application-specified argument; unuesd by + * bleadc. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +bleadc_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + BLEADC_LOG(INFO, "connection %s; status=%d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + bleadc_print_conn_desc(&desc); + } + BLEADC_LOG(INFO, "\n"); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising. */ + bleadc_advertise(); + } + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + BLEADC_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason); + bleadc_print_conn_desc(&event->disconnect.conn); + BLEADC_LOG(INFO, "\n"); + + /* Connection terminated; resume advertising. */ + bleadc_advertise(); + return 0; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + BLEADC_LOG(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + bleadc_print_conn_desc(&desc); + BLEADC_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + BLEADC_LOG(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + bleadc_print_conn_desc(&desc); + BLEADC_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_SUBSCRIBE: + BLEADC_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", + event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + return 0; + + case BLE_GAP_EVENT_MTU: + BLEADC_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + } + + return 0; +} + +static void +bleadc_on_reset(int reason) +{ + BLEADC_LOG(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +bleadc_on_sync(void) +{ + /* Begin advertising. */ + bleadc_advertise(); +} + +int +adc_read_event(struct adc_dev *dev, void *arg, uint8_t etype, + void *buffer, int buffer_len) +{ + int i; + int adc_result; + int my_result_mv; + uint16_t chr_val_handle; + int rc; + for (i = 0; i < ADC_NUMBER_SAMPLES; i++) { + rc = adc_buf_read(dev, buffer, buffer_len, i, &adc_result); + if (rc != 0) { + goto err; + } + + my_result_mv = adc_result_mv(dev, 0, adc_result); + gatt_adc_val = my_result_mv; + rc = ble_gatts_find_chr(gatt_svr_svc_sns_uuid, BLE_UUID16(ADC_SNS_VAL), NULL, &chr_val_handle); + assert(rc == 0); + ble_gatts_chr_updated(chr_val_handle); + } + + adc_buf_release(dev, buffer, buffer_len); + return (0); +err: + return (rc); +} + +/** + * Event loop for the main bleadc task. + */ +static void +bleadc_task_handler(void *unused) +{ + while (1) { + os_eventq_run(&bleadc_evq); + } +} + +/** + * Event loop for the ADC task. + */ +static void +adc_task_handler(void *unused) +{ + + struct adc_dev *adc; + nrf_saadc_channel_config_t cc = + NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1); + cc.gain = NRF_SAADC_GAIN1_6; + cc.reference = NRF_SAADC_REFERENCE_INTERNAL; + adc = (struct adc_dev *) os_dev_open("adc0", 0, &adc_config); + assert(adc != NULL); + + adc_chan_config(adc, 0, &cc); + + sample_buffer1 = malloc(adc_buf_size(adc, ADC_NUMBER_CHANNELS, ADC_NUMBER_SAMPLES)); + sample_buffer2 = malloc(adc_buf_size(adc, ADC_NUMBER_CHANNELS, ADC_NUMBER_SAMPLES)); + memset(sample_buffer1, 0, adc_buf_size(adc, ADC_NUMBER_CHANNELS, ADC_NUMBER_SAMPLES)); + memset(sample_buffer2, 0, adc_buf_size(adc, ADC_NUMBER_CHANNELS, ADC_NUMBER_SAMPLES)); + + adc_buf_set(adc, sample_buffer1, sample_buffer2, + adc_buf_size(adc, ADC_NUMBER_CHANNELS, ADC_NUMBER_SAMPLES)); + adc_event_handler_set(adc, adc_read_event, (void *) NULL); + + while (1) { + adc_sample(adc); + /* Wait 2 second */ + os_time_delay(OS_TICKS_PER_SEC * 2); + + } +} + +/** + * Event loop for the SPI task. + */ +static void +spi_task_handler(void *unused) +{ + + gatt_spi_val = 10; + int rc = 0; + + + while (1) { + gatt_spi_val += 4; + uint16_t chr_val_handle; + + rc = ble_gatts_find_chr(gatt_svr_svc_sns_uuid, + BLE_UUID16(SPI_SNS_VAL), + NULL, &chr_val_handle); + assert(rc == 0); + ble_gatts_chr_updated(chr_val_handle); + //ble_gatts_chr_updated(24); + /* Wait 2 second */ + os_time_delay(OS_TICKS_PER_SEC*3); + + } +} + +/** + * main + * + * The main function for the project. This function initializes the os, calls + * init_tasks to initialize tasks (and possibly other objects), then starts the + * OS. We should not return from os start. + * + * @return int NOTE: this function should never return! + */ +int +main(void) +{ + int rc; + + /* Set initial BLE device address. */ + memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}, 6); + + /* Initialize OS */ + sysinit(); + + + /* Initialize the bleadc log. */ + log_register("bleadc", &bleadc_log, &log_console_handler, NULL, + LOG_SYSLEVEL); + + /* Initialize eventq */ + os_eventq_init(&bleadc_evq); + + /* Create the bleadc task. All application logic and NimBLE host + * operations are performed in this task. + */ + os_task_init(&bleadc_task, "bleadc", bleadc_task_handler, + NULL, BLEADC_TASK_PRIO, OS_WAIT_FOREVER, + bleadc_stack, BLEADC_STACK_SIZE); + + os_task_init(&adc_task, "adc", adc_task_handler, + NULL, ADC_TASK_PRIO, OS_WAIT_FOREVER, + adc_stack, ADC_STACK_SIZE); + os_task_init(&spi_task, "adc", spi_task_handler, + NULL, SPI_TASK_PRIO, OS_WAIT_FOREVER, + spi_stack, SPI_STACK_SIZE); + /* Initialize the NimBLE host configuration. */ + log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL, + LOG_SYSLEVEL); + ble_hs_cfg.reset_cb = bleadc_on_reset; + ble_hs_cfg.sync_cb = bleadc_on_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + + rc = gatt_svr_init(); + assert(rc == 0); + + + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble-bleadc"); + assert(rc == 0); + + /* Set the default eventq for packages that lack a dedicated task. */ + os_eventq_dflt_set(&bleadc_evq); + + + + // BLEADC_LOG(INFO, "Created the ADC device\n"); + /* Start the OS */ + os_start(); + + /* os start should never return. If it does, this should be an error */ + assert(0); + + return 0; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/src/misc.c ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/src/misc.c b/apps/nrf52_adc/src/misc.c new file mode 100644 index 0000000..66bdb2b --- /dev/null +++ b/apps/nrf52_adc/src/misc.c @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include "bleadc.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + BLEADC_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + BLEADC_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/apps/nrf52_adc/syscfg.yml ---------------------------------------------------------------------- diff --git a/apps/nrf52_adc/syscfg.yml b/apps/nrf52_adc/syscfg.yml new file mode 100644 index 0000000..46c68ce --- /dev/null +++ b/apps/nrf52_adc/syscfg.yml @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# + +# Package: apps/bleadc + +syscfg.vals: + # Use INFO log level to reduce code size. DEBUG is too large for nRF51. + LOG_LEVEL: 1 + + # Disable central and observer roles. + BLE_ROLE_BROADCASTER: 1 + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + BLE_ROLE_PERIPHERAL: 1 + + # Disable unused eddystone feature. + BLE_EDDYSTONE: 0 + + # Log reboot messages to a flash circular buffer. + REBOOT_LOG_FCB: 1 + LOG_FCB: 1 + CONFIG_FCB: 1 + + # Enable newtmgr commands. + STATS_NEWTMGR: 1 + LOG_NEWTMGR: 1 + + # Enable Config. + CONFIG_NEWTMGR: 1 + + # Enable Shell + SHELL_TASK: 1 + + CONSOLE_TICKS: 1 + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/hw/bsp/nrf52dk/src/hal_bsp.c ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52dk/src/hal_bsp.c b/hw/bsp/nrf52dk/src/hal_bsp.c index be8322e..9e6c34f 100644 --- a/hw/bsp/nrf52dk/src/hal_bsp.c +++ b/hw/bsp/nrf52dk/src/hal_bsp.c @@ -35,6 +35,12 @@ #include "uart_hal/uart_hal.h" #include "os/os_dev.h" #include "bsp.h" +#include "nrf_drv_config.h" +#include "app_util_platform.h" +#include "nrf.h" +#include "app_error.h" +#include "adc_nrf52/adc_nrf52.h" +#include "nrf_drv_saadc.h" #if MYNEWT_VAL(UART_0) static struct uart_dev os_bsp_uart0; @@ -84,6 +90,15 @@ static const struct nrf52_hal_i2c_cfg hal_i2c_cfg = { }; #endif +#if MYNEWT_VAL(ADC_0) +static struct adc_dev os_bsp_adc0; +static nrf_drv_saadc_config_t os_bsp_adc0_config = { + .resolution = MYNEWT_VAL(ADC_0_RESOLUTION), + .oversample = MYNEWT_VAL(ADC_0_OVERSAMPLE), + .interrupt_priority = MYNEWT_VAL(ADC_0_INTERRUPT_PRIORITY), +}; +#endif + /* * What memory to include in coredump. */ @@ -200,5 +215,10 @@ hal_bsp_init(void) OS_DEV_INIT_PRIMARY, 0, uart_bitbang_init, (void *)&os_bsp_uart1_cfg); assert(rc == 0); #endif - +#if MYNEWT_VAL(ADC_0) + rc = os_dev_create((struct os_dev *) &os_bsp_adc0, "adc0", + OS_DEV_INIT_KERNEL, OS_DEV_INIT_PRIO_DEFAULT, + nrf52_adc_dev_init, &os_bsp_adc0_config); + assert(rc == 0); +#endif } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5095a8d2/hw/bsp/nrf52dk/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/bsp/nrf52dk/syscfg.yml b/hw/bsp/nrf52dk/syscfg.yml index 18024af..63776e4 100644 --- a/hw/bsp/nrf52dk/syscfg.yml +++ b/hw/bsp/nrf52dk/syscfg.yml @@ -91,11 +91,22 @@ syscfg.defs: TIMER_4: description: 'NRF52 Timer 4' value: 0 - I2C_0: description: 'NRF52 I2C (TWI) interface 0' value: '0' - + ADC_0: + description: 'TBD' + value: 1 + ADC_0_RESOLUTION: + description: 'TBD' + value: 'SAADC_CONFIG_RESOLUTION' + ADC_0_OVERSAMPLE: + description: 'TBD' + value: 'SAADC_CONFIG_OVERSAMPLE' + ADC_0_INTERRUPT_PRIORITY: + description: 'TBD' + value: 'SAADC_CONFIG_IRQ_PRIORITY' + syscfg.vals: CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
