mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-05 21:04:49 +00:00
babblesim: Add babblesim pkg
Co-authored-by: Jakub Rotkiewicz <jakub.rotkiewicz@codecoup.pl> Co-authored-by: Andrzej Kaczmarek <andrzej.kaczmarek@codecoup.pl>
This commit is contained in:
committed by
Andrzej Kaczmarek
parent
bf31ad05b7
commit
9abe36cc3c
@@ -0,0 +1,3 @@
|
||||
hw/babblesim/components
|
||||
hw/babblesim/src
|
||||
nrfx/src
|
||||
@@ -0,0 +1 @@
|
||||
BabbleSim support for Apache NimBLE
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef BSIM_NRF_ARGS_H
|
||||
#define BSIM_NRF_ARGS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "NRF_hw_args.h"
|
||||
#include "bs_cmd_line.h"
|
||||
#include "bs_cmd_line_typical.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nrf52_bsim_args_t {
|
||||
BS_BASIC_DEVICE_OPTIONS_FIELDS
|
||||
nrf_hw_sub_args_t nrf_hw;
|
||||
};
|
||||
|
||||
struct nrf52_bsim_args_t *nrfbsim_argsparse(int argc, char *argv[]);
|
||||
void nrfbsim_register_args(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* This header defines replacements for inline
|
||||
* ARM Cortex-M CMSIS intrinsics.
|
||||
*/
|
||||
|
||||
#ifndef BOARDS_POSIX_NRF52_BSIM_CMSIS_H
|
||||
#define BOARDS_POSIX_NRF52_BSIM_CMSIS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Implement the following ARM intrinsics as no-op:
|
||||
* - ARM Data Synchronization Barrier
|
||||
* - ARM Data Memory Synchronization Barrier
|
||||
* - ARM Instruction Synchronization Barrier
|
||||
* - ARM No Operation
|
||||
*/
|
||||
#ifndef __DMB
|
||||
#define __DMB()
|
||||
#endif
|
||||
|
||||
#ifndef __DSB
|
||||
#define __DSB()
|
||||
#endif
|
||||
|
||||
#ifndef __ISB
|
||||
#define __ISB()
|
||||
#endif
|
||||
|
||||
#ifndef __NOP
|
||||
#define __NOP()
|
||||
#endif
|
||||
|
||||
void NVIC_SystemReset(void);
|
||||
void __disable_irq(void);
|
||||
void __enable_irq(void);
|
||||
uint32_t __get_PRIMASK(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARDS_POSIX_NRF52_BSIM_CMSIS_H */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _BSIM_CORE_CM4_H
|
||||
#define _BSIM_CORE_CM4_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Include the original ext_NRF52_hw_models core_cm4.h */
|
||||
#include <../HW_models/core_cm4.h>
|
||||
|
||||
/* Add missing function definitions */
|
||||
extern void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority);
|
||||
extern void NVIC_EnableIRQ(IRQn_Type IRQn);
|
||||
extern void NVIC_DisableIRQ(IRQn_Type IRQn);
|
||||
|
||||
void __WFI(void);
|
||||
|
||||
#ifndef __REV
|
||||
#define __REV __builtin_bswap32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _TIME_MACHINE_H
|
||||
#define _TIME_MACHINE_H
|
||||
|
||||
#include "bs_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
extern bs_time_t now;
|
||||
bs_time_t tm_get_abs_time(void);
|
||||
bs_time_t tm_get_hw_time(void);
|
||||
bs_time_t tm_hw_time_to_abs_time(bs_time_t hwtime);
|
||||
bs_time_t tm_abs_time_to_hw_time(bs_time_t abstime);
|
||||
|
||||
void tm_reset_hw_times(void);
|
||||
|
||||
void tm_find_next_timer_to_trigger(void);
|
||||
bs_time_t tm_get_next_timer_abstime(void);
|
||||
|
||||
void tm_update_last_phy_sync_time(bs_time_t abs_time);
|
||||
|
||||
void tm_set_phy_max_resync_offset(bs_time_t offset_in_us);
|
||||
|
||||
void tm_run_forever(void);
|
||||
|
||||
void tm_sleep_until_hw_time(bs_time_t hw_time);
|
||||
|
||||
void tm_sleep_until_abs_time(bs_time_t time);
|
||||
|
||||
void tm_start(void);
|
||||
|
||||
void tm_tick(void);
|
||||
|
||||
void tm_tick_limited(bs_time_t max_time_diff);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# 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: babblesim/core
|
||||
pkg.type: sdk
|
||||
pkg.description: time machine, irq handeler, core
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/kernel/os"
|
||||
- "@apache-mynewt-nimble/nimble/controller"
|
||||
- "@apache-mynewt-nimble/nimble/transport"
|
||||
- "babblesim/hw/babblesim"
|
||||
|
||||
pkg.req_apis:
|
||||
- ble_transport
|
||||
|
||||
pkg.init:
|
||||
bsim_start: 9999
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "bs_tracing.h"
|
||||
#include "bs_oswrap.h"
|
||||
#include "bs_dump_files.h"
|
||||
#include "argparse.h"
|
||||
#include "NRF_hw_args.h"
|
||||
#include "bs_cmd_line.h"
|
||||
#include "bs_dynargs.h"
|
||||
#include "bs_cmd_line_typical.h"
|
||||
#include "NRF_HWLowL.h"
|
||||
|
||||
static bs_args_struct_t *args_struct;
|
||||
static struct nrf52_bsim_args_t arg;
|
||||
const char *bogus_sim_id = "bogus";
|
||||
|
||||
static void cmd_trace_lvl_found(char *argv, int offset)
|
||||
{
|
||||
bs_trace_set_level(arg.verb);
|
||||
}
|
||||
|
||||
static void cmd_gdev_nbr_found(char *argv, int offset)
|
||||
{
|
||||
bs_trace_set_prefix_dev(arg.global_device_nbr);
|
||||
}
|
||||
|
||||
static bool nosim;
|
||||
static void cmd_nosim_found(char *argv, int offset)
|
||||
{
|
||||
hwll_set_nosim(true);
|
||||
}
|
||||
|
||||
static void print_no_sim_warning(void)
|
||||
{
|
||||
bs_trace_warning("Neither simulation id or the device number "
|
||||
"have been set. I assume you want to run "
|
||||
"without a BabbleSim phy (-nosim)\n");
|
||||
bs_trace_warning("If this is not what you wanted, check with "
|
||||
"--help how to set them\n");
|
||||
bs_trace_raw(3, "setting sim_id to 'bogus', device number to 0 "
|
||||
"and nosim\n");
|
||||
}
|
||||
|
||||
void nrfbsim_register_args(void)
|
||||
{
|
||||
#define args (&arg)
|
||||
/* This define is quite ugly, but allows reusing the definitions
|
||||
* provided by the utils library */
|
||||
static bs_args_struct_t args_struct_toadd[] = {
|
||||
ARG_TABLE_S_ID,
|
||||
ARG_TABLE_P_ID_2G4,
|
||||
ARG_TABLE_DEV_NBR,
|
||||
ARG_TABLE_GDEV_NBR,
|
||||
ARG_TABLE_VERB,
|
||||
ARG_TABLE_SEED,
|
||||
ARG_TABLE_COLOR,
|
||||
ARG_TABLE_NOCOLOR,
|
||||
ARG_TABLE_FORCECOLOR,
|
||||
_NRF_HW_SUB_CMD_ARG_STRUCT,
|
||||
/*
|
||||
* Fields:
|
||||
* manual, mandatory, switch,
|
||||
* option_name, var_name, type,
|
||||
* destination, callback,
|
||||
* description
|
||||
*/
|
||||
{false, false, true,
|
||||
"nosim", "", 'b',
|
||||
(void *)&nosim, cmd_nosim_found,
|
||||
"(debug feature) Do not connect to the phy"},
|
||||
BS_DUMP_FILES_ARGS,
|
||||
{true, false, false,
|
||||
"argsmain", "arg", 'l',
|
||||
NULL, NULL,
|
||||
"The arguments that follow will be passed to main (default)"},
|
||||
ARG_TABLE_ENDMARKER
|
||||
};
|
||||
#undef args
|
||||
|
||||
bs_add_dynargs(&args_struct, args_struct_toadd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the arguments provided in the command line: set args based on it or
|
||||
* defaults, and check they are correct
|
||||
*/
|
||||
struct nrf52_bsim_args_t *nrfbsim_argsparse(int argc, char *argv[])
|
||||
{
|
||||
bs_args_set_defaults(args_struct);
|
||||
arg.verb = 2;
|
||||
bs_trace_set_level(arg.verb);
|
||||
nrf_hw_sub_cmline_set_defaults(&arg.nrf_hw);
|
||||
static const char default_phy[] = "2G4";
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (bs_is_option(argv[i], "argsmain", 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bs_args_parse_one_arg(argv[i], args_struct)) {
|
||||
bs_args_print_switches_help(args_struct);
|
||||
bs_trace_error_line("Incorrect option %s\n",
|
||||
argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user did not set the simulation id or device number
|
||||
* we assume he wanted to run with nosim (but warn him)
|
||||
*/
|
||||
if ((!nosim) && (arg.s_id == NULL) && (arg.device_nbr == UINT_MAX)) {
|
||||
print_no_sim_warning();
|
||||
nosim = true;
|
||||
hwll_set_nosim(true);
|
||||
}
|
||||
if (nosim) {
|
||||
if (arg.s_id == NULL) {
|
||||
arg.s_id = (char *)bogus_sim_id;
|
||||
}
|
||||
if (arg.device_nbr == UINT_MAX) {
|
||||
arg.device_nbr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg.device_nbr == UINT_MAX) {
|
||||
bs_args_print_switches_help(args_struct);
|
||||
bs_trace_error_line("The command line option <device number> "
|
||||
"needs to be set\n");
|
||||
}
|
||||
if (arg.global_device_nbr == UINT_MAX) {
|
||||
arg.global_device_nbr = arg.device_nbr;
|
||||
bs_trace_set_prefix_dev(arg.global_device_nbr);
|
||||
}
|
||||
if (!arg.s_id) {
|
||||
bs_args_print_switches_help(args_struct);
|
||||
bs_trace_error_line("The command line option <simulation ID> "
|
||||
"needs to be set\n");
|
||||
}
|
||||
if (!arg.p_id) {
|
||||
arg.p_id = (char *)default_phy;
|
||||
}
|
||||
|
||||
if (arg.rseed == UINT_MAX) {
|
||||
arg.rseed = 0x1000 + arg.device_nbr;
|
||||
}
|
||||
return &arg;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2020 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "irq_ctrl.h"
|
||||
|
||||
#include "irq_sources.h"
|
||||
#include <nrfx.h>
|
||||
#include "cmsis.h"
|
||||
#include "os/sim.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "irq_sources.h"
|
||||
#include <nrfx.h>
|
||||
#include "cmsis.h"
|
||||
|
||||
extern void (* systemVectors[256])(void);
|
||||
|
||||
/*
|
||||
* Replacement for ARMs NVIC functions()
|
||||
*/
|
||||
void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
hw_irq_ctrl_raise_im_from_sw(IRQn);
|
||||
}
|
||||
|
||||
void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
hw_irq_ctrl_clear_irq(IRQn);
|
||||
}
|
||||
|
||||
void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
hw_irq_ctrl_disable_irq(IRQn);
|
||||
}
|
||||
|
||||
void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
hw_irq_ctrl_enable_irq(IRQn);
|
||||
}
|
||||
|
||||
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
hw_irq_ctrl_prio_set(IRQn, priority);
|
||||
}
|
||||
|
||||
uint32_t NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
return hw_irq_ctrl_get_prio(IRQn);
|
||||
}
|
||||
|
||||
void NVIC_SystemReset(void)
|
||||
{
|
||||
inner_main_clean_up(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replacements for some other CMSIS functions
|
||||
*/
|
||||
void __enable_irq(void)
|
||||
{
|
||||
hw_irq_ctrl_change_lock(false);
|
||||
}
|
||||
|
||||
void __disable_irq(void)
|
||||
{
|
||||
hw_irq_ctrl_change_lock(true);
|
||||
}
|
||||
|
||||
uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
return hw_irq_ctrl_get_current_lock();
|
||||
}
|
||||
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
systemVectors[(int32_t)IRQn + 16] = (void(*)(void))vector;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* SW side of the IRQ handling
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "irq_ctrl.h"
|
||||
#include "irq_sources.h"
|
||||
#include "os/sim.h"
|
||||
|
||||
static int currently_running_irq = -1;
|
||||
extern void (* const systemVectors[256])(void);
|
||||
|
||||
/**
|
||||
* When an interrupt is raised, this function is called to handle it and, if
|
||||
* needed, swap to a re-enabled thread
|
||||
*
|
||||
* Note that even that this function is executing in a Zephyr thread, it is
|
||||
* effectively the model of the interrupt controller passing context to the IRQ
|
||||
* handler and therefore its priority handling
|
||||
*/
|
||||
|
||||
void posix_interrupt_raised(void)
|
||||
{
|
||||
uint64_t irq_lock;
|
||||
int irq_nbr;
|
||||
|
||||
irq_lock = hw_irq_ctrl_get_current_lock();
|
||||
|
||||
if (irq_lock) {
|
||||
/* "spurious" wakes can happen with interrupts locked */
|
||||
return;
|
||||
}
|
||||
|
||||
while ((irq_nbr = hw_irq_ctrl_get_highest_prio_irq()) != -1) {
|
||||
int last_current_running_prio = hw_irq_ctrl_get_cur_prio();
|
||||
int last_running_irq = currently_running_irq;
|
||||
|
||||
hw_irq_ctrl_set_cur_prio(hw_irq_ctrl_get_prio(irq_nbr));
|
||||
hw_irq_ctrl_clear_irq(irq_nbr);
|
||||
|
||||
currently_running_irq = irq_nbr;
|
||||
systemVectors[irq_nbr + 16]();
|
||||
currently_running_irq = last_running_irq;
|
||||
|
||||
hw_irq_ctrl_set_cur_prio(last_current_running_prio);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thru this function the IRQ controller can raise an immediate interrupt which
|
||||
* will interrupt the SW itself
|
||||
* (this function should only be called from the HW model code, from SW threads)
|
||||
*/
|
||||
void posix_irq_handler_im_from_sw(void)
|
||||
{
|
||||
int sr = 0;
|
||||
|
||||
sr = sig_block_irq_on();
|
||||
/*
|
||||
* if a higher priority interrupt than the possibly currently running is
|
||||
* pending we go immediately into irq_handler() to vector into its
|
||||
* handler
|
||||
*/
|
||||
if (hw_irq_ctrl_get_highest_prio_irq() != -1) {
|
||||
posix_interrupt_raised();
|
||||
}
|
||||
if (sr) {
|
||||
sig_unblock_irq_off();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "NRF_HW_model_top.h"
|
||||
#include "NRF_HWLowL.h"
|
||||
#include "bs_tracing.h"
|
||||
#include "bs_symbols.h"
|
||||
#include "bs_types.h"
|
||||
#include "bs_rand_main.h"
|
||||
#include "bs_pc_backchannel.h"
|
||||
#include "bs_dump_files.h"
|
||||
#include "argparse.h"
|
||||
#include "time_machine.h"
|
||||
#include "os/mynewt.h"
|
||||
#include <stdio.h>
|
||||
#include "os/sim.h"
|
||||
|
||||
uint global_device_nbr;
|
||||
struct nrf52_bsim_args_t *args;
|
||||
|
||||
void
|
||||
bst_tick(bs_time_t time)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
inner_main_clean_up(int exit_code)
|
||||
{
|
||||
hwll_terminate_simulation();
|
||||
nrf_hw_models_free_all();
|
||||
bs_dump_files_close_all();
|
||||
|
||||
bs_clean_back_channels();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
main_clean_up_trace_wrap(void)
|
||||
{
|
||||
return inner_main_clean_up(0);
|
||||
}
|
||||
|
||||
void
|
||||
bsim_init(int argc, char** argv, int (*main_fn)(int argc, char **arg))
|
||||
{
|
||||
setvbuf(stdout, NULL, _IOLBF, 512);
|
||||
setvbuf(stderr, NULL, _IOLBF, 512);
|
||||
|
||||
bs_trace_register_cleanup_function(main_clean_up_trace_wrap);
|
||||
bs_trace_register_time_function(tm_get_abs_time);
|
||||
|
||||
nrf_hw_pre_init();
|
||||
nrfbsim_register_args();
|
||||
|
||||
args = nrfbsim_argsparse(argc, argv);
|
||||
global_device_nbr = args->global_device_nbr;
|
||||
|
||||
bs_read_function_names_from_Tsymbols(argv[0]);
|
||||
|
||||
nrf_hw_initialize(&args->nrf_hw);
|
||||
os_init(main_fn);
|
||||
os_start();
|
||||
}
|
||||
|
||||
void
|
||||
bsim_start(void)
|
||||
{
|
||||
bs_trace_raw(9, "%s: Connecting to phy...\n", __func__);
|
||||
hwll_connect_to_phy(args->device_nbr, args->s_id, args->p_id);
|
||||
bs_trace_raw(9, "%s: Connected\n", __func__);
|
||||
|
||||
bs_random_init(args->rseed);
|
||||
bs_dump_files_open(args->s_id, args->global_device_nbr);
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Oticon A/S
|
||||
* Copyright (c) 2021 Codecoup
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "NRF_HW_model_top.h"
|
||||
#include "NRF_HWLowL.h"
|
||||
#include "bs_tracing.h"
|
||||
#include "bs_types.h"
|
||||
#include "bs_utils.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Note: All timers are relative to hw_time and NOT to 'now' */
|
||||
extern bs_time_t timer_nrf_main_timer;
|
||||
|
||||
/* The events priorities are as in this list from top to bottom
|
||||
* Priority being which timer executes first if several trigger at the same
|
||||
* instant
|
||||
*/
|
||||
static enum {
|
||||
NRF_HW_MAIN_TIMER = 0,
|
||||
NUMBER_OF_TIMERS,
|
||||
NONE
|
||||
} next_timer_index = NONE;
|
||||
|
||||
static bs_time_t *Timer_list[NUMBER_OF_TIMERS] = {
|
||||
&timer_nrf_main_timer,
|
||||
};
|
||||
static bs_time_t next_timer_time = TIME_NEVER;
|
||||
|
||||
/*
|
||||
* Current absolute time of this device, as the device knows it.
|
||||
* It is never reset:
|
||||
*/
|
||||
bs_time_t now;
|
||||
/* Current time the HW of this device things it is */
|
||||
static bs_time_t hw_time;
|
||||
/*
|
||||
* Offset between the current absolute time of the device and the HW time
|
||||
* That is, the absolute time when the HW_time got reset
|
||||
*/
|
||||
static bs_time_t hw_time_delta;
|
||||
|
||||
/* Last time we synchronized with the bsim PHY, in device abs time */
|
||||
static bs_time_t last_bsim_phy_sync_time;
|
||||
|
||||
#define BSIM_DEFAULT_PHY_MAX_RESYNC_OFFSET 1000000
|
||||
/* At least every second we will inform the simulator about our timing */
|
||||
static bs_time_t max_resync_offset = BSIM_DEFAULT_PHY_MAX_RESYNC_OFFSET;
|
||||
|
||||
/**
|
||||
* Set the maximum amount of time the device will spend without talking
|
||||
* (synching) with the phy.
|
||||
* This does not change the functional behavior of the Zephyr code or of the
|
||||
* radio emulation, and it is only relevant if special test code running in the
|
||||
* device interacts behind the scenes with other devices test code.
|
||||
* Setting for example a value of 5ms will ensure that this device time
|
||||
* will never be more than 5ms away from the phy. Setting it in all devices
|
||||
* to 5ms would then ensure no device time is farther apart than 5ms from any
|
||||
* other.
|
||||
*
|
||||
* Note that setting low values has a performance penalty.
|
||||
*/
|
||||
void
|
||||
tm_set_phy_max_resync_offset(bs_time_t offset_in_us)
|
||||
{
|
||||
max_resync_offset = offset_in_us;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the absolute current time (no HW model except the RADIO
|
||||
* should look into this)
|
||||
*/
|
||||
bs_time_t
|
||||
tm_get_abs_time(void)
|
||||
{
|
||||
return now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current HW time
|
||||
*/
|
||||
bs_time_t
|
||||
tm_get_hw_time(void)
|
||||
{
|
||||
return hw_time;
|
||||
}
|
||||
|
||||
bs_time_t
|
||||
posix_get_hw_cycle(void)
|
||||
{
|
||||
return tm_get_hw_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the HW time
|
||||
*/
|
||||
static void
|
||||
tm_reset_hw_time(void)
|
||||
{
|
||||
hw_time = 0;
|
||||
hw_time_delta = now;
|
||||
if (now != 0) {
|
||||
bs_trace_error_line("Reset not supposed to happen after "
|
||||
"initialization\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current hw_time value given the absolute time
|
||||
*/
|
||||
INLINE void
|
||||
tm_update_HW_time(void)
|
||||
{
|
||||
hw_time = now - hw_time_delta;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the HW time
|
||||
*/
|
||||
void
|
||||
tm_reset_hw_times(void)
|
||||
{
|
||||
tm_reset_hw_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the internal time values of this device until time
|
||||
*/
|
||||
void
|
||||
tm_sleep_until_abs_time(bs_time_t time)
|
||||
{
|
||||
if (time >= now) {
|
||||
/*
|
||||
* Ensure that at least we sync with the phy
|
||||
* every max_resync_offset
|
||||
*/
|
||||
if (time > last_bsim_phy_sync_time + max_resync_offset) {
|
||||
hwll_sync_time_with_phy(time);
|
||||
last_bsim_phy_sync_time = time;
|
||||
}
|
||||
|
||||
now = time;
|
||||
} else {
|
||||
/* LCOV_EXCL_START */
|
||||
bs_trace_warning_manual_time_line(now, "next_time_time "
|
||||
"corrupted (%"PRItime"<= %"PRItime", timer idx=%i)\n",
|
||||
time, now, next_timer_index);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
tm_update_HW_time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of the last time we synchronized the time with the scheduler
|
||||
*/
|
||||
void
|
||||
tm_update_last_phy_sync_time(bs_time_t abs_time)
|
||||
{
|
||||
last_bsim_phy_sync_time = abs_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance the internal time values of this device
|
||||
* until the HW time reaches hw_time
|
||||
*/
|
||||
void
|
||||
tm_sleep_until_hw_time(bs_time_t hw_time)
|
||||
{
|
||||
bs_time_t next_time = TIME_NEVER;
|
||||
|
||||
if (hw_time != TIME_NEVER) {
|
||||
next_time = hw_time + hw_time_delta;
|
||||
}
|
||||
|
||||
tm_sleep_until_abs_time(next_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look into all timers and update next_timer accordingly
|
||||
* To be called each time a "timed process" updates its timer
|
||||
*/
|
||||
void
|
||||
tm_find_next_timer_to_trigger(void)
|
||||
{
|
||||
next_timer_time = *Timer_list[0];
|
||||
next_timer_index = 0;
|
||||
|
||||
for (uint i = 1; i < NUMBER_OF_TIMERS; i++) {
|
||||
if (next_timer_time > *Timer_list[i]) {
|
||||
next_timer_time = *Timer_list[i];
|
||||
next_timer_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs_time_t
|
||||
tm_get_next_timer_abstime(void)
|
||||
{
|
||||
return next_timer_time + hw_time_delta;
|
||||
}
|
||||
|
||||
bs_time_t
|
||||
tm_hw_time_to_abs_time(bs_time_t hwtime)
|
||||
{
|
||||
if (hwtime == TIME_NEVER) {
|
||||
return TIME_NEVER;
|
||||
}
|
||||
return hwtime + hw_time_delta;
|
||||
}
|
||||
|
||||
bs_time_t
|
||||
tm_abs_time_to_hw_time(bs_time_t abstime)
|
||||
{
|
||||
if (abstime == TIME_NEVER) {
|
||||
return TIME_NEVER;
|
||||
}
|
||||
return abstime - hw_time_delta;
|
||||
}
|
||||
|
||||
void
|
||||
tm_tick_limited(bs_time_t max_time_diff)
|
||||
{
|
||||
bs_time_t time_to_wait;
|
||||
|
||||
if (max_time_diff != TIME_NEVER && now + max_time_diff < next_timer_time) {
|
||||
time_to_wait = now + max_time_diff;
|
||||
} else {
|
||||
time_to_wait = next_timer_time;
|
||||
}
|
||||
|
||||
tm_sleep_until_hw_time(time_to_wait);
|
||||
switch (next_timer_index) {
|
||||
case NRF_HW_MAIN_TIMER:
|
||||
nrf_hw_some_timer_reached();
|
||||
break;
|
||||
default:
|
||||
bs_trace_error_time_line("next_timer_index "
|
||||
"corrupted\n");
|
||||
break;
|
||||
}
|
||||
tm_find_next_timer_to_trigger();
|
||||
}
|
||||
|
||||
void
|
||||
tm_tick(void)
|
||||
{
|
||||
tm_tick_limited(TIME_NEVER);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# 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: babblesim/hw/babblesim
|
||||
pkg.description: BabbleSim stuff
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
|
||||
pkg.type: sdk
|
||||
|
||||
pkg.include_dirs:
|
||||
- components/ext_NRF52_hw_models/src/nrfx/mdk_replacements
|
||||
- components/ext_NRF52_hw_models/src/HW_models
|
||||
- components/ext_NRF52_hw_models/src/nrfx_config
|
||||
- components/ext_NRF52_hw_models/src/nrfx/nrfx_replacements
|
||||
- components/libUtilv1/src/
|
||||
- components/libPhyComv1/src/
|
||||
- components/libRandv2/src/
|
||||
- components/ext_libCryptov1/src/
|
||||
|
||||
pkg.src_dirs:
|
||||
- src
|
||||
|
||||
pkg.pre_build_cmds:
|
||||
scripts/pre_build1.sh: 1
|
||||
|
||||
pkg.lflags:
|
||||
- -ldl
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/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.
|
||||
#
|
||||
|
||||
if [ -z ${BSIM_COMPONENTS_PATH+x} ]; then
|
||||
echo "This board requires the BabbleSim simulator. Please set" \
|
||||
"the environment variable BSIM_COMPONENTS_PATH to point to its components" \
|
||||
"folder. More information can be found in" \
|
||||
"https://babblesim.github.io/folder_structure_and_env.html"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z ${BSIM_OUT_PATH+x} ]; then
|
||||
echo "This board requires the BabbleSim simulator. Please set" \
|
||||
"the environment variable BSIM_OUT_PATH to point to the folder where the" \
|
||||
"simulator is compiled to. More information can be found in" \
|
||||
"https://babblesim.github.io/folder_structure_and_env.html"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "$(pwd)/components" ]]
|
||||
then
|
||||
echo "Babblesim components: Directory exists. Removing and linking again..."
|
||||
rm -r $(pwd)/components
|
||||
else
|
||||
echo "Babblesim components: Linking components..."
|
||||
fi
|
||||
|
||||
ln -nsf $BSIM_OUT_PATH/components
|
||||
|
||||
if [[ -d "$(pwd)/src" ]]
|
||||
then
|
||||
echo "Babblesim libraries src: Directory exists. Removing and linking again..."
|
||||
rm -r $(pwd)/src
|
||||
else
|
||||
echo "Babblesim components: Linking components..."
|
||||
fi
|
||||
|
||||
mkdir -p src
|
||||
ln -nsf $BSIM_OUT_PATH/components
|
||||
|
||||
# Create links to all .32.a files
|
||||
# find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec ln -t src -nsf {} \;
|
||||
|
||||
# Copy all .32.a files
|
||||
find $BSIM_OUT_PATH/lib/$lib -name "*.32.a" -type f -exec cp -t src -f {} \;
|
||||
|
||||
# XXX: Workaround for bad linking by newt. Sometimes newt will link
|
||||
# nrf weak functions from nrf_hal_originals.o instead of their BabbleSim
|
||||
# replacements inside libNRF52_hw_models.32.a. But as long as the other
|
||||
# weak functions, that do not have their replacements, are not used,
|
||||
# we can just remove the file from the .a library here.
|
||||
ar d src/libNRF52_hw_models.32.a nrf_hal_originals.o
|
||||
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
bsp.name: "nRF52 DK"
|
||||
bsp.url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52-DK
|
||||
bsp.maker: "Nordic Semiconductor"
|
||||
bsp.arch: bsim_arch
|
||||
bsp.compiler: "@apache-mynewt-core/compiler/sim"
|
||||
bsp.downloadscript: "hw/bsp/nrf52_bsim/nordic_pca10040_download.sh"
|
||||
bsp.debugscript: "hw/bsp/nrf52_bsim/nordic_pca10040_debug.sh"
|
||||
bsp.downloadscript.WINDOWS.OVERWRITE: "hw/bsp/nrf52_bsim/nordic_pca10040_download.cmd"
|
||||
bsp.debugscript.WINDOWS.OVERWRITE: "hw/bsp/nrf52_bsim/nordic_pca10040_debug.cmd"
|
||||
|
||||
bsp.flash_map:
|
||||
areas:
|
||||
# System areas.
|
||||
FLASH_AREA_BOOTLOADER:
|
||||
device: 0
|
||||
offset: 0x00000000
|
||||
size: 16kB
|
||||
FLASH_AREA_IMAGE_0:
|
||||
device: 0
|
||||
offset: 0x00008000
|
||||
size: 232kB
|
||||
FLASH_AREA_IMAGE_1:
|
||||
device: 0
|
||||
offset: 0x00042000
|
||||
size: 232kB
|
||||
FLASH_AREA_IMAGE_SCRATCH:
|
||||
device: 0
|
||||
offset: 0x0007c000
|
||||
size: 4kB
|
||||
|
||||
# User areas.
|
||||
FLASH_AREA_REBOOT_LOG:
|
||||
user_id: 0
|
||||
device: 0
|
||||
offset: 0x00004000
|
||||
size: 16kB
|
||||
FLASH_AREA_NFFS:
|
||||
user_id: 1
|
||||
device: 0
|
||||
offset: 0x0007d000
|
||||
size: 12kB
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "os/mynewt.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")))
|
||||
#define sec_bss_nz_core __attribute__((section(".bss.core.nz")))
|
||||
|
||||
/* More convenient section placement macros. */
|
||||
#define bssnz_t sec_bss_nz_core
|
||||
|
||||
extern uint8_t _ram_start;
|
||||
#define RAM_SIZE 0x10000
|
||||
|
||||
/* LED pins */
|
||||
#define LED_1 (17)
|
||||
#define LED_2 (18)
|
||||
#define LED_3 (19)
|
||||
#define LED_4 (20)
|
||||
#define LED_BLINK_PIN (LED_1)
|
||||
|
||||
/* Buttons */
|
||||
#define BUTTON_1 (13)
|
||||
#define BUTTON_2 (14)
|
||||
#define BUTTON_3 (15)
|
||||
#define BUTTON_4 (16)
|
||||
|
||||
/* Arduino pins */
|
||||
#define ARDUINO_PIN_D0 11
|
||||
#define ARDUINO_PIN_D1 12
|
||||
#define ARDUINO_PIN_D2 13
|
||||
#define ARDUINO_PIN_D3 14
|
||||
#define ARDUINO_PIN_D4 15
|
||||
#define ARDUINO_PIN_D5 16
|
||||
#define ARDUINO_PIN_D6 17
|
||||
#define ARDUINO_PIN_D7 18
|
||||
#define ARDUINO_PIN_D8 19
|
||||
#define ARDUINO_PIN_D9 20
|
||||
#define ARDUINO_PIN_D10 22
|
||||
#define ARDUINO_PIN_D11 23
|
||||
#define ARDUINO_PIN_D12 24
|
||||
#define ARDUINO_PIN_D13 25
|
||||
#define ARDUINO_PIN_A0 3
|
||||
#define ARDUINO_PIN_A1 4
|
||||
#define ARDUINO_PIN_A2 28
|
||||
#define ARDUINO_PIN_A3 29
|
||||
#define ARDUINO_PIN_A4 30
|
||||
#define ARDUINO_PIN_A5 31
|
||||
|
||||
#define ARDUINO_PIN_RX ARDUINO_PIN_D0
|
||||
#define ARDUINO_PIN_TX ARDUINO_PIN_D1
|
||||
|
||||
#define ARDUINO_PIN_SCL 27
|
||||
#define ARDUINO_PIN_SDA 26
|
||||
|
||||
#define ARDUINO_PIN_SCK ARDUINO_PIN_D13
|
||||
#define ARDUINO_PIN_MOSI ARDUINO_PIN_D11
|
||||
#define ARDUINO_PIN_MISO ARDUINO_PIN_D12
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_BSP_H */
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 _OS_ARCH_ARM_H
|
||||
#define _OS_ARCH_ARM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "mcu/cmsis_nvic.h"
|
||||
#include "mcu/cortex_m4.h"
|
||||
#include <irq_ctrl.h>
|
||||
#include "mcu/mcu_sim.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* CPU status register */
|
||||
typedef uint32_t os_sr_t;
|
||||
|
||||
/* Stack element */
|
||||
typedef uint32_t os_stack_t;
|
||||
|
||||
struct stack_frame;
|
||||
void os_arch_frame_init(struct stack_frame *sf);
|
||||
|
||||
/* Stack sizes for common OS tasks */
|
||||
#define OS_SANITY_STACK_SIZE (2000)
|
||||
#if MYNEWT_VAL(OS_SYSVIEW)
|
||||
#define OS_IDLE_STACK_SIZE (80)
|
||||
#else
|
||||
#define OS_IDLE_STACK_SIZE (4000)
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
os_arch_in_isr(void)
|
||||
{
|
||||
return hw_irq_ctrl_get_irq_status();
|
||||
}
|
||||
|
||||
/* Include common arch definitions and APIs */
|
||||
#include "os/arch/common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_ARCH_ARM_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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_KERNEL_SIM_
|
||||
#define H_KERNEL_SIM_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include "os/mynewt.h"
|
||||
#include "mcu/mcu_sim.h"
|
||||
struct os_task;
|
||||
struct stack_frame;
|
||||
|
||||
struct stack_frame {
|
||||
int sf_mainsp; /* stack on which main() is executing */
|
||||
sigjmp_buf sf_jb;
|
||||
struct os_task *sf_task;
|
||||
};
|
||||
|
||||
void sim_task_start(struct stack_frame *sf, int rc);
|
||||
os_stack_t *sim_task_stack_init(struct os_task *t, os_stack_t *stack_top,
|
||||
int size);
|
||||
os_error_t sim_os_start(void);
|
||||
void sim_os_stop(void);
|
||||
os_error_t sim_os_init(void);
|
||||
void sim_ctx_sw(struct os_task *next_t);
|
||||
os_sr_t sim_save_sr(void);
|
||||
void sim_restore_sr(os_sr_t osr);
|
||||
int sim_in_critical(void);
|
||||
void sim_tick_idle(os_time_t ticks);
|
||||
int sig_block_irq_on();
|
||||
void sig_unblock_irq_off();
|
||||
|
||||
uint8_t inner_main_clean_up(int exit_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
@rem
|
||||
@rem Licensed to the Apache Software Foundation (ASF) under one
|
||||
@rem or more contributor license agreements. See the NOTICE file
|
||||
@rem distributed with this work for additional information
|
||||
@rem regarding copyright ownership. The ASF licenses this file
|
||||
@rem to you under the Apache License, Version 2.0 (the
|
||||
@rem "License"); you may not use this file except in compliance
|
||||
@rem with the License. You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing,
|
||||
@rem software distributed under the License is distributed on an
|
||||
@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@rem KIND, either express or implied. See the License for the
|
||||
@rem specific language governing permissions and limitations
|
||||
@rem under the License.
|
||||
@rem
|
||||
|
||||
@rem Execute a shell with a script of the same name and .sh extension
|
||||
|
||||
@bash "%~dp0%~n0.sh"
|
||||
+45
@@ -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 with following variables set:
|
||||
# - CORE_PATH is absolute path to @apache-mynewt-core
|
||||
# - BSP_PATH is absolute path to hw/bsp/bsp_name
|
||||
# - BIN_BASENAME is the path to prefix to target binary,
|
||||
# .elf appended to name is the ELF file
|
||||
# - FEATURES holds the target features string
|
||||
# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software
|
||||
# - RESET set if target should be reset when attaching
|
||||
# - NO_GDB set if we should not start gdb to debug
|
||||
#
|
||||
|
||||
. $CORE_PATH/hw/scripts/jlink.sh
|
||||
|
||||
FILE_NAME=$BIN_BASENAME.elf
|
||||
|
||||
if [ $# -gt 2 ]; then
|
||||
SPLIT_ELF_NAME=$3.elf
|
||||
# TODO -- this magic number 0x42000 is the location of the second image
|
||||
# slot. we should either get this from a flash map file or somehow learn
|
||||
# this from the image itself
|
||||
EXTRA_GDB_CMDS="add-symbol-file $SPLIT_ELF_NAME 0x8000 -readnow"
|
||||
fi
|
||||
|
||||
JLINK_DEV="nRF52"
|
||||
|
||||
jlink_debug
|
||||
@@ -0,0 +1,22 @@
|
||||
@rem
|
||||
@rem Licensed to the Apache Software Foundation (ASF) under one
|
||||
@rem or more contributor license agreements. See the NOTICE file
|
||||
@rem distributed with this work for additional information
|
||||
@rem regarding copyright ownership. The ASF licenses this file
|
||||
@rem to you under the Apache License, Version 2.0 (the
|
||||
@rem "License"); you may not use this file except in compliance
|
||||
@rem with the License. You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing,
|
||||
@rem software distributed under the License is distributed on an
|
||||
@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@rem KIND, either express or implied. See the License for the
|
||||
@rem specific language governing permissions and limitations
|
||||
@rem under the License.
|
||||
@rem
|
||||
|
||||
@rem Execute a shell with a script of the same name and .sh extension
|
||||
|
||||
@bash "%~dp0%~n0.sh"
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#!/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 with following variables set:
|
||||
# - CORE_PATH is absolute path to @apache-mynewt-core
|
||||
# - BSP_PATH is absolute path to hw/bsp/bsp_name
|
||||
# - BIN_BASENAME is the path to prefix to target binary,
|
||||
# .elf appended to name is the ELF file
|
||||
# - IMAGE_SLOT is the image slot to download to (for non-mfg-image, non-boot)
|
||||
# - FEATURES holds the target features string
|
||||
# - EXTRA_JTAG_CMD holds extra parameters to pass to jtag software
|
||||
# - MFG_IMAGE is "1" if this is a manufacturing image
|
||||
# - FLASH_OFFSET contains the flash offset to download to
|
||||
# - BOOT_LOADER is set if downloading a bootloader
|
||||
|
||||
. $CORE_PATH/hw/scripts/jlink.sh
|
||||
|
||||
if [ "$MFG_IMAGE" ]; then
|
||||
FLASH_OFFSET=0x0
|
||||
fi
|
||||
|
||||
JLINK_DEV="nRF52"
|
||||
|
||||
common_file_to_load
|
||||
jlink_load
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# 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: babblesim/hw/bsp/nrf52_bsim
|
||||
pkg.type: bsp
|
||||
pkg.description: nRF52 on BabbleSim
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
|
||||
pkg.cflags:
|
||||
- '-DNRF52832_XXAA'
|
||||
- '-DBABBLESIM'
|
||||
|
||||
pkg.cflags.HARDFLOAT:
|
||||
- -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/hw/drivers/uart/uart_hal"
|
||||
- "babblesim/hw/mcu/nordic/nrf52_bsim"
|
||||
- "babblesim/hw/babblesim"
|
||||
- "babblesim/core"
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 "os/mynewt.h"
|
||||
#include "os/sim.h"
|
||||
#include "sim_priv.h"
|
||||
#include <irq_ctrl.h>
|
||||
|
||||
/*
|
||||
* From HAL_CM4.s
|
||||
*/
|
||||
extern void SVC_Handler(void);
|
||||
extern void PendSV_Handler(void);
|
||||
extern void SysTick_Handler(void);
|
||||
|
||||
/*
|
||||
* Assert that 'sf_mainsp' and 'sf_jb' are at the specific offsets where
|
||||
* os_arch_frame_init() expects them to be.
|
||||
*/
|
||||
CTASSERT(offsetof(struct stack_frame, sf_mainsp) == 0);
|
||||
CTASSERT(offsetof(struct stack_frame, sf_jb) == 4);
|
||||
|
||||
void
|
||||
os_arch_task_start(struct stack_frame *sf, int rc)
|
||||
{
|
||||
sim_task_start(sf, rc);
|
||||
}
|
||||
|
||||
os_stack_t *
|
||||
os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
|
||||
{
|
||||
return sim_task_stack_init(t, stack_top, size);
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_arch_os_start(void)
|
||||
{
|
||||
return sim_os_start();
|
||||
}
|
||||
|
||||
void
|
||||
os_arch_os_stop(void)
|
||||
{
|
||||
sim_os_stop();
|
||||
}
|
||||
|
||||
void
|
||||
PendSV_Handler(void)
|
||||
{
|
||||
sim_switch_tasks();
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_arch_os_init(void)
|
||||
{
|
||||
NVIC_SetVector(PendSV_IRQn, (uint32_t)PendSV_Handler);
|
||||
return sim_os_init();
|
||||
}
|
||||
|
||||
void
|
||||
os_arch_ctx_sw(struct os_task *next_t)
|
||||
{
|
||||
sim_ctx_sw(next_t);
|
||||
}
|
||||
|
||||
os_sr_t
|
||||
os_arch_save_sr(void)
|
||||
{
|
||||
sim_save_sr();
|
||||
return hw_irq_ctrl_change_lock(1);
|
||||
}
|
||||
|
||||
void
|
||||
os_arch_restore_sr(os_sr_t osr)
|
||||
{
|
||||
hw_irq_ctrl_change_lock(osr);
|
||||
sim_restore_sr(osr);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
os_arch_in_critical(void)
|
||||
{
|
||||
return sim_in_critical();
|
||||
}
|
||||
|
||||
void
|
||||
__assert_func(const char *file, int line, const char *func, const char *e)
|
||||
{
|
||||
#if MYNEWT_VAL(OS_ASSERT_CB)
|
||||
os_assert_cb();
|
||||
#endif
|
||||
_Exit(1);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined MN_LINUX
|
||||
#define sigsetjmp __sigsetjmp
|
||||
#define CNAME(x) x
|
||||
#elif defined MN_OSX
|
||||
#define sigsetjmp sigsetjmp
|
||||
#define CNAME(x) _ ## x
|
||||
#elif defined MN_FreeBSD
|
||||
#define sigsetjmp sigsetjmp
|
||||
#define CNAME(x) x
|
||||
#else
|
||||
#error "unsupported platform"
|
||||
#endif
|
||||
|
||||
.text
|
||||
.code32
|
||||
.p2align 4, 0x90 /* align on 16-byte boundary and fill with NOPs */
|
||||
|
||||
.globl CNAME(os_arch_frame_init)
|
||||
.globl _os_arch_frame_init
|
||||
/*
|
||||
* void os_arch_frame_init(struct stack_frame *sf)
|
||||
*/
|
||||
CNAME(os_arch_frame_init):
|
||||
push %ebp /* function prologue for backtrace */
|
||||
mov %esp,%ebp
|
||||
push %esi /* save %esi before using it as a tmpreg */
|
||||
|
||||
/*
|
||||
* At this point we are executing on the main() stack:
|
||||
* ----------------
|
||||
* stack_frame ptr 0xc(%esp)
|
||||
* ----------------
|
||||
* return address 0x8(%esp)
|
||||
* ----------------
|
||||
* saved ebp 0x4(%esp)
|
||||
* ----------------
|
||||
* saved esi 0x0(%esp)
|
||||
* ----------------
|
||||
*/
|
||||
movl 0xc(%esp),%esi /* %esi = 'sf' */
|
||||
movl %esp,0x0(%esi) /* sf->mainsp = %esp */
|
||||
|
||||
/*
|
||||
* Switch the stack so the stack pointer stored in 'sf->sf_jb' points
|
||||
* to the task stack. This is slightly complicated because OS X wants
|
||||
* the incoming stack pointer to be 16-byte aligned.
|
||||
*
|
||||
* ----------------
|
||||
* sf (other fields)
|
||||
* ----------------
|
||||
* sf (sf_jb) 0x4(%esi)
|
||||
* ----------------
|
||||
* sf (sf_mainsp) 0x0(%esi)
|
||||
* ----------------
|
||||
* alignment padding variable (0 to 12 bytes)
|
||||
* ----------------
|
||||
* savemask (0) 0x4(%esp)
|
||||
* ----------------
|
||||
* pointer to sf_jb 0x0(%esp)
|
||||
* ----------------
|
||||
*/
|
||||
movl %esi,%esp
|
||||
subl $0x8,%esp /* make room for sigsetjmp() arguments */
|
||||
andl $0xfffffff0,%esp /* align %esp on 16-byte boundary */
|
||||
leal 0x4(%esi),%eax /* %eax = &sf->sf_jb */
|
||||
movl %eax,0x0(%esp)
|
||||
movl $0, 0x4(%esp)
|
||||
call CNAME(sigsetjmp) /* sigsetjmp(sf->sf_jb, 0) */
|
||||
test %eax,%eax
|
||||
jne 1f
|
||||
movl 0x0(%esi),%esp /* switch back to the main() stack */
|
||||
pop %esi
|
||||
pop %ebp
|
||||
ret /* return to os_arch_task_stack_init() */
|
||||
1:
|
||||
lea 2f,%ecx
|
||||
push %ecx /* retaddr */
|
||||
push $0 /* frame pointer */
|
||||
movl %esp,%ebp /* handcrafted prologue for backtrace */
|
||||
push %eax /* rc */
|
||||
push %esi /* sf */
|
||||
call CNAME(os_arch_task_start) /* os_arch_task_start(sf, rc) */
|
||||
/* never returns */
|
||||
2:
|
||||
nop
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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_SIM_PRIV_
|
||||
#define H_SIM_PRIV_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "os/mynewt.h"
|
||||
#include "mcu/mcu_sim.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OS_USEC_PER_TICK (1000000 / OS_TICKS_PER_SEC)
|
||||
|
||||
void sim_switch_tasks(void);
|
||||
void sim_tick(void);
|
||||
void sim_signals_init(void);
|
||||
void sim_signals_cleanup(void);
|
||||
|
||||
extern pid_t sim_pid;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains code that is shared by both sim implementations (signals
|
||||
* and no-signals).
|
||||
*/
|
||||
|
||||
#include "os/mynewt.h"
|
||||
|
||||
#include <hal/hal_bsp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
#include <hal/hal_os_tick.h>
|
||||
#include "os/sim.h"
|
||||
#include "sim_priv.h"
|
||||
|
||||
#define sim_setjmp(__jb) sigsetjmp(__jb, 0)
|
||||
#define sim_longjmp(__jb, __ret) siglongjmp(__jb, __ret)
|
||||
|
||||
pid_t sim_pid;
|
||||
|
||||
void
|
||||
sim_switch_tasks(void)
|
||||
{
|
||||
struct os_task *t, *next_t;
|
||||
struct stack_frame *sf;
|
||||
int rc;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
t = os_sched_get_current_task();
|
||||
next_t = os_sched_next_task();
|
||||
if (t == next_t) {
|
||||
/*
|
||||
* Context switch not needed - just return.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (t) {
|
||||
sf = (struct stack_frame *) t->t_stackptr;
|
||||
|
||||
rc = sim_setjmp(sf->sf_jb);
|
||||
if (rc != 0) {
|
||||
OS_ASSERT_CRITICAL();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
os_sched_ctx_sw_hook(next_t);
|
||||
|
||||
os_sched_set_current_task(next_t);
|
||||
|
||||
sf = (struct stack_frame *) next_t->t_stackptr;
|
||||
sim_longjmp(sf->sf_jb, 1);
|
||||
}
|
||||
|
||||
void
|
||||
sim_tick(void)
|
||||
{
|
||||
struct timeval time_now, time_diff;
|
||||
int ticks;
|
||||
|
||||
static struct timeval time_last;
|
||||
static int time_inited;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
if (!time_inited) {
|
||||
gettimeofday(&time_last, NULL);
|
||||
time_inited = 1;
|
||||
}
|
||||
|
||||
gettimeofday(&time_now, NULL);
|
||||
if (timercmp(&time_now, &time_last, <)) {
|
||||
/*
|
||||
* System time going backwards.
|
||||
*/
|
||||
time_last = time_now;
|
||||
} else {
|
||||
timersub(&time_now, &time_last, &time_diff);
|
||||
|
||||
ticks = time_diff.tv_sec * OS_TICKS_PER_SEC;
|
||||
ticks += time_diff.tv_usec / OS_USEC_PER_TICK;
|
||||
|
||||
/*
|
||||
* Update 'time_last' but account for the remainder usecs that did not
|
||||
* contribute towards whole 'ticks'.
|
||||
*/
|
||||
time_diff.tv_sec = 0;
|
||||
time_diff.tv_usec %= OS_USEC_PER_TICK;
|
||||
timersub(&time_now, &time_diff, &time_last);
|
||||
|
||||
os_time_advance(ticks);
|
||||
}
|
||||
}
|
||||
|
||||
#define OS_TICK_PRIO 7
|
||||
|
||||
static void
|
||||
sim_start_timer(void)
|
||||
{
|
||||
/* Intitialize and start system clock timer */
|
||||
os_tick_init(OS_TICKS_PER_SEC, OS_TICK_PRIO);
|
||||
}
|
||||
|
||||
static void
|
||||
sim_stop_timer(void)
|
||||
{
|
||||
struct itimerval it;
|
||||
int rc;
|
||||
|
||||
memset(&it, 0, sizeof(it));
|
||||
|
||||
rc = setitimer(ITIMER_REAL, &it, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from 'os_arch_frame_init()' when setjmp returns indirectly via
|
||||
* longjmp. The return value of setjmp is passed to this function as 'rc'.
|
||||
*/
|
||||
void
|
||||
sim_task_start(struct stack_frame *sf, int rc)
|
||||
{
|
||||
struct os_task *task;
|
||||
|
||||
/*
|
||||
* Interrupts are disabled when a task starts executing. This happens in
|
||||
* two different ways:
|
||||
* - via sim_os_start() for the first task.
|
||||
* - via os_sched() for all other tasks.
|
||||
*
|
||||
* Enable interrupts before starting the task.
|
||||
*/
|
||||
OS_EXIT_CRITICAL(0);
|
||||
|
||||
task = sf->sf_task;
|
||||
task->t_func(task->t_arg);
|
||||
|
||||
/* A task handler should never return. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
os_stack_t *
|
||||
sim_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
|
||||
{
|
||||
struct stack_frame *sf;
|
||||
|
||||
sf = (struct stack_frame *) ((uint8_t *) stack_top - sizeof(*sf));
|
||||
sf->sf_task = t;
|
||||
|
||||
os_arch_frame_init(sf);
|
||||
|
||||
return ((os_stack_t *)sf);
|
||||
}
|
||||
|
||||
os_error_t
|
||||
sim_os_start(void)
|
||||
{
|
||||
struct stack_frame *sf;
|
||||
struct os_task *t;
|
||||
os_sr_t sr;
|
||||
|
||||
/*
|
||||
* Disable interrupts before enabling any interrupt sources. Pending
|
||||
* interrupts will be recognized when the first task starts executing.
|
||||
*/
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
assert(sr == 0);
|
||||
|
||||
/* Enable the interrupt sources */
|
||||
sim_start_timer();
|
||||
|
||||
t = os_sched_next_task();
|
||||
os_sched_set_current_task(t);
|
||||
|
||||
g_os_started = 1;
|
||||
|
||||
sf = (struct stack_frame *) t->t_stackptr;
|
||||
sim_longjmp(sf->sf_jb, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the tick timer and clears the "started" flag. This function is only
|
||||
* implemented for sim.
|
||||
*/
|
||||
void
|
||||
sim_os_stop(void)
|
||||
{
|
||||
sim_stop_timer();
|
||||
sim_signals_cleanup();
|
||||
g_os_started = 0;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
sim_os_init(void)
|
||||
{
|
||||
sim_pid = getpid();
|
||||
g_current_task = NULL;
|
||||
|
||||
STAILQ_INIT(&g_os_task_list);
|
||||
TAILQ_INIT(&g_os_run_list);
|
||||
TAILQ_INIT(&g_os_sleep_list);
|
||||
|
||||
sim_signals_init();
|
||||
|
||||
os_init_idle_task();
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file implements the "no-signals" version of sim. This implementation
|
||||
* does not use signals to perform context switches. This is the less correct
|
||||
* version of sim: the OS tick timer only runs while the idle task is active.
|
||||
* Therefore, a sleeping high-priority task will not preempt a low-priority
|
||||
* task due to a timing event (e.g., delay or callout expired). However, this
|
||||
* version of sim does not suffer from the stability issues that affect the
|
||||
* "signals" implementation.
|
||||
*
|
||||
* To use this version of sim, disable the MCU_NATIVE_USE_SIGNALS syscfg
|
||||
* setting.
|
||||
*/
|
||||
|
||||
#include "os/mynewt.h"
|
||||
|
||||
#if !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS)
|
||||
|
||||
#include <hal/hal_bsp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
#include "sim_priv.h"
|
||||
|
||||
static sigset_t nosigs;
|
||||
static sigset_t suspsigs; /* signals delivered in sigsuspend() */
|
||||
|
||||
static int ctx_sw_pending;
|
||||
static int interrupts_enabled = 1;
|
||||
|
||||
void
|
||||
sim_ctx_sw(struct os_task *next_t)
|
||||
{
|
||||
if (interrupts_enabled) {
|
||||
/* Perform the context switch immediately. */
|
||||
sim_switch_tasks();
|
||||
} else {
|
||||
/* Remember that we want to perform a context switch. Perform it when
|
||||
* interrupts are re-enabled.
|
||||
*/
|
||||
ctx_sw_pending = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical section.
|
||||
*
|
||||
* Returns 1 if interrupts were already disabled; 0 otherwise.
|
||||
*/
|
||||
os_sr_t
|
||||
sim_save_sr(void)
|
||||
{
|
||||
if (!interrupts_enabled) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
interrupts_enabled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sim_restore_sr(os_sr_t osr)
|
||||
{
|
||||
OS_ASSERT_CRITICAL();
|
||||
assert(osr == 0 || osr == 1);
|
||||
|
||||
if (osr == 1) {
|
||||
/* Exiting a nested critical section */
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx_sw_pending) {
|
||||
/* A context switch was requested while interrupts were disabled.
|
||||
* Perform it now that interrupts are enabled again.
|
||||
*/
|
||||
ctx_sw_pending = 0;
|
||||
sim_switch_tasks();
|
||||
}
|
||||
interrupts_enabled = 1;
|
||||
}
|
||||
|
||||
int
|
||||
sim_in_critical(void)
|
||||
{
|
||||
return !interrupts_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unblocks the SIGALRM signal that is delivered by the OS tick timer.
|
||||
*/
|
||||
static void
|
||||
unblock_timer(void)
|
||||
{
|
||||
sigset_t sigs;
|
||||
int rc;
|
||||
|
||||
sigemptyset(&sigs);
|
||||
sigaddset(&sigs, SIGALRM);
|
||||
|
||||
rc = sigprocmask(SIG_UNBLOCK, &sigs, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks the SIGALRM signal that is delivered by the OS tick timer.
|
||||
*/
|
||||
static void
|
||||
block_timer(void)
|
||||
{
|
||||
sigset_t sigs;
|
||||
int rc;
|
||||
|
||||
sigemptyset(&sigs);
|
||||
sigaddset(&sigs, SIGALRM);
|
||||
|
||||
rc = sigprocmask(SIG_BLOCK, &sigs, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
sig_handler_alrm(int sig)
|
||||
{
|
||||
/* Wake the idle task. */
|
||||
sigaddset(&suspsigs, sig);
|
||||
}
|
||||
|
||||
void
|
||||
sim_tick_idle(os_time_t ticks)
|
||||
{
|
||||
int rc;
|
||||
struct itimerval it;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Enter tickless regime and set the timer to fire after 'ticks'
|
||||
* worth of time has elapsed.
|
||||
*/
|
||||
it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC;
|
||||
it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = OS_USEC_PER_TICK;
|
||||
rc = setitimer(ITIMER_REAL, &it, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
unblock_timer();
|
||||
|
||||
sigemptyset(&suspsigs);
|
||||
sigsuspend(&nosigs); /* Wait for a signal to wake us up */
|
||||
|
||||
block_timer();
|
||||
|
||||
/*
|
||||
* Call handlers for signals delivered to the process during sigsuspend().
|
||||
* The SIGALRM handler is called before any other handlers to ensure that
|
||||
* OS time is always correct.
|
||||
*/
|
||||
if (sigismember(&suspsigs, SIGALRM)) {
|
||||
sim_tick();
|
||||
}
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Enable the periodic timer interrupt.
|
||||
*/
|
||||
it.it_value.tv_sec = 0;
|
||||
it.it_value.tv_usec = OS_USEC_PER_TICK;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = OS_USEC_PER_TICK;
|
||||
rc = setitimer(ITIMER_REAL, &it, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sim_signals_init(void)
|
||||
{
|
||||
sigset_t sigset_alrm;
|
||||
struct sigaction sa;
|
||||
int error;
|
||||
|
||||
block_timer();
|
||||
|
||||
sigemptyset(&nosigs);
|
||||
|
||||
sigemptyset(&sigset_alrm);
|
||||
sigaddset(&sigset_alrm, SIGALRM);
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = sig_handler_alrm;
|
||||
sa.sa_mask = sigset_alrm;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
error = sigaction(SIGALRM, &sa, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
void
|
||||
sim_signals_cleanup(void)
|
||||
{
|
||||
int error;
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
error = sigaction(SIGALRM, &sa, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
#endif /* !MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file implements the "signals" version of sim. This implementation uses
|
||||
* signals to perform context switches. This is the more correct version of
|
||||
* sim: the OS tick timer will cause a high-priority task to preempt a
|
||||
* low-priority task. Unfortunately, there are stability issues because a task
|
||||
* can be preempted while it is in the middle of a system call, potentially
|
||||
* causing deadlock or memory corruption.
|
||||
*
|
||||
* To use this version of sim, enable the MCU_NATIVE_USE_SIGNALS syscfg
|
||||
* setting.
|
||||
*/
|
||||
|
||||
#include "os/mynewt.h"
|
||||
|
||||
#if MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS)
|
||||
|
||||
#include "sim_priv.h"
|
||||
|
||||
#include <hal/hal_bsp.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
|
||||
static bool suspended; /* process is blocked in sigsuspend() */
|
||||
static sigset_t suspsigs; /* signals delivered in sigsuspend() */
|
||||
static sigset_t allsigs;
|
||||
static sigset_t nosigs;
|
||||
|
||||
static int in_irq;
|
||||
int counter = 0;
|
||||
|
||||
int
|
||||
sig_block_irq_on()
|
||||
{
|
||||
int error;
|
||||
|
||||
counter++;
|
||||
|
||||
error = sigprocmask(SIG_BLOCK, &allsigs, NULL);
|
||||
|
||||
in_irq = 1;
|
||||
assert(error == 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sig_unblock_irq_off()
|
||||
{
|
||||
int error;
|
||||
|
||||
in_irq = 0;
|
||||
|
||||
if (counter > 0) {
|
||||
counter--;
|
||||
return;
|
||||
}
|
||||
|
||||
error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
|
||||
assert(error == 0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
sim_ctx_sw(struct os_task *next_t)
|
||||
{
|
||||
/*
|
||||
* gdb will stop execution of the program on most signals (e.g. SIGUSR1)
|
||||
* whereas it passes SIGURG to the process without any special settings.
|
||||
*/
|
||||
kill(sim_pid, SIGURG);
|
||||
}
|
||||
|
||||
static void
|
||||
ctxsw_handler(int sig)
|
||||
{
|
||||
assert(in_irq==0);
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
/*
|
||||
* Just record that this handler was called when the process was blocked.
|
||||
* The handler will be called after sigsuspend() returns in the correct
|
||||
* order.
|
||||
*/
|
||||
if (suspended) {
|
||||
sigaddset(&suspsigs, sig);
|
||||
} else {
|
||||
sim_switch_tasks();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable signals and enter a critical section.
|
||||
*
|
||||
* Returns 1 if signals were already blocked and 0 otherwise.
|
||||
*/
|
||||
os_sr_t
|
||||
sim_save_sr(void)
|
||||
{
|
||||
int error;
|
||||
sigset_t omask;
|
||||
|
||||
counter++;
|
||||
|
||||
error = sigprocmask(SIG_BLOCK, &allsigs, &omask);
|
||||
assert(error == 0);
|
||||
|
||||
/*
|
||||
* If any one of the signals in 'allsigs' is present in 'omask' then
|
||||
* we are already inside a critical section.
|
||||
*/
|
||||
return (sigismember(&omask, SIGURG));
|
||||
}
|
||||
|
||||
void
|
||||
sim_restore_sr(os_sr_t osr)
|
||||
{
|
||||
int error;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
assert(osr == 0 || osr == 1);
|
||||
|
||||
if (counter > 0) {
|
||||
counter--;
|
||||
}
|
||||
|
||||
if (osr == 1 || in_irq == 1 || counter > 0) {
|
||||
/* Exiting a nested critical section */
|
||||
return;
|
||||
}
|
||||
|
||||
error = sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
int
|
||||
sim_in_critical(void)
|
||||
{
|
||||
int error;
|
||||
sigset_t omask;
|
||||
|
||||
error = sigprocmask(SIG_SETMASK, NULL, &omask);
|
||||
assert(error == 0);
|
||||
|
||||
/*
|
||||
* If any one of the signals in 'allsigs' is present in 'omask' then
|
||||
* we are already inside a critical section.
|
||||
*/
|
||||
return (sigismember(&omask, SIGURG));
|
||||
}
|
||||
|
||||
static struct {
|
||||
int num;
|
||||
void (*handler)(int sig);
|
||||
} signals[] = {
|
||||
// { SIGALRM, timer_handler },
|
||||
{ SIGURG, ctxsw_handler },
|
||||
};
|
||||
|
||||
#define NUMSIGS (sizeof(signals)/sizeof(signals[0]))
|
||||
|
||||
void
|
||||
sim_tick_idle(os_time_t ticks)
|
||||
{
|
||||
int i, rc, sig;
|
||||
struct itimerval it;
|
||||
void (*handler)(int sig);
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Enter tickless regime and set the timer to fire after 'ticks'
|
||||
* worth of time has elapsed.
|
||||
*/
|
||||
it.it_value.tv_sec = ticks / OS_TICKS_PER_SEC;
|
||||
it.it_value.tv_usec = (ticks % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = OS_USEC_PER_TICK;
|
||||
rc = setitimer(ITIMER_REAL, &it, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
suspended = true;
|
||||
sigemptyset(&suspsigs);
|
||||
sigsuspend(&nosigs); /* Wait for a signal to wake us up */
|
||||
suspended = false;
|
||||
|
||||
/*
|
||||
* Call handlers for signals delivered to the process during sigsuspend().
|
||||
* The SIGALRM handler is called before any other handlers to ensure that
|
||||
* OS time is always correct.
|
||||
*/
|
||||
if (sigismember(&suspsigs, SIGALRM)) {
|
||||
sim_tick();
|
||||
}
|
||||
for (i = 0; i < NUMSIGS; i++) {
|
||||
sig = signals[i].num;
|
||||
handler = signals[i].handler;
|
||||
if (sig != SIGALRM && sigismember(&suspsigs, sig)) {
|
||||
handler(sig);
|
||||
}
|
||||
}
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Enable the periodic timer interrupt.
|
||||
*/
|
||||
it.it_value.tv_sec = 0;
|
||||
it.it_value.tv_usec = OS_USEC_PER_TICK;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = OS_USEC_PER_TICK;
|
||||
rc = setitimer(ITIMER_REAL, &it, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sim_signals_init(void)
|
||||
{
|
||||
int i, error;
|
||||
struct sigaction sa;
|
||||
|
||||
sigemptyset(&nosigs);
|
||||
sigemptyset(&allsigs);
|
||||
for (i = 0; i < NUMSIGS; i++) {
|
||||
sigaddset(&allsigs, signals[i].num);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMSIGS; i++) {
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = signals[i].handler;
|
||||
sa.sa_mask = allsigs;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
error = sigaction(signals[i].num, &sa, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We use SIGALRM as a proxy for 'allsigs' to check if we are inside
|
||||
* a critical section (for e.g. see sim_in_critical()). Make sure
|
||||
* that SIGALRM is indeed present in 'allsigs'.
|
||||
*/
|
||||
// assert(sigismember(&allsigs, SIGALRM));
|
||||
}
|
||||
|
||||
void
|
||||
sim_signals_cleanup(void)
|
||||
{
|
||||
int i, error;
|
||||
struct sigaction sa;
|
||||
|
||||
for (i = 0; i < NUMSIGS; i++) {
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
error = sigaction(signals[i].num, &sa, NULL);
|
||||
assert(error == 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MYNEWT_VAL(MCU_NATIVE_USE_SIGNALS) */
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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 "nrf.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Weak symbol reference. */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
/**************************************************************************************************
|
||||
Functions
|
||||
**************************************************************************************************/
|
||||
|
||||
extern void SystemInit(void);
|
||||
static void SystemDefaultHandler(void);
|
||||
|
||||
/* Core vectors. */
|
||||
void WEAK Reset_Handler(void);
|
||||
void WEAK NMI_Handler(void);
|
||||
void WEAK HardFault_Handler(void);
|
||||
void WEAK MemoryManagement_Handler(void);
|
||||
void WEAK BusFault_Handler(void);
|
||||
void WEAK UsageFault_Handler(void);
|
||||
void WEAK SVC_Handler(void);
|
||||
void WEAK DebugMon_Handler(void);
|
||||
void WEAK PendSV_Handler(void);
|
||||
void WEAK SysTick_Handler(void);
|
||||
void WEAK POWER_CLOCK_IRQHandler(void);
|
||||
void WEAK RADIO_IRQHandler(void);
|
||||
void WEAK UARTE0_UART0_IRQHandler(void);
|
||||
void WEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void);
|
||||
void WEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void);
|
||||
void WEAK NFCT_IRQHandler(void);
|
||||
void WEAK GPIOTE_IRQHandler(void);
|
||||
void WEAK SAADC_IRQHandler(void);
|
||||
void WEAK TIMER0_IRQHandler(void);
|
||||
void WEAK TIMER1_IRQHandler(void);
|
||||
void WEAK TIMER2_IRQHandler(void);
|
||||
void WEAK RTC0_IRQHandler(void);
|
||||
void WEAK TEMP_IRQHandler(void);
|
||||
void WEAK RNG_IRQHandler(void);
|
||||
void WEAK ECB_IRQHandler(void);
|
||||
void WEAK CCM_AAR_IRQHandler(void);
|
||||
void WEAK WDT_IRQHandler(void);
|
||||
void WEAK RTC1_IRQHandler(void);
|
||||
void WEAK QDEC_IRQHandler(void);
|
||||
void WEAK COMP_LPCOMP_IRQHandler(void);
|
||||
void WEAK SWI0_EGU0_IRQHandler(void);
|
||||
void WEAK SWI1_EGU1_IRQHandler(void);
|
||||
void WEAK SWI2_EGU2_IRQHandler(void);
|
||||
void WEAK SWI3_EGU3_IRQHandler(void);
|
||||
void WEAK SWI4_EGU4_IRQHandler(void);
|
||||
void WEAK SWI5_EGU5_IRQHandler(void);
|
||||
void WEAK TIMER3_IRQHandler(void);
|
||||
void WEAK TIMER4_IRQHandler(void);
|
||||
void WEAK PWM0_IRQHandler(void);
|
||||
void WEAK PDM_IRQHandler(void);
|
||||
void WEAK MWU_IRQHandler(void);
|
||||
void WEAK PWM1_IRQHandler(void);
|
||||
void WEAK PWM2_IRQHandler(void);
|
||||
void WEAK SPIM2_SPIS2_SPI2_IRQHandler(void);
|
||||
void WEAK RTC2_IRQHandler(void);
|
||||
void WEAK I2S_IRQHandler(void);
|
||||
void WEAK FPU_IRQHandler(void);
|
||||
|
||||
/* Assign default weak references. Override these values by defining a new function with the same name. */
|
||||
#pragma weak NMI_Handler = SystemDefaultHandler
|
||||
#pragma weak HardFault_Handler = SystemDefaultHandler
|
||||
#pragma weak MemoryManagement_Handler = SystemDefaultHandler
|
||||
#pragma weak BusFault_Handler = SystemDefaultHandler
|
||||
#pragma weak UsageFault_Handler = SystemDefaultHandler
|
||||
#pragma weak SVC_Handler = SystemDefaultHandler
|
||||
#pragma weak DebugMon_Handler = SystemDefaultHandler
|
||||
#pragma weak PendSV_Handler = SystemDefaultHandler
|
||||
#pragma weak SysTick_Handler = SystemDefaultHandler
|
||||
#pragma weak POWER_CLOCK_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak RADIO_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak UARTE0_UART0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak NFCT_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak GPIOTE_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SAADC_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TIMER0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TIMER1_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TIMER2_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak RTC0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TEMP_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak RNG_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak ECB_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak CCM_AAR_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak WDT_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak RTC1_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak QDEC_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak COMP_LPCOMP_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI0_EGU0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI1_EGU1_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI2_EGU2_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI3_EGU3_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI4_EGU4_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SWI5_EGU5_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TIMER3_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak TIMER4_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak PWM0_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak PDM_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak MWU_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak PWM1_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak PWM2_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak SPIM2_SPIS2_SPI2_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak RTC2_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak I2S_IRQHandler = SystemDefaultHandler
|
||||
#pragma weak FPU_IRQHandler = SystemDefaultHandler
|
||||
|
||||
/**************************************************************************************************
|
||||
Global variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Core vector table */
|
||||
void (* systemVectors[256])(void) =
|
||||
{
|
||||
0, /* 0: The initial stack pointer */
|
||||
Reset_Handler, /* 1: The reset handler */
|
||||
NMI_Handler, /* 2: The NMI handler */
|
||||
HardFault_Handler, /* 3: The hard fault handler */
|
||||
MemoryManagement_Handler, /* 4: The MPU fault handler */
|
||||
BusFault_Handler, /* 5: The bus fault handler */
|
||||
UsageFault_Handler, /* 6: The usage fault handler */
|
||||
0, /* 7: Reserved */
|
||||
0, /* 8: Reserved */
|
||||
0, /* 9: Reserved */
|
||||
0, /* 10: Reserved */
|
||||
SVC_Handler, /* 11: SVCall handler */
|
||||
DebugMon_Handler, /* 12: Debug monitor handler */
|
||||
0, /* 13: Reserved */
|
||||
PendSV_Handler, /* 14: The PendSV handler */
|
||||
SysTick_Handler, /* 15: The SysTick handler */
|
||||
|
||||
/* External interrupts */
|
||||
POWER_CLOCK_IRQHandler, /* 16: POWER_CLOCK */
|
||||
RADIO_IRQHandler, /* 17: RADIO */
|
||||
UARTE0_UART0_IRQHandler, /* 18: UART0 */
|
||||
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler, /* 19: SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 */
|
||||
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler, /* 20: SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 */
|
||||
NFCT_IRQHandler, /* 21: NFCT */
|
||||
GPIOTE_IRQHandler, /* 22: GPIOTE */
|
||||
SAADC_IRQHandler, /* 23: SAADC */
|
||||
TIMER0_IRQHandler, /* 24: TIMER0 */
|
||||
TIMER1_IRQHandler, /* 25: TIMER1 */
|
||||
TIMER2_IRQHandler, /* 26: TIMER2 */
|
||||
RTC0_IRQHandler, /* 27: RTC0 */
|
||||
TEMP_IRQHandler, /* 28: TEMP */
|
||||
RNG_IRQHandler, /* 29: RNG */
|
||||
ECB_IRQHandler, /* 30: ECB */
|
||||
CCM_AAR_IRQHandler, /* 31: CCM_AAR */
|
||||
WDT_IRQHandler, /* 32: WDT */
|
||||
RTC1_IRQHandler, /* 33: RTC1 */
|
||||
QDEC_IRQHandler, /* 34: QDEC */
|
||||
COMP_LPCOMP_IRQHandler, /* 35: COMP_LPCOMP */
|
||||
SWI0_EGU0_IRQHandler, /* 36: SWI0_EGU0 */
|
||||
SWI1_EGU1_IRQHandler, /* 37: SWI1_EGU1 */
|
||||
SWI2_EGU2_IRQHandler, /* 38: SWI2_EGU2 */
|
||||
SWI3_EGU3_IRQHandler, /* 39: SWI3_EGU3 */
|
||||
SWI4_EGU4_IRQHandler, /* 40: SWI4_EGU4 */
|
||||
SWI5_EGU5_IRQHandler, /* 41: SWI5_EGU5 */
|
||||
TIMER3_IRQHandler, /* 42: TIMER3 */
|
||||
TIMER4_IRQHandler, /* 43: TIMER4 */
|
||||
PWM0_IRQHandler, /* 44: PWM0 */
|
||||
PDM_IRQHandler, /* 45: PDM */
|
||||
0, /* 46: Reserved */
|
||||
0, /* 47: Reserved */
|
||||
MWU_IRQHandler, /* 48: MWU */
|
||||
PWM1_IRQHandler, /* 49: PWM1 */
|
||||
PWM2_IRQHandler, /* 50: PWM2 */
|
||||
SPIM2_SPIS2_SPI2_IRQHandler, /* 51: SPIM2_SPIS2_SPI2 */
|
||||
RTC2_IRQHandler, /* 52: RTC2 */
|
||||
I2S_IRQHandler, /* 53: I2S */
|
||||
FPU_IRQHandler, /* 54: FPU */
|
||||
0, /* 55: Reserved */
|
||||
0, /* 56: Reserved */
|
||||
0, /* 57: Reserved */
|
||||
0, /* 58: Reserved */
|
||||
0, /* 59: Reserved */
|
||||
0, /* 60: Reserved */
|
||||
0, /* 61: Reserved */
|
||||
0, /* 62: Reserved */
|
||||
0 /* 63: Reserved */
|
||||
/* 64..127: Reserved */
|
||||
};
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Reset handler.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void Reset_Handler(void)
|
||||
{
|
||||
/* Core initialization. */
|
||||
SystemInit();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Default vector handler.
|
||||
*
|
||||
* \param None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void SystemDefaultHandler(void)
|
||||
{
|
||||
volatile unsigned int forever = 1;
|
||||
while (forever);
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include "os/mynewt.h"
|
||||
#include "nrfx.h"
|
||||
#include "flash_map/flash_map.h"
|
||||
#include "hal/hal_bsp.h"
|
||||
#include "hal/hal_flash.h"
|
||||
#include "hal/hal_system.h"
|
||||
#include "mcu/nrf52_hal.h"
|
||||
#include "mcu/nrf52_periph.h"
|
||||
#include "bsp/bsp.h"
|
||||
#include "defs/sections.h"
|
||||
#include "uart_hal/uart_hal.h"
|
||||
#include "uart/uart.h"
|
||||
#if MYNEWT_VAL(ENC_FLASH_DEV)
|
||||
#include <ef_nrf5x/ef_nrf5x.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* What memory to include in coredump.
|
||||
*/
|
||||
static const struct hal_bsp_mem_dump dump_cfg[] = {
|
||||
[0] = {
|
||||
.hbmd_start = &_ram_start,
|
||||
.hbmd_size = RAM_SIZE
|
||||
}
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(ENC_FLASH_DEV)
|
||||
static sec_data_secret struct eflash_nrf5x_dev enc_flash_dev0 = {
|
||||
.end_dev = {
|
||||
.efd_hal = {
|
||||
.hf_itf = &enc_flash_funcs,
|
||||
},
|
||||
.efd_hwdev = &nrf52k_flash_dev
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
const struct hal_flash *
|
||||
hal_bsp_flash_dev(uint8_t id)
|
||||
{
|
||||
// /*
|
||||
// * Internal flash mapped to id 0.
|
||||
// */
|
||||
// if (id == 0) {
|
||||
// return &nrf52k_flash_dev;
|
||||
// }
|
||||
//#if MYNEWT_VAL(ENC_FLASH_DEV)
|
||||
// if (id == 1) {
|
||||
// return &enc_flash_dev0.end_dev.efd_hal;
|
||||
// }
|
||||
//#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct hal_bsp_mem_dump *
|
||||
hal_bsp_core_dump(int *area_cnt)
|
||||
{
|
||||
*area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]);
|
||||
return dump_cfg;
|
||||
}
|
||||
|
||||
int
|
||||
hal_bsp_power_state(int state)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured priority for the given interrupt. If no priority
|
||||
* configured, return the priority passed in
|
||||
*
|
||||
* @param irq_num
|
||||
* @param pri
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
uint32_t
|
||||
hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
|
||||
{
|
||||
uint32_t cfg_pri;
|
||||
|
||||
switch (irq_num) {
|
||||
/* Radio gets highest priority */
|
||||
case RADIO_IRQn:
|
||||
cfg_pri = 0;
|
||||
break;
|
||||
default:
|
||||
cfg_pri = pri;
|
||||
}
|
||||
return cfg_pri;
|
||||
}
|
||||
|
||||
static void
|
||||
nrf52_periph_create_timers(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
(void)rc;
|
||||
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
rc = hal_timer_init(0, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
rc = hal_timer_init(1, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
rc = hal_timer_init(2, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
rc = hal_timer_init(3, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
rc = hal_timer_init(4, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
rc = hal_timer_init(5, NULL);
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) >= 0
|
||||
rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
|
||||
assert(rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct uart_dev os_bsp_uart0;
|
||||
|
||||
void
|
||||
hal_bsp_init(void)
|
||||
{
|
||||
/* Make sure system clocks have started */
|
||||
hal_system_clock_start();
|
||||
|
||||
/* Create all available nRF52840 peripherals */
|
||||
// nrf52_periph_create();
|
||||
nrf52_periph_create_timers();
|
||||
|
||||
int rc;
|
||||
|
||||
rc = os_dev_create((struct os_dev *) &os_bsp_uart0, "uart0",
|
||||
OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *) NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void
|
||||
hal_bsp_deinit(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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_bsp.h>
|
||||
|
||||
/* put these in the data section so they are not cleared by _start */
|
||||
static char *sbrkBase __attribute__ ((section (".data")));
|
||||
static char *sbrkLimit __attribute__ ((section (".data")));
|
||||
static char *brk __attribute__ ((section (".data")));
|
||||
|
||||
void
|
||||
_sbrkInit(char *base, char *limit) {
|
||||
sbrkBase = base;
|
||||
sbrkLimit = limit;
|
||||
brk = base;
|
||||
}
|
||||
|
||||
void *
|
||||
_sbrk(int incr)
|
||||
{
|
||||
void *prev_brk;
|
||||
|
||||
if (incr < 0) {
|
||||
/* Returning memory to the heap. */
|
||||
incr = -incr;
|
||||
if (brk - incr < sbrkBase) {
|
||||
prev_brk = (void *)-1;
|
||||
} else {
|
||||
prev_brk = brk;
|
||||
brk -= incr;
|
||||
}
|
||||
} else {
|
||||
/* Allocating memory from the heap. */
|
||||
if (sbrkLimit - brk >= incr) {
|
||||
prev_brk = brk;
|
||||
brk += incr;
|
||||
} else {
|
||||
prev_brk = (void *)-1;
|
||||
}
|
||||
}
|
||||
|
||||
return prev_brk;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
syscfg.defs:
|
||||
BSP_NRF52:
|
||||
description: 'Set to indicate that BSP has NRF52'
|
||||
value: 1
|
||||
SOFT_PWM:
|
||||
description: 'Enable soft PWM'
|
||||
value: 0
|
||||
ENC_FLASH_DEV:
|
||||
description: 'Encrypting flash driver over interal flash for testing'
|
||||
value: 0
|
||||
UARTBB_0:
|
||||
description: 'Enable bit-banger UART 0'
|
||||
value: 0
|
||||
RAM_RESIDENT:
|
||||
description: 'Compile app to be loaded to RAM'
|
||||
value: 0
|
||||
|
||||
syscfg.vals:
|
||||
OS_MAIN_STACK_SIZE: 8000
|
||||
BLE_HCI_TRANSPORT: uart
|
||||
MCU_TIMER_POLLER_PRIO: 0
|
||||
BLE_LL_PRIO: 1
|
||||
MCU_UART_POLLER_PRIO: 2
|
||||
|
||||
# Enable nRF52832 MCU
|
||||
MCU_TARGET: nRF52832
|
||||
# Set default pins for peripherals
|
||||
UART_0_PIN_TX: 6
|
||||
UART_0_PIN_RX: 8
|
||||
UART_0_PIN_RTS: 5
|
||||
UART_0_PIN_CTS: 7
|
||||
SPI_0_MASTER_PIN_SCK: 23
|
||||
SPI_0_MASTER_PIN_MOSI: 24
|
||||
SPI_0_MASTER_PIN_MISO: 25
|
||||
SPI_0_SLAVE_PIN_SCK: 23
|
||||
SPI_0_SLAVE_PIN_MOSI: 24
|
||||
SPI_0_SLAVE_PIN_MISO: 25
|
||||
SPI_0_SLAVE_PIN_SS: 22
|
||||
I2C_0_PIN_SCL: 27
|
||||
I2C_0_PIN_SDA: 26
|
||||
|
||||
CONFIG_FCB_FLASH_AREA: FLASH_AREA_NFFS
|
||||
REBOOT_LOG_FLASH_AREA: FLASH_AREA_REBOOT_LOG
|
||||
NFFS_FLASH_AREA: FLASH_AREA_NFFS
|
||||
COREDUMP_FLASH_AREA: FLASH_AREA_IMAGE_1
|
||||
MCU_DCDC_ENABLED: 1
|
||||
MCU_LFCLK_SOURCE: LFXO
|
||||
BOOT_SERIAL_DETECT_PIN: 13 # Button 1
|
||||
|
||||
syscfg.vals.BLE_CONTROLLER:
|
||||
TIMER_0: 0
|
||||
TIMER_5: 1
|
||||
OS_CPUTIME_FREQ: 32768
|
||||
OS_CPUTIME_TIMER_NUM: 5
|
||||
BLE_LL_RFMGMT_ENABLE_TIME: 1500
|
||||
@@ -0,0 +1,28 @@
|
||||
/* 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>
|
||||
#include "nrf.h"
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 38) // CORE + MCU Peripherals
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 __MCU_CORTEX_M4_H__
|
||||
#define __MCU_CORTEX_M4_H__
|
||||
|
||||
#include "nrf.h"
|
||||
#include <syscfg/syscfg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_CORTEX_M4_H__ */
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 __MCU_MCU_H_
|
||||
#define __MCU_MCU_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Defines for naming GPIOs. NOTE: the nordic chip docs use numeric labels for
|
||||
* ports. Port A corresponds to Port 0, B to 1, etc. The nrf52832 has only one
|
||||
* port and thus uses pins 0 - 31. The nrf52840 has two ports but Port 1 only
|
||||
* has 16 pins.
|
||||
*/
|
||||
#define MCU_GPIO_PORTA(pin) ((0 * 16) + (pin))
|
||||
#define MCU_GPIO_PORTB(pin) ((1 * 16) + (pin))
|
||||
|
||||
#if NRF52
|
||||
|
||||
#define MCU_SYSVIEW_INTERRUPTS \
|
||||
"I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \
|
||||
"I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \
|
||||
"I#16=POWER_CLOCK,I#17=RADIO,I#18=UARTE0_UART0,I#19=SPIx0_TWIx0," \
|
||||
"I#20=SPIx1_TWIx1,I#21=NFCT,I#22=GPIOTE,I#23=SAADC," \
|
||||
"I#24=TIMER0,I#25=TIMER1,I#26=TIMER2,I#27=RTC0,I#28=TEMP,I#29=RNG,I#30=ECB," \
|
||||
"I#31=CCM_AAR,I#32=WDT,I#33=RTC1,I#34=QDEC,I#35=COMP_LPCOMP,I#36=SWI0_EGU0," \
|
||||
"I#37=SWI1_EGU1,I#38=SWI2_EGU2,I#39=SWI3_EGU3,I#40=SWI4_EGU4,I#41=SWI5_EGU5," \
|
||||
"I#42=TIMER3,I#43=TIMER4,I#44=PWM0,I#45=PDM,I#48=MWU,I#49=PWM1,I#50=PWM2," \
|
||||
"I#51=SPIx2,I#52=RTC2,I#53=I2S,I#54=FPU"
|
||||
|
||||
#elif NRF52840_XXAA
|
||||
|
||||
#define MCU_SYSVIEW_INTERRUPTS \
|
||||
"I#1=Reset,I#2=MNI,I#3=HardFault,I#4=MemoryMgmt,I#5=BusFault,I#6=UsageFault," \
|
||||
"I#11=SVCall,I#12=DebugMonitor,I#14=PendSV,I#15=SysTick," \
|
||||
"I#16=POWER_CLOCK,I#17=RADIO,I#18=UARTE0_UART0,I#19=SPIx0_TWIx0," \
|
||||
"I#20=SPIx1_TWIx1,I#21=NFCT,I#22=GPIOTE,I#23=SAADC," \
|
||||
"I#24=TIMER0,I#25=TIMER1,I#26=TIMER2,I#27=RTC0,I#28=TEMP,I#29=RNG,I#30=ECB," \
|
||||
"I#31=CCM_AAR,I#32=WDT,I#33=RTC1,I#34=QDEC,I#35=COMP_LPCOMP,I#36=SWI0_EGU0," \
|
||||
"I#37=SWI1_EGU1,I#38=SWI2_EGU2,I#39=SWI3_EGU3,I#40=SWI4_EGU4,I#41=SWI5_EGU5," \
|
||||
"I#42=TIMER3,I#43=TIMER4,I#44=PWM0,I#45=PDM,I#48=MWU,I#49=PWM1,I#50=PWM2," \
|
||||
"I#51=SPIx2,I#52=RTC2,I#53=I2S,I#54=FPU,I#55=USBD," \
|
||||
"I#56=UARTE1,I#57=QSPI,I#58=CRYPTOCELL,I#61=PWM3,I#63=SPIM3"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_MCU_H_ */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 __MCU_SIM_H__
|
||||
#define __MCU_SIM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *native_flash_file;
|
||||
extern char *native_uart_log_file;
|
||||
extern const char *native_uart_dev_strs[];
|
||||
|
||||
void mcu_sim_parse_args(int argc, char **argv);
|
||||
|
||||
void static inline hal_debug_break(void) {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MCU_SIM_H__ */
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#ifndef H_NRF52_CLOCK_
|
||||
#define H_NRF52_CLOCK_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Request HFXO clock be turned on. Note that each request must have a
|
||||
* corresponding release.
|
||||
*
|
||||
* @return int 0: hfxo was already on. 1: hfxo was turned on.
|
||||
*/
|
||||
int nrf52_clock_hfxo_request(void);
|
||||
|
||||
/**
|
||||
* Release the HFXO; caller no longer needs the HFXO to be turned on. Each call
|
||||
* to release should have been preceeded by a corresponding call to request the
|
||||
* HFXO
|
||||
*
|
||||
*
|
||||
* @return int 0: HFXO not stopped by this call (others using it) 1: HFXO
|
||||
* stopped.
|
||||
*/
|
||||
int nrf52_clock_hfxo_release(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_NRF52_CLOCK_ */
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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_NRF52_HAL_
|
||||
#define H_NRF52_HAL_
|
||||
|
||||
#include "cmsis.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Helper functions to enable/disable interrupts. */
|
||||
#define __HAL_DISABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
x = __get_PRIMASK(); \
|
||||
__disable_irq(); \
|
||||
} while(0);
|
||||
|
||||
#define __HAL_ENABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
if (!x) { \
|
||||
__enable_irq(); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
struct nrf52_uart_cfg {
|
||||
int8_t suc_pin_tx; /* pins for IO */
|
||||
int8_t suc_pin_rx;
|
||||
int8_t suc_pin_rts;
|
||||
int8_t suc_pin_cts;
|
||||
};
|
||||
const struct nrf52_uart_cfg *bsp_uart_config(void);
|
||||
|
||||
struct nrf52_hal_i2c_cfg {
|
||||
int scl_pin;
|
||||
int sda_pin;
|
||||
uint32_t i2c_frequency;
|
||||
};
|
||||
struct hal_flash;
|
||||
extern const struct hal_flash nrf52k_flash_dev;
|
||||
extern const struct hal_flash nrf52k_qspi_dev;
|
||||
|
||||
/* SPI configuration (used for both master and slave) */
|
||||
struct nrf52_hal_spi_cfg {
|
||||
uint8_t sck_pin;
|
||||
uint8_t mosi_pin;
|
||||
uint8_t miso_pin;
|
||||
uint8_t ss_pin;
|
||||
};
|
||||
|
||||
/*
|
||||
* GPIO pin mapping
|
||||
*
|
||||
* The logical GPIO pin numbers (0 to N) are mapped to ports in the following
|
||||
* manner:
|
||||
* pins 0 - 31: Port 0
|
||||
* pins 32 - 48: Port 1.
|
||||
*
|
||||
* The nrf52832 has only one port with 32 pins. The nrf52840 has 48 pins and
|
||||
* uses two ports.
|
||||
*
|
||||
* NOTE: in order to save code space, there is no checking done to see if the
|
||||
* user specifies a pin that is not used by the processor. If an invalid pin
|
||||
* number is used unexpected and/or erroneous behavior will result.
|
||||
*/
|
||||
#if defined(NRF52832_XXAA) || defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
|
||||
#define HAL_GPIO_INDEX(pin) (pin)
|
||||
#define HAL_GPIO_PORT(pin) (NRF_P0)
|
||||
#define HAL_GPIO_MASK(pin) (1 << pin)
|
||||
#define HAL_GPIOTE_PIN_MASK GPIOTE_CONFIG_PSEL_Msk
|
||||
#endif
|
||||
|
||||
#ifdef NRF52840_XXAA
|
||||
#define HAL_GPIO_INDEX(pin) ((pin) & 0x1F)
|
||||
#define HAL_GPIO_PORT(pin) ((pin) > 31 ? NRF_P1 : NRF_P0)
|
||||
#define HAL_GPIO_MASK(pin) (1 << HAL_GPIO_INDEX(pin))
|
||||
#define HAL_GPIOTE_PIN_MASK (0x3FUL << GPIOTE_CONFIG_PSEL_Pos)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_NRF52_HAL_ */
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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_NRF52_PERIPH_
|
||||
#define H_NRF52_PERIPH_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void nrf52_periph_create(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_NRF52_PERIPH_ */
|
||||
@@ -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: babblesim/hw/mcu/nordic/nrf52_bsim
|
||||
pkg.description: nRF52 on BabbleSim
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
|
||||
pkg.deps:
|
||||
- "babblesim/nrfx"
|
||||
|
||||
pkg.deps.BLE_CONTROLLER:
|
||||
- "@apache-mynewt-nimble/nimble/drivers/nrf52"
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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 "os/mynewt.h"
|
||||
#include "hal/hal_os_tick.h"
|
||||
#include "nrf.h"
|
||||
#include "mcu/cmsis_nvic.h"
|
||||
#include "mcu/mcu_sim.h"
|
||||
#include <time_machine.h>
|
||||
#include <NRF_HWLowL.h>
|
||||
#include <NRF_HW_model_top.h>
|
||||
#include <NRF_RTC.h>
|
||||
#include <hal/nrf_rtc.h>
|
||||
|
||||
/* The OS scheduler requires a low-frequency timer. */
|
||||
#if MYNEWT_VAL(OS_SCHEDULING) && !MYNEWT_VAL(MCU_LFCLK_SOURCE)
|
||||
#error The OS scheduler requires a low-frequency timer; configure MCU_LFCLK_SOURCE
|
||||
#endif
|
||||
|
||||
#define RTC_FREQ 32768 /* in Hz */
|
||||
#define OS_TICK_TIMER NRF_RTC1
|
||||
#define OS_TICK_IRQ RTC1_IRQn
|
||||
#define OS_TICK_CMPREG 3 /* generate timer interrupt */
|
||||
#define RTC_COMPARE_INT_MASK(ccreg) (1UL << ((ccreg) + 16))
|
||||
|
||||
struct hal_os_tick
|
||||
{
|
||||
int ticks_per_ostick;
|
||||
os_time_t max_idle_ticks;
|
||||
uint32_t lastocmp;
|
||||
};
|
||||
|
||||
struct hal_os_tick g_hal_os_tick;
|
||||
|
||||
/*
|
||||
* Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* sub24(0, 0xffffff) = 1
|
||||
* sub24(0xffffff, 0xfffffe) = 1
|
||||
* sub24(0xffffff, 0) = -1
|
||||
* sub24(0x7fffff, 0) = 8388607
|
||||
* sub24(0x800000, 0) = -8388608
|
||||
*/
|
||||
static inline int
|
||||
sub24(uint32_t x, uint32_t y)
|
||||
{
|
||||
int result;
|
||||
|
||||
assert(x <= 0xffffff);
|
||||
assert(y <= 0xffffff);
|
||||
|
||||
result = x - y;
|
||||
if (result & 0x800000) {
|
||||
return (result | 0xff800000);
|
||||
} else {
|
||||
return (result & 0x007fffff);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
nrf52_os_tick_counter(void)
|
||||
{
|
||||
return nrf_rtc_counter_get(OS_TICK_TIMER);
|
||||
}
|
||||
|
||||
static inline void
|
||||
nrf52_os_tick_set_ocmp(uint32_t ocmp)
|
||||
{
|
||||
int delta;
|
||||
uint32_t counter;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
while (1) {
|
||||
ocmp &= 0xffffff;
|
||||
nrf_rtc_cc_set(OS_TICK_TIMER, OS_TICK_CMPREG, ocmp);
|
||||
counter = nrf52_os_tick_counter();
|
||||
/*
|
||||
* From nRF52 Product specification
|
||||
*
|
||||
* - If Counter is 'N' writing (N) or (N + 1) to CC register
|
||||
* may not trigger a compare event.
|
||||
*
|
||||
* - If Counter is 'N' writing (N + 2) to CC register is guaranteed
|
||||
* to trigger a compare event at 'N + 2'.
|
||||
*/
|
||||
delta = sub24(ocmp, counter);
|
||||
if (delta > 2) {
|
||||
break;
|
||||
}
|
||||
ocmp += g_hal_os_tick.ticks_per_ostick;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nrf52_timer_handler(void)
|
||||
{
|
||||
int delta;
|
||||
int ticks;
|
||||
os_sr_t sr;
|
||||
uint32_t counter;
|
||||
|
||||
os_trace_isr_enter();
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Calculate elapsed ticks and advance OS time. */
|
||||
|
||||
counter = nrf52_os_tick_counter();
|
||||
delta = sub24(counter, g_hal_os_tick.lastocmp);
|
||||
ticks = delta / g_hal_os_tick.ticks_per_ostick;
|
||||
os_time_advance(ticks);
|
||||
|
||||
/* Clear timer interrupt */
|
||||
OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0;
|
||||
|
||||
/* Update the time associated with the most recent tick */
|
||||
g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp +
|
||||
(ticks * g_hal_os_tick.ticks_per_ostick)) & 0xffffff;
|
||||
|
||||
/* Update the output compare to interrupt at the next tick */
|
||||
nrf52_os_tick_set_ocmp(g_hal_os_tick.lastocmp + g_hal_os_tick.ticks_per_ostick);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
os_trace_isr_exit();
|
||||
}
|
||||
|
||||
/* Wait For Interrupt */
|
||||
void
|
||||
__WFI(void)
|
||||
{
|
||||
while (hw_irq_ctrl_get_irq_status() == 0) {
|
||||
tm_tick();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
os_tick_idle(os_time_t ticks)
|
||||
{
|
||||
uint32_t ocmp;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Enter tickless regime during long idle durations.
|
||||
*/
|
||||
if (ticks > g_hal_os_tick.max_idle_ticks) {
|
||||
ticks = g_hal_os_tick.max_idle_ticks;
|
||||
}
|
||||
ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick);
|
||||
nrf52_os_tick_set_ocmp(ocmp);
|
||||
}
|
||||
|
||||
__WFI();
|
||||
|
||||
if (ticks > 0) {
|
||||
/*
|
||||
* Update OS time before anything else when coming out of
|
||||
* the tickless regime.
|
||||
*/
|
||||
nrf52_timer_handler();
|
||||
}
|
||||
}
|
||||
|
||||
extern void nrf_rtc_regw_sideeffects(int i);
|
||||
|
||||
void
|
||||
os_tick_init(uint32_t os_ticks_per_sec, int prio)
|
||||
{
|
||||
uint32_t sr;
|
||||
|
||||
assert(RTC_FREQ % os_ticks_per_sec == 0);
|
||||
|
||||
g_hal_os_tick.lastocmp = 0;
|
||||
g_hal_os_tick.ticks_per_ostick = RTC_FREQ / os_ticks_per_sec;
|
||||
|
||||
/*
|
||||
* The maximum number of OS ticks allowed to elapse during idle is
|
||||
* limited to 1/4th the number of timer ticks before the 24-bit counter
|
||||
* rolls over.
|
||||
*/
|
||||
g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick;
|
||||
|
||||
/* disable interrupts */
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Set isr in vector table and enable interrupt */
|
||||
NVIC_SetPriority(OS_TICK_IRQ, prio);
|
||||
NVIC_SetVector(OS_TICK_IRQ, (uint32_t)nrf52_timer_handler);
|
||||
NVIC_EnableIRQ(OS_TICK_IRQ);
|
||||
|
||||
/*
|
||||
* Program the OS_TICK_TIMER to operate at 32KHz and trigger an output
|
||||
* compare interrupt at a rate of 'os_ticks_per_sec'.
|
||||
*/
|
||||
nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_STOP);
|
||||
nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_CLEAR);
|
||||
nrf_rtc_event_disable(OS_TICK_TIMER, 0xffffffff);
|
||||
nrf_rtc_int_disable(OS_TICK_TIMER, 0xffffffff);
|
||||
nrf_rtc_int_enable(OS_TICK_TIMER, RTC_COMPARE_INT_MASK(OS_TICK_CMPREG));
|
||||
|
||||
OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0;
|
||||
nrf_rtc_cc_set(OS_TICK_TIMER, OS_TICK_CMPREG, g_hal_os_tick.ticks_per_ostick);
|
||||
|
||||
nrf_rtc_task_trigger(OS_TICK_TIMER, NRF_RTC_TASK_START);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 <nrf.h>
|
||||
#include "hal/hal_system.h"
|
||||
|
||||
enum hal_reset_reason
|
||||
hal_reset_cause(void)
|
||||
{
|
||||
static enum hal_reset_reason reason;
|
||||
uint32_t reg;
|
||||
|
||||
if (reason) {
|
||||
return reason;
|
||||
}
|
||||
reg = NRF_POWER->RESETREAS;
|
||||
|
||||
if (reg & (POWER_RESETREAS_DOG_Msk | POWER_RESETREAS_LOCKUP_Msk)) {
|
||||
reason = HAL_RESET_WATCHDOG;
|
||||
} else if (reg & POWER_RESETREAS_SREQ_Msk) {
|
||||
reason = HAL_RESET_SOFT;
|
||||
} else if (reg & POWER_RESETREAS_RESETPIN_Msk) {
|
||||
reason = HAL_RESET_PIN;
|
||||
} else if (reg & POWER_RESETREAS_OFF_Msk) {
|
||||
reason = HAL_RESET_SYS_OFF_INT;
|
||||
} else {
|
||||
reason = HAL_RESET_POR; /* could also be brownout */
|
||||
}
|
||||
NRF_POWER->RESETREAS = reg;
|
||||
return reason;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 "syscfg/syscfg.h"
|
||||
#include "hal/hal_system.h"
|
||||
#include "hal/hal_debug.h"
|
||||
#include "nrf.h"
|
||||
#include "cmsis.h"
|
||||
#include "mcu/mcu_sim.h"
|
||||
#include "hal/nrf_clock.h"
|
||||
|
||||
/**
|
||||
* Function called at startup. Called after BSS and .data initialized but
|
||||
* prior to the _start function.
|
||||
*
|
||||
* NOTE: this function is called by both the bootloader and the application.
|
||||
* If you add code here that you do not want executed in either case you need
|
||||
* to conditionally compile it using the config variable BOOT_LOADER (will
|
||||
* be set to 1 in case of bootloader build)
|
||||
*
|
||||
*/
|
||||
void
|
||||
hal_system_init(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_DCDC_ENABLED)
|
||||
NRF_POWER->DCDCEN = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
hal_system_reset(void)
|
||||
{
|
||||
|
||||
#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB)
|
||||
hal_system_reset_cb();
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
HAL_DEBUG_BREAK();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
hal_debugger_connected(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal system clock start
|
||||
*
|
||||
* Makes sure the LFCLK and/or HFCLK is started.
|
||||
*/
|
||||
void
|
||||
hal_system_clock_start(void)
|
||||
{
|
||||
#if MYNEWT_VAL(MCU_LFCLK_SOURCE)
|
||||
uint32_t regmsk;
|
||||
uint32_t regval;
|
||||
uint32_t clksrc;
|
||||
|
||||
regmsk = CLOCK_LFCLKSTAT_STATE_Msk | CLOCK_LFCLKSTAT_SRC_Msk;
|
||||
regval = CLOCK_LFCLKSTAT_STATE_Running << CLOCK_LFCLKSTAT_STATE_Pos;
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFXO)
|
||||
regval |= CLOCK_LFCLKSTAT_SRC_Xtal << CLOCK_LFCLKSTAT_SRC_Pos;
|
||||
clksrc = CLOCK_LFCLKSRC_SRC_Xtal;
|
||||
#elif MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFSYNTH)
|
||||
regval |= CLOCK_LFCLKSTAT_SRC_Synth << CLOCK_LFCLKSTAT_SRC_Pos;
|
||||
clksrc = CLOCK_LFCLKSRC_SRC_Synth;
|
||||
#elif MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFRC)
|
||||
regval |= CLOCK_LFCLKSTAT_SRC_RC << CLOCK_LFCLKSTAT_SRC_Pos;
|
||||
clksrc = CLOCK_LFCLKSRC_SRC_RC;
|
||||
#else
|
||||
#error Unknown LFCLK source selected
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_LFCLK_SOURCE, LFSYNTH)
|
||||
/* Must turn on HFLCK for synthesized 32768 crystal */
|
||||
nrf52_clock_hfxo_request();
|
||||
#else
|
||||
/* Make sure HFCLK is stopped */
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
#endif
|
||||
|
||||
/* Check if this clock source is already running */
|
||||
if ((NRF_CLOCK_regs.LFCLKSTAT & regmsk) != regval) {
|
||||
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTOP);
|
||||
NRF_CLOCK_regs.EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK_regs.LFCLKSRC = clksrc;
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_LFCLKSTART);
|
||||
|
||||
/* Wait here till started! */
|
||||
// while (1) {
|
||||
// if (NRF_CLOCK_regs.EVENTS_LFCLKSTARTED) {
|
||||
// if ((NRF_CLOCK_regs.LFCLKSTAT & regmsk) == regval) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
NRF_RADIO_BASE_FUN(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,949 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <hal/nrf_rtc.h>
|
||||
#include "os/mynewt.h"
|
||||
#include "mcu/cmsis_nvic.h"
|
||||
#include "hal/hal_timer.h"
|
||||
#include "nrf.h"
|
||||
#include "mcu/nrf52_hal.h"
|
||||
#include "mcu/nrf52_clock.h"
|
||||
#include "hal/nrf_timer.h"
|
||||
|
||||
/* IRQ prototype */
|
||||
typedef void (*hal_timer_irq_handler_t)(void);
|
||||
|
||||
/* User CC 2 for reading counter, CC 3 for timer isr */
|
||||
#define NRF_TIMER_CC_READ (NRF_TIMER_CC_CHANNEL2)
|
||||
#define NRF_TIMER_CC_INT (3)
|
||||
|
||||
/* Output compare 2 used for RTC timers */
|
||||
#define NRF_RTC_TIMER_CC_INT (2)
|
||||
|
||||
/* Maximum number of hal timers used */
|
||||
#define NRF52_HAL_TIMER_MAX (6)
|
||||
|
||||
/* Maximum timer frequency */
|
||||
#define NRF52_MAX_TIMER_FREQ (16000000)
|
||||
|
||||
struct nrf52_hal_timer {
|
||||
uint8_t tmr_enabled;
|
||||
uint8_t tmr_irq_num;
|
||||
uint8_t tmr_rtc;
|
||||
uint8_t tmr_pad;
|
||||
uint32_t tmr_cntr;
|
||||
uint32_t timer_isrs;
|
||||
uint32_t tmr_freq;
|
||||
void *tmr_reg;
|
||||
TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q;
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
struct nrf52_hal_timer nrf52_hal_timer0;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
struct nrf52_hal_timer nrf52_hal_timer1;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
struct nrf52_hal_timer nrf52_hal_timer2;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
struct nrf52_hal_timer nrf52_hal_timer3;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
struct nrf52_hal_timer nrf52_hal_timer4;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
struct nrf52_hal_timer nrf52_hal_timer5;
|
||||
#endif
|
||||
|
||||
static const struct nrf52_hal_timer *nrf52_hal_timers[NRF52_HAL_TIMER_MAX] = {
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
&nrf52_hal_timer0,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
&nrf52_hal_timer1,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
&nrf52_hal_timer2,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
&nrf52_hal_timer3,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
&nrf52_hal_timer4,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
&nrf52_hal_timer5
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Resolve timer number into timer structure */
|
||||
#define NRF52_HAL_TIMER_RESOLVE(__n, __v) \
|
||||
if ((__n) >= NRF52_HAL_TIMER_MAX) { \
|
||||
rc = EINVAL; \
|
||||
goto err; \
|
||||
} \
|
||||
(__v) = (struct nrf52_hal_timer *) nrf52_hal_timers[(__n)]; \
|
||||
if ((__v) == NULL) { \
|
||||
rc = EINVAL; \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
/* Interrupt mask for interrupt enable/clear */
|
||||
#define NRF_TIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << 16)
|
||||
|
||||
static uint32_t
|
||||
nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer)
|
||||
{
|
||||
uint32_t tcntr;
|
||||
|
||||
/* Force a capture of the timer into 'cntr' capture channel; read it */
|
||||
nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_CAPTURE2);
|
||||
tcntr = hwtimer->CC[NRF_TIMER_CC_READ];
|
||||
|
||||
return tcntr;
|
||||
}
|
||||
|
||||
/**
|
||||
* nrf timer set ocmp
|
||||
*
|
||||
* Set the OCMP used by the timer to the desired expiration tick
|
||||
*
|
||||
* NOTE: Must be called with interrupts disabled.
|
||||
*
|
||||
* @param timer Pointer to timer.
|
||||
*/
|
||||
static void
|
||||
nrf_timer_set_ocmp(struct nrf52_hal_timer *bsptimer, uint32_t expiry)
|
||||
{
|
||||
int32_t delta_t;
|
||||
uint32_t temp;
|
||||
uint32_t cntr;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
if (bsptimer->tmr_rtc) {
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT));
|
||||
temp = bsptimer->tmr_cntr;
|
||||
cntr = nrf_rtc_counter_get(rtctimer);
|
||||
if (rtctimer->EVENTS_OVRFLW) {
|
||||
temp += (1UL << 24);
|
||||
cntr = nrf_rtc_counter_get(rtctimer);
|
||||
}
|
||||
temp |= cntr;
|
||||
delta_t = (int32_t)(expiry - temp);
|
||||
|
||||
/*
|
||||
* The nRF52xxx documentation states that COMPARE event is guaranteed
|
||||
* only if value written to CC register is at least 2 greater than the
|
||||
* current counter value. We also need to account for possible extra
|
||||
* tick during calculations so effectively any delta less than 3 needs
|
||||
* to be handled differently. TICK event is used to have interrupt on
|
||||
* each subsequent tick so we won't miss any and in case we detected
|
||||
* mentioned extra tick during calculations, interrupt is triggered
|
||||
* immediately. Delta 0 or less means we should always fire immediately.
|
||||
*/
|
||||
if (delta_t < 1) {
|
||||
nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk);
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
} else if (delta_t < 3 && 0) {
|
||||
nrf_rtc_int_enable(rtctimer, RTC_INTENSET_TICK_Msk);
|
||||
if (nrf_rtc_counter_get(rtctimer) != cntr) {
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
}
|
||||
} else {
|
||||
nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk);
|
||||
|
||||
if (delta_t < (1UL << 24)) {
|
||||
nrf_rtc_cc_set(rtctimer, NRF_RTC_TIMER_CC_INT, expiry & 0x00ffffff);
|
||||
} else {
|
||||
/* CC too far ahead. Just make sure we set compare far ahead */
|
||||
nrf_rtc_cc_set(rtctimer, NRF_RTC_TIMER_CC_INT, cntr + (1UL << 23));
|
||||
}
|
||||
nrf_rtc_int_enable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT));
|
||||
}
|
||||
} else {
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
|
||||
/* Disable ocmp interrupt and set new value */
|
||||
nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT));
|
||||
|
||||
/* Set output compare register to timer expiration */
|
||||
nrf_timer_cc_set(hwtimer, NRF_TIMER_CC_INT, expiry);
|
||||
|
||||
/* Clear interrupt flag */
|
||||
hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0;
|
||||
|
||||
/* Enable the output compare interrupt */
|
||||
nrf_timer_int_enable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT));
|
||||
|
||||
/* Force interrupt to occur as we may have missed it */
|
||||
if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) {
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable output compare used for timer */
|
||||
static void
|
||||
nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer)
|
||||
{
|
||||
nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT));
|
||||
}
|
||||
|
||||
static void
|
||||
nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer)
|
||||
{
|
||||
nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT));
|
||||
nrf_rtc_int_disable(rtctimer, RTC_INTENCLR_TICK_Msk);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hal_timer_read_bsptimer(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t low32;
|
||||
uint32_t ctx;
|
||||
uint32_t tcntr;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
tcntr = bsptimer->tmr_cntr;
|
||||
low32 = nrf_rtc_counter_get(rtctimer);
|
||||
if (rtctimer->EVENTS_OVRFLW) {
|
||||
tcntr += (1UL << 24);
|
||||
bsptimer->tmr_cntr = tcntr;
|
||||
low32 = nrf_rtc_counter_get(rtctimer);
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
}
|
||||
tcntr |= low32;
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return tcntr;
|
||||
}
|
||||
|
||||
#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \
|
||||
MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4) || MYNEWT_VAL(TIMER_5))
|
||||
/**
|
||||
* hal timer chk queue
|
||||
*
|
||||
*
|
||||
* @param bsptimer
|
||||
*/
|
||||
static void
|
||||
hal_timer_chk_queue(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t tcntr;
|
||||
uint32_t ctx;
|
||||
struct hal_timer *timer;
|
||||
|
||||
/* disable interrupts */
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tcntr = hal_timer_read_bsptimer(bsptimer);
|
||||
} else {
|
||||
tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg);
|
||||
}
|
||||
if ((int32_t)(tcntr - timer->expiry) >= 0) {
|
||||
TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link);
|
||||
timer->link.tqe_prev = NULL;
|
||||
timer->cb_func(timer->cb_arg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Any timers left on queue? If so, we need to set OCMP */
|
||||
timer = TAILQ_FIRST(&bsptimer->hal_timer_q);
|
||||
if (timer) {
|
||||
nrf_timer_set_ocmp(bsptimer, timer->expiry);
|
||||
} else {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg);
|
||||
} else {
|
||||
nrf_timer_disable_ocmp(bsptimer->tmr_reg);
|
||||
}
|
||||
}
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal timer irq handler
|
||||
*
|
||||
* Generic HAL timer irq handler.
|
||||
*
|
||||
* @param tmr
|
||||
*/
|
||||
/**
|
||||
* hal timer irq handler
|
||||
*
|
||||
* This is the global timer interrupt routine.
|
||||
*
|
||||
*/
|
||||
#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \
|
||||
MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4))
|
||||
|
||||
static void
|
||||
hal_timer_irq_handler(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t compare;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
|
||||
os_trace_isr_enter();
|
||||
|
||||
/* Check interrupt source. If set, clear them */
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT];
|
||||
if (compare) {
|
||||
hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0;
|
||||
}
|
||||
|
||||
/* XXX: make these stats? */
|
||||
/* Count # of timer isrs */
|
||||
++bsptimer->timer_isrs;
|
||||
|
||||
/*
|
||||
* NOTE: we dont check the 'compare' variable here due to how the timer
|
||||
* is implemented on this chip. There is no way to force an output
|
||||
* compare, so if we are late setting the output compare (i.e. the timer
|
||||
* counter is already passed the output compare value), we use the NVIC
|
||||
* to set a pending interrupt. This means that there will be no compare
|
||||
* flag set, so all we do is check to see if the compare interrupt is
|
||||
* enabled.
|
||||
*/
|
||||
if (hwtimer->INTENCLR & NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)) {
|
||||
hal_timer_chk_queue(bsptimer);
|
||||
/* XXX: Recommended by nordic to make sure interrupts are cleared */
|
||||
compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT];
|
||||
}
|
||||
|
||||
os_trace_isr_exit();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
static void
|
||||
hal_rtc_timer_irq_handler(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t overflow;
|
||||
uint32_t compare;
|
||||
uint32_t tick;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
os_trace_isr_enter();
|
||||
|
||||
/* Check interrupt source. If set, clear them */
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT];
|
||||
if (compare) {
|
||||
rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0;
|
||||
}
|
||||
|
||||
tick = rtctimer->EVENTS_TICK;
|
||||
if (tick) {
|
||||
rtctimer->EVENTS_TICK = 0;
|
||||
}
|
||||
|
||||
overflow = rtctimer->EVENTS_OVRFLW;
|
||||
if (overflow) {
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
bsptimer->tmr_cntr += (1UL << 24);
|
||||
}
|
||||
|
||||
/* Count # of timer isrs */
|
||||
++bsptimer->timer_isrs;
|
||||
|
||||
/*
|
||||
* NOTE: we dont check the 'compare' variable here due to how the timer
|
||||
* is implemented on this chip. There is no way to force an output
|
||||
* compare, so if we are late setting the output compare (i.e. the timer
|
||||
* counter is already passed the output compare value), we use the NVIC
|
||||
* to set a pending interrupt. This means that there will be no compare
|
||||
* flag set, so all we do is check to see if the compare interrupt is
|
||||
* enabled.
|
||||
*/
|
||||
hal_timer_chk_queue(bsptimer);
|
||||
|
||||
/* Recommended by nordic to make sure interrupts are cleared */
|
||||
compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT];
|
||||
|
||||
os_trace_isr_exit();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
void
|
||||
nrf52_timer0_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
void
|
||||
nrf52_timer1_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
void
|
||||
nrf52_timer2_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
void
|
||||
nrf52_timer3_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
void
|
||||
nrf52_timer4_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
void
|
||||
nrf52_timer5_irq_handler(void)
|
||||
{
|
||||
hal_rtc_timer_irq_handler(&nrf52_hal_timer5);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal timer init
|
||||
*
|
||||
* Initialize platform specific timer items
|
||||
*
|
||||
* @param timer_num Timer number to initialize
|
||||
* @param cfg Pointer to platform specific configuration
|
||||
*
|
||||
* @return int 0: success; error code otherwise
|
||||
*/
|
||||
int
|
||||
hal_timer_init(int timer_num, void *cfg)
|
||||
{
|
||||
int rc;
|
||||
uint8_t irq_num;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
void *hwtimer;
|
||||
hal_timer_irq_handler_t irq_isr;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
/* If timer is enabled do not allow init */
|
||||
if (bsptimer->tmr_enabled) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (timer_num) {
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
case 0:
|
||||
irq_num = TIMER0_IRQn;
|
||||
hwtimer = NRF_TIMER0;
|
||||
irq_isr = nrf52_timer0_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
case 1:
|
||||
irq_num = TIMER1_IRQn;
|
||||
hwtimer = NRF_TIMER1;
|
||||
irq_isr = nrf52_timer1_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
case 2:
|
||||
irq_num = TIMER2_IRQn;
|
||||
hwtimer = NRF_TIMER2;
|
||||
irq_isr = nrf52_timer2_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
case 3:
|
||||
irq_num = TIMER3_IRQn;
|
||||
hwtimer = NRF_TIMER3;
|
||||
irq_isr = nrf52_timer3_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
case 4:
|
||||
irq_num = TIMER4_IRQn;
|
||||
hwtimer = NRF_TIMER4;
|
||||
irq_isr = nrf52_timer4_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
case 5:
|
||||
irq_num = RTC0_IRQn;
|
||||
hwtimer = NRF_RTC0;
|
||||
irq_isr = nrf52_timer5_irq_handler;
|
||||
bsptimer->tmr_rtc = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
hwtimer = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hwtimer == NULL) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bsptimer->tmr_reg = hwtimer;
|
||||
bsptimer->tmr_irq_num = irq_num;
|
||||
|
||||
/* Disable IRQ, set priority and set vector in table */
|
||||
NVIC_DisableIRQ(irq_num);
|
||||
NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
NVIC_SetVector(irq_num, (uint32_t)irq_isr);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer config
|
||||
*
|
||||
* Configure a timer to run at the desired frequency. This starts the timer.
|
||||
*
|
||||
* @param timer_num
|
||||
* @param freq_hz
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_config(int timer_num, uint32_t freq_hz)
|
||||
{
|
||||
int rc;
|
||||
uint8_t prescaler;
|
||||
uint32_t ctx;
|
||||
uint32_t div;
|
||||
uint32_t min_delta;
|
||||
uint32_t max_delta;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
NRF_RTC_Type *rtctimer;
|
||||
#endif
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
if (timer_num == 5) {
|
||||
/* NOTE: we only allow the RTC frequency to be set at 32768 */
|
||||
if (bsptimer->tmr_enabled || (freq_hz != 32768) ||
|
||||
(bsptimer->tmr_reg == NULL)) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bsptimer->tmr_freq = freq_hz;
|
||||
bsptimer->tmr_enabled = 1;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
|
||||
/* Stop the timer first */
|
||||
nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_STOP);
|
||||
nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_CLEAR);
|
||||
|
||||
/* Always no prescaler */
|
||||
rtctimer->PRESCALER = 0;
|
||||
|
||||
/* Clear overflow events and set overflow interrupt */
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
nrf_rtc_int_enable(rtctimer, RTC_INTENSET_OVRFLW_Msk);
|
||||
|
||||
/* Start the timer */
|
||||
nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_START);
|
||||
/* Set isr in vector table and enable interrupt */
|
||||
NVIC_EnableIRQ(bsptimer->tmr_irq_num);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set timer to desired frequency */
|
||||
div = NRF52_MAX_TIMER_FREQ / freq_hz;
|
||||
|
||||
/*
|
||||
* Largest prescaler is 2^9 and must make sure frequency not too high.
|
||||
* If hwtimer is NULL it means that the timer was not initialized prior
|
||||
* to call.
|
||||
*/
|
||||
if (bsptimer->tmr_enabled || (div == 0) || (div > 512) ||
|
||||
(bsptimer->tmr_reg == NULL)) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (div == 1) {
|
||||
prescaler = 0;
|
||||
} else {
|
||||
/* Find closest prescaler */
|
||||
for (prescaler = 1; prescaler < 10; ++prescaler) {
|
||||
if (div <= (1 << prescaler)) {
|
||||
min_delta = div - (1 << (prescaler - 1));
|
||||
max_delta = (1 << prescaler) - div;
|
||||
if (min_delta < max_delta) {
|
||||
prescaler -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now set the actual frequency */
|
||||
bsptimer->tmr_freq = NRF52_MAX_TIMER_FREQ / (1 << prescaler);
|
||||
bsptimer->tmr_enabled = 1;
|
||||
|
||||
/* disable interrupts */
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFXO)
|
||||
/* Make sure HFXO is started */
|
||||
nrf52_clock_hfxo_request();
|
||||
#endif
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
|
||||
/* Stop the timer first */
|
||||
nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_STOP);
|
||||
nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_CLEAR);
|
||||
|
||||
/* Put the timer in timer mode using 32 bits. */
|
||||
nrf_timer_mode_set(hwtimer, NRF_TIMER_MODE_TIMER);
|
||||
hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
|
||||
|
||||
/* Set the pre-scalar */
|
||||
hwtimer->PRESCALER = prescaler;
|
||||
|
||||
/* Start the timer */
|
||||
nrf_timer_task_trigger(hwtimer, NRF_TIMER_TASK_START);
|
||||
|
||||
NVIC_EnableIRQ(bsptimer->tmr_irq_num);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer deinit
|
||||
*
|
||||
* De-initialize a HW timer.
|
||||
*
|
||||
* @param timer_num
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_deinit(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t ctx;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
rc = 0;
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
if (bsptimer->tmr_rtc) {
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
nrf_rtc_int_disable(rtctimer, NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT));
|
||||
nrf_rtc_task_trigger(rtctimer, NRF_RTC_TASK_STOP);
|
||||
} else {
|
||||
hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg;
|
||||
nrf_timer_int_disable(hwtimer, NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT));
|
||||
hwtimer->TASKS_SHUTDOWN = 1;
|
||||
}
|
||||
bsptimer->tmr_enabled = 0;
|
||||
bsptimer->tmr_reg = NULL;
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFXO)
|
||||
if (timer_num != 5) {
|
||||
nrf52_clock_hfxo_release();
|
||||
}
|
||||
#endif
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer get resolution
|
||||
*
|
||||
* Get the resolution of the timer. This is the timer period, in nanoseconds
|
||||
*
|
||||
* @param timer_num
|
||||
*
|
||||
* @return uint32_t The
|
||||
*/
|
||||
uint32_t
|
||||
hal_timer_get_resolution(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t resolution;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
resolution = 1000000000 / bsptimer->tmr_freq;
|
||||
return resolution;
|
||||
|
||||
err:
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer read
|
||||
*
|
||||
* Returns the timer counter. NOTE: if the timer is a 16-bit timer, only
|
||||
* the lower 16 bits are valid. If the timer is a 64-bit timer, only the
|
||||
* low 32-bits are returned.
|
||||
*
|
||||
* @return uint32_t The timer counter register.
|
||||
*/
|
||||
uint32_t
|
||||
hal_timer_read(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t tcntr;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tcntr = hal_timer_read_bsptimer(bsptimer);
|
||||
} else {
|
||||
tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg);
|
||||
}
|
||||
|
||||
return tcntr;
|
||||
|
||||
/* Assert here since there is no invalid return code */
|
||||
err:
|
||||
assert(0);
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer delay
|
||||
*
|
||||
* Blocking delay for n ticks
|
||||
*
|
||||
* @param timer_num
|
||||
* @param ticks
|
||||
*
|
||||
* @return int 0 on success; error code otherwise.
|
||||
*/
|
||||
int
|
||||
hal_timer_delay(int timer_num, uint32_t ticks)
|
||||
{
|
||||
uint32_t until;
|
||||
|
||||
until = hal_timer_read(timer_num) + ticks;
|
||||
while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) {
|
||||
/* Loop here till finished */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Initialize the HAL timer structure with the callback and the callback
|
||||
* argument. Also initializes the HW specific timer pointer.
|
||||
*
|
||||
* @param cb_func
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func,
|
||||
void *arg)
|
||||
{
|
||||
int rc;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
timer->cb_func = cb_func;
|
||||
timer->cb_arg = arg;
|
||||
timer->link.tqe_prev = NULL;
|
||||
timer->bsp_timer = bsptimer;
|
||||
|
||||
rc = 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hal_timer_start(struct hal_timer *timer, uint32_t ticks)
|
||||
{
|
||||
int rc;
|
||||
uint32_t tick;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
/* Set the tick value at which the timer should expire */
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tick = hal_timer_read_bsptimer(bsptimer) + ticks;
|
||||
} else {
|
||||
tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks;
|
||||
}
|
||||
rc = hal_timer_start_at(timer, tick);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hal_timer_start_at(struct hal_timer *timer, uint32_t tick)
|
||||
{
|
||||
uint32_t ctx;
|
||||
struct hal_timer *entry;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
if ((timer == NULL) || (timer->link.tqe_prev != NULL) ||
|
||||
(timer->cb_func == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
timer->expiry = tick;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
if (TAILQ_EMPTY(&bsptimer->hal_timer_q)) {
|
||||
TAILQ_INSERT_HEAD(&bsptimer->hal_timer_q, timer, link);
|
||||
} else {
|
||||
TAILQ_FOREACH(entry, &bsptimer->hal_timer_q, link) {
|
||||
if ((int32_t)(timer->expiry - entry->expiry) < 0) {
|
||||
TAILQ_INSERT_BEFORE(entry, timer, link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!entry) {
|
||||
TAILQ_INSERT_TAIL(&bsptimer->hal_timer_q, timer, link);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is the head, we need to set new OCMP */
|
||||
if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) {
|
||||
nrf_timer_set_ocmp(bsptimer, timer->expiry);
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer stop
|
||||
*
|
||||
* Stop a timer.
|
||||
*
|
||||
* @param timer
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_stop(struct hal_timer *timer)
|
||||
{
|
||||
uint32_t ctx;
|
||||
int reset_ocmp;
|
||||
struct hal_timer *entry;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
if (timer == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
if (timer->link.tqe_prev != NULL) {
|
||||
reset_ocmp = 0;
|
||||
if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) {
|
||||
/* If first on queue, we will need to reset OCMP */
|
||||
entry = TAILQ_NEXT(timer, link);
|
||||
reset_ocmp = 1;
|
||||
}
|
||||
TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link);
|
||||
timer->link.tqe_prev = NULL;
|
||||
if (reset_ocmp) {
|
||||
if (entry) {
|
||||
nrf_timer_set_ocmp((struct nrf52_hal_timer *)entry->bsp_timer,
|
||||
entry->expiry);
|
||||
} else {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg);
|
||||
} else {
|
||||
nrf_timer_disable_ocmp(bsptimer->tmr_reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* 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 "os/mynewt.h"
|
||||
#include "hal/hal_uart.h"
|
||||
#include "bsp/bsp.h"
|
||||
|
||||
#ifdef MN_LINUX
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#ifdef MN_OSX
|
||||
#include <util.h>
|
||||
#endif
|
||||
#ifdef MN_FreeBSD
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "mcu/mcu_sim.h"
|
||||
#include "native_uart_cfg_priv.h"
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#define UART_CNT 2
|
||||
|
||||
#if MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE)
|
||||
#define UART_MAX_BYTES_PER_POLL MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE) - 2
|
||||
#else
|
||||
#define UART_MAX_BYTES_PER_POLL 64
|
||||
#endif
|
||||
#define UART_POLLER_STACK_SZ OS_STACK_ALIGN(1024)
|
||||
|
||||
struct uart {
|
||||
int u_open;
|
||||
int u_fd;
|
||||
int u_tx_run;
|
||||
int u_rx_char;
|
||||
hal_uart_rx_char u_rx_func;
|
||||
hal_uart_tx_char u_tx_func;
|
||||
hal_uart_tx_done u_tx_done;
|
||||
void *u_func_arg;
|
||||
};
|
||||
|
||||
const char *native_uart_dev_strs[UART_CNT];
|
||||
|
||||
/*
|
||||
* XXXX should try to use O_ASYNC/SIGIO for byte arrival notification,
|
||||
* so we wouldn't need an OS for pseudo ttys.
|
||||
*/
|
||||
char *native_uart_log_file = NULL;
|
||||
static int uart_log_fd = -1;
|
||||
|
||||
static struct uart uarts[UART_CNT];
|
||||
static int uart_poller_running;
|
||||
static struct os_task uart_poller_task;
|
||||
static os_stack_t uart_poller_stack[UART_POLLER_STACK_SZ];
|
||||
|
||||
static void
|
||||
uart_open_log(void)
|
||||
{
|
||||
if (native_uart_log_file && uart_log_fd < 0) {
|
||||
uart_log_fd = open(native_uart_log_file, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
0666);
|
||||
assert(uart_log_fd >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
uart_log_data(struct uart *u, int istx, uint8_t data)
|
||||
{
|
||||
static struct {
|
||||
struct uart *uart;
|
||||
int istx;
|
||||
uint32_t time;
|
||||
int chars_in_line;
|
||||
} state = {
|
||||
.uart = NULL,
|
||||
.istx = 0
|
||||
};
|
||||
uint32_t now;
|
||||
char tmpbuf[32];
|
||||
int len;
|
||||
|
||||
if (uart_log_fd < 0) {
|
||||
return;
|
||||
}
|
||||
now = os_time_get();
|
||||
if (state.uart) {
|
||||
if (u != state.uart || now != state.time || istx != state.istx) {
|
||||
/*
|
||||
* End current printout.
|
||||
*/
|
||||
if (write(uart_log_fd, "\n", 1) != 1) {
|
||||
assert(0);
|
||||
}
|
||||
state.uart = NULL;
|
||||
} else {
|
||||
if (state.chars_in_line == 8) {
|
||||
if (write(uart_log_fd, "\n\t", 2) != 2) {
|
||||
assert(0);
|
||||
}
|
||||
state.chars_in_line = 0;
|
||||
}
|
||||
len = snprintf(tmpbuf, sizeof(tmpbuf), "%c (%02x) ",
|
||||
isalnum(data) ? data : '?', data);
|
||||
if (write(uart_log_fd, tmpbuf, len) != len) {
|
||||
assert(0);
|
||||
}
|
||||
state.chars_in_line++;
|
||||
}
|
||||
}
|
||||
if (u && state.uart == NULL) {
|
||||
len = snprintf(tmpbuf, sizeof(tmpbuf), "%u:uart%d %s\n\t%c (%02x) ",
|
||||
now, u - uarts, istx ? "tx" : "rx", isalnum(data) ? data : '?', data);
|
||||
if (write(uart_log_fd, tmpbuf, len) != len) {
|
||||
assert(0);
|
||||
}
|
||||
state.chars_in_line = 1;
|
||||
state.uart = u;
|
||||
state.istx = istx;
|
||||
state.time = now;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
uart_transmit_char(struct uart *uart)
|
||||
{
|
||||
int sr;
|
||||
int rc;
|
||||
char ch;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
rc = uart->u_tx_func(uart->u_func_arg);
|
||||
if (rc < 0) {
|
||||
/*
|
||||
* No more data to send.
|
||||
*/
|
||||
uart->u_tx_run = 0;
|
||||
if (uart->u_tx_done) {
|
||||
uart->u_tx_done(uart->u_func_arg);
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return 0;
|
||||
}
|
||||
ch = rc;
|
||||
uart_log_data(uart, 1, ch);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
rc = write(uart->u_fd, &ch, 1);
|
||||
if (rc <= 0) {
|
||||
/* XXX EOF/error, what now? */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
uart_poller(void *arg)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
int bytes;
|
||||
int sr;
|
||||
int didwork;
|
||||
unsigned char ch;
|
||||
struct uart *uart;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < UART_CNT; i++) {
|
||||
if (!uarts[i].u_open) {
|
||||
continue;
|
||||
}
|
||||
uart = &uarts[i];
|
||||
|
||||
for (bytes = 0; bytes < UART_MAX_BYTES_PER_POLL; bytes++) {
|
||||
didwork = 0;
|
||||
if (uart->u_tx_run) {
|
||||
uart_transmit_char(uart);
|
||||
didwork = 1;
|
||||
}
|
||||
if (uart->u_rx_char < 0) {
|
||||
rc = read(uart->u_fd, &ch, 1);
|
||||
if (rc == 0) {
|
||||
/* XXX EOF, what now? */
|
||||
assert(0);
|
||||
} else if (rc > 0) {
|
||||
uart->u_rx_char = ch;
|
||||
}
|
||||
}
|
||||
if (uart->u_rx_char >= 0) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
uart_log_data(uart, 0, uart->u_rx_char);
|
||||
rc = uart->u_rx_func(uart->u_func_arg, uart->u_rx_char);
|
||||
/* Delivered */
|
||||
if (rc >= 0) {
|
||||
uart->u_rx_char = -1;
|
||||
didwork = 1;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
if (!didwork) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
uart_log_data(NULL, 0, 0);
|
||||
os_time_delay(OS_TICKS_PER_SEC / 100);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_nonblock(int fd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags == -1) {
|
||||
const char msg[] = "fcntl(F_GETFL) fail";
|
||||
write(1, msg, sizeof(msg));
|
||||
return;
|
||||
}
|
||||
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
const char msg[] = "fcntl(F_SETFL) fail";
|
||||
write(1, msg, sizeof(msg));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
uart_pty_set_attr(int fd)
|
||||
{
|
||||
struct termios tios;
|
||||
|
||||
if (tcgetattr(fd, &tios)) {
|
||||
const char msg[] = "tcgetattr() failed";
|
||||
write(1, msg, sizeof(msg));
|
||||
return -1;
|
||||
}
|
||||
|
||||
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
|
||||
tios.c_cflag |= CS8 | CREAD;
|
||||
tios.c_iflag = IGNPAR;
|
||||
tios.c_oflag = 0;
|
||||
tios.c_lflag = 0;
|
||||
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
|
||||
const char msg[] = "tcsetattr() failed";
|
||||
write(1, msg, sizeof(msg));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
uart_pty(int port)
|
||||
{
|
||||
int fd;
|
||||
int loop_slave;
|
||||
char pty_name[32];
|
||||
char msg[64];
|
||||
|
||||
if (openpty(&fd, &loop_slave, pty_name, NULL, NULL) < 0) {
|
||||
const char msg[] = "openpty() failed";
|
||||
write(1, msg, sizeof(msg));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uart_pty_set_attr(loop_slave)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg), "uart%d at %s\n", port, pty_name);
|
||||
write(1, msg, strlen(msg));
|
||||
return fd;
|
||||
err:
|
||||
close(fd);
|
||||
close(loop_slave);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an external device terminal (/dev/cu.<...>).
|
||||
*/
|
||||
static int
|
||||
uart_open_dev(int port, int32_t baudrate, uint8_t databits,
|
||||
uint8_t stopbits, enum hal_uart_parity parity,
|
||||
enum hal_uart_flow_ctl flow_ctl)
|
||||
{
|
||||
const char *filename;
|
||||
int fd;
|
||||
int rc;
|
||||
|
||||
filename = native_uart_dev_strs[port];
|
||||
assert(filename != NULL);
|
||||
|
||||
fd = open(filename, O_RDWR);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = uart_dev_set_attr(fd, baudrate, databits,
|
||||
stopbits, parity, flow_ctl);
|
||||
if (rc != 0) {
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
dprintf(1, "uart%d at %s\n", port, filename);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
hal_uart_start_tx(int port)
|
||||
{
|
||||
int sr;
|
||||
|
||||
if (port >= UART_CNT || uarts[port].u_open == 0) {
|
||||
return;
|
||||
}
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
uarts[port].u_tx_run = 1;
|
||||
if (!os_started()) {
|
||||
/*
|
||||
* XXX this is a hack.
|
||||
*/
|
||||
uart_transmit_char(&uarts[port]);
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
void
|
||||
hal_uart_start_rx(int port)
|
||||
{
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
void
|
||||
hal_uart_blocking_tx(int port, uint8_t data)
|
||||
{
|
||||
if (port >= UART_CNT || uarts[port].u_open == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Count statistics and add error checking here. */
|
||||
(void) write(uarts[port].u_fd, &data, sizeof(data));
|
||||
}
|
||||
|
||||
int
|
||||
hal_uart_init_cbs(int port, hal_uart_tx_char tx_func, hal_uart_tx_done tx_done,
|
||||
hal_uart_rx_char rx_func, void *arg)
|
||||
{
|
||||
struct uart *uart;
|
||||
int rc;
|
||||
|
||||
if (port >= UART_CNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uart = &uarts[port];
|
||||
if (uart->u_open) {
|
||||
return -1;
|
||||
}
|
||||
uart->u_tx_func = tx_func;
|
||||
uart->u_tx_done = tx_done;
|
||||
uart->u_rx_func = rx_func;
|
||||
uart->u_func_arg = arg;
|
||||
uart->u_rx_char = -1;
|
||||
|
||||
if (!uart_poller_running) {
|
||||
uart_poller_running = 1;
|
||||
rc = os_task_init(&uart_poller_task, "uartpoll", uart_poller, NULL,
|
||||
MYNEWT_VAL(MCU_UART_POLLER_PRIO), OS_WAIT_FOREVER, uart_poller_stack,
|
||||
UART_POLLER_STACK_SZ);
|
||||
assert(rc == 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hal_uart_config(int port, int32_t baudrate, uint8_t databits, uint8_t stopbits,
|
||||
enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl)
|
||||
{
|
||||
struct uart *uart;
|
||||
|
||||
if (port >= UART_CNT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uart = &uarts[port];
|
||||
if (uart->u_open) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (native_uart_dev_strs[port] == NULL) {
|
||||
uart->u_fd = uart_pty(port);
|
||||
} else {
|
||||
uart->u_fd = uart_open_dev(port, baudrate, databits, stopbits,
|
||||
parity, flow_ctl);
|
||||
}
|
||||
|
||||
if (uart->u_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
set_nonblock(uart->u_fd);
|
||||
|
||||
|
||||
uart_open_log();
|
||||
uart->u_open = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hal_uart_close(int port)
|
||||
{
|
||||
struct uart *uart;
|
||||
int rc;
|
||||
|
||||
if (port >= UART_CNT) {
|
||||
rc = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
uart = &uarts[port];
|
||||
if (!uart->u_open) {
|
||||
rc = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
close(uart->u_fd);
|
||||
|
||||
uart->u_open = 0;
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
int
|
||||
hal_uart_init(int port, void *arg)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
uart_set_dev(int port, const char *dev_str)
|
||||
{
|
||||
if (port < 0 || port >= UART_CNT) {
|
||||
return SYS_EINVAL;
|
||||
}
|
||||
|
||||
if (uarts[port].u_open) {
|
||||
return SYS_EBUSY;
|
||||
}
|
||||
|
||||
native_uart_dev_strs[port] = dev_str;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
#include "hal/hal_watchdog.h"
|
||||
|
||||
int
|
||||
hal_watchdog_init(uint32_t expire_msecs)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
hal_watchdog_enable(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
hal_watchdog_tickle(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* B0 defined in bits/termios.h collides with nrfx/mdk/nrf52.h */
|
||||
#undef B0
|
||||
|
||||
#include "os/mynewt.h"
|
||||
#include "native_uart_cfg_priv.h"
|
||||
|
||||
/* uint64 is used here to accommodate speed_t, whatever that is. */
|
||||
static const uint64_t uart_baud_table[][2] = {
|
||||
#ifdef B50
|
||||
{ 50, B50 },
|
||||
#endif
|
||||
#ifdef B75
|
||||
{ 75, B75 },
|
||||
#endif
|
||||
#ifdef B110
|
||||
{ 110, B110 },
|
||||
#endif
|
||||
#ifdef B134
|
||||
{ 134, B134 },
|
||||
#endif
|
||||
#ifdef B150
|
||||
{ 150, B150 },
|
||||
#endif
|
||||
#ifdef B200
|
||||
{ 200, B200 },
|
||||
#endif
|
||||
#ifdef B300
|
||||
{ 300, B300 },
|
||||
#endif
|
||||
#ifdef B600
|
||||
{ 600, B600 },
|
||||
#endif
|
||||
#ifdef B1200
|
||||
{ 1200, B1200 },
|
||||
#endif
|
||||
#ifdef B1800
|
||||
{ 1800, B1800 },
|
||||
#endif
|
||||
#ifdef B2400
|
||||
{ 2400, B2400 },
|
||||
#endif
|
||||
#ifdef B4800
|
||||
{ 4800, B4800 },
|
||||
#endif
|
||||
#ifdef B9600
|
||||
{ 9600, B9600 },
|
||||
#endif
|
||||
#ifdef B19200
|
||||
{ 19200, B19200 },
|
||||
#endif
|
||||
#ifdef B38400
|
||||
{ 38400, B38400 },
|
||||
#endif
|
||||
#ifdef B57600
|
||||
{ 57600, B57600 },
|
||||
#endif
|
||||
#ifdef B115200
|
||||
{ 115200, B115200 },
|
||||
#endif
|
||||
#ifdef B230400
|
||||
{ 230400, B230400 },
|
||||
#endif
|
||||
#ifdef B460800
|
||||
{ 460800, B460800 },
|
||||
#endif
|
||||
#ifdef B500000
|
||||
{ 500000, B500000 },
|
||||
#endif
|
||||
#ifdef B576000
|
||||
{ 576000, B576000 },
|
||||
#endif
|
||||
#ifdef B921600
|
||||
{ 921600, B921600 },
|
||||
#endif
|
||||
#ifdef B1000000
|
||||
{ 1000000, B1000000 },
|
||||
#endif
|
||||
#ifdef B1152000
|
||||
{ 1152000, B1152000 },
|
||||
#endif
|
||||
#ifdef B1500000
|
||||
{ 1500000, B1500000 },
|
||||
#endif
|
||||
#ifdef B2000000
|
||||
{ 2000000, B2000000 },
|
||||
#endif
|
||||
#ifdef B2500000
|
||||
{ 2500000, B2500000 },
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
{ 3000000, B3000000 },
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
{ 3500000, B3500000 },
|
||||
#endif
|
||||
#ifdef B3710000
|
||||
{ 3710000, B3710000 },
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
{ 4000000, B4000000 },
|
||||
#endif
|
||||
};
|
||||
#define UART_BAUD_TABLE_SZ (sizeof uart_baud_table / sizeof uart_baud_table[0])
|
||||
|
||||
/**
|
||||
* Returns 0 on failure.
|
||||
*/
|
||||
speed_t
|
||||
uart_baud_to_speed(int_least32_t baud)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < UART_BAUD_TABLE_SZ; i++) {
|
||||
if (uart_baud_table[i][0] == baud) {
|
||||
return uart_baud_table[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures an external device terminal (/dev/cu.<...>).
|
||||
*/
|
||||
int
|
||||
uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits,
|
||||
uint8_t stopbits, enum hal_uart_parity parity,
|
||||
enum hal_uart_flow_ctl flow_ctl)
|
||||
{
|
||||
struct termios tty;
|
||||
speed_t speed;
|
||||
int rc;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
memset(&tty, 0, sizeof(tty));
|
||||
cfmakeraw(&tty);
|
||||
|
||||
speed = uart_baud_to_speed(baudrate);
|
||||
if (speed == 0) {
|
||||
fprintf(stderr, "invalid baud rate: %d\n", (int)baudrate);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tty.c_cflag |= (speed | CLOCAL | CREAD);
|
||||
|
||||
/* Set flow control. */
|
||||
switch (flow_ctl) {
|
||||
case HAL_UART_FLOW_CTL_NONE:
|
||||
tty.c_cflag &= ~CRTSCTS;
|
||||
break;
|
||||
|
||||
case HAL_UART_FLOW_CTL_RTS_CTS:
|
||||
tty.c_cflag |= CRTSCTS;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "invalid flow control setting: %d\n", flow_ctl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rc = cfsetospeed(&tty, speed);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "cfsetospeed failed; %d (%s) baudrate=%d\n",
|
||||
errno, strerror(errno), (int)baudrate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rc = cfsetispeed(&tty, speed);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "cfsetispeed failed; %d (%s) baudrate=%d\n",
|
||||
errno, strerror(errno), (int)baudrate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (databits) {
|
||||
case 7:
|
||||
tty.c_cflag |= CS7;
|
||||
|
||||
switch (parity) {
|
||||
case HAL_UART_PARITY_ODD:
|
||||
tty.c_cflag |= PARENB;
|
||||
tty.c_cflag |= PARODD;
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CSIZE;
|
||||
break;
|
||||
|
||||
case HAL_UART_PARITY_EVEN:
|
||||
tty.c_cflag |= PARENB;
|
||||
tty.c_cflag &= ~PARODD;
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SYS_EINVAL;
|
||||
}
|
||||
|
||||
case 8:
|
||||
if (parity != HAL_UART_PARITY_NONE) {
|
||||
return SYS_EINVAL;
|
||||
}
|
||||
tty.c_cflag |= CS8;
|
||||
tty.c_cflag &= ~PARENB;
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SYS_EINVAL;
|
||||
}
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &tty);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "tcsetattr failed; %d (%s)\n", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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_NATIVE_UART_CFG_PRIV_
|
||||
#define H_NATIVE_UART_CFG_PRIV_
|
||||
|
||||
#include <termios.h>
|
||||
#include "hal/hal_uart.h"
|
||||
|
||||
speed_t uart_baud_to_speed(int_least32_t baud);
|
||||
int uart_dev_set_attr(int fd, int32_t baudrate, uint8_t databits,
|
||||
uint8_t stopbits, enum hal_uart_parity parity,
|
||||
enum hal_uart_flow_ctl flow_ctl);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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 <stdint.h>
|
||||
#include <hal/nrf_clock.h>
|
||||
#include <time_machine.h>
|
||||
#include "mcu/nrf52_hal.h"
|
||||
#include "nrfx.h"
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os.h"
|
||||
|
||||
static uint8_t nrf52_clock_hfxo_refcnt;
|
||||
|
||||
/**
|
||||
* Request HFXO clock be turned on. Note that each request must have a
|
||||
* corresponding release.
|
||||
*
|
||||
* @return int 0: hfxo was already on. 1: hfxo was turned on.
|
||||
*/
|
||||
int
|
||||
nrf52_clock_hfxo_request(void)
|
||||
{
|
||||
int started;
|
||||
uint32_t ctx;
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFINT)
|
||||
/* Cannot enable/disable hfxo if it is not present */
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
started = 0;
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
assert(nrf52_clock_hfxo_refcnt < 0xff);
|
||||
if (nrf52_clock_hfxo_refcnt == 0) {
|
||||
/* Check the current STATE and SRC of HFCLK */
|
||||
if ((NRF_CLOCK->HFCLKSTAT &
|
||||
(CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) !=
|
||||
(CLOCK_HFCLKSTAT_SRC_Xtal << CLOCK_HFCLKSTAT_SRC_Pos |
|
||||
CLOCK_HFCLKSTAT_STATE_Running << CLOCK_HFCLKSTAT_STATE_Pos)) {
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
|
||||
while (!NRF_CLOCK->EVENTS_HFCLKSTARTED) {
|
||||
#if BABBLESIM
|
||||
tm_tick();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
started = 1;
|
||||
}
|
||||
++nrf52_clock_hfxo_refcnt;
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return started;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the HFXO. This means that the caller no longer needs the HFXO to be
|
||||
* turned on. Each call to release should have been preceeded by a corresponding
|
||||
* call to request the HFXO
|
||||
*
|
||||
*
|
||||
* @return int 0: HFXO not stopped by this call (others using it) 1: HFXO
|
||||
* stopped.
|
||||
*/
|
||||
int
|
||||
nrf52_clock_hfxo_release(void)
|
||||
{
|
||||
int stopped;
|
||||
uint32_t ctx;
|
||||
|
||||
#if MYNEWT_VAL_CHOICE(MCU_HFCLK_SOURCE, HFINT)
|
||||
/* Cannot enable/disable hfxo if it is not present */
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
stopped = 0;
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
assert(nrf52_clock_hfxo_refcnt != 0);
|
||||
--nrf52_clock_hfxo_refcnt;
|
||||
if (nrf52_clock_hfxo_refcnt == 0) {
|
||||
nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTOP);
|
||||
stopped = 1;
|
||||
}
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return stopped;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Copyright (c) 2012 ARM LIMITED
|
||||
* 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 ARM 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 "mcu/cmsis_nvic.h"
|
||||
#include "nrf.h"
|
||||
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
syscfg.defs:
|
||||
MCU_TARGET:
|
||||
description: >
|
||||
Specifies target MCU, shall be set by BSP.
|
||||
value:
|
||||
restrictions:
|
||||
- $notnull
|
||||
choices:
|
||||
- nRF52810
|
||||
- nRF52811
|
||||
- nRF52832
|
||||
- nRF52840
|
||||
|
||||
MCU_FLASH_MIN_WRITE_SIZE:
|
||||
description: >
|
||||
Specifies the required alignment for internal flash writes.
|
||||
Used internally by the newt tool.
|
||||
value: 1
|
||||
|
||||
MCU_DCDC_ENABLED:
|
||||
description: >
|
||||
Specifies whether or not to enable DC/DC regulator. This requires
|
||||
external circuitry so is defined to be zero by default and
|
||||
expected to be overridden by the BSP.
|
||||
value: 0
|
||||
|
||||
MCU_HFCLK_SOURCE:
|
||||
description: >
|
||||
Selected source for high frequency clock (HFCLK).
|
||||
Selecting HFXO will still mostly use the HFINT but will switch to HFXO when requested (BLE, certain timers, etc...)
|
||||
Selecting HFINT should only be used in the case where an external 32MHz crystal oscillator is not present.
|
||||
value: HFXO
|
||||
choices:
|
||||
- HFXO
|
||||
- HFINT
|
||||
restrictions:
|
||||
- '(MCU_HFCLK_SOURCE == "HFXO") || (MCU_LFCLK_SOURCE != "LFSYNTH")'
|
||||
|
||||
MCU_LFCLK_SOURCE:
|
||||
description: >
|
||||
Selected source for low frequency clock (LFCLK).
|
||||
value:
|
||||
choices:
|
||||
- LFRC # 32.768 kHz RC oscillator
|
||||
- LFXO # 32.768 kHz crystal oscillator
|
||||
- LFSYNTH # 32.768 kHz synthesized from HFCLK
|
||||
|
||||
MCU_I2C_RECOVERY_DELAY_USEC:
|
||||
description: >
|
||||
Time to wait for activity on SCL line after triggering start task
|
||||
before restarting TWI controller. This is to recover from state
|
||||
where controller is unresponsive due to glitch on I2C bus.
|
||||
Note: Default value seems to work fine, but may need to be tuned.
|
||||
value: 100
|
||||
|
||||
MCU_BUS_DRIVER_I2C_USE_TWIM:
|
||||
description: >
|
||||
Enables usage of i2c_nrf52_twim bus driver for I2C.
|
||||
If disabled, standard i2c_hal driver is used.
|
||||
value: 0
|
||||
|
||||
MCU_GPIO_USE_PORT_EVENT:
|
||||
description: >
|
||||
When enabled, hal_gpio will use GPIOTE PORT event instead of PIN
|
||||
events for interrupts. This mode may be less accurate (i.e. pulse
|
||||
length needs to be longer in order to be detected) but it reduces
|
||||
power consumption since it does not require HFCLK to be running.
|
||||
Refer to nRF52xxx Product Specification document for more details.
|
||||
value: 0
|
||||
|
||||
MCU_DEBUG_IGNORE_BKPT:
|
||||
description: >
|
||||
When enabled, asm(bkpt) will be ignored. If not set, it will hit
|
||||
the breakpoint wherever it gets called, For example, reset and crash
|
||||
value: 0
|
||||
|
||||
|
||||
# MCU peripherals definitions
|
||||
I2C_0:
|
||||
description: 'Enable nRF52xxx I2C (TWI) 0'
|
||||
value: 0
|
||||
restrictions:
|
||||
- '!(SPI_0_MASTER && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
- '!(SPI_0_SLAVE && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
- '!(SPI_1_MASTER && (MCU_TARGET == "nrf52811"))'
|
||||
- '!(SPI_1_SLAVE && (MCU_TARGET == "nrf52811"))'
|
||||
I2C_0_PIN_SCL:
|
||||
description: 'SCL pin for I2C_0'
|
||||
value: ''
|
||||
I2C_0_PIN_SDA:
|
||||
description: 'SDA pin for I2C_0'
|
||||
value: ''
|
||||
I2C_0_FREQ_KHZ:
|
||||
description: 'Frequency [kHz] for I2C_0'
|
||||
value: 100
|
||||
|
||||
I2C_1:
|
||||
description: 'Enable nRF52xxx I2C (TWI) 1'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_1_MASTER"
|
||||
- "!SPI_1_SLAVE"
|
||||
I2C_1_PIN_SCL:
|
||||
description: 'SCL pin for I2C_1'
|
||||
value: ''
|
||||
I2C_1_PIN_SDA:
|
||||
description: 'SDA pin for I2C_1'
|
||||
value: ''
|
||||
I2C_1_FREQ_KHZ:
|
||||
description: 'Frequency [kHz] for I2C_1'
|
||||
value: 100
|
||||
|
||||
SPI_0_MASTER:
|
||||
description: 'Enable nRF52xxx SPI Master 0'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_0_SLAVE"
|
||||
- '!(I2C_0 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
SPI_0_MASTER_PIN_SCK:
|
||||
description: 'SCK pin for SPI_0_MASTER'
|
||||
value: ''
|
||||
SPI_0_MASTER_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_0_MASTER'
|
||||
value: ''
|
||||
SPI_0_MASTER_PIN_MISO:
|
||||
description: 'MISO pin for SPI_0_MASTER'
|
||||
value: ''
|
||||
|
||||
SPI_0_SLAVE:
|
||||
description: 'Enable nRF52xxx SPI Slave 0'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_0_MASTER"
|
||||
- '!(I2C_0 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
SPI_0_SLAVE_PIN_SCK:
|
||||
description: 'SCK pin for SPI_0_SLAVE'
|
||||
value: ''
|
||||
SPI_0_SLAVE_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_0_SLAVE'
|
||||
value: ''
|
||||
SPI_0_SLAVE_PIN_MISO:
|
||||
description: 'MISO pin for SPI_0_SLAVE'
|
||||
value: ''
|
||||
SPI_0_SLAVE_PIN_SS:
|
||||
description: 'SS pin for SPI_0_SLAVE'
|
||||
value: ''
|
||||
|
||||
SPI_1_MASTER:
|
||||
description: 'Enable nRF52xxx SPI Master 1'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_1_SLAVE"
|
||||
- '!(I2C_1 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
- '!(I2C_0 && ((MCU_TARGET == "nrf52811")))'
|
||||
SPI_1_MASTER_PIN_SCK:
|
||||
description: 'SCK pin for SPI_1_MASTER'
|
||||
value: ''
|
||||
SPI_1_MASTER_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_1_MASTER'
|
||||
value: ''
|
||||
SPI_1_MASTER_PIN_MISO:
|
||||
description: 'MISO pin for SPI_1_MASTER'
|
||||
value: ''
|
||||
|
||||
SPI_1_SLAVE:
|
||||
description: 'Enable nRF52xxx SPI Slave 1'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_1_MASTER"
|
||||
- '!(I2C_1 && ((MCU_TARGET == "nrf52832") || (MCU_TARGET == "nrf52840")))'
|
||||
- '!(I2C_0 && ((MCU_TARGET == "nrf52811")))'
|
||||
SPI_1_SLAVE_PIN_SCK:
|
||||
description: 'SCK pin for SPI_1_SLAVE'
|
||||
value: ''
|
||||
SPI_1_SLAVE_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_1_SLAVE'
|
||||
value: ''
|
||||
SPI_1_SLAVE_PIN_MISO:
|
||||
description: 'MISO pin for SPI_1_SLAVE'
|
||||
value: ''
|
||||
SPI_1_SLAVE_PIN_SS:
|
||||
description: 'SS pin for SPI_1_SLAVE'
|
||||
value: ''
|
||||
|
||||
SPI_2_MASTER:
|
||||
description: 'Enable nRF52xxx SPI Master 2'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_2_SLAVE"
|
||||
SPI_2_MASTER_PIN_SCK:
|
||||
description: 'SCK pin for SPI_2_MASTER'
|
||||
value: ''
|
||||
SPI_2_MASTER_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_2_MASTER'
|
||||
value: ''
|
||||
SPI_2_MASTER_PIN_MISO:
|
||||
description: 'MISO pin for SPI_2_MASTER'
|
||||
value: ''
|
||||
|
||||
SPI_2_SLAVE:
|
||||
description: 'Enable nRF52xxx SPI Slave 2'
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!SPI_2_MASTER"
|
||||
SPI_2_SLAVE_PIN_SCK:
|
||||
description: 'SCK pin for SPI_2_SLAVE'
|
||||
value: ''
|
||||
SPI_2_SLAVE_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_2_SLAVE'
|
||||
value: ''
|
||||
SPI_2_SLAVE_PIN_MISO:
|
||||
description: 'MISO pin for SPI_2_SLAVE'
|
||||
value: ''
|
||||
SPI_2_SLAVE_PIN_SS:
|
||||
description: 'SS pin for SPI_2_SLAVE'
|
||||
value: ''
|
||||
|
||||
SPI_3_MASTER:
|
||||
description: 'Enable nRF52xxx SPI Master 3'
|
||||
value: 0
|
||||
restrictions:
|
||||
- 'MCU_TARGET == "nRF52840" || !SPI_3_MASTER'
|
||||
SPI_3_MASTER_PIN_SCK:
|
||||
description: 'SCK pin for SPI_3_MASTER'
|
||||
value: ''
|
||||
SPI_3_MASTER_PIN_MOSI:
|
||||
description: 'MOSI pin for SPI_3_MASTER'
|
||||
value: ''
|
||||
SPI_3_MASTER_PIN_MISO:
|
||||
description: 'MISO pin for SPI_3_MASTER'
|
||||
value: ''
|
||||
|
||||
ADC_0:
|
||||
description: 'Enable nRF52xxx ADC 0'
|
||||
value: 0
|
||||
|
||||
ADC_0_REFMV_0:
|
||||
description: 'reference mV in AREF0 if used'
|
||||
value: 0
|
||||
|
||||
PWM_0:
|
||||
description: 'Enable nRF52xxx PWM 0'
|
||||
value: 0
|
||||
PWM_1:
|
||||
description: 'Enable nRF52xxx PWM 1'
|
||||
value: 0
|
||||
PWM_2:
|
||||
description: 'Enable nRF52xxx PWM 2'
|
||||
value: 0
|
||||
PWM_3:
|
||||
description: 'Enable nRF52xxx PWM 3'
|
||||
value: 0
|
||||
restrictions:
|
||||
- 'MCU_TARGET == "nRF52840" || !PWM_3'
|
||||
|
||||
TRNG:
|
||||
description: 'Enable nRF52xxx TRNG'
|
||||
value: 0
|
||||
|
||||
CRYPTO:
|
||||
description: 'Enable nRF52xxx CRYPTO'
|
||||
value: 0
|
||||
|
||||
UART_0:
|
||||
description: 'Enable nRF52xxx UART0'
|
||||
value: 1
|
||||
UART_0_PIN_TX:
|
||||
description: 'TX pin for UART0'
|
||||
value: ''
|
||||
UART_0_PIN_RX:
|
||||
description: 'RX pin for UART0'
|
||||
value: ''
|
||||
UART_0_PIN_RTS:
|
||||
description: 'RTS pin for UART0'
|
||||
value: -1
|
||||
UART_0_PIN_CTS:
|
||||
description: 'CTS pin for UART0'
|
||||
value: -1
|
||||
|
||||
UART_1:
|
||||
description: 'Enable nRF52xxx UART1'
|
||||
value: 0
|
||||
restrictions:
|
||||
- 'MCU_TARGET == "nRF52840" || !UART_1'
|
||||
UART_1_PIN_TX:
|
||||
description: 'TX pin for UART1'
|
||||
value: ''
|
||||
UART_1_PIN_RX:
|
||||
description: 'RX pin for UART1'
|
||||
value: ''
|
||||
UART_1_PIN_RTS:
|
||||
description: 'RTS pin for UART1'
|
||||
value: -1
|
||||
UART_1_PIN_CTS:
|
||||
description: 'CTS pin for UART1'
|
||||
value: -1
|
||||
|
||||
TEMP:
|
||||
description: 'Enable nRF52xxx internal temperature mesurement'
|
||||
value: 0
|
||||
|
||||
TIMER_0:
|
||||
description: 'Enable nRF52xxx Timer 0'
|
||||
value: 1
|
||||
TIMER_1:
|
||||
description: 'Enable nRF52xxx Timer 1'
|
||||
value: 0
|
||||
TIMER_2:
|
||||
description: 'Enable nRF52xxx Timer 2'
|
||||
value: 0
|
||||
TIMER_3:
|
||||
description: 'Enable nRF52xxx Timer 3'
|
||||
value: 0
|
||||
TIMER_4:
|
||||
description: 'Enable nRF52xxx Timer 4'
|
||||
value: 0
|
||||
TIMER_5:
|
||||
description: 'Enable nRF52xxx RTC 0'
|
||||
value: 0
|
||||
|
||||
QSPI_ENABLE:
|
||||
description: 'NRF52 QSPI'
|
||||
value: 0
|
||||
|
||||
QSPI_READOC:
|
||||
description: >
|
||||
QSPI Command to use
|
||||
0 - 0x09 Fast Read
|
||||
1 - 0x3B Fast Read Dual Output
|
||||
2 - 0xBB Fast Read Dual I/O
|
||||
3 - 0x6B Fast Read Quad Output
|
||||
4 - 0xEB Fast Read Quad I/O
|
||||
value: 0
|
||||
QSPI_WRITEOC:
|
||||
description: >
|
||||
QSPI Command to use
|
||||
0 - 0x02 Page program
|
||||
1 - 0xA2 Page program Dual Data
|
||||
2 - 0x32 Page program Quad Data
|
||||
3 - 0x38 Page program Quad I/O
|
||||
value: 0
|
||||
QSPI_ADDRMODE:
|
||||
description: 'Address lentgh 0=24 bits, 1=32 bits'
|
||||
value: 0
|
||||
QSPI_DPMCONFIG:
|
||||
description: 'Deep power mode enable'
|
||||
value: 0
|
||||
QSPI_SCK_DELAY:
|
||||
description: >
|
||||
Minimum amount of time that the CSN pin must stay high
|
||||
before it can go low again. Value is specified in number of 16
|
||||
MHz periods (62.5 ns).
|
||||
value: 0
|
||||
QSPI_SCK_FREQ:
|
||||
description: '32MHz clock divider (0-31). Clock = 32MHz / (1+divider)'
|
||||
value: 0
|
||||
QSPI_SPI_MODE:
|
||||
description: 'SPI 0=Mode0 or 1=Mode3'
|
||||
value: 0
|
||||
|
||||
QSPI_FLASH_SECTOR_SIZE:
|
||||
description: 'QSPI sector size. In most cases it should be 4096.'
|
||||
value: 0
|
||||
QSPI_FLASH_PAGE_SIZE:
|
||||
description: >
|
||||
QSPI page size. Writes can only be performed to one page at a time.
|
||||
In most cases it should be 256.
|
||||
value: 0
|
||||
|
||||
QSPI_FLASH_SECTOR_COUNT:
|
||||
description: 'QSPI sector count'
|
||||
value: -1
|
||||
QSPI_PIN_CS:
|
||||
description: 'CS pin for QSPI'
|
||||
value: -1
|
||||
QSPI_PIN_SCK:
|
||||
description: 'SCK pin for QSPI'
|
||||
value: -1
|
||||
QSPI_PIN_DIO0:
|
||||
description: 'DIO0 pin for QSPI'
|
||||
value: -1
|
||||
QSPI_PIN_DIO1:
|
||||
description: 'DIO1 pin for QSPI'
|
||||
value: -1
|
||||
QSPI_PIN_DIO2:
|
||||
description: 'DIO2 pin for QSPI'
|
||||
value: -1
|
||||
QSPI_PIN_DIO3:
|
||||
description: 'DIO3 pin for QSPI'
|
||||
value: -1
|
||||
|
||||
NFC_PINS_AS_GPIO:
|
||||
description: 'Use NFC pins as GPIOs instead of NFC functionality'
|
||||
value: 1
|
||||
|
||||
GPIO_AS_PIN_RESET:
|
||||
description: 'Enable pin reset'
|
||||
value: 0
|
||||
|
||||
# Deprecated settings
|
||||
|
||||
MCU_NRF52832:
|
||||
description: Use MCU_TARGET instead
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!MCU_NRF52840"
|
||||
deprecated: 1
|
||||
MCU_NRF52840:
|
||||
description: Use MCU_TARGET instead
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!MCU_NRF52832"
|
||||
deprecated: 1
|
||||
|
||||
XTAL_32768:
|
||||
description: Use MCU_LFCLK_SOURCE instead
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!XTAL_RC"
|
||||
- "!XTAL_32768_SYNTH"
|
||||
deprecated: 1
|
||||
XTAL_RC:
|
||||
description: Use MCU_LFCLK_SOURCE instead
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!XTAL_32768"
|
||||
- "!XTAL_32768_SYNTH"
|
||||
deprecated: 1
|
||||
XTAL_32768_SYNTH:
|
||||
description: Use MCU_LFCLK_SOURCE instead
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!XTAL_32768"
|
||||
- "!XTAL_RC"
|
||||
deprecated: 1
|
||||
|
||||
MCU_NATIVE_USE_SIGNALS:
|
||||
description: >
|
||||
Whether to use POSIX signals to implement context switches. Valid
|
||||
values are as follows:
|
||||
1: More correctness; less stability. The OS tick timer will
|
||||
cause a high-priority task to preempt a low-priority task.
|
||||
This causes stability issues because a task can be preempted
|
||||
while it is in the middle of a system call, potentially
|
||||
causing deadlock or memory corruption.
|
||||
|
||||
0: Less correctness; more stability. The OS tick timer only
|
||||
runs while the idle task is active. Therefore, a sleeping
|
||||
high-priority task will not preempt a low-priority task due
|
||||
to a timing event (e.g., delay or callout expired).
|
||||
However, this version of sim does not suffer from the
|
||||
stability issues that affect the "signals" implementation.
|
||||
|
||||
Unit tests should use 1. Long-running sim processes should use 0.
|
||||
|
||||
value: 1
|
||||
MCU_NATIVE:
|
||||
description: >
|
||||
Set to indicate that we are using native mcu.
|
||||
value: 1
|
||||
MCU_FLASH_STYLE_ST:
|
||||
description: Emulated flash layout is similar to one in STM32.
|
||||
value: 1
|
||||
restrictions:
|
||||
- "!MCU_FLASH_STYLE_NORDIC"
|
||||
MCU_FLASH_STYLE_NORDIC:
|
||||
description: >
|
||||
Emulated flash layout is similar to one in NRF51/2 and SAMD21.
|
||||
value: 0
|
||||
restrictions:
|
||||
- "!MCU_FLASH_STYLE_ST"
|
||||
MCU_UART_POLLER_PRIO:
|
||||
description: 'Priority of native UART poller task.'
|
||||
type: task_priority
|
||||
value: 1
|
||||
MCU_TIMER_POLLER_PRIO:
|
||||
description: 'Priority of native HAL timer task.'
|
||||
type: task_priority
|
||||
value: 0
|
||||
|
||||
syscfg.vals:
|
||||
OS_TICKS_PER_SEC: 128
|
||||
|
||||
syscfg.vals.MCU_NRF52832:
|
||||
MCU_TARGET: nRF52832
|
||||
syscfg.vals.MCU_NRF52840:
|
||||
MCU_TARGET: nRF52840
|
||||
|
||||
syscfg.vals.XTAL_32768:
|
||||
MCU_LFCLK_SOURCE: LFXO
|
||||
syscfg.vals.XTAL_RC:
|
||||
MCU_LFCLK_SOURCE: LFRC
|
||||
syscfg.vals.XTAL_32768_SYNTH:
|
||||
MCU_LFCLK_SOURCE: LFSYNTH
|
||||
|
||||
syscfg.restrictions:
|
||||
- "!I2C_0 || (I2C_0_PIN_SCL && I2C_0_PIN_SDA)"
|
||||
- "!I2C_1 || (I2C_1_PIN_SCL && I2C_1_PIN_SDA)"
|
||||
- "!SPI_0_MASTER || (SPI_0_MASTER_PIN_SCK && SPI_0_MASTER_PIN_MOSI && SPI_0_MASTER_PIN_MISO)"
|
||||
- "!SPI_1_MASTER || (SPI_1_MASTER_PIN_SCK && SPI_1_MASTER_PIN_MOSI && SPI_1_MASTER_PIN_MISO)"
|
||||
- "!SPI_2_MASTER || (SPI_2_MASTER_PIN_SCK && SPI_2_MASTER_PIN_MOSI && SPI_2_MASTER_PIN_MISO)"
|
||||
- "!SPI_3_MASTER || (SPI_3_MASTER_PIN_SCK && SPI_3_MASTER_PIN_MOSI && SPI_3_MASTER_PIN_MISO)"
|
||||
- "!SPI_0_SLAVE || (SPI_0_SLAVE_PIN_SCK && SPI_0_SLAVE_PIN_MOSI && SPI_0_SLAVE_PIN_MISO && SPI_0_SLAVE_PIN_SS)"
|
||||
- "!SPI_1_SLAVE || (SPI_1_SLAVE_PIN_SCK && SPI_1_SLAVE_PIN_MOSI && SPI_1_SLAVE_PIN_MISO && SPI_1_SLAVE_PIN_SS)"
|
||||
- "!SPI_2_SLAVE || (SPI_2_SLAVE_PIN_SCK && SPI_2_SLAVE_PIN_MOSI && SPI_2_SLAVE_PIN_MISO && SPI_2_SLAVE_PIN_SS)"
|
||||
- "!UART_0 || (UART_0_PIN_TX && UART_0_PIN_RX)"
|
||||
- "!UART_1 || (UART_1_PIN_TX && UART_1_PIN_RX)"
|
||||
- "(OS_TICKS_PER_SEC == 128 || OS_TICKS_PER_SEC == 256 || OS_TICKS_PER_SEC == 512 || OS_TICKS_PER_SEC == 1024)"
|
||||
@@ -0,0 +1,133 @@
|
||||
Baselibc is based on klibc 1.5.23 and tinyprintf modules.
|
||||
None of the GPL-licensed parts of klibc are used.
|
||||
|
||||
Baselibc is licensed under the BSD license:
|
||||
|
||||
Copyright (c) 2012 Petteri Aimonen <jpa at blc.mail.kapsi.fi>
|
||||
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 Kustaa Nyholm or SpareTimeLabs 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 COPYRIGHT HOLDER 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.
|
||||
|
||||
The original licenses of the modules are included below:
|
||||
|
||||
------------------ Tinyprintf license ------------------
|
||||
|
||||
Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
|
||||
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 Kustaa Nyholm or SpareTimeLabs 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 COPYRIGHT HOLDER 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.
|
||||
|
||||
------------------- klibc license -------------------------
|
||||
This license applies to all files in directory and its subdirectories,
|
||||
unless otherwise noted in individual files.
|
||||
|
||||
|
||||
Some files are derived from files derived from the include/ directory
|
||||
of the Linux kernel, and are licensed under the terms of the GNU
|
||||
General Public License, version 2, as released by the Free Software
|
||||
Foundation, Inc.; incorporated herein by reference.
|
||||
[These files are not included in the baselibc.]
|
||||
|
||||
-----
|
||||
|
||||
Some files are derived from files copyrighted by the Regents of The
|
||||
University of California, and are available under the following
|
||||
license:
|
||||
|
||||
Note: The advertising clause in the license appearing on BSD Unix
|
||||
files was officially rescinded by the Director of the Office of
|
||||
Technology Licensing of the University of California on July 22
|
||||
1999. He states that clause 3 is "hereby deleted in its entirety."
|
||||
|
||||
* Copyright (c)
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||
|
||||
For all remaining files [of klibc], the following license applies:
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* Any copyright notice(s) and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# 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: babblesim/libc
|
||||
pkg.type: sdk
|
||||
pkg.description: Functions from apache-mynewt-core/libc that not exists in Linux system.
|
||||
pkg.author: "Codecoup"
|
||||
pkg.homepage: "http://mynewt.apache.org/"
|
||||
pkg.keywords:
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/kernel/os"
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* strlcat.c
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t strlcat(char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
char *q = dst;
|
||||
const char *p = src;
|
||||
char ch;
|
||||
|
||||
while (bytes < size && *q) {
|
||||
q++;
|
||||
bytes++;
|
||||
}
|
||||
if (bytes == size)
|
||||
return (bytes + strlen(src));
|
||||
|
||||
while ((ch = *p++)) {
|
||||
if (bytes + 1 < size)
|
||||
*q++ = ch;
|
||||
|
||||
bytes++;
|
||||
}
|
||||
|
||||
*q = '\0';
|
||||
return bytes;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* strlcpy.c
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t strlcpy(char *dst, const char *src, size_t size)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
char *q = dst;
|
||||
const char *p = src;
|
||||
char ch;
|
||||
|
||||
while ((ch = *p++)) {
|
||||
if (bytes + 1 < size)
|
||||
*q++ = ch;
|
||||
|
||||
bytes++;
|
||||
}
|
||||
|
||||
/* If size == 0 there is no space for a final null... */
|
||||
if (size)
|
||||
*q = '\0';
|
||||
|
||||
return bytes;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# 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: babblesim/nrfx
|
||||
pkg.description: nrfx wrapper for BabbleSim
|
||||
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||
pkg.homepage: "https://mynewt.apache.org/"
|
||||
pkg.type: sdk
|
||||
|
||||
pkg.cflags: -std=gnu99
|
||||
pkg.include_dirs:
|
||||
- src/
|
||||
- src/drivers/
|
||||
- src/hal/
|
||||
- src/mdk/
|
||||
|
||||
pkg.deps:
|
||||
- "@apache-mynewt-core/hw/hal"
|
||||
|
||||
pkg.pre_build_cmds:
|
||||
scripts/link_nrfx.sh: 1
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/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.
|
||||
#
|
||||
|
||||
mkdir -p ./src/
|
||||
for f in nrfx.h drivers hal mdk; do
|
||||
ln -sfn ${NRFX_BASE}/${f} ./src/${f}
|
||||
done
|
||||
Reference in New Issue
Block a user