diff options
author | William San Filippo <wills@runtime.io> | 2016-05-10 18:01:50 -0700 |
---|---|---|
committer | William San Filippo <wills@runtime.io> | 2016-05-10 18:01:50 -0700 |
commit | 4146b1a4b7fb68201946b22a479a46b87b19f4ee (patch) | |
tree | c642151ab6a2fd3313f7b504763bd3d058594783 | |
parent | c7755e0a62c9b2d09a62cc4332119c8a47aacf8f (diff) | |
parent | 03e36e70de3655dcca8089fb84839e53268bb0bd (diff) |
This closes #48.
Merge remote-tracking branch '01org/develop' into develop
-rw-r--r-- | apps/blehci/pkg.yml | 29 | ||||
-rwxr-xr-x | apps/blehci/src/main.c | 392 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/boot-nrf51-arduino_101.ld | 177 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/include/bsp/bsp.h | 48 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/include/bsp/bsp_sysid.h | 36 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/include/bsp/cmsis_nvic.h | 30 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/nrf51-arduino_101.ld | 183 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_debug.sh | 45 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_download.sh | 103 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_no_boot.ld | 178 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/pkg.yml | 40 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/src/arch/cortex_m0/gcc_startup_nrf51.s | 267 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/src/hal_bsp.c | 46 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/src/libc_stubs.c | 85 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/src/os_bsp.c | 141 | ||||
-rw-r--r-- | hw/bsp/nrf51-arduino_101/src/sbrk.c | 53 | ||||
-rwxr-xr-x | hw/bsp/nrf51-arduino_101/src/system_nrf51.c | 121 |
17 files changed, 1974 insertions, 0 deletions
diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml new file mode 100644 index 00000000..f36e383f --- /dev/null +++ b/apps/blehci/pkg.yml @@ -0,0 +1,29 @@ +# 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/blehci +pkg.type: app +pkg.description: BLE controller application exposing HCI over UART +pkg.author: "Johan Hedberg <johan.hedberg@intel.com>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - libs/os + - net/nimble/controller + - libs/baselibc + - libs/console/stub diff --git a/apps/blehci/src/main.c b/apps/blehci/src/main.c new file mode 100755 index 00000000..ca2e39d9 --- /dev/null +++ b/apps/blehci/src/main.c @@ -0,0 +1,392 @@ +/** + * 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 "bsp/bsp.h" +#include "os/os.h" +#include "bsp/bsp.h" +#include "hal/hal_gpio.h" +#include "hal/hal_cputime.h" +#include "hal/hal_uart.h" + +/* BLE */ +#include "nimble/ble.h" +#include "nimble/nimble_opt.h" +#include "nimble/hci_transport.h" +#include "controller/ble_ll.h" + +#define HCI_UART_SPEED 1000000 +#define HCI_UART CONSOLE_UART + +/* Nimble task priorities */ +#define BLE_LL_TASK_PRI (OS_TASK_PRI_HIGHEST) + +/* Create a mbuf pool of BLE mbufs */ +#define MBUF_NUM_MBUFS (7) +#define MBUF_BUF_SIZE OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4) +#define MBUF_MEMBLOCK_SIZE (MBUF_BUF_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD) +#define MBUF_MEMPOOL_SIZE OS_MEMPOOL_SIZE(MBUF_NUM_MBUFS, MBUF_MEMBLOCK_SIZE) + +/* Our global device address (public) */ +uint8_t g_dev_addr[BLE_DEV_ADDR_LEN] = { 0 }; + +/* Our random address (in case we need it) */ +uint8_t g_random_addr[BLE_DEV_ADDR_LEN] = { 0 }; + +#define HCI_MAX_BUFS (5) + +#define HCI_CMD_BUF_SIZE (260) +struct os_mempool g_hci_cmd_pool; +static void *hci_cmd_buf; + +#define HCI_OS_EVENT_BUF_SIZE (sizeof(struct os_event)) + +#define BLE_HOST_HCI_EVENT_CTLR_EVENT (OS_EVENT_T_PERUSER + 0) +#define BLE_HOST_HCI_EVENT_CTLR_DATA (OS_EVENT_T_PERUSER + 1) + +struct os_mempool g_hci_os_event_pool; +static void *hci_os_event_buf; + +os_membuf_t default_mbuf_mpool_data[MBUF_MEMPOOL_SIZE]; + +struct os_mbuf_pool default_mbuf_pool; +struct os_mempool default_mbuf_mpool; + +#define H4_NONE 0x00 +#define H4_CMD 0x01 +#define H4_ACL 0x02 +#define H4_SCO 0x03 +#define H4_EVT 0x04 + +#define HCI_CMD_HDR_LEN 3 +#define HCI_ACL_HDR_LEN 4 +#define HCI_EVT_HDR_LEN 2 + +struct memblock { + uint8_t *data; /* Pointer to memblock data */ + uint16_t cur; /* Number of bytes read/written */ + uint16_t len; /* Total number of bytes to read/write */ +}; + +struct tx_acl { + struct os_mbuf *buf; /* Buffer containing the data */ + uint16_t len; /* Target size when buf is considered complete */ +}; + +static struct { + /* State of data from host to controller */ + uint8_t tx_type; /* Pending packet type. 0 means nothing pending */ + union { + struct memblock tx_cmd; + struct tx_acl tx_acl; + }; + + /* State of data from controller to host */ + uint8_t rx_type; /* Pending packet type. 0 means nothing pending */ + union { + struct memblock rx_evt; + struct os_mbuf *rx_acl; + }; + STAILQ_HEAD(, os_event) rx_pkts; /* Packet queue to send to UART */ +} hci; + +int +ble_hs_rx_data(struct os_mbuf *om) +{ + struct os_event *ev; + os_sr_t sr; + + ev = os_memblock_get(&g_hci_os_event_pool); + if (!ev) { + os_mbuf_free_chain(om); + return -1; + } + + ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_DATA; + ev->ev_arg = om; + ev->ev_queued = 1; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&hci.rx_pkts, ev, ev_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(HCI_UART); + + return 0; +} + +int +ble_hci_transport_ctlr_event_send(uint8_t *hci_ev) +{ + struct os_event *ev; + os_sr_t sr; + + ev = os_memblock_get(&g_hci_os_event_pool); + if (!ev) { + os_error_t err; + + err = os_memblock_put(&g_hci_cmd_pool, hci_ev); + assert(err == OS_OK); + + return -1; + } + + ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT; + ev->ev_arg = hci_ev; + ev->ev_queued = 1; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&hci.rx_pkts, ev, ev_next); + OS_EXIT_CRITICAL(sr); + + hal_uart_start_tx(HCI_UART); + + return 0; +} + +static int +uart_tx_pkt_type(void) +{ + struct os_event *ev; + os_sr_t sr; + int rc; + + OS_ENTER_CRITICAL(sr); + + ev = STAILQ_FIRST(&hci.rx_pkts); + if (!ev) { + OS_EXIT_CRITICAL(sr); + return -1; + } + + STAILQ_REMOVE(&hci.rx_pkts, ev, os_event, ev_next); + ev->ev_queued = 0; + + OS_EXIT_CRITICAL(sr); + + switch (ev->ev_type) { + case BLE_HOST_HCI_EVENT_CTLR_EVENT: + hci.rx_type = H4_EVT; + hci.rx_evt.data = ev->ev_arg; + hci.rx_evt.cur = 0; + hci.rx_evt.len = hci.rx_evt.data[1] + HCI_EVT_HDR_LEN; + rc = H4_EVT; + break; + case BLE_HOST_HCI_EVENT_CTLR_DATA: + hci.rx_type = H4_ACL; + hci.rx_acl = ev->ev_arg; + rc = H4_ACL; + break; + default: + rc = -1; + break; + } + + os_memblock_put(&g_hci_os_event_pool, ev); + + return rc; +} + +static int +uart_tx_char(void *arg) +{ + int rc = -1; + + switch (hci.rx_type) { + case H4_NONE: /* No pending packet, pick one from the queue */ + rc = uart_tx_pkt_type(); + break; + case H4_EVT: + rc = hci.rx_evt.data[hci.rx_evt.cur++]; + + if (hci.rx_evt.cur == hci.rx_evt.len) { + os_memblock_put(&g_hci_cmd_pool, hci.rx_evt.data); + hci.rx_type = H4_NONE; + } + + break; + case H4_ACL: + rc = *OS_MBUF_DATA(hci.rx_acl, uint8_t *); + os_mbuf_adj(hci.rx_acl, 1); + if (!OS_MBUF_PKTLEN(hci.rx_acl)) { + os_mbuf_free_chain(hci.rx_acl); + hci.rx_type = H4_NONE; + } + + break; + } + + return rc; +} + +static int +uart_rx_pkt_type(uint8_t data) +{ + hci.tx_type = data; + + switch (hci.tx_type) { + case H4_CMD: + hci.tx_cmd.data = os_memblock_get(&g_hci_cmd_pool); + hci.tx_cmd.len = 0; + hci.tx_cmd.cur = 0; + break; + case H4_ACL: + hci.tx_acl.buf = os_msys_get_pkthdr(HCI_ACL_HDR_LEN, 0); + hci.tx_acl.len = 0; + break; + default: + hci.tx_type = H4_NONE; + return -1; + } + + return 0; +} + +static int +uart_rx_cmd(uint8_t data) +{ + hci.tx_cmd.data[hci.tx_cmd.cur++] = data; + + if (hci.tx_cmd.cur < HCI_CMD_HDR_LEN) { + return 0; + } else if (hci.tx_cmd.cur == HCI_CMD_HDR_LEN) { + hci.tx_cmd.len = hci.tx_cmd.data[2] + HCI_CMD_HDR_LEN; + } + + if (hci.tx_cmd.cur == hci.tx_cmd.len) { + ble_hci_transport_host_cmd_send(hci.tx_cmd.data); + hci.tx_type = H4_NONE; + } + + return 0; +} + +static int +uart_rx_acl(uint8_t data) +{ + os_mbuf_append(hci.tx_acl.buf, &data, 1); + + if (OS_MBUF_PKTLEN(hci.tx_acl.buf) < HCI_ACL_HDR_LEN) { + return 0; + } else if (OS_MBUF_PKTLEN(hci.tx_acl.buf) == HCI_ACL_HDR_LEN) { + os_mbuf_copydata(hci.tx_acl.buf, 2, sizeof(hci.tx_acl.len), + &hci.tx_acl.len); + hci.tx_acl.len = le16toh(&hci.tx_acl.len) + HCI_ACL_HDR_LEN; + } + + if (OS_MBUF_PKTLEN(hci.tx_acl.buf) == hci.tx_acl.len) { + ble_hci_transport_host_acl_data_send(hci.tx_acl.buf); + hci.tx_type = H4_NONE; + } + + return 0; +} + +static int +uart_rx_char(void *arg, uint8_t data) +{ + switch (hci.tx_type) { + case H4_NONE: + return uart_rx_pkt_type(data); + case H4_CMD: + return uart_rx_cmd(data); + case H4_ACL: + return uart_rx_acl(data); + default: + return -1; + } +} + +static int +uart_init(void) +{ + int rc; + + memset(&hci, 0, sizeof(hci)); + + STAILQ_INIT(&hci.rx_pkts); + + rc = hal_uart_init_cbs(HCI_UART, uart_tx_char, NULL, uart_rx_char, NULL); + if (rc) { + return rc; + } + + return hal_uart_config(HCI_UART, HCI_UART_SPEED, 8, 1, HAL_UART_PARITY_NONE, + HAL_UART_FLOW_CTL_RTS_CTS); +} + +int +main(void) +{ + int rc; + + /* Initialize OS */ + os_init(); + + /* Set cputime to count at 1 usec increments */ + rc = cputime_init(1000000); + assert(rc == 0); + + rc = os_mempool_init(&default_mbuf_mpool, MBUF_NUM_MBUFS, + MBUF_MEMBLOCK_SIZE, default_mbuf_mpool_data, + "default_mbuf_data"); + assert(rc == 0); + + rc = os_mbuf_pool_init(&default_mbuf_pool, &default_mbuf_mpool, + MBUF_MEMBLOCK_SIZE, MBUF_NUM_MBUFS); + assert(rc == 0); + + rc = os_msys_register(&default_mbuf_pool); + assert(rc == 0); + + /* Initialize the BLE LL */ + rc = ble_ll_init(BLE_LL_TASK_PRI, MBUF_NUM_MBUFS, BLE_MBUF_PAYLOAD_SIZE); + assert(rc == 0); + + hci_cmd_buf = malloc(OS_MEMPOOL_BYTES(HCI_MAX_BUFS, HCI_CMD_BUF_SIZE)); + assert(hci_cmd_buf != NULL); + + /* Create memory pool of command buffers */ + rc = os_mempool_init(&g_hci_cmd_pool, HCI_MAX_BUFS, HCI_CMD_BUF_SIZE, + hci_cmd_buf, "HCICmdPool"); + assert(rc == 0); + + hci_os_event_buf = malloc(OS_MEMPOOL_BYTES(HCI_MAX_BUFS, + HCI_OS_EVENT_BUF_SIZE)); + assert(hci_os_event_buf != NULL); + + /* Create memory pool of OS events */ + rc = os_mempool_init(&g_hci_os_event_pool, HCI_MAX_BUFS, + HCI_OS_EVENT_BUF_SIZE, hci_os_event_buf, + "HCIOsEventPool"); + assert(rc == 0); + + rc = uart_init(); + assert(rc == 0); + + /* Start the OS */ + os_start(); + + /* os start should never return. If it does, this should be an error */ + assert(0); + + return 0; +} diff --git a/hw/bsp/nrf51-arduino_101/boot-nrf51-arduino_101.ld b/hw/bsp/nrf51-arduino_101/boot-nrf51-arduino_101.ld new file mode 100755 index 00000000..20a5b2c7 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/boot-nrf51-arduino_101.ld @@ -0,0 +1,177 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x8000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/hw/bsp/nrf51-arduino_101/include/bsp/bsp.h b/hw/bsp/nrf51-arduino_101/include/bsp/bsp.h new file mode 100644 index 00000000..d81c149b --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/include/bsp/bsp.h @@ -0,0 +1,48 @@ +/** + * 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_BSP_H +#define H_BSP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define special stackos sections */ +#define sec_data_core __attribute__((section(".data.core"))) +#define sec_bss_core __attribute__((section(".bss.core"))) + +/* More convenient section placement macros. */ +#define bssnz_t + +/* LED pins */ +#define LED_BLINK_PIN (21) + +/* UART info */ +#define CONSOLE_UART 0 + +int bsp_imgr_current_slot(void); + +#define NFFS_AREA_MAX (8) + +#ifdef __cplusplus +} +#endif + +#endif /* H_BSP_H */ diff --git a/hw/bsp/nrf51-arduino_101/include/bsp/bsp_sysid.h b/hw/bsp/nrf51-arduino_101/include/bsp/bsp_sysid.h new file mode 100644 index 00000000..c4ac688c --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/include/bsp/bsp_sysid.h @@ -0,0 +1,36 @@ +/** + * 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 BSP_SYSID_H +#define BSP_SYSID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* stub until this BSP gets new HAL */ +enum system_device_id +{ + RESERVED, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_SYSID_H */
\ No newline at end of file diff --git a/hw/bsp/nrf51-arduino_101/include/bsp/cmsis_nvic.h b/hw/bsp/nrf51-arduino_101/include/bsp/cmsis_nvic.h new file mode 100644 index 00000000..fe7fc9a4 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/include/bsp/cmsis_nvic.h @@ -0,0 +1,30 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include <stdint.h> + +/* NOTE: the nrf51 SoC has 26 interrupts. */ +#define NVIC_USER_IRQ_OFFSET 16 +#define NVIC_NUM_VECTORS (NVIC_USER_IRQ_OFFSET + 26) + +#include "mcu/nrf51.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/nrf51-arduino_101/nrf51-arduino_101.ld b/hw/bsp/nrf51-arduino_101/nrf51-arduino_101.ld new file mode 100755 index 00000000..73fd2546 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/nrf51-arduino_101.ld @@ -0,0 +1,183 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00008000, LENGTH = 0x1b800 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .imghdr (NOLOAD): + { + . = . + 0x20; + } > FLASH + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + /* Keep first in RAM, as well as in bootloader */ + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_debug.sh b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_debug.sh new file mode 100755 index 00000000..d5464dd8 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_debug.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# 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. +# +# Called: $0 <bsp_directory_path> <binary> [features...] +# - bsp_directory_path is absolute path to hw/bsp/bsp_name +# - binary is the path to prefix to target binary, .elf.bin appended to this +# name is the raw binary format of the binary. +# - features are the target features. So you can have e.g. different +# flash offset for bootloader 'feature' +# +# +if [ $# -lt 2 ]; then + echo "Need binary to download" + exit 1 +fi + +FILE_NAME=$2.elf +GDB_CMD_FILE=.gdb_cmds + +echo "Debugging" $FILE_NAME + +set -m +JLinkGDBServer -device nRF51422_xxAC -speed 4000 -if SWD -port 3333 -singlerun > /dev/null & +set +m + +echo "target remote localhost:3333" > $GDB_CMD_FILE + +arm-none-eabi-gdb --tui -x $GDB_CMD_FILE $FILE_NAME + +rm $GDB_CMD_FILE diff --git a/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_download.sh b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_download.sh new file mode 100755 index 00000000..958ef1f5 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_download.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# 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. +# +# Called: $0 <bsp_directory_path> <binary> [features...] +# - bsp_directory_path is absolute path to hw/bsp/bsp_name +# - binary is the path to prefix to target binary, .elf.bin appended to this +# name is the raw binary format of the binary. +# - features are the target features. So you can have e.g. different +# flash offset for bootloader 'feature' +# +# +if [ $# -lt 2 ]; then + echo "Need binary to download" + exit 1 +fi + +IS_BOOTLOADER=0 +BASENAME=$2 +#JLINK_SCRIPT=.download.jlink +GDB_CMD_FILE=.gdb_cmds + +# Look for 'bootloader' from 2nd arg onwards +shift +shift +while [ $# -gt 0 ]; do + if [ $1 = "bootloader" ]; then + IS_BOOTLOADER=1 + fi + shift +done + +if [ $IS_BOOTLOADER -eq 1 ]; then + FLASH_OFFSET=0x0 + FILE_NAME=$BASENAME.elf.bin +else + FLASH_OFFSET=0x8000 + FILE_NAME=$BASENAME.img +fi + +echo "Downloading" $FILE_NAME "to" $FLASH_OFFSET + +# XXX for some reason JLinkExe overwrites flash at offset 0 when +# downloading somewhere in the flash. So need to figure out how to tell it +# not to do that, or report failure if gdb fails to write this file +# +echo "shell /bin/sh -c 'trap \"\" 2;JLinkGDBServer -device nRF51422_xxAC -speed 4000 -if SWD -port 3333 -singlerun' & " > $GDB_CMD_FILE +echo "target remote localhost:3333" >> $GDB_CMD_FILE +echo "restore $FILE_NAME binary $FLASH_OFFSET" >> $GDB_CMD_FILE +echo "quit" >> $GDB_CMD_FILE + +msgs=`arm-none-eabi-gdb -x $GDB_CMD_FILE 2>&1` +echo $msgs > .gdb_out + +rm $GDB_CMD_FILE + +#cat > $JLINK_SCRIPT <<EOF +#w 4001e504 1 +#loadbin $FILE_NAME,$FLASH_OFFSET +#q +#EOF + +#msgs=`JLinkExe -device nRF51422_xxAC -speed 4000 -if SWD $JLINK_SCRIPT` + +# Echo output from script run, so newt can show it if things go wrong. +echo $msgs +#rm $JLINK_SCRIPT + +error=`echo $msgs | grep error` +if [ -n "$error" ]; then + exit 1 +fi + +error=`echo $msgs | grep -i failed` +if [ -n "$error" ]; then + exit 1 +fi + +error=`echo $msgs | grep -i "unknown / supported"` +if [ -n "$error" ]; then + exit 1 +fi + +error=`echo $msgs | grep -i "not found"` +if [ -n "$error" ]; then + exit 1 +fi + +exit 0 diff --git a/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_no_boot.ld b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_no_boot.ld new file mode 100755 index 00000000..bf06c920 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/nrf51dk-16kbram_no_boot.ld @@ -0,0 +1,178 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __bssnz_start__ + * __bssnz_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + /* Keep first in RAM, as well as in bootloader */ + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + /* Heap starts after BSS */ + __HeapBase = .; + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Top of head is the bottom of the stack */ + __HeapLimit = __StackLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/hw/bsp/nrf51-arduino_101/pkg.yml b/hw/bsp/nrf51-arduino_101/pkg.yml new file mode 100644 index 00000000..ee292875 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/pkg.yml @@ -0,0 +1,40 @@ +# +# 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: hw/bsp/nrf51-arduino_101 +pkg.type: bsp +pkg.description: BSP definition for a Nordic nRF51 DK SoC with 16kB RAM. +pkg.author: "Apache Mynewt <dev@mynewt.incubator.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf51 + - nrf51dk + +pkg.arch: cortex_m0 +pkg.compiler: compiler/arm-none-eabi-m0 +pkg.linkerscript: "nrf51-arduino_101.ld" +pkg.linkerscript.bootloader.OVERWRITE: "boot-nrf51-arduino_101.ld" +pkg.downloadscript: nrf51dk-16kbram_download.sh +pkg.debugscript: nrf51dk-16kbram_debug.sh +pkg.cflags: -DNRF51 +pkg.deps: + - hw/mcu/nordic/nrf51xxx + - libs/baselibc +pkg.deps.BLE_DEVICE: + - net/nimble/drivers/nrf51 diff --git a/hw/bsp/nrf51-arduino_101/src/arch/cortex_m0/gcc_startup_nrf51.s b/hw/bsp/nrf51-arduino_101/src/arch/cortex_m0/gcc_startup_nrf51.s new file mode 100755 index 00000000..89fcf6d0 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/arch/cortex_m0/gcc_startup_nrf51.s @@ -0,0 +1,267 @@ +/* +Copyright (c) 2015, Nordic Semiconductor ASA +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +NOTE: Template files (including this one) are application specific and therefore +expected to be copied into the application project folder prior to its use! +*/ + + .syntax unified + .arch armv6-m + + .section .stack + .align 3 + .equ Stack_Size, 384 + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long _NMI_Handler /* NMI Handler */ + .long _HardFault_Handler /* Hard Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long _SVC_Handler /* SVCall Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long _PendSV_Handler /* PendSV Handler */ + .long _SysTick_Handler /* SysTick Handler */ + + /* External Interrupts */ + .long _POWER_CLOCK_IRQHandler + .long _RADIO_IRQHandler + .long _UART0_IRQHandler + .long _SPI0_TWI0_IRQHandler + .long _SPI1_TWI1_IRQHandler + .long 0 /*Reserved */ + .long _GPIOTE_IRQHandler + .long _ADC_IRQHandler + .long _TIMER0_IRQHandler + .long _TIMER1_IRQHandler + .long _TIMER2_IRQHandler + .long _RTC0_IRQHandler + .long _TEMP_IRQHandler + .long _RNG_IRQHandler + .long _ECB_IRQHandler + .long _CCM_AAR_IRQHandler + .long _WDT_IRQHandler + .long _RTC1_IRQHandler + .long _QDEC_IRQHandler + .long _LPCOMP_IRQHandler + .long _SWI0_IRQHandler + .long _SWI1_IRQHandler + .long _SWI2_IRQHandler + .long _SWI3_IRQHandler + .long _SWI4_IRQHandler + .long _SWI5_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + .equ NRF_POWER_RAMON_ADDRESS, 0x40000524 + .equ NRF_POWER_RAMONB_ADDRESS, 0x40000554 + .equ NRF_POWER_RAMONx_RAMxON_ONMODE_Msk, 0x3 + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + .fnstart + +/* Make sure ALL RAM banks are powered on */ + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk + + LDR R0, =NRF_POWER_RAMON_ADDRESS + LDR R2, [R0] + ORRS R2, R1 + STR R2, [R0] + + LDR R0, =NRF_POWER_RAMONB_ADDRESS + LDR R2, [R0] + ORRS R2, R1 + STR R2, [R0] + +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .LC0 + +.LC1: + subs r3, 4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .LC1 +.LC0: + + LDR R0, =SystemInit + BLX R0 + LDR R0, =_start + BX R0 + + .pool + .cantunwind + .fnend + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + B . + .size NMI_Handler, . - NMI_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + B . + .size SVC_Handler, . - SVC_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + B . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + B . + .size SysTick_Handler, . - SysTick_Handler + +/* Default handler. This uses the vector in the relocated vector table */ + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + LDR R2, =__vector_tbl_reloc__ + MRS R0, PSR + MOVS R1, #0x3F + ANDS R0, R1 + LSLS R0, R0, #2 + LDR R0, [R0, R2] + BX R0 + .size Default_Handler, . - Default_Handler + +/* + * All of the following IRQ Handlers will point to the default handler unless + * they are defined elsewhere. + */ + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ _NMI_Handler + IRQ _HardFault_Handler + IRQ _SVC_Handler + IRQ _PendSV_Handler + IRQ _SysTick_Handler + IRQ _POWER_CLOCK_IRQHandler + IRQ _RADIO_IRQHandler + IRQ _UART0_IRQHandler + IRQ _SPI0_TWI0_IRQHandler + IRQ _SPI1_TWI1_IRQHandler + IRQ _GPIOTE_IRQHandler + IRQ _ADC_IRQHandler + IRQ _TIMER0_IRQHandler + IRQ _TIMER1_IRQHandler + IRQ _TIMER2_IRQHandler + IRQ _RTC0_IRQHandler + IRQ _TEMP_IRQHandler + IRQ _RNG_IRQHandler + IRQ _ECB_IRQHandler + IRQ _CCM_AAR_IRQHandler + IRQ _WDT_IRQHandler + IRQ _RTC1_IRQHandler + IRQ _QDEC_IRQHandler + IRQ _LPCOMP_IRQHandler + IRQ _SWI0_IRQHandler + IRQ _SWI1_IRQHandler + IRQ _SWI2_IRQHandler + IRQ _SWI3_IRQHandler + IRQ _SWI4_IRQHandler + IRQ _SWI5_IRQHandler + + .end diff --git a/hw/bsp/nrf51-arduino_101/src/hal_bsp.c b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c new file mode 100644 index 00000000..d694c7bb --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/hal_bsp.c @@ -0,0 +1,46 @@ +/** + * 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 <stdint.h> +#include <stddef.h> +#include "mcu/nrf51_hal.h" + +static const struct nrf51_uart_cfg uart_cfg = { + .suc_pin_tx = 9, + .suc_pin_rx = 11, + .suc_pin_rts = 12, + .suc_pin_cts = 10 +}; + +const struct nrf51_uart_cfg *bsp_uart_config(void) +{ + return &uart_cfg; +} + +const struct hal_flash * +bsp_flash_dev(uint8_t id) +{ + /* + * Internal flash mapped to id 0. + */ + if (id != 0) { + return NULL; + } + return &nrf51_flash_dev; +} diff --git a/hw/bsp/nrf51-arduino_101/src/libc_stubs.c b/hw/bsp/nrf51-arduino_101/src/libc_stubs.c new file mode 100644 index 00000000..d880d324 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/libc_stubs.c @@ -0,0 +1,85 @@ +/** + * 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 <hal/hal_system.h> + +void * _sbrk(int c); +int _close(int fd); +int _fstat(int fd, void *s); +void _exit(int s); +int _kill(int pid, int sig); +int _write(int fd, void *b, int nb); +int _isatty(int c); +int _lseek(int fd, int off, int w); +int _read(int fd, void *b, int nb); +int _getpid(void); + +int +_close(int fd) +{ + return -1; +} + +int +_fstat(int fd, void *s) +{ + return -1; +} + + +void +_exit(int s) +{ + system_reset(); +} + +int +_kill(int pid, int sig) +{ + return -1; +} + +int +_write(int fd, void *b, int nb) +{ + return -1; +} + +int +_isatty(int c) +{ + return -1; +} + +int +_lseek(int fd, int off, int w) +{ + return -1; +} + +int +_read(int fd, void *b, int nb) +{ + return -1; +} + +int +_getpid(void) { + return -1; +} diff --git a/hw/bsp/nrf51-arduino_101/src/os_bsp.c b/hw/bsp/nrf51-arduino_101/src/os_bsp.c new file mode 100644 index 00000000..b9d52e4c --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/os_bsp.c @@ -0,0 +1,141 @@ +/** + * 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 <hal/flash_map.h> +#include "bsp/cmsis_nvic.h" +#include "mcu/nrf51.h" +#include "mcu/nrf51_bitfields.h" +#include "mcu/nrf51_hal.h" + +#define BSP_LOWEST_PRIO ((1 << __NVIC_PRIO_BITS) - 1) + +static struct flash_area bsp_flash_areas[] = { + [FLASH_AREA_BOOTLOADER] = { + .fa_flash_id = 0, /* internal flash */ + .fa_off = 0x00000000, /* beginning */ + .fa_size = (32 * 1024) + }, + [FLASH_AREA_IMAGE_0] = { + .fa_flash_id = 0, + .fa_off = 0x00008000, + .fa_size = (110 * 1024) + }, + [FLASH_AREA_IMAGE_1] = { + .fa_flash_id = 0, + .fa_off = 0x00023800, + .fa_size = (110 * 1024) + }, + [FLASH_AREA_IMAGE_SCRATCH] = { + .fa_flash_id = 0, + .fa_off = 0x0003f000, + .fa_size = (2 * 1024) + }, + [FLASH_AREA_NFFS] = { + .fa_flash_id = 0, + .fa_off = 0x0003f800, + .fa_size = (2 * 1024) + } +}; + +void *_sbrk(int incr); +void _close(int fd); + +/* + * Returns the flash map slot where the currently active image is located. + * If executing from internal flash from fixed location, that slot would + * be easy to find. + * If images are in external flash, and copied to RAM for execution, then + * this routine would have to figure out which one of those slots is being + * used. + */ +int +bsp_imgr_current_slot(void) +{ + return FLASH_AREA_IMAGE_0; +} + +void +os_bsp_init(void) +{ + /* + * XXX this reference is here to keep this function in. + */ + _sbrk(0); + _close(0); + + flash_area_init(bsp_flash_areas, + sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0])); + +} + +extern void timer_handler(void); +static void +rtc0_timer_handler(void) +{ + if (NRF_RTC0->EVENTS_TICK) { + NRF_RTC0->EVENTS_TICK = 0; + timer_handler(); + } +} + +void +os_bsp_systick_init(uint32_t os_ticks_per_sec) +{ + uint32_t ctx; + uint32_t mask; + uint32_t pre_scaler; + + /* Turn on the LFCLK */ + NRF_CLOCK->XTALFREQ = CLOCK_XTALFREQ_XTALFREQ_16MHz; + NRF_CLOCK->TASKS_LFCLKSTOP = 1; + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_Xtal; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + /* Wait here till started! */ + mask = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Xtal; + while (1) { + if (NRF_CLOCK->EVENTS_LFCLKSTARTED) { + if ((NRF_CLOCK->LFCLKSTAT & mask) == mask) { + break; + } + } + } + + /* Is this exact frequency obtainable? */ + pre_scaler = (32768 / os_ticks_per_sec) - 1; + + /* disable interrupts */ + __HAL_DISABLE_INTERRUPTS(ctx); + + NRF_RTC0->TASKS_STOP = 1; + NRF_RTC0->EVENTS_TICK = 0; + NRF_RTC0->PRESCALER = pre_scaler; + NRF_RTC0->INTENCLR = 0xffffffff; + NRF_RTC0->TASKS_CLEAR = 1; + + /* Set isr in vector table and enable interrupt */ + NVIC_SetPriority(RTC0_IRQn, BSP_LOWEST_PRIO - 1); + NVIC_SetVector(RTC0_IRQn, (uint32_t)rtc0_timer_handler); + NVIC_EnableIRQ(RTC0_IRQn); + + NRF_RTC0->INTENSET = RTC_INTENSET_TICK_Msk; + NRF_RTC0->TASKS_START = 1; + + __HAL_ENABLE_INTERRUPTS(ctx); +} diff --git a/hw/bsp/nrf51-arduino_101/src/sbrk.c b/hw/bsp/nrf51-arduino_101/src/sbrk.c new file mode 100644 index 00000000..27f1486b --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/sbrk.c @@ -0,0 +1,53 @@ +/** + * 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 <errno.h> + +extern char __HeapBase; +extern char __HeapLimit; + +static char *brk = &__HeapBase; +void * +_sbrk(int incr) +{ + void *prev_brk; + + if (incr < 0) { + /* Returning memory to the heap. */ + incr = -incr; + if (brk - incr < &__HeapBase) { + prev_brk = (void *)-1; + errno = EINVAL; + } else { + prev_brk = brk; + brk -= incr; + } + } else { + /* Allocating memory from the heap. */ + if (&__HeapLimit - brk >= incr) { + prev_brk = brk; + brk += incr; + } else { + prev_brk = (void *)-1; + errno = ENOMEM; + } + } + + return prev_brk; +} diff --git a/hw/bsp/nrf51-arduino_101/src/system_nrf51.c b/hw/bsp/nrf51-arduino_101/src/system_nrf51.c new file mode 100755 index 00000000..4c349a72 --- /dev/null +++ b/hw/bsp/nrf51-arduino_101/src/system_nrf51.c @@ -0,0 +1,121 @@ +/* Copyright (c) 2015, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <stdint.h> +#include <stdbool.h> +#include "bsp/cmsis_nvic.h" +#include "mcu/nrf.h" +#include "mcu/system_nrf51.h" + +/*lint ++flb "Enter library region" */ + + +#define __SYSTEM_CLOCK (16000000UL) /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */ + +static bool is_manual_peripheral_setup_needed(void); +static bool is_disabled_in_debug_needed(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +void SystemInit(void) +{ + /* If desired, switch off the unused RAM to lower consumption by the use of RAMON register. + It can also be done in the application main() function. */ + + /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required + to enable the use of peripherals" found at Product Anomaly document for your device found at + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + that do not need it is that the new peripherals in the second generation devices (LPCOMP for + example) will not be available. */ + if (is_manual_peripheral_setup_needed()) + { + *(uint32_t volatile *)0x40000504 = 0xC007FFDF; + *(uint32_t volatile *)0x40006C18 = 0x00008000; + } + + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG + register is incorrect" found at Product Anomaly document four your device found at + https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ + if (is_disabled_in_debug_needed()) + { + NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos; + } + + NVIC_Relocate(); +} + + +static bool is_manual_peripheral_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x00) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +static bool is_disabled_in_debug_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +/*lint --flb "Leave library region" */ |