Initial commit

Combined BM-Lite SDK and examples for Raspberry Pi and nRF52840 MCU
into one project
This commit is contained in:
Andrey Perminov 2021-06-21 13:49:30 -07:00
commit a8bf0d4d76
198 changed files with 105479 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
out
.cproject
.project
.cortex-debug.*.json

131
BMLite_examples/Makefile Normal file
View File

@ -0,0 +1,131 @@
# Copyright (c) 2020 Fingerprint Cards AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://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.
# Make sure that 'all' target become default target
.DEFAULT_GOAL := all
PLATFORM ?= RaspberryPi
APP ?= console_app
PRODUCT := $(APP)
# Setup paths
ROOT := ..
HAL_BASE := $(ROOT)/HAL_Driver
HAL_PATH := $(HAL_BASE)/$(PLATFORM)
BMLITE_PATH := $(ROOT)/BMLite_sdk
APP_PATH := $(ROOT)/BMLite_examples
OUT_BASE := $(APP_PATH)/out
OUT := $(OUT_BASE)/$(APP)/$(PLATFORM)
HAL_DIRS = $(subst $(HAL_BASE),, $(sort $(dir $(wildcard $(HAL_BASE)/*/))))
HAL_LIST = $(subst /,,$(HAL_DIRS))
APP_LIST = $(subst /,, $(sort $(dir $(wildcard */))))
ifneq ($(PLATFORM),)
ifeq ($(filter $(PLATFORM),$(HAL_LIST)),)
$(error "Unknown platform: $(PLATFORM). Use one of $(HAL_LIST)")
endif
endif
ifneq ($(APP),)
ifeq ($(filter $(APP),$(APP_LIST)),)
$(error "Unknown application: $(APP). Use one of $(HAL_LIST)")
endif
endif
ifeq ($(PLATFORM),RaspberryPi)
ifeq ($(APP),embedded_app)
$(error 'embedded_app is not supported for $(PLATFORM)')
endif
else
ifeq ($(APP),console_app)
$(error 'console_app is not supported for $(PLATFORM)')
endif
endif
# Main target
TARGET := $(OUT)/$(PRODUCT)
# Common flags
CFLAGS +=\
-std=c99 \
-Wall \
-Wextra \
-Werror \
-Wno-unused-parameter \
-fdata-sections \
-ffunction-sections \
-MMD \
-MP
ifeq ($(DEBUG),y)
CFLAGS +=\
-g3\
-Og\
-DDEBUG
endif
# Include main application
include $(APP_PATH)/$(APP)/app.mk
# Include BM-Lite SDK
include $(BMLITE_PATH)/bmlite.mk
# Include HAL driver
include $(HAL_PATH)/$(PLATFORM).mk
# Object files and search paths
VPATH += $(sort $(dir $(C_SRCS)))
OBJECTS = $(patsubst %.c,$(OUT)/obj/%.o,$(notdir $(C_SRCS)))
# Dependency files
DEP := $(OBJECTS:.o=.d)
DEP_CFLAGS=$(OUT)/dep_cflags.txt
all: $(TARGET)
# Create binary from object files and external libraries
$(TARGET): $(OBJECTS) $(DEP_CFLAGS) $(S_SRCS)
@mkdir -p $(@D)
$(CC) $(CFLAGS) $(C_INC) $(S_SRCS) $(OBJECTS) $(LDFLAGS) -o $@
# Compile source files
$(OUT)/obj/%.o: %.c $(DEP_CFLAGS)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(C_INC) -o $@ -c $<
# Detect changes in CFLAGS
$(DEP_CFLAGS): force
@mkdir -p $(dir $@)
@echo '$(CFLAGS)' | cmp -s - $@ || echo '$(CFLAGS)' > $@
-include $(DEP)
# Empty rule for dep files, they will be created when compiling
%.d: ;
list_apps:
@echo Available apps: $(APP_LIST)
list_hals:
@echo Available HAL: $(HAL_LIST)
clean:
rm -rf $(OUT)
clean_all:
rm -rf $(OUT_BASE)
.PHONY: clean clean_all force

View File

@ -0,0 +1,13 @@
# BM-Lite Raspberry PI example
BM-Lite example console application for Raspberry Pi 3.
Based on [BM-LIte Development Kit](https://www.fingerprints.com/solutions/access/bm-lite-development-kit/ "BM-LIte Development Kit")
### HW configuration
| | PIN # |
| :------------ | :------------: |
| BMLITE_RESET | 0 |
| BMLITE_IRQ | 22 |
| SPI_CHANNEL | 1 |
HW configuration can be changed in **BMLite_examples/RaspberryPi/inc/raspberry_pi_hal.h**

View File

@ -0,0 +1,27 @@
# Copyright (c) 2020 Fingerprint Cards AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://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.
# C source files
APP_DIR = $(APP_PATH)/$(APP)
C_SRCS += $(wildcard $(APP_DIR)/src/*.c)
# Include directories
PATH_INC += $(APP_DIR)/inc
C_INC += $(addprefix -I,$(PATH_INC))
CFLAGS +=\
-DBMLITE_USE_CALLBACK \

View File

@ -0,0 +1,359 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for FPC BM-Lite applications
*
* 04/14/2020: Added SPI interface support
*/
/**
* @file main.c
* @brief Main file for FPC BM-Lite Communication example.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include "bmlite_if.h"
#include "hcp_tiny.h"
#include "platform.h"
#include "bmlite_hal.h"
#include "platform_rpi.h"
#define DATA_BUFFER_SIZE 102400
static uint8_t hcp_txrx_buffer[MTU];
static uint8_t hcp_data_buffer[DATA_BUFFER_SIZE];
static HCP_comm_t hcp_chain = {
.read = platform_bmlite_receive,
.write = platform_bmlite_send,
.pkt_buffer = hcp_data_buffer,
.txrx_buffer = hcp_txrx_buffer,
.pkt_size = 0,
.pkt_size_max = sizeof(hcp_data_buffer),
.phy_rx_timeout = 2000,
};
static void help(void)
{
fprintf(stderr, "BEP Host Communication Application\n");
fprintf(stderr, "Syntax: bep_host_com [-s] [-p port] [-b baudrate] [-t timeout]\n");
}
void bmlite_on_error(bmlite_error_t error, int32_t value)
{
printf("Error: %d, return code %d\n", error, (int16_t)value);
}
void bmlite_on_start_capture()
{
printf("Put finger on the sensor\n");
}
void bmlite_on_finish_capture()
{
printf("Remove finger from the sensor\n");
}
void bmlite_on_start_enroll()
{
printf("Start enrolling\n");
}
void bmlite_on_finish_enroll()
{
printf("Finish enrolling\n");
}
void bmlite_on_start_enrollcapture() {}
void bmlite_on_finish_enrollcapture() {}
void bmlite_on_identify_start()
{
printf("Start Identifying\n");
}
void bmlite_on_identify_finish()
{
printf("Finish Identifying\n");
}
void save_to_pgm(FILE *f, uint8_t *image, int res_x, int res_y)
{
/* Print 8-bpp PGM ASCII header */
fprintf(f, "P2\n%d %d\n255\n", res_x, res_y);
for (int y = 0; y < res_y; y++) {
for (int x = 0; x < res_x; x++, image++)
fprintf(f,"%d ", *image);
fprintf(f,"\n");
}
fprintf(f,"\x04"); /* End Of Transmission */
}
int main (int argc, char **argv)
{
int index;
int c;
rpi_initparams_t rpi_params;
rpi_params.iface = COM_INTERFACE;
rpi_params.hcp_comm = &hcp_chain;
rpi_params.baudrate = 921600;
rpi_params.timeout = 5;
rpi_params.port = NULL;
opterr = 0;
while ((c = getopt (argc, argv, "sb:p:t:")) != -1) {
switch (c) {
case 's':
rpi_params.iface = SPI_INTERFACE;
if(rpi_params.baudrate == 921600)
rpi_params.baudrate = 1000000;
break;
case 'b':
rpi_params.baudrate = atoi(optarg);
break;
case 'p':
rpi_params.port = optarg;
break;
case 't':
rpi_params.timeout = atoi(optarg);
break;
case '?':
if (optopt == 'b')
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf(stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
help();
exit(1);
}
}
if (rpi_params.iface == COM_INTERFACE && rpi_params.port == NULL) {
printf("port must be specified\n");
help();
exit(1);
}
for (index = optind; index < argc; index++) {
printf ("Non-option argument %s\n", argv[index]);
}
if(platform_init(&rpi_params) != FPC_BEP_RESULT_OK) {
help();
exit(1);
}
while(1) {
char cmd[100];
fpc_bep_result_t res = FPC_BEP_RESULT_OK;
uint16_t template_id;
bool match;
rpi_clear_screen();
printf("BM-Lite Interface\n");
if (rpi_params.iface == SPI_INTERFACE)
printf("SPI port: speed %d Hz\n", rpi_params.baudrate);
else
printf("Com port: %s [speed: %d]\n", rpi_params.port, rpi_params.baudrate);
printf("Timeout: %ds\n", rpi_params.timeout);
printf("-------------------\n\n");
printf("Possible options:\n");
printf("a: Enroll finger\n");
printf("b: Capture and identify finger\n");
printf("c: Remove all templates\n");
printf("d: Save template\n");
printf("e: Remove template\n");
printf("l: List of templates\n");
printf("t: Save template to file\n");
printf("T: Push template from file\n");
printf("f: Capture image\n");
printf("g: Pull captured image\n");
printf("h: Get version\n");
printf("r: SW Reset\n");
printf("q: Exit program\n");
printf("\nOption>> ");
fgets(cmd, sizeof(cmd), stdin);
switch (cmd[0]) {
case 'a':
res = bep_enroll_finger(&hcp_chain);
break;
case 'b':
res = bep_identify_finger(&hcp_chain, 0, &template_id, &match);
if (res == FPC_BEP_RESULT_OK) {
if (match) {
printf("Match with template id: %d\n", template_id);
} else {
printf("No match\n");
}
}
break;
case 'c':
res = bep_template_remove_all(&hcp_chain);
break;
case 'd':
printf("Template id: ");
fgets(cmd, sizeof(cmd), stdin);
template_id = atoi(cmd);
res = bep_template_save(&hcp_chain, template_id);
// res = bep_template_remove_ram(&hcp_chain);
break;
case 'e':
printf("Template id: ");
fgets(cmd, sizeof(cmd), stdin);
template_id = atoi(cmd);
res = bep_template_remove(&hcp_chain, template_id);
break;
case 'l':
res = bep_template_get_ids(&hcp_chain);
if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) {
printf("Template list\n");
for(uint i=0; i < hcp_chain.arg.size/2; i++) {
printf("%d ", *(uint16_t *)(hcp_chain.arg.data+i*2));
}
printf("\n");
}
break;
case 'f': {
printf("Timeout (ms): ");
fgets(cmd, sizeof(cmd), stdin);
uint32_t prev_timeout = hcp_chain.phy_rx_timeout;
hcp_chain.phy_rx_timeout = atoi(cmd);
res = bep_capture(&hcp_chain, atoi(cmd));
hcp_chain.phy_rx_timeout = prev_timeout;
break;
}
case 'g': {
uint32_t size;
res = bep_image_get_size(&hcp_chain, &size);
if (res == FPC_BEP_RESULT_OK) {
uint8_t *buf = malloc(size);
if (buf) {
res = bep_image_get(&hcp_chain, buf, size);
if (res == FPC_BEP_RESULT_OK) {
// if(size != hcp_chain.arg.size) {
printf("Image size: %d. Received %d bytes\n", size, hcp_chain.arg.size);
// }
FILE *f = fopen("image.raw", "wb");
if (f) {
fwrite(buf, 1, size, f);
fclose(f);
printf("Image saved as image.raw\n");
}
f = fopen("image.pgm", "wb");
if(f) {
save_to_pgm(f, buf, 160, 160);
fclose(f);
printf("Image saved as image.pgm\n");
}
free(buf);
}
}
}
break;
}
case 'T': {
uint32_t size;
printf("Read template from file: ");
fscanf(stdin, "%s", cmd);
uint8_t *buf = malloc(102400);
FILE *f = fopen(cmd, "rb");
if (f) {
size = fread(buf, 1, 102400, f);
fclose(f);
if(size > 0) {
printf("Pushing template size %d\n", size);
res = bep_template_put(&hcp_chain, buf, size);
if (res != FPC_BEP_RESULT_OK) {
printf("Pushing template error: %d\n", res);
}
}
} else {
printf("Can't open %s\n", cmd);
}
free(buf);
break;
}
case 't': {
uint8_t *buf = malloc(102400);
printf("Save template to file: ");
fscanf(stdin, "%s", cmd);
if (buf) {
res = bep_template_get(&hcp_chain, buf, 102400);
if (res == FPC_BEP_RESULT_OK) {
// if(size != hcp_chain.arg.size) {
printf("Template size received %d bytes\n", hcp_chain.arg.size);
// }
FILE *f = fopen(cmd, "wb");
if (f) {
fwrite(buf, 1, hcp_chain.arg.size, f);
fclose(f);
printf("Image saved as %s\n", cmd);
}
}
}
free(buf);
break;
}
case 'h': {
char version[100];
memset(version, 0, 100);
res = bep_version(&hcp_chain, version, 99);
if (res == FPC_BEP_RESULT_OK) {
printf("%s\n", version);
}
break;
}
case 'r':
bep_sw_reset(&hcp_chain);
break;
case 'q':
return 0;
default:
printf("\nUnknown command\n");
}
if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) {
printf("\nCommand succeded\n");
} else {
printf("\nCommand failed with error code %d\n", hcp_chain.bep_result);
}
if (res == FPC_BEP_RESULT_OK) {
printf("Transfer succeded\n");
} else {
printf("Transfer failed with error code %d\n", res);
}
printf("Press any key to continue...");
fgets(cmd, sizeof(cmd), stdin);
}
return 0;
}

View File

@ -0,0 +1,6 @@
## FPC BM-Lite example application
Demo application. Suitable for any microcontroller.
Use a HW button to start enrolling and show authentication result using LED.

View File

@ -0,0 +1,26 @@
# Copyright (c) 2020 Fingerprint Cards AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://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.
# C source files
APP_DIR = $(APP_PATH)/$(APP)
C_SRCS += $(wildcard $(APP_DIR)/src/*.c)
# Include directories
PATH_INC += $(APP_DIR)/inc
C_INC += $(addprefix -I,$(PATH_INC))
CFLAGS +=\
-DBMLITE_USE_CALLBACK \

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for running on microcontrollers
*/
/**
* @file main.c
* @brief Main file for FPC BM-Lite Communication example.
*/
#include <unistd.h>
#include <string.h>
#include "bmlite_if.h"
#include "hcp_tiny.h"
#include "platform.h"
#include "bmlite_hal.h"
#define DATA_BUFFER_SIZE (1024*5)
static uint8_t hcp_txrx_buffer[MTU];
static uint8_t hcp_data_buffer[DATA_BUFFER_SIZE];
static HCP_comm_t hcp_chain = {
.read = platform_bmlite_receive,
.write = platform_bmlite_send,
.pkt_buffer = hcp_data_buffer,
.txrx_buffer = hcp_txrx_buffer,
.pkt_size = 0,
.pkt_size_max = sizeof(hcp_data_buffer),
.phy_rx_timeout = 2000,
};
void bmlite_on_error(bmlite_error_t error, int32_t value)
{
if(value != FPC_BEP_RESULT_TIMEOUT) {
hal_set_leds(BMLITE_LED_STATUS_ERROR, false);
} else {
// Timeout - not really an error here
hal_set_leds(BMLITE_LED_STATUS_ERROR, true);
}
}
// void bmlite_on_start_capture();
// void bmlite_on_finish_capture();
void bmlite_on_start_enroll()
{
hal_set_leds(BMLITE_LED_STATUS_ENROLL, true);
}
void bmlite_on_finish_enroll()
{
hal_set_leds(BMLITE_LED_STATUS_ENROLL, false);
}
void bmlite_on_start_enrollcapture()
{
hal_set_leds(BMLITE_LED_STATUS_WAITTOUCH, true);
}
void bmlite_on_finish_enrollcapture()
{
hal_set_leds(BMLITE_LED_STATUS_READY, false);
}
void bmlite_on_identify_start()
{
hal_set_leds(BMLITE_LED_STATUS_READY, true);
}
// void bmlite_on_identify_finish();
int main (int argc, char **argv)
{
platform_init(NULL);
{
char version[100];
uint16_t template_id;
uint32_t current_id = 0;
bool match;
// These two lines for debug purpose only
memset(version, 0, 100);
fpc_bep_result_t res = bep_version(&hcp_chain, version, 99);
while (1)
{
uint32_t btn_time = hal_get_button_press_time();
hal_set_leds(BMLITE_LED_STATUS_READY,0);
if (btn_time < 200) {
// nothing hapened
} else if (btn_time < 5000) {
// Enroll
res = bep_enroll_finger(&hcp_chain);
res = bep_template_save(&hcp_chain, current_id++);
} else {
// Erase All templates
hal_set_leds(BMLITE_LED_STATUS_DELETE_TEMPLATES, true);
res = bep_template_remove_all(&hcp_chain);
current_id = 0;
}
res = bep_identify_finger(&hcp_chain, 0, &template_id, &match);
if (res == FPC_BEP_RESULT_TIMEOUT) {
platform_bmlite_reset();
} else if (res != FPC_BEP_RESULT_OK) {
continue;
}
hal_set_leds(BMLITE_LED_STATUS_MATCH, match);
res = sensor_wait_finger_not_present(&hcp_chain, 0);
}
}
}

13
BMLite_sdk/bmlite.mk Normal file
View File

@ -0,0 +1,13 @@
# Binary sources
BMLITE_SDK = $(ROOT)/BMLite_sdk
VPATH += $(BMLITE_SDK)
C_INC += -I$(BMLITE_SDK)/inc
# Source Folders
VPATH += $(BMLITE_SDK)/src/
# C Sources
C_SRCS += $(notdir $(wildcard $(BMLITE_SDK)/src/*.c))

132
BMLite_sdk/inc/bmlite_hal.h Executable file
View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*/
/**
* @file bmlite_hal.h
* @brief BM-Lite HAL functions.
*
* All functions must be implemented in order to support BM-Lite on a Board
*/
#ifndef BMLITE_H
#define BMLITE_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "fpc_bep_types.h"
#ifdef __arm__
typedef uint32_t hal_tick_t;
#else
typedef uint64_t hal_tick_t;
#endif
/**
* @brief LED status.
*
* Different LED status.
*/
typedef enum {
BMLITE_LED_STATUS_READY = 0,
BMLITE_LED_STATUS_MATCH,
BMLITE_LED_STATUS_WAITTOUCH,
BMLITE_LED_STATUS_ENROLL,
BMLITE_LED_STATUS_DELETE_TEMPLATES,
BMLITE_LED_STATUS_ERROR,
} platform_led_status_t;
/*
* @brief Board initialization
* @param[in] params - pointer to additional parameters
*/
fpc_bep_result_t hal_board_init(void *params);
/*
* @brief Control BM-Lite Reset pin
* @param[in] True - Activate RESET
* False - Deactivate RESET
*/
void hal_bmlite_reset(bool state);
/*
* @brief SPI write-read
* @param[in] Write buffer
* @param[in] Read buffer
* @param[in] Size
* @param[in] Leave CS asserted
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t hal_bmlite_spi_write_read(uint8_t *write, uint8_t *read, size_t size,
bool leave_cs_asserted);
/*
* @brief Check if BM-Lite IRQ pin is set
* @return ::bool
*/
bool hal_bmlite_get_status(void);
/**
* @brief Initializes timebase. Starts system tick counter.
*/
void hal_timebase_init(void);
/**
* @brief Reads the system tick counter.
*
* @return Tick count since hal_timebase_init() call. [ms]
*/
hal_tick_t hal_timebase_get_tick(void);
/**
* @brief Busy wait.
*
* @param[in] ms Time to wait [ms].
* 0 => return immediately
* 1 => wait at least 1ms etc.
*/
void hal_timebase_busy_wait(uint32_t ms);
/**
* Optional functions for Buttons & Leds control
*/
/**
* @brief Get button press time (msec)
*
* @return ::uint32_t
*/
uint32_t hal_get_button_press_time(void);
/**
* @brief Check if button was pressed and released.
*
* @return Button press time in milli seconds.
*/
uint32_t hal_check_button_pressed(void);
/**
* @brief Set LED(s) status
* @param[in] Status
* @param[in] Status modifier
*/
void hal_set_leds(platform_led_status_t status, uint16_t mode);
#endif /* BMLITE_H */

365
BMLite_sdk/inc/bmlite_if.h Normal file
View File

@ -0,0 +1,365 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 BMLITE_IF_H
#define BMLITE_IF_H
#include "hcp_tiny.h"
#include "bmlite_if_callbacks.h"
/**
* @brief Enroll finger. Created template must be saved to FLASH storage
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain);
/**
* @brief Capture and identify finger against existing templates in Flash storage
*
* @param[in] chain - HCP com chain
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
* set to 0 for waiting indefinitely
*
* @param[out] template_id - pointer for matched template ID
* @param[out] match - pointer to match result
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout,
uint16_t *template_id, bool *match);
/**
* @brief Wait for finger present on sensor"
*
* @param[in] chain - HCP com chain
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
* set to 0 for waiting indefinitely
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout);
/**
* @brief Wait for finger not present on sensor"
*
* @param[in] chain - HCP com chain
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
* set to 0 for waiting indefinitely
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout);
/**
* @brief Wait for finger present on sensor and capture image"
*
* @param[in] chain - HCP com chain
* @param[in] timeout - timeout (msec). Maximum timeout 65535 msec
* set to 0 for waiting indefinitely
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout);
/**
* @brief Get size of captured image
*
* @param[in] chain - HCP com chain
*
* @param[out] size
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size);
/**
* @brief Allocates image buffer on FPC BM-LIte
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t image_create(HCP_comm_t *chain);
/**
* @brief Deletes image buffer on FPC BM-LIte
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t image_delete(HCP_comm_t *chain);
/**
* @brief Pull captured image from FPC BM-Lite
*
* @param[in] chain - HCP com chain
*
* @param[in] data - pointer to image buffer
* @param[in] size - size of the image buffer
* if buffer size is not enough the image
* will be truncated
* chain->arg.size will contain real size of the image
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size);
/**
* @brief Push image to FPC BM-Lite
*
* @param[in] chain - HCP com chain
*
* @param[in] data - pointer to image buffer
* @param[in] size - size of the image buffer
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size);
/**
* @brief Extract image features to prepare image for enrolling or matching
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain);
/**
* @brief Identify prepared image against existing templates in Flash storage
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_identify(HCP_comm_t *chain);
/**
* @brief Save template after enroll is finished to FLASH storage
*
* @param[in] chain - HCP com chain
* @param[out] template_id - template ID
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id);
/**
* @brief Remove template from RAM
*
* @param[in] chain - HCP com chain
* @param[in] template_id - template ID
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain);
/**
* @brief Pull template stored in RAM from FPC BM-Lite
*
* @param[in] chain - HCP com chain
*
* @param[in] data - pointer to template buffer
* @param[in] size - size of the template buffer
* if buffer size is not enough the template
* will be truncated
* chain->arg.size will contain real size of the template
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size);
/**
* @brief Push template to FPC BM-Lite and stored it to RAM
*
* @param[in] chain - HCP com chain
*
* @param[in] data - pointer to template buffer
* @param[in] size - size of the template buffer
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length);
/**
* @brief Remove template from FLASH storage
*
* @param[in] chain - HCP com chain
* @param[in] template_id - template ID
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id);
/**
* @brief Remove all templates from FLASH storage
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain);
/**
* @brief Copy template from FLASH storage to RAM
*
* @param[in] chain - HCP com chain
* @param[in] template_id - template ID
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id);
/**
* @brief Remove template from FLASH storage
*
* @param[in] chain - HCP com chain
* @param[out] template_id - template ID
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count);
/**
* @brief Get array of template ID stored on FPC BM-LIte
*
* @param[in] chain - HCP com chain
* @return ::fpc_bep_result_t
* chain->arg.data - pointer to array of uint16_t of IDs
* chain->arg.size - length of the array (in bytes). For calculating
* number of templates divide the arg.size by 2
*/
fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain);
/**
* @brief Software reset of FCP BM-Lite
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain);
/**
* @brief Calibrate FPC BM-LIte sensor and store calibration data to FLASH storage
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*
* FPC BM-Lite must be restarted to activate new calibration data
*/
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain);
/**
* @brief Remove FPC BM-LIte sensor calibration data from FLASH storage
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*
* FPC BM-Lite must be restarted to activate
*/
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain);
/**
* @brief Get version of FPC BM-LIte firmware
*
* @param[in] chain - HCP com chain
* @param[in] version - pointer to data buffer
* @param[in] size - size of the data buffer
* if buffer size is not enough the data
* will be truncated
* chain->arg.size will contain real size of the data
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len);
/**
* @brief Get version of FPC BM-LIte firmware
*
* @param[in] chain - HCP com chain
* @param[in] unique_id - pointer to data buffer
* chain->arg.size will contain real size of the data
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id);
/**
* @brief Set requested UART communication speed
*
* @param[in] chain - HCP com chain
* @param[in] speed - UART speed
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed);
/**
* @brief Get current UART communication speed
*
* @param[in] chain - HCP com chain
* @param[out] speed - UART speed
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed);
/**
* @brief Reset FPC BM-Lite fingerprint sensor
*
* @param[in] chain - HCP com chain
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain);
/**
* @brief Build and send command to FPC BM-Lite and receive answer
*
* @param[in] chain - HCP com chain
* @param[in] cmd - BM-Lite command
* @param[in] arg_type - Argument without parameters
* set to ARG_NONE if the command has no argument
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type);
/**
* @brief Build and send command with additiona argument with parameters
*
* @param[in] chain - HCP com chain
* @param[in] cmd - BM-Lite command
* @param[in] arg1_type - argument 1 without parameters
* set to ARG_NONE if the command has no argument without paramener
* @param[in] arg2_type - argument 2
* @param[in] arg2_data - data pointer for argument 2
* set to 0 if argument 2 has no parameter
* @param[in] arg2_length - length of data for argument 2
* set to 0 if argument 2 has no parameter
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length);
#endif

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 BMLITE_IF_CALLBACKS_H
#define BMLITE_IF_CALLBACKS_H
#include <stdint.h>
#ifndef BMLITE_USE_CALLBACK
#define bmlite_on_error(error, value)
#define bmlite_on_start_capture()
#define bmlite_on_finish_capture()
#define bmlite_on_finish_enroll()
#define bmlite_on_start_enroll()
#define bmlite_on_start_enrollcapture()
#define bmlite_on_finish_enrollcapture()
#define bmlite_on_identify_start()
#define bmlite_on_identify_finish()
#else
typedef enum {
BMLITE_ERROR_OK = 0,
BMLITE_ERROR_CAPTURE,
BMLITE_ERROR_CAPTURE_START,
BMLITE_ERROR_ENROLL_START,
BMLITE_ERROR_ENROLL_ADD,
BMLITE_ERROR_ENROLL_FINISH,
BMLITE_ERROR_WRONG_ANSWER,
BMLITE_ERROR_FINGER_WAIT,
BMLITE_ERROR_IDENTYFY,
BMLITE_ERROR_TEMPLATE_SAVE,
BMLITE_ERROR_TEMPLATE_DELETE,
BMLITE_ERROR_TEMPLATE_COUNT,
BMLITE_ERROR_TEMPLATE_GETIDS,
BMLITE_ERROR_IMAGE_EXTRACT,
BMLITE_ERROR_IMAGE_GETSIZE,
BMLITE_ERROR_IMAGE_GET,
BMLITE_ERROR_GETVERSION,
BMLITE_ERROR_SW_RESET,
BMLITE_ERROR_CALIBRATE,
BMLITE_ERROR_CALIBRATE_DELETE,
BMLITE_ERROR_SEND_CMD,
BMLITE_ERROR_GET_ARG,
} bmlite_error_t;
/**
* @brief Error Callback function
*
* @param[in] Callback Error Code
* @param[in] BEP result code
*/
void bmlite_on_error(bmlite_error_t error, int32_t value);
/**
* @brief Starting Capture Callback function
*/
void bmlite_on_start_capture();
/**
* @brief Finishing Capture Callback function
*/
void bmlite_on_finish_capture();
/**
* @brief Starting Enroll Callback function
*/
void bmlite_on_start_enroll();
/**
* @brief Finishing Enroll Callback function
*/
void bmlite_on_finish_enroll();
/**
* @brief Starting Capture for Enroll Callback function
*/
void bmlite_on_start_enrollcapture();
/**
* @brief Finishing Capture for Enroll Callback function
*/
void bmlite_on_finish_enrollcapture();
/**
* @brief Starting Identify Callback function
*/
void bmlite_on_identify_start();
/**
* @brief Finishing Identify Callback function
*/
void bmlite_on_identify_finish();
#endif // BMLITE_USE_CALLBACK
#endif

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 FPC_BEP_TYPES_H
#define FPC_BEP_TYPES_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/**
* @file fpc_bep_types.h
* @brief Biometric Embedded Platform types.
*
* This is the common types used by Biometric Embedded Platform (BEP) library.
*
* @note This is a work-in-progress specification. Implementers are informed
* that this API may change without providing any backward compatibility.
* However it is FPC's ambition that the API shall remain compatible between
* releases.
*/
/** @brief Common result returned by BEP functions. */
typedef enum {
/** No errors occurred. */
FPC_BEP_RESULT_OK = 0,
/** General error. */
FPC_BEP_RESULT_GENERAL_ERROR = -1,
/** Internal error. */
FPC_BEP_RESULT_INTERNAL_ERROR = -2,
/** Invalid argument. */
FPC_BEP_RESULT_INVALID_ARGUMENT = -3,
/** The functionality is not implemented. */
FPC_BEP_RESULT_NOT_IMPLEMENTED = -4,
/** The operation was cancelled. */
FPC_BEP_RESULT_CANCELLED = -5,
/** Out of memory. */
FPC_BEP_RESULT_NO_MEMORY = -6,
/** Resources are not available. */
FPC_BEP_RESULT_NO_RESOURCE = -7,
/** An I/O error occurred. */
FPC_BEP_RESULT_IO_ERROR = -8,
/** Sensor is broken. */
FPC_BEP_RESULT_BROKEN_SENSOR = -9,
/** The operation cannot be performed in the current state. */
FPC_BEP_RESULT_WRONG_STATE = -10,
/** The operation timed out. */
FPC_BEP_RESULT_TIMEOUT = -11,
/** The ID is not unique. */
FPC_BEP_RESULT_ID_NOT_UNIQUE = -12,
/** The ID is not found. */
FPC_BEP_RESULT_ID_NOT_FOUND = -13,
/** The format is invalid. */
FPC_BEP_RESULT_INVALID_FORMAT = -14,
/** An image capture error occurred. */
FPC_BEP_RESULT_IMAGE_CAPTURE_ERROR = -15,
/** Sensor hardware id or sensor configuration mismatch. */
FPC_BEP_RESULT_SENSOR_MISMATCH = -16,
/** Invalid parameter. */
FPC_BEP_RESULT_INVALID_PARAMETER = -17,
/** Missing Template. */
FPC_BEP_RESULT_MISSING_TEMPLATE = -18,
/** Invalid Calibration.*/
FPC_BEP_RESULT_INVALID_CALIBRATION = -19,
/** Calibration/template storage not formatted.*/
FPC_BEP_RESULT_STORAGE_NOT_FORMATTED = -20,
/** Sensor hasn't been initialized. */
FPC_BEP_RESULT_SENSOR_NOT_INITIALIZED = -21,
/** Enroll fail after too many bad images. */
FPC_BEP_RESULT_TOO_MANY_BAD_IMAGES = -22,
/** Cryptographic operation failed. */
FPC_BEP_RESULT_CRYPTO_ERROR = -23,
/** The functionality is not supported. */
FPC_BEP_RESULT_NOT_SUPPORTED = -24,
/** Finger not stable during image capture. */
FPC_BEP_FINGER_NOT_STABLE = -25,
/** The functionality could not be used before it's initialized. */
FPC_BEP_RESULT_NOT_INITIALIZED = -26,
} fpc_bep_result_t;
#endif /* FPC_BEP_TYPES_H */

37
BMLite_sdk/inc/fpc_crc.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 FPC_CRC_H
#define FPC_CRC_H
/**
* @file fpc_crc.h
* @brief Functionality for calculating CRC-32.
*/
#include <stdint.h>
/**
* @brief Calculates CRC-32 value for the data in the buffer.
*
* @param crc Accumulated CRC-32 value, must be 0 on first call.
* @param buf Buffer with data to calculate CRC-32 for.
* @param size Size of buffer in number of bytes.
* @return CRC-32 value for the data in buffer.
*/
uint32_t fpc_crc(uint32_t crc, const void *buf, uint32_t size);
#endif /* FPC_CRC_H */

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*/
/**
* @file fpc_hcp_common.h
* @brief Host Communication Protocol common type definitions.
*/
#ifndef FPC_HCP_COMMON_H
#define FPC_HCP_COMMON_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** Returns the smallest of two values. */
#define HCP_MIN(x, y) (((x) < (y)) ? (x) : (y))
/** Program specific commands base number */
#define CMD_APP_BASE_VAL 0xE000
/** Program specific arguments base number */
#define ARG_APP_BASE_VAL 0x7000
/** HCP Command definitions */
enum fpc_hcp_cmd {
CMD_NONE = 0x0000,
/* Biometry */
CMD_CAPTURE = 0x0001,
CMD_ENROLL = 0x0002,
CMD_IDENTIFY = 0x0003,
CMD_MATCH = 0x0004,
CMD_IMAGE = 0x0005,
CMD_TEMPLATE = 0x0006,
CMD_WAIT = 0x0007,
CMD_SETTINGS = 0x0008,
/* Sensor */
CMD_NAVIGATE = 0x1001,
CMD_SENSOR = 0x1002,
CMD_DEADPIXELS = 0x1003,
/* Security */
CMD_CONNECT = 0x2001,
CMD_RECONNECT = 0x2002,
/* Firmware */
CMD_RESET = 0x3002,
CMD_CANCEL = 0x3003,
CMD_INFO = 0x3004,
/* Storage */
CMD_STORAGE_TEMPLATE = 0x4002,
CMD_STORAGE_CALIBRATION = 0x4003,
CMD_STORAGE_LOG = 0x4004,
CMD_STORAGE_SETTINGS = 0x4005,
/* Hardware */
CMD_TEST = 0x5001,
CMD_MCU = 0x5002,
CMD_GPIO = 0x5003,
/* Communication */
CMD_COMMUNICATION = 0x6001,
/* Application specific commands */
CMD_APP_BASE = CMD_APP_BASE_VAL,
/* Debug */
CMD_DIAG = 0xF003,
CMD_FFFF = 0xFFFF,
};
/** HCP Command type */
typedef uint16_t fpc_hcp_cmd_t;
/** HCP Argument definitions */
enum fpc_hcp_arg {
ARG_NONE = 0x0000,
/* Biometry */
ARG_FINGER_DOWN = 0x0001,
ARG_FINGER_UP = 0x0002,
ARG_START = 0x0003,
ARG_ADD = 0x0004,
ARG_FINISH = 0x0005,
ARG_ID = 0x0006,
ARG_ALL = 0x0007,
ARG_EXTRACT = 0x0008,
ARG_MATCH_IMAGE = 0x0009,
ARG_MATCH = 0x000A,
/* Data */
ARG_ACQUIRE = 0x1001,
ARG_RELEASE = 0x1002,
ARG_SET = 0x1003,
ARG_GET = 0x1004,
ARG_UPLOAD = 0x1005,
ARG_DOWNLOAD = 0x1006,
ARG_CREATE = 0x1007,
ARG_SAVE = 0x1008,
ARG_DELETE = 0x1009,
ARG_DATA = 0x100A,
ARG_UPDATE = 0x100B,
ARG_SEQ_NR = 0x100C,
ARG_SEQ_LEN = 0x100D,
/* Results */
ARG_RESULT = 0x2001,
ARG_COUNT = 0x2002,
ARG_SIZE = 0x2003,
ARG_LEVEL = 0x2004,
ARG_FORMAT = 0x2005,
ARG_FLAG = 0x2006,
ARG_PROPERTIES = 0x2007,
ARG_SPEED = 0x2008,
ARG_PROD_TEST = 0x2009,
/* Sensor */
ARG_SENSOR_TYPE = 0x3001,
ARG_WIDTH = 0x3002,
ARG_HEIGHT = 0x3003,
ARG_RESET = 0x3004,
ARG_DPI = 0x3005,
ARG_MAX_SPI_CLOCK = 0x3006,
ARG_NUM_SUB_AREAS_WIDTH = 0x3007,
ARG_NUM_SUB_AREAS_HEIGHT = 0x3008,
ARG_IRQ_STATUS = 0x3009,
ARG_RESET_HARD = 0x300A,
/* MCU */
ARG_IDLE = 0x4001,
ARG_SLEEP = 0x4002,
ARG_DEEP_SLEEP = 0x4003,
ARG_POWER_MODE = 0x4004,
ARG_BUSY_WAIT = 0x4005,
/* Misc */
ARG_TIMEOUT = 0x5001,
ARG_DONE = 0x5002,
/* Info */
ARG_BOOT = 0x6001,
ARG_STATUS = 0x6002,
ARG_VERSION = 0x6003,
ARG_UNIQUE_ID = 0x6004,
/* Application specific arguments */
ARG_APP_BASE = ARG_APP_BASE_VAL,
/* VSM */
ARG_NONCE = 0x8001,
ARG_MAC = 0x8002,
ARG_RANDOM = 0x8003,
ARG_CLAIM = 0x8004,
ARG_PUBLIC_KEY = 0x8005,
ARG_CIPHERTEXT = 0x8006,
/* Communication */
ARG_MTU = 0x9001,
/* Debug */
ARG_STACK = 0xE001,
ARG_FILL = 0xE002,
ARG_HEAP = 0xE003,
/* Log */
ARG_MODE = 0xF001,
ARG_DEBUG = 0xF002,
ARG_FFFF = 0xFFFF,
};
/** HCP Argument type */
typedef uint16_t fpc_hcp_arg_t;
/**
* @brief Command Argument
*/
typedef struct fpc_hcp_arg_data {
/** Argument */
fpc_hcp_arg_t arg;
/** Size of data */
uint16_t size;
/** Free data inside HCP */
bool free_data;
/** Pointer to data */
uint8_t *data;
} fpc_hcp_arg_data_t;
/**
* @brief Application Command Packet
*/
typedef struct fpc_hcp_packet {
/** Command ID */
fpc_hcp_cmd_t id;
/** Number of arguments */
uint16_t num_args;
/** Pointer to argument data */
fpc_hcp_arg_data_t *arguments;
} fpc_hcp_packet_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FPC_HCP_COMMON_H */

146
BMLite_sdk/inc/hcp_tiny.h Normal file
View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 HCP_H
#define HCP_H
#include "fpc_bep_types.h"
#include "fpc_hcp_common.h"
/** MTU for HCP physical layer */
#define MTU 256
/** Communication acknowledge definition */
#define FPC_BEP_ACK 0x7f01ff7f
typedef struct {
uint32_t size;
uint8_t *data;
} HCP_arg_t;
typedef struct {
/** Send data to BM-Lite */
fpc_bep_result_t (*write) (uint16_t, const uint8_t *, uint32_t, void *);
/** Receive data from BM-Lite */
fpc_bep_result_t (*read)(uint16_t, uint8_t *, uint32_t, void *);
/** Receive timeout (msec). Applys ONLY to receiving packet from BM-Lite on physical layer */
uint32_t phy_rx_timeout;
/** Data buffer for application layer */
uint8_t *pkt_buffer;
/** Size of data buffer */
uint32_t pkt_size_max;
/** Current size of incoming or outcoming command packet */
uint32_t pkt_size;
/** Buffer of MTU size for transport layer */
uint8_t *txrx_buffer;
/** Values of last argument pulled by bmlite_get_arg
Values are valid only right after bmlite_get_arg() call */
HCP_arg_t arg;
/** Result of execution command on BM-Lite */
fpc_bep_result_t bep_result;
} HCP_comm_t;
/**
* @brief Send prepared command packet to FPC BM-LIte
*
* @param[in] hcp_comm - pointer to HCP_comm struct
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm);
/**
* @brief Receive answer from FPC BM-LIte
*
* @param[in] hcp_comm - pointer to HCP_comm struct
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm);
/**
* @brief Send prepared command packet to FPC BM-LIte and receive answer
*
* @param[in] hcp_comm - pointer to HCP_comm struct
*
* Returns result of executing command in BM-LIte in hcp_comm->bep_result
* if communication with BM-Lite was successful.
* Please not that some BM-Lite command does not return result in ARG_RESULT.
* They return data with some other argument instead.
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm);
/**
* @brief Initialize new command for BM-Lite
*
* @param[in] hcp_comm - pointer to HCP_comm struct
* @param[in] cmd - command to send
* @param[in] arg - Argument for the command without parameterd
* Use ARG_NONE and add arguments by bmlite_add_arg() if
* you need to add argument with parameter
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg);
/**
* @brief Add argument to command.
* Must be used only after command buffer is initialized by bmlite_init_cmd()
*
* @param[in] hcp_comm - pointer to HCP_comm struct
* @param[in] arg_type - argument key
* @param[in] arg_data - argument data
* @param[in] arg_size - argument data length
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, void *arg_data, uint16_t arg_size);
/**
* @brief Search for argument in received answer.
*
* @param[in] hcp_comm - pointer to HCP_comm struct
* @param[in] arg_type - argument key
*
* If found, place pointer to argument data in receiving buffer to hcp_comm->arg.data
* and size of the argument in hcp_comm->arg.size
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type);
/**
* @brief Search for argument in received answer and copy argument's data
* to arg_data
*
* @param[in] hcp_comm - pointer to HCP_comm struct
* @param[in] arg_type - argument key
* @param[out] arg_data - pointer for memory to copy argument value
* @param[out] arg_data_size - size of data area for copying argument value
*
* If found, argument's data will be copyed to arg_data
* If received argument's size greater that arg_data_size, the copyed data will be
* truncated to arg_data_size.
* Still hcp_comm->arg.data will be pointed to argument's data in receiving buffer
* and real size of the argument will be hcp_comm->arg.size
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_size);
#endif

82
BMLite_sdk/inc/platform.h Normal file
View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for FPC BM-Lite applications
*/
#ifndef PLATFORM_H
#define PLATFORM_H
/**
* @file platform.h
* @brief Platform specific function interface
*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "fpc_bep_types.h"
/**
* @brief Initializes board
*
* @param[in] params - pointer to additional parameters.
*/
fpc_bep_result_t platform_init(void *params);
/**
* @brief Does BM-Lite HW Reset
*
*/
void platform_bmlite_reset(void);
/**
* @brief Sends data over communication port in blocking mode.
*
* @param[in] size Number of bytes to send.
* @param[in] data Data buffer to send.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_com_result_t
*/
fpc_bep_result_t platform_bmlite_send(uint16_t size, const uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Receives data from communication port in blocking mode.
*
* @param[in] size Number of bytes to receive.
* @param[in, out] data Data buffer to fill.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_com_result_t
*/
fpc_bep_result_t platform_bmlite_receive(uint16_t size, uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Stops execution if a debug interface is attached.
*/
void platform_halt_if_debug(void);
/**
* @brief Performs a software reset.
*/
void platform_sw_reset(void) __attribute__((__noreturn__));
#endif /* PLATFORM_H */

325
BMLite_sdk/src/bmlite_if.c Normal file
View File

@ -0,0 +1,325 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 "hcp_tiny.h"
#include "bmlite_if.h"
#include "bmlite_hal.h"
#include "platform.h"
#include <stdio.h>
#include "bmlite_if_callbacks.h"
#define MAX_CAPTURE_ATTEMPTS 15
#define MAX_SINGLE_CAPTURE_ATTEMPTS 3
#define CAPTURE_TIMEOUT 3000
#define exit_if_err(c) { bep_result = c; if(bep_result || chain->bep_result) goto exit; }
#define assert(c) { fpc_bep_result_t res = c; if(res) return res; }
#ifdef BMLITE_USE_CALLBACK
/**
* @brief Mock callback functions
*/
__attribute__((weak)) void bmlite_on_error(bmlite_error_t error, int32_t value) { (void)error; (void)value; }
__attribute__((weak)) void bmlite_on_start_capture() {}
__attribute__((weak)) void bmlite_on_finish_capture() {}
__attribute__((weak)) void bmlite_on_start_enroll() {}
__attribute__((weak)) void bmlite_on_finish_enroll() {}
__attribute__((weak)) void bmlite_on_start_enrollcapture() {}
__attribute__((weak)) void bmlite_on_finish_enrollcapture() {}
__attribute__((weak)) void bmlite_on_identify_start() {}
__attribute__((weak)) void bmlite_on_identify_finish() {}
#endif
fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain)
{
uint32_t samples_remaining = 0;
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
bool enroll_done = false;
bmlite_on_start_enroll();
/* Enroll start */
exit_if_err(bmlite_send_cmd(chain, CMD_ENROLL, ARG_START));
for (uint8_t i = 0; i < MAX_CAPTURE_ATTEMPTS; ++i) {
bmlite_on_start_enrollcapture();
bep_result = bep_capture(chain, CAPTURE_TIMEOUT);
bmlite_on_finish_enrollcapture();
if (bep_result != FPC_BEP_RESULT_OK) {
continue;
}
/* Enroll add */
bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_ADD);
if (bep_result != FPC_BEP_RESULT_OK) {
continue;
}
bmlite_get_arg(chain, ARG_COUNT);
samples_remaining = *(uint32_t *)chain->arg.data;
// DEBUG("Enroll samples remaining: %d\n", samples_remaining);
/* Break enrolling if we can't collect enough correct images for enroll*/
if (samples_remaining == 0U) {
enroll_done = true;
break;
}
sensor_wait_finger_not_present(chain, 0);
}
bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_FINISH);
exit:
bmlite_on_finish_enroll();
return (!enroll_done) ? FPC_BEP_RESULT_GENERAL_ERROR : bep_result;
}
fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match)
{
fpc_bep_result_t bep_result;
*match = false;
bmlite_on_identify_start();
exit_if_err(bep_capture(chain, timeout));
exit_if_err(bep_image_extract(chain));
exit_if_err(bep_identify(chain));
exit_if_err(bmlite_get_arg(chain, ARG_MATCH));
*match = *(bool *)chain->arg.data;
if(*match) {
bmlite_get_arg(chain, ARG_ID);
*template_id = *(uint16_t *)chain->arg.data;
// Delay for possible updating template on BM-Lite
hal_timebase_busy_wait(50);
}
exit:
bmlite_on_identify_finish();
return bep_result;
}
fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout)
{
fpc_bep_result_t bep_result;
uint32_t prev_timeout = chain->phy_rx_timeout;
bmlite_on_start_capture();
chain->phy_rx_timeout = timeout;
bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_DOWN, ARG_TIMEOUT, &timeout, sizeof(timeout));
chain->phy_rx_timeout = prev_timeout;
bmlite_on_finish_capture();
return bep_result;
}
fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout)
{
fpc_bep_result_t bep_result;
uint32_t prev_timeout = chain->phy_rx_timeout;
chain->phy_rx_timeout = timeout;
bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_UP, ARG_TIMEOUT, &timeout, sizeof(timeout));
chain->phy_rx_timeout = prev_timeout;
return bep_result;
}
fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout)
{
fpc_bep_result_t bep_result;
uint32_t prev_timeout = chain->phy_rx_timeout;
bmlite_on_start_capture();
chain->phy_rx_timeout = timeout;
for(int i=0; i< MAX_SINGLE_CAPTURE_ATTEMPTS; i++) {
bep_result = bmlite_send_cmd_arg(chain, CMD_CAPTURE, ARG_NONE, ARG_TIMEOUT, &timeout, sizeof(timeout));
if( !(bep_result || chain->bep_result))
break;
}
chain->phy_rx_timeout = prev_timeout;
bmlite_on_finish_capture();
return bep_result;
}
fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size)
{
assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_SIZE));
assert(bmlite_get_arg(chain, ARG_SIZE));
*size = *(uint32_t*)chain->arg.data;
return FPC_BEP_RESULT_OK;
}
fpc_bep_result_t image_create(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_CREATE);
}
fpc_bep_result_t image_delete(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_DELETE);
}
fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size)
{
assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_UPLOAD));
return bmlite_copy_arg(chain, ARG_DATA, data, size);
}
fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size)
{
return bmlite_send_cmd_arg(chain, CMD_IMAGE, ARG_DOWNLOAD, ARG_DATA, data, size);
}
fpc_bep_result_t bep_image_extract(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_IMAGE, ARG_EXTRACT);
}
fpc_bep_result_t bep_identify(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_IDENTIFY, ARG_NONE);
}
fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id)
{
return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_SAVE, ARG_ID, &template_id, sizeof(template_id));
}
fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_DELETE);
}
fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size)
{
assert(bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_UPLOAD));
return bmlite_copy_arg(chain, ARG_DATA, data, size);
}
fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length)
{
return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_DOWNLOAD,
ARG_DATA, data, length);
}
fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id)
{
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE,
ARG_ID, &template_id, sizeof(template_id));
}
fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain)
{
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE,
ARG_ALL, 0, 0);
}
fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id)
{
return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_UPLOAD,
ARG_ID, &template_id, sizeof(template_id));
}
fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count)
{
assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_COUNT));
assert(bmlite_get_arg(chain, ARG_COUNT));
*count = *(uint16_t*)chain->arg.data;
return FPC_BEP_RESULT_OK;
}
fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain)
{
assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_ID));
return bmlite_get_arg(chain, ARG_DATA);
}
fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_RESET, ARG_NONE);
}
fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_NONE);
}
fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain)
{
return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_DELETE);
}
fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len)
{
assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_VERSION, 0, 0));
return bmlite_copy_arg(chain, ARG_VERSION, version, len);
}
fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id)
{
assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_UNIQUE_ID, 0, 0));
return bmlite_copy_arg(chain, ARG_UNIQUE_ID, unique_id, 12);
}
fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed)
{
assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED));
assert(bmlite_add_arg(chain, ARG_SET, 0, 0));
assert(bmlite_add_arg(chain, ARG_DATA, (uint8_t*)&speed, sizeof(speed)));
return bmlite_tranceive(chain);
}
fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed)
{
assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED));
assert(bmlite_add_arg(chain, ARG_GET, 0, 0));
assert(bmlite_tranceive(chain));
return bmlite_copy_arg(chain, ARG_DATA, speed, sizeof(speed));
}
fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain)
{
// Delay for possible updating template on BM-Lite
hal_timebase_busy_wait(50);
return bmlite_send_cmd(chain, CMD_SENSOR, ARG_RESET);
}
fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type)
{
assert(bmlite_init_cmd(chain, cmd, arg_type));
return bmlite_tranceive(chain);
}
fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length)
{
assert(bmlite_init_cmd(chain, cmd, arg1_type));
assert(bmlite_add_arg(chain, arg2_type, arg2_data, arg2_length));
return bmlite_tranceive(chain);
}

88
BMLite_sdk/src/fpc_crc.c Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*/
/**
* @file fpc_crc.c
* @brief CRC32 calculation.
*/
#include <stdint.h>
#include "fpc_crc.h"
/**
* The constants here are for the CRC-32 generator polynomial, as defined in
* the Microsoft Systems Journal, March 1995, pp. 107-108.
*/
static const uint32_t crc32_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t fpc_crc(uint32_t crc, const void *buf, uint32_t size)
{
const uint8_t *p;
p = buf;
crc = crc ^ ~0U;
while (size--) {
crc = crc32_table[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
}
return crc ^ ~0U;
}

308
BMLite_sdk/src/hcp_tiny.c Normal file
View File

@ -0,0 +1,308 @@
/*
* Copyright (c) 2020 Andrey Perminov <andrey.ppp@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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 "platform.h"
#include "fpc_crc.h"
#include "fpc_hcp_common.h"
#include "hcp_tiny.h"
#include "bmlite_if_callbacks.h"
#ifdef DEBUG
#include <stdio.h>
#include <stdlib.h>
#define LOG_DEBUG(...) printf(__VA_ARGS__)
#else
#define LOG_DEBUG(...)
#endif
static uint32_t fpc_com_ack = FPC_BEP_ACK;
static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm);
static fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm);
typedef struct {
uint16_t cmd;
uint16_t args_nr;
uint8_t args[];
} _HCP_cmd_t;
typedef struct {
uint16_t arg;
uint16_t size;
uint8_t pld[];
} _CMD_arg_t;
typedef struct {
uint16_t lnk_chn;
uint16_t lnk_size;
uint16_t t_size;
uint16_t t_seq_nr;
uint16_t t_seq_len;
_HCP_cmd_t t_pld;
} _HPC_pkt_t;
fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg_key)
{
fpc_bep_result_t bep_result;
_HCP_cmd_t *out = (_HCP_cmd_t *)hcp_comm->pkt_buffer;
out->cmd = cmd;
out->args_nr = 0;
hcp_comm->pkt_size = 4;
if(arg_key != ARG_NONE) {
bep_result = bmlite_add_arg(hcp_comm, arg_key, NULL, 0);
if(bep_result) {
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
return bep_result;
}
}
return FPC_BEP_RESULT_OK;
}
fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, void *arg_data, uint16_t arg_size)
{
if(hcp_comm->pkt_size + 4 + arg_size > hcp_comm->pkt_size_max) {
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_NO_MEMORY);
return FPC_BEP_RESULT_NO_MEMORY;
}
((_HCP_cmd_t *)hcp_comm->pkt_buffer)->args_nr++;
_CMD_arg_t *args = (_CMD_arg_t *)(&hcp_comm->pkt_buffer[hcp_comm->pkt_size]);
args->arg = arg_type;
args->size = arg_size;
if(arg_size) {
memcpy(&args->pld, arg_data, arg_size);
}
hcp_comm->pkt_size += 4 + arg_size;
return FPC_BEP_RESULT_OK;
}
fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type)
{
uint16_t i = 0;
uint8_t *buffer = hcp_comm->pkt_buffer;
uint16_t args_nr = ((_HCP_cmd_t *)(buffer))->args_nr;
uint8_t *pdata = (uint8_t *)&((_HCP_cmd_t *)(buffer))->args;
while (i < args_nr && (uint32_t)(pdata - buffer) <= hcp_comm->pkt_size) {
_CMD_arg_t *parg = (_CMD_arg_t *)pdata;
if(parg->arg == arg_type) {
hcp_comm->arg.size = parg->size;
hcp_comm->arg.data = parg->pld;
return FPC_BEP_RESULT_OK;
} else {
i++;
pdata += 4 + parg->size;
}
}
// Ignore missing ARG_RESULT because some command return result other way
// if (arg_type != ARG_RESULT) {
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT);
// }
return FPC_BEP_RESULT_INVALID_ARGUMENT;
}
fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_size)
{
fpc_bep_result_t bep_result;
bep_result = bmlite_get_arg(hcp_comm, arg_key);
if(bep_result == FPC_BEP_RESULT_OK) {
if(arg_data == NULL) {
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_NO_MEMORY);
return FPC_BEP_RESULT_NO_MEMORY;
}
memcpy(arg_data, hcp_comm->arg.data, HCP_MIN(arg_data_size, hcp_comm->arg.size));
} else {
bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT);
return FPC_BEP_RESULT_INVALID_ARGUMENT;
}
return bep_result;
}
fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm)
{
fpc_bep_result_t bep_result;
bep_result = bmlite_send(hcp_comm);
if (bep_result == FPC_BEP_RESULT_OK) {
bep_result = bmlite_receive(hcp_comm);
if (bmlite_get_arg(hcp_comm, ARG_RESULT) == FPC_BEP_RESULT_OK) {
hcp_comm->bep_result = *(int8_t*)hcp_comm->arg.data;
} else {
hcp_comm->bep_result = FPC_BEP_RESULT_OK;
}
}
return bep_result;
}
fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm)
{
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
fpc_bep_result_t com_result = FPC_BEP_RESULT_OK;
uint16_t seq_nr = 0;
uint16_t seq_len = 1;
uint8_t *p = hcp_comm->pkt_buffer;
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
uint16_t buf_len = 0;
while(seq_nr < seq_len) {
bep_result = _rx_link(hcp_comm);
if (!bep_result) {
seq_nr = pkt->t_seq_nr;
seq_len = pkt->t_seq_len;
if(pkt->t_size != pkt->lnk_size - 6) {
com_result = FPC_BEP_RESULT_IO_ERROR;
continue;
}
if(buf_len + pkt->t_size < hcp_comm->pkt_size_max) {
memcpy(p, &pkt->t_pld, pkt->t_size);
p += pkt->t_size;
buf_len += pkt->t_size;
} else {
com_result = FPC_BEP_RESULT_NO_MEMORY;
}
#ifdef DEBUG
if (seq_len > 1)
LOG_DEBUG("Received data chunk %d of %d\n", seq_nr, seq_len);
#endif
} else {
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
return bep_result;
}
}
hcp_comm->pkt_size = buf_len;
if(com_result != FPC_BEP_RESULT_OK) {
bmlite_on_error(BMLITE_ERROR_SEND_CMD, com_result);
}
return com_result;
}
static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm)
{
// Get size, msg and CRC
uint16_t result = hcp_comm->read(4, hcp_comm->txrx_buffer, hcp_comm->phy_rx_timeout, NULL);
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
uint16_t size;
if (result) {
LOG_DEBUG("Timed out waiting for response.\n");
return result;
}
size = pkt->lnk_size;
// Check if size plus header and crc is larger than max package size.
if (MTU < size + 8) {
// LOG_DEBUG("S: Invalid size %d, larger than MTU %d.\n", size, MTU);
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR);
return FPC_BEP_RESULT_IO_ERROR;
}
hcp_comm->read(size + 4, hcp_comm->txrx_buffer + 4, 100, NULL);
uint32_t crc = *(uint32_t *)(hcp_comm->txrx_buffer + 4 + size);
uint32_t crc_calc = fpc_crc(0, hcp_comm->txrx_buffer+4, size);
if (crc_calc != crc) {
LOG_DEBUG("CRC mismatch. Calculated %04X, received %04X\n",
(unsigned int)crc_calc, (unsigned int)crc);
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR);
return FPC_BEP_RESULT_IO_ERROR;
}
// Send Ack
hcp_comm->write(4, (uint8_t *)&fpc_com_ack, 0, NULL);
return FPC_BEP_RESULT_OK;
}
fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm)
{
uint16_t seq_nr = 1;
fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK;
uint16_t data_left = hcp_comm->pkt_size;
uint8_t *p = hcp_comm->pkt_buffer;
_HPC_pkt_t *phy_frm = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
// Application MTU size is PHY MTU - (Transport and Link overhead)
uint16_t app_mtu = MTU - 6 - 8;
// Calculate sequence length
uint16_t seq_len = (data_left / app_mtu) + 1;
phy_frm->lnk_chn = 0;
phy_frm->t_seq_len = seq_len;
for (seq_nr = 1; seq_nr <= seq_len && !bep_result; seq_nr++) {
phy_frm->t_seq_nr = seq_nr;
if (data_left < app_mtu) {
phy_frm->t_size = data_left;
} else {
phy_frm->t_size = app_mtu;
}
memcpy(&phy_frm->t_pld, p, phy_frm->t_size);
phy_frm->lnk_size = phy_frm->t_size + 6;
p += phy_frm->t_size;
data_left -= phy_frm->t_size;
bep_result = _tx_link(hcp_comm);
}
if(bep_result) {
bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result);
}
return bep_result;
}
static fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm)
{
fpc_bep_result_t bep_result;
_HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer;
uint32_t crc_calc = fpc_crc(0, &pkt->t_size, pkt->lnk_size);
*(uint32_t *)(hcp_comm->txrx_buffer + pkt->lnk_size + 4) = crc_calc;
uint16_t size = pkt->lnk_size + 8;
bep_result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL);
// Wait for ACK
uint32_t ack;
bep_result = hcp_comm->read(4, (uint8_t *)&ack, 500, NULL);
if (bep_result == FPC_BEP_RESULT_TIMEOUT) {
LOG_DEBUG("ASK read timeout\n");
bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_TIMEOUT);
return FPC_BEP_RESULT_IO_ERROR;
}
if(ack != fpc_com_ack) {
return FPC_BEP_RESULT_IO_ERROR;
}
return FPC_BEP_RESULT_OK;
}

102
BMLite_sdk/src/platform.c Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for BM-Lite applications
*/
/**
* @file platform.c
* @brief Platform specific functions
*/
#ifdef DEBUG_COMM
#include <stdio.h>
#define LOG_DEBUG(...) printf(__VA_ARGS__)
#else
#define LOG_DEBUG(...)
#endif
#include "fpc_bep_types.h"
#include "platform.h"
#include "bmlite_hal.h"
fpc_bep_result_t platform_init(void *params)
{
fpc_bep_result_t result;
result = hal_board_init(params);
if(result == FPC_BEP_RESULT_OK) {
hal_timebase_init();
platform_bmlite_reset();
}
return result;
}
void platform_bmlite_reset(void)
{
hal_bmlite_reset(true);
hal_timebase_busy_wait(100);
hal_bmlite_reset(false);
hal_timebase_busy_wait(100);
}
fpc_bep_result_t platform_bmlite_send(uint16_t size, const uint8_t *data, uint32_t timeout,
void *session)
{
uint8_t buff[size];
#ifdef DEBUG_COMM
LOG_DEBUG("-> ");
for (int i=0; i<size; i++)
LOG_DEBUG("%02X ", data[i]);
LOG_DEBUG("\n");
#endif
return hal_bmlite_spi_write_read((uint8_t *)data, buff, size, false);
}
fpc_bep_result_t platform_bmlite_receive(uint16_t size, uint8_t *data, uint32_t timeout,
void *session)
{
volatile uint32_t start_time = hal_timebase_get_tick();
volatile uint32_t curr_time = start_time;
// Wait for BM_Lite Ready for timeout or indefinitely if timeout is 0
while (!hal_bmlite_get_status() &&
(!timeout || (curr_time = hal_timebase_get_tick()) - start_time < timeout)) {
if(hal_check_button_pressed()) {
return FPC_BEP_RESULT_TIMEOUT;
}
}
if(timeout && curr_time - start_time >= timeout) {
return FPC_BEP_RESULT_TIMEOUT;
}
uint8_t buff[size];
fpc_bep_result_t res = hal_bmlite_spi_write_read(buff, data, size, false);
#ifdef DEBUG_COMM
LOG_DEBUG("<- ");
for (int i=0; i<size; i++)
LOG_DEBUG("%02X ", data[i]);
LOG_DEBUG("\n");
#endif
return res;
}
__attribute__((weak)) uint32_t hal_check_button_pressed()
{
return 0;
}

View File

@ -0,0 +1,13 @@
# BM-Lite Raspberry PI HAL
BM-Lite HAL implementation for Raspberry Pi 3.
Based on [BM-LIte Development Kit](https://www.fingerprints.com/solutions/access/bm-lite-development-kit/ "BM-LIte Development Kit")
### HW configuration
| | PIN # |
| :------------ | :------------: |
| BMLITE_RESET | 0 |
| BMLITE_IRQ | 22 |
| SPI_CHANNEL | 1 |
HW configuration can be changed in **BMLite_examples/RaspberryPiinc/raspberry_pi_hal.h**

View File

@ -0,0 +1,19 @@
# Binary sources
HAL = $(ROOT)/HAL_Driver/RaspberryPi
PATH := /work/devtools/gcc-arm-hf/bin:$(PATH)
CC := arm-linux-gnueabihf-gcc
CFLAGS +=\
-D_DEFAULT_SOURCE
VPATH += $(HAL)
C_INC += -I$(HAL)/inc
LDFLAGS += -lwiringPi -L$(HAL)/lib/
# Source Folders
VPATH += $(HAL)/src/
# C Sources
C_SRCS += $(notdir $(wildcard $(HAL)/src/*.c))

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for FPC BM-Lite applications
*/
#ifndef PLATFORM_RPI_H
#define PLATFORM_RPI_H
/**
* @file platform.h
* @brief Platform specific function interface
*/
#include <stdint.h>
#include <stdbool.h>
#include "fpc_bep_types.h"
#include "hcp_tiny.h"
typedef enum {
COM_INTERFACE = 0,
SPI_INTERFACE
} interface_t;
typedef struct {
interface_t iface;
char *port;
uint32_t baudrate;
uint32_t timeout;
HCP_comm_t *hcp_comm;
} rpi_initparams_t;
/*
* Pin definitions for RPI 3
*/
#define BMLITE_RESET_PIN 0
#define BMLITE_IRQ_PIN 22
#define SPI_CHANNEL 0
/**
* @brief Initializes COM Physical layer.
*
* @param[in] port tty port to use.
* @param[in] baudrate Baudrate.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*/
bool rpi_com_init(char *port, int baudrate, int timeout);
/**
* @brief Sends data over communication port in blocking mode.
*
* @param[in] size Number of bytes to send.
* @param[in] data Data buffer to send.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t rpi_com_send(uint16_t size, const uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Receives data from communication port in blocking mode.
*
* @param[in] size Number of bytes to receive.
* @param[in, out] data Data buffer to fill.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t rpi_com_receive(uint16_t size, uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Initializes SPI Physical layer.
*
* @param[in] speed_hz Baudrate.
*/
bool rpi_spi_init(uint32_t speed_hz);
/**
* @brief Sends data over communication port in blocking mode.
*
* @param[in] size Number of bytes to send.
* @param[in] data Data buffer to send.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t platform_spi_send(uint16_t size, const uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Receives data from communication port in blocking mode.
*
* @param[in] size Number of bytes to receive.
* @param[in, out] data Data buffer to fill.
* @param[in] timeout Timeout in ms. Use 0 for infinity.
*
* @return ::fpc_bep_result_t
*/
fpc_bep_result_t platform_spi_receive(uint16_t size, uint8_t *data, uint32_t timeout,
void *session);
/**
* @brief Get time in micro seconds
*
* @return time in us.
*/
// uint64_t platform_get_time(void);
/**
* @brief Clear console screen
*/
void rpi_clear_screen(void);
/**
* @brief Busy wait.
*
* @param[in] ms Time to wait [ms].
* 0 => return immediately
* 1 => wait at least 1ms etc.
*/
void hal_timebase_busy_wait(uint32_t ms);
#endif /* PLATFORM_RPI_H */

View File

@ -0,0 +1,256 @@
/*
* wiringPi.h:
* Arduino like Wiring library for the Raspberry Pi.
* Copyright (c) 2012-2017 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#ifndef __WIRING_PI_H__
#define __WIRING_PI_H__
// C doesn't have true/false by default and I can never remember which
// way round they are, so ...
// (and yes, I know about stdbool.h but I like capitals for these and I'm old)
#ifndef TRUE
# define TRUE (1==1)
# define FALSE (!TRUE)
#endif
// GCC warning suppressor
#define UNU __attribute__((unused))
// Mask for the bottom 64 pins which belong to the Raspberry Pi
// The others are available for the other devices
#define PI_GPIO_MASK (0xFFFFFFC0)
// Handy defines
// wiringPi modes
#define WPI_MODE_PINS 0
#define WPI_MODE_GPIO 1
#define WPI_MODE_GPIO_SYS 2
#define WPI_MODE_PHYS 3
#define WPI_MODE_PIFACE 4
#define WPI_MODE_UNINITIALISED -1
// Pin modes
#define INPUT 0
#define OUTPUT 1
#define PWM_OUTPUT 2
#define GPIO_CLOCK 3
#define SOFT_PWM_OUTPUT 4
#define SOFT_TONE_OUTPUT 5
#define PWM_TONE_OUTPUT 6
#define LOW 0
#define HIGH 1
// Pull up/down/none
#define PUD_OFF 0
#define PUD_DOWN 1
#define PUD_UP 2
// PWM
#define PWM_MODE_MS 0
#define PWM_MODE_BAL 1
// Interrupt levels
#define INT_EDGE_SETUP 0
#define INT_EDGE_FALLING 1
#define INT_EDGE_RISING 2
#define INT_EDGE_BOTH 3
// Pi model types and version numbers
// Intended for the GPIO program Use at your own risk.
#define PI_MODEL_A 0
#define PI_MODEL_B 1
#define PI_MODEL_AP 2
#define PI_MODEL_BP 3
#define PI_MODEL_2 4
#define PI_ALPHA 5
#define PI_MODEL_CM 6
#define PI_MODEL_07 7
#define PI_MODEL_3 8
#define PI_MODEL_ZERO 9
#define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12
#define PI_VERSION_1 0
#define PI_VERSION_1_1 1
#define PI_VERSION_1_2 2
#define PI_VERSION_2 3
#define PI_MAKER_SONY 0
#define PI_MAKER_EGOMAN 1
#define PI_MAKER_EMBEST 2
#define PI_MAKER_UNKNOWN 3
extern const char *piModelNames [16] ;
extern const char *piRevisionNames [16] ;
extern const char *piMakerNames [16] ;
extern const int piMemorySize [ 8] ;
// Intended for the GPIO program Use at your own risk.
// Threads
#define PI_THREAD(X) void *X (UNU void *dummy)
// Failure modes
#define WPI_FATAL (1==1)
#define WPI_ALMOST (1==2)
// wiringPiNodeStruct:
// This describes additional device nodes in the extended wiringPi
// 2.0 scheme of things.
// It's a simple linked list for now, but will hopefully migrate to
// a binary tree for efficiency reasons - but then again, the chances
// of more than 1 or 2 devices being added are fairly slim, so who
// knows....
struct wiringPiNodeStruct
{
int pinBase ;
int pinMax ;
int fd ; // Node specific
unsigned int data0 ; // ditto
unsigned int data1 ; // ditto
unsigned int data2 ; // ditto
unsigned int data3 ; // ditto
void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ;
void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ;
int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ;
//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ;
void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ;
void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ;
void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ;
struct wiringPiNodeStruct *next ;
} ;
extern struct wiringPiNodeStruct *wiringPiNodes ;
// Function prototypes
// c++ wrappers thanks to a comment by Nick Lott
// (and others on the Raspberry Pi forums)
#ifdef __cplusplus
extern "C" {
#endif
// Data
// Internal
extern int wiringPiFailure (int fatal, const char *message, ...) ;
// Core wiringPi functions
extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ;
extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ;
extern void wiringPiVersion (int *major, int *minor) ;
extern int wiringPiSetup (void) ;
extern int wiringPiSetupSys (void) ;
extern int wiringPiSetupGpio (void) ;
extern int wiringPiSetupPhys (void) ;
extern void pinModeAlt (int pin, int mode) ;
extern void pinMode (int pin, int mode) ;
extern void pullUpDnControl (int pin, int pud) ;
extern int digitalRead (int pin) ;
extern void digitalWrite (int pin, int value) ;
extern unsigned int digitalRead8 (int pin) ;
extern void digitalWrite8 (int pin, int value) ;
extern void pwmWrite (int pin, int value) ;
extern int analogRead (int pin) ;
extern void analogWrite (int pin, int value) ;
// PiFace specifics
// (Deprecated)
extern int wiringPiSetupPiFace (void) ;
extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only
// On-Board Raspberry Pi hardware specific stuff
extern int piGpioLayout (void) ;
extern int piBoardRev (void) ; // Deprecated
extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ;
extern int wpiPinToGpio (int wpiPin) ;
extern int physPinToGpio (int physPin) ;
extern void setPadDrive (int group, int value) ;
extern int getAlt (int pin) ;
extern void pwmToneWrite (int pin, int freq) ;
extern void pwmSetMode (int mode) ;
extern void pwmSetRange (unsigned int range) ;
extern void pwmSetClock (int divisor) ;
extern void gpioClockSet (int pin, int freq) ;
extern unsigned int digitalReadByte (void) ;
extern unsigned int digitalReadByte2 (void) ;
extern void digitalWriteByte (int value) ;
extern void digitalWriteByte2 (int value) ;
// Interrupts
// (Also Pi hardware specific)
extern int waitForInterrupt (int pin, int mS) ;
extern int wiringPiISR (int pin, int mode, void (*function)(void)) ;
// Threads
extern int piThreadCreate (void *(*fn)(void *)) ;
extern void piLock (int key) ;
extern void piUnlock (int key) ;
// Schedulling priority
extern int piHiPri (const int pri) ;
// Extras from arduino land
extern void delay (unsigned int howLong) ;
/*Headerfile was missing the hard delay.*/
extern void delayMicrosecondsHard (unsigned int howLong) ;
extern void delayMicroseconds (unsigned int howLong) ;
extern unsigned int millis (void) ;
extern unsigned int micros (void) ;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
/*
* wiringPiSPI.h:
* Simplified SPI access routines
* Copyright (c) 2012-2015 Gordon Henderson
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with wiringPi.
* If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
int wiringPiSPIGetFd (int channel) ;
int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ;
int wiringPiSPISetupMode (int channel, int speed, int mode) ;
int wiringPiSPISetup (int channel, int speed) ;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1 @@
libwiringPi.so.2.46

Binary file not shown.

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for FPC BM-Lite applications
*/
/**
* @file platform_linux.c
* @brief Linux platform specific functions
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <sys/time.h>
#include <unistd.h>
#include "bmlite_hal.h"
#include "platform_rpi.h"
#include "platform.h"
hal_tick_t hal_timebase_get_tick(void)
{
struct timeval current_time;
uint64_t time_in_ms;
gettimeofday(&current_time, NULL);
/* Seconds and microseconds are converted to milliseconds */
time_in_ms = current_time.tv_usec / 1000 + current_time.tv_sec * 1000;
return time_in_ms;
}
void hal_timebase_busy_wait(uint32_t ms)
{
usleep(ms * 1000);
}
void rpi_clear_screen(void)
{
system("clear");
}
void hal_timebase_init()
{
}
fpc_bep_result_t hal_board_init(void *params)
{
rpi_initparams_t *p = (rpi_initparams_t *)params;
switch (p->iface) {
case SPI_INTERFACE:
if(!rpi_spi_init(p->baudrate)) {
printf("SPI initialization failed\n");
return FPC_BEP_RESULT_INTERNAL_ERROR;
}
break;
case COM_INTERFACE:
if (!rpi_com_init(p->port, p->baudrate, p->timeout)) {
printf("Com initialization failed\n");
return FPC_BEP_RESULT_INTERNAL_ERROR;
}
break;
default:
printf("Interface not specified'n");
return FPC_BEP_RESULT_INTERNAL_ERROR;
}
if (p->iface == COM_INTERFACE) {
p->hcp_comm->read = rpi_com_receive;
p->hcp_comm->write = rpi_com_send;
} else {
p->hcp_comm->read = platform_bmlite_receive;
p->hcp_comm->write = platform_bmlite_send;
}
p->hcp_comm->phy_rx_timeout = p->timeout*1000;
return FPC_BEP_RESULT_OK;
}

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*/
/**
* @file platform_com.c
* @brief Linux COM platform specific functions
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <sys/time.h>
#include "platform_rpi.h"
static int fd = -1;
static int set_interface_attribs(int fd, int speed, int timeout)
{
struct termios tty;
memset(&tty, 0, sizeof tty);
if (tcgetattr (fd, &tty) != 0) {
fprintf(stderr, "error %d from tcgetattr", errno);
return -1;
}
cfsetospeed(&tty, speed);
cfsetispeed(&tty, speed);
tty.c_iflag = 0; // Clear input modes
tty.c_oflag = 0; // Clear output modes
tty.c_cflag = 0; // Clear control modes
tty.c_lflag = 0; // Clear local modes
tty.c_cflag |= CS8; // Set size mask to 8 bits
tty.c_cflag |= CREAD; // Enable receiver
tty.c_cflag |= HUPCL; // Lower modem control lines after last process closes the device (hang up)
tty.c_cflag |= CLOCAL; // Ignore modem control lines
tty.c_cc[VMIN] = 0; // Minimum number of characters for non-canonical read
tty.c_cc[VTIME] = 0; // Timeout in deciseconds for non-canonical read
tcsetattr(fd, TCSANOW, &tty);
return 0;
}
bool rpi_com_init(char *port, int baudrate, int timeout)
{
int baud;
fd = open(port, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
fprintf(stderr, "error %d opening %s: %s", errno, port, strerror (errno));
return false;
}
if (baudrate == 921600) {
baud = B921600;
} else {
baud = B115200;
}
set_interface_attribs(fd, baud, timeout);
return true;
}
fpc_bep_result_t rpi_com_send(uint16_t size, const uint8_t *data, uint32_t timeout,
void *session)
{
fpc_bep_result_t res = FPC_BEP_RESULT_OK;
int n;
if (fd < 0) {
fprintf(stderr, "error invalid file descriptor");
return FPC_BEP_RESULT_INVALID_ARGUMENT;
}
n = write(fd, data, size);
if (n != size) {
res = FPC_BEP_RESULT_IO_ERROR;
}
return res;
}
fpc_bep_result_t rpi_com_receive(uint16_t size, uint8_t *data, uint32_t timeout,
void *session)
{
fpc_bep_result_t res = FPC_BEP_RESULT_OK;
int n_read = 0;
int n = 0;
fd_set rfds;
int retval;
unsigned char c;
if (fd < 0) {
fprintf(stderr, "error invalid file descriptor");
return FPC_BEP_RESULT_INVALID_ARGUMENT;
}
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
while (n_read < size) {
retval = select(fd + 1, &rfds, NULL, NULL, NULL);
if (retval == -1) {
perror("select()");
exit(EXIT_FAILURE);
} else if (retval != 0) {
n = read(fd, &c, sizeof(c));
if (n > 0) {
*data = c;
data++;
n_read++;
}
}
}
return res;
}

View File

@ -0,0 +1,175 @@
/*
* Copyright (c) 2020 Fingerprint Cards AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.
*
* Modified by Andrey Perminov <andrey.ppp@gmail.com>
* for FPC BM-Lite applications
*/
/**
* @file platform_linux.c
* @brief Linux SPI platform specific functions
*/
#define _BSD_SOURCE
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <sys/time.h>
#include "platform.h"
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <asm/ioctl.h>
#include "wiringPi.h"
#include "wiringPiSPI.h"
#include "platform_rpi.h"
#define SPI_BUF_MIN_SIZE 40000
// This path is used to determine the SPI buffer size.
static char SPIBufPath[] = "/sys/module/spidev/parameters/bufsiz";
static const uint16_t spiDelay = 0;
static const uint8_t spiBPW = 8;
uint32_t speed_hz_int;
void fpc_sensor_spi_reset(bool state);
static void raspberryPi_init()
{
/* Start wiringPi functions. */
wiringPiSetup();
/* Set correct pin modes */
pinMode(BMLITE_IRQ_PIN, INPUT);
pinMode(BMLITE_RESET_PIN, OUTPUT);
/* Set reset high */
digitalWrite(BMLITE_RESET_PIN, 1);
}
void hal_bmlite_reset(bool state)
{
/* The reset pin is controlled by WiringPis digitalWrite function*/
if (state) {
digitalWrite(BMLITE_RESET_PIN, 0);
} else {
digitalWrite(BMLITE_RESET_PIN, 1);
}
}
bool hal_bmlite_get_status(void)
{
return digitalRead(BMLITE_IRQ_PIN);
}
bool rpi_spi_init(uint32_t speed_hz)
{
raspberryPi_init();
/* In standard the SPI drivers buffer is 4096 bytes, the current buffer
* size is read and compared to minimum required size.
*/
FILE *fp;
fp = fopen(SPIBufPath, "r");
/* The file is opened, and if this failed the program exits. */
if (fp == NULL) {
printf("Could not open %s to get buffersize\n", SPIBufPath);
exit(1);
}
/* The size of the file is determined, then the whole file is read. */
fseek(fp, 0, SEEK_END); // Seek to end of file.
size_t filesize = ftell(fp); // Get current file pointer.
fseek(fp, 0, SEEK_SET); // Seek back to beginning of file.
char buffersize[filesize];
if (fread(buffersize, 1, filesize, fp) == filesize) {
printf("Failed to read data from %s.\n", SPIBufPath);
exit(1);
}
fclose(fp);
/* Verify that SPI buffer meets minimum size. */
if (atoi(buffersize) < SPI_BUF_MIN_SIZE) {
printf("SPI buffer size is too small, if the standard RPI driver is "
"used, this can be changed by adding \"spidev.bufsiz=<size>\" "
"to /boot/cmdline.txt. <size> needs to be larger than %d for this "
"sensor.\n",
SPI_BUF_MIN_SIZE);
exit(1);
}
/*
* If the buffer has been verified as large enough the SPI will initialize,
* the reset and IRQ pin will also be set up.
*/
int SpiRef;
SpiRef = wiringPiSPISetup(SPI_CHANNEL, speed_hz);
speed_hz_int = speed_hz;
if (SpiRef == -1) {
printf("WiringPi GPIO setup failed with error %d", errno);
return false;
}
return true;
}
fpc_bep_result_t hal_bmlite_spi_write_read(const uint8_t *write, uint8_t *read, size_t size,
bool leave_cs_asserted)
{
/*
* SPI data is transmitted using an edited version of wiringPiSPIDataRW,
* since the original function does not have support for holding the CS
* signal low after a transmission which is needed by bep-lib.
*/
size_t status;
struct spi_ioc_transfer spi;
memset (&spi, 0, sizeof (spi));
/* The file descriptor is fetched from wiringPi. */
int spiFds = wiringPiSPIGetFd(SPI_CHANNEL);
spi.tx_buf = (unsigned long)write;
spi.rx_buf = (unsigned long)read;
spi.len = size;
spi.delay_usecs = spiDelay;
spi.speed_hz = speed_hz_int;
spi.bits_per_word = spiBPW;
spi.cs_change = leave_cs_asserted;
status = ioctl(spiFds, SPI_IOC_MESSAGE(1), &spi);
/*
* Status returns the number of bytes sent, if this number is different
* from the the number of bytes written an error has occured.
*/
if (status == size) {
return FPC_BEP_RESULT_OK;
}
return FPC_BEP_RESULT_IO_ERROR;
}

View File

@ -0,0 +1,136 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 19. October 2015
* $Revision: V.1.4.5 a
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* 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 LIMITED 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 OWNER 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.
* -------------------------------------------------------------------- */
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
/* extern const q31_t realCoefAQ31[1024]; */
/* extern const q31_t realCoefBQ31[1024]; */
extern const float32_t twiddleCoef_16[32];
extern const float32_t twiddleCoef_32[64];
extern const float32_t twiddleCoef_64[128];
extern const float32_t twiddleCoef_128[256];
extern const float32_t twiddleCoef_256[512];
extern const float32_t twiddleCoef_512[1024];
extern const float32_t twiddleCoef_1024[2048];
extern const float32_t twiddleCoef_2048[4096];
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
extern const q31_t twiddleCoef_16_q31[24];
extern const q31_t twiddleCoef_32_q31[48];
extern const q31_t twiddleCoef_64_q31[96];
extern const q31_t twiddleCoef_128_q31[192];
extern const q31_t twiddleCoef_256_q31[384];
extern const q31_t twiddleCoef_512_q31[768];
extern const q31_t twiddleCoef_1024_q31[1536];
extern const q31_t twiddleCoef_2048_q31[3072];
extern const q31_t twiddleCoef_4096_q31[6144];
extern const q15_t twiddleCoef_16_q15[24];
extern const q15_t twiddleCoef_32_q15[48];
extern const q15_t twiddleCoef_64_q15[96];
extern const q15_t twiddleCoef_128_q15[192];
extern const q15_t twiddleCoef_256_q15[384];
extern const q15_t twiddleCoef_512_q15[768];
extern const q15_t twiddleCoef_1024_q15[1536];
extern const q15_t twiddleCoef_2048_q15[3072];
extern const q15_t twiddleCoef_4096_q15[6144];
extern const float32_t twiddleCoef_rfft_32[32];
extern const float32_t twiddleCoef_rfft_64[64];
extern const float32_t twiddleCoef_rfft_128[128];
extern const float32_t twiddleCoef_rfft_256[256];
extern const float32_t twiddleCoef_rfft_512[512];
extern const float32_t twiddleCoef_rfft_1024[1024];
extern const float32_t twiddleCoef_rfft_2048[2048];
extern const float32_t twiddleCoef_rfft_4096[4096];
/* floating-point bit reversal tables */
#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
/* fixed-point bit reversal tables */
#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
/* Tables for Fast Math Sine and Cosine */
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* ARM_COMMON_TABLES_H */

View File

@ -0,0 +1,79 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
*
* $Date: 19. March 2015
* $Revision: V.1.4.5
*
* Project: CMSIS DSP Library
* Title: arm_const_structs.h
*
* Description: This file has constant structs that are initialized for
* user convenience. For example, some can be given as
* arguments to the arm_cfft_f32() function.
*
* Target Processor: Cortex-M4/Cortex-M3
*
* 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 LIMITED 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 OWNER 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.
* -------------------------------------------------------------------- */
#ifndef _ARM_CONST_STRUCTS_H
#define _ARM_CONST_STRUCTS_H
#include "arm_math.h"
#include "arm_common_tables.h"
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,734 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS Cortex-M Core Function/Instruction Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* (__CORTEX_M >= 0x04) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,798 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000U
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

View File

@ -0,0 +1,914 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex-M0+
@{
*/
/* CMSIS CM0+ definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000U
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0U
#warning "__VTOR_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex-M0+ */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
#if (__VTOR_PRESENT == 1U)
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
#if (__VTOR_PRESENT == 1U)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1U)
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/**
\brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register Definitions */
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register Definitions */
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register Definitions */
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register Definitions */
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register Definitions */
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0+ header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0+ Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1U)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,87 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,96 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
/*------------------ RealView Compiler -----------------*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*------------------ ARM Compiler V6 -------------------*/
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armcc_V6.h"
/*------------------ GNU Compiler ----------------------*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*------------------ ICC Compiler ----------------------*/
#elif defined ( __ICCARM__ )
#include <cmsis_iar.h>
/*------------------ TI CCS Compiler -------------------*/
#elif defined ( __TMS470__ )
#include <cmsis_ccs.h>
/*------------------ TASKING Compiler ------------------*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
/*------------------ COSMIC Compiler -------------------*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */

View File

@ -0,0 +1,926 @@
/**************************************************************************//**
* @file core_sc000.h
* @brief CMSIS SC000 Core Peripheral Access Layer Header File
* @version V4.30
* @date 20. October 2015
******************************************************************************/
/* Copyright (c) 2009 - 2015 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 COPYRIGHT HOLDERS AND 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_SC000_H_GENERIC
#define __CORE_SC000_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup SC000
@{
*/
/* CMSIS SC000 definitions */
#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
__SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_SC (000U) /*!< Cortex secure core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __TMS470__ )
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __CSMC__ )
#define __packed
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
#define __STATIC_INLINE static inline
#else
#error Unknown compiler
#endif
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TMS470__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "core_cmInstr.h" /* Core Instruction Access */
#include "core_cmFunc.h" /* Core Function Access */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_SC000_H_DEPENDANT
#define __CORE_SC000_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __SC000_REV
#define __SC000_REV 0x0000U
#warning "__SC000_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0U
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group SC000 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core MPU Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED0[1U];
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
uint32_t RESERVED1[154U];
__IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
\brief Type definitions for the System Control and ID Register not in the SCB
@{
*/
/**
\brief Structure type to access the System Control and ID Register not in the SCB.
*/
typedef struct
{
uint32_t RESERVED0[2U];
__IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
} SCnSCB_Type;
/* Auxiliary Control Register Definitions */
#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
/*@} end of group CMSIS_SCnotSCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
#if (__MPU_PRESENT == 1U)
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/**
\brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register Definitions */
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register Definitions */
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register Definitions */
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register Definitions */
#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register Definitions */
#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the SC000 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of SC000 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
#if (__MPU_PRESENT == 1U)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable External Interrupt
\details Enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Disable External Interrupt
\details Disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Get Pending Interrupt
\details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
/**
\brief Set Interrupt Priority
\details Sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) < 0)
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of an interrupt.
The interrupt number can be positive to specify an external (device specific) interrupt,
or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) < 0)
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_SC000_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,4 @@
## FPC BM-Lite HAL implementation
Implementation BM-Lite HAL for Nordic nRF52840-DK development board. FPC BM-Lite module connected to the dev board using SPI interface.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
../config/sdk_config.h

View File

@ -0,0 +1,14 @@
/* Define size of stack. Size must be multiple of 4. */
#define __STARTUP_CONFIG_STACK_SIZE 0x2000
/* Define alignement of stack. Alignment will be 2 to the power of __STARTUP_CONFIG_STACK_ALIGNEMENT. Since calling convention requires that the stack is aligned to 8-bytes when a function is called, the minimum __STARTUP_CONFIG_STACK_ALIGNEMENT is therefore 3. */
#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3
/* Define size of heap. Size must be multiple of 4. */
#define __STARTUP_CONFIG_HEAP_SIZE 0x12000
/* Define entry point */
#define __START main
/* Clear BSS at startup */
#define __STARTUP_CLEAR_BSS

View File

@ -0,0 +1,165 @@
#
# Copyright (c) 2020 Fingerprint Cards AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://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.
#
#
# Modified by Andrey Perminov <andrey.ppp@gmail.com>
# for FPC BM-Lite applications
#
CPU = cortex_m4
LOG :=
CC := arm-none-eabi-gcc
CFLAGS +=\
-mcpu=cortex-m4\
-mthumb -mabi=aapcs\
-ffunction-sections -fdata-sections -fno-strict-aliasing\
-fno-builtin --short-enums \
-Wno-expansion-to-defined \
# SDK definitions
CFLAGS +=\
-DBOARD_PCA10056\
-DCONFIG_GPIO_AS_PINRESET\
-DNRF52840_XXAA\
-D__STARTUP_CONFIG \
-DMALLOC_PROVIDED \
-DFPC_MALLOC \
-DBSP_SIMPLE \
-Wa,--defsym,_STARTUP_CONFIG=1 \
-DUART_CMDS \
CFLAGS +=\
-DUSE_HAL_DRIVER \
-DARM_MATH_CM4\
ifeq ($(FPU),soft)
CFLAGS +=\
-mfloat-abi=soft
else
CFLAGS +=\
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16
endif
HAL := $(HAL_PATH)
SDK_ROOT := $(HAL)/sdk
# Linker flags
LDFILE = $(HAL)/spi_gcc_nrf52.ld
TEMPLATE_PATH := $(SDK_ROOT)/modules/nrfx/mdk
LDFLAGS += -T $(LDFILE) -L $(TEMPLATE_PATH)
LDLAGS +=\
-mthumb -mabi=aapcs\
-mcpu=cortex-m4\
-L $(TEMPLATE_PATH)
LDFLAGS +=\
-lc -lgcc \
AR_LIBS +=\
$(HAL)/CMSIS/dsp/GCC/libarm_cortexM4lf_math.a
HAL_SRCS += \
$(SDK_ROOT)/components/boards/boards.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_rtt.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_uart.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_default_backends.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_str_formatter.c \
$(SDK_ROOT)/components/libraries/button/app_button.c \
$(SDK_ROOT)/components/libraries/util/app_error.c \
$(SDK_ROOT)/components/libraries/util/app_error_handler_gcc.c \
$(SDK_ROOT)/components/libraries/util/app_error_weak.c \
$(SDK_ROOT)/components/libraries/util/app_util_platform.c \
$(SDK_ROOT)/components/libraries/util/nrf_assert.c \
$(SDK_ROOT)/components/libraries/fifo/app_fifo.c \
$(SDK_ROOT)/components/libraries/uart/app_uart_fifo.c \
$(SDK_ROOT)/components/libraries/scheduler/app_scheduler.c \
$(SDK_ROOT)/components/libraries/timer/app_timer.c \
$(SDK_ROOT)/components/libraries/atomic/nrf_atomic.c \
$(SDK_ROOT)/components/libraries/balloc/nrf_balloc.c \
$(SDK_ROOT)/components/libraries/memobj/nrf_memobj.c \
$(SDK_ROOT)/components/libraries/ringbuf/nrf_ringbuf.c \
$(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
$(SDK_ROOT)/components/libraries/bsp/bsp.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_spi.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_gpiote.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/prs/nrfx_prs.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_spi.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_spim.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uart.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uarte.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_timer.c \
$(SDK_ROOT)/modules/nrfx/soc/nrfx_atomic.c \
$(SDK_ROOT)/modules/nrfx/mdk/system_nrf52840.c \
$(SDK_ROOT)/modules/nrfx/hal/nrf_nvmc.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf_format.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
# $(PROJ_DIR)/main.c \
VPATH += $(dir $(HAL_SRCS))
C_SRCS += $(notdir $(HAL_SRCS))
# Source Folders
VPATH += $(HAL)/src/
# C Sources
C_SRCS += $(notdir $(wildcard $(HAL)/src/*.c))
# S Sources
S_SRCS += $(HAL)/src/gcc_startup_nrf52840.S
# Includes
C_INC +=\
-I$(HAL)/config \
-I$(HAL)/inc \
-I$(HAL)/CMSIS/Include \
-I$(SDK_ROOT)/components \
-I$(SDK_ROOT)/components/libraries/scheduler \
-I$(SDK_ROOT)/components/libraries/timer \
-I$(SDK_ROOT)/components/libraries/strerror \
-I$(SDK_ROOT)/components/toolchain/cmsis/include \
-I$(SDK_ROOT)/components/libraries/util \
-I$(SDK_ROOT)/components/libraries/balloc \
-I$(SDK_ROOT)/components/libraries/ringbuf \
-I$(SDK_ROOT)/components/libraries/fifo \
-I$(SDK_ROOT)/components/libraries/bsp \
-I$(SDK_ROOT)/components/libraries/log \
-I$(SDK_ROOT)/components/libraries/uart \
-I$(SDK_ROOT)/components/libraries/button \
-I$(SDK_ROOT)/components/libraries/experimental_section_vars \
-I$(SDK_ROOT)/integration/nrfx/legacy \
-I$(SDK_ROOT)/components/libraries/delay \
-I$(SDK_ROOT)/integration/nrfx \
-I$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
-I$(SDK_ROOT)/external/segger_rtt \
-I$(SDK_ROOT)/components/boards \
-I$(SDK_ROOT)/components/libraries/memobj \
-I$(SDK_ROOT)/modules/nrfx/drivers/include \
-I$(SDK_ROOT)/components/libraries/log/src \
-I$(SDK_ROOT)/external/fprintf \
-I$(SDK_ROOT)/components/libraries/atomic \
-I$(SDK_ROOT)/modules/nrfx \
-I$(SDK_ROOT)/modules/nrfx/hal \
-I$(SDK_ROOT)/modules/nrfx/mdk \

View File

@ -0,0 +1,228 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "boards.h"
#if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
#include "nrf_dfu_trigger_usb.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#if LEDS_NUMBER > 0
static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST;
#endif
#if BUTTONS_NUMBER > 0
static const uint8_t m_board_btn_list[BUTTONS_NUMBER] = BUTTONS_LIST;
#endif
#if LEDS_NUMBER > 0
bool bsp_board_led_state_get(uint32_t led_idx)
{
ASSERT(led_idx < LEDS_NUMBER);
bool pin_set = nrf_gpio_pin_out_read(m_board_led_list[led_idx]) ? true : false;
return (pin_set == (LEDS_ACTIVE_STATE ? true : false));
}
void bsp_board_led_on(uint32_t led_idx)
{
ASSERT(led_idx < LEDS_NUMBER);
nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 1 : 0);
}
void bsp_board_led_off(uint32_t led_idx)
{
ASSERT(led_idx < LEDS_NUMBER);
nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 0 : 1);
}
void bsp_board_leds_off(void)
{
uint32_t i;
for (i = 0; i < LEDS_NUMBER; ++i)
{
bsp_board_led_off(i);
}
}
void bsp_board_leds_on(void)
{
uint32_t i;
for (i = 0; i < LEDS_NUMBER; ++i)
{
bsp_board_led_on(i);
}
}
void bsp_board_led_invert(uint32_t led_idx)
{
ASSERT(led_idx < LEDS_NUMBER);
nrf_gpio_pin_toggle(m_board_led_list[led_idx]);
}
#if defined(BOARD_PCA10059)
/**
* Function for configuring UICR_REGOUT0 register
* to set GPIO output voltage to 3.0V.
*/
static void gpio_output_voltage_setup(void)
{
// Configure UICR_REGOUT0 register only if it is set to default value.
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) ==
(UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos))
{
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
(UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos);
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
// System reset is needed to update UICR registers.
NVIC_SystemReset();
}
}
#endif
static void bsp_board_leds_init(void)
{
#if defined(BOARD_PCA10059)
// If nRF52 USB Dongle is powered from USB (high voltage mode),
// GPIO output voltage is set to 1.8 V by default, which is not
// enough to turn on green and blue LEDs. Therefore, GPIO voltage
// needs to be increased to 3.0 V by configuring the UICR register.
if (NRF_POWER->MAINREGSTATUS &
(POWER_MAINREGSTATUS_MAINREGSTATUS_High << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos))
{
gpio_output_voltage_setup();
}
#endif
uint32_t i;
for (i = 0; i < LEDS_NUMBER; ++i)
{
nrf_gpio_cfg_output(m_board_led_list[i]);
}
bsp_board_leds_off();
}
uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx)
{
ASSERT(led_idx < LEDS_NUMBER);
return m_board_led_list[led_idx];
}
uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number)
{
uint32_t ret = 0xFFFFFFFF;
uint32_t i;
for (i = 0; i < LEDS_NUMBER; ++i)
{
if (m_board_led_list[i] == pin_number)
{
ret = i;
break;
}
}
return ret;
}
#endif //LEDS_NUMBER > 0
#if BUTTONS_NUMBER > 0
bool bsp_board_button_state_get(uint32_t button_idx)
{
ASSERT(button_idx < BUTTONS_NUMBER);
bool pin_set = nrf_gpio_pin_read(m_board_btn_list[button_idx]) ? true : false;
return (pin_set == (BUTTONS_ACTIVE_STATE ? true : false));
}
static void bsp_board_buttons_init(void)
{
uint32_t i;
for (i = 0; i < BUTTONS_NUMBER; ++i)
{
nrf_gpio_cfg_input(m_board_btn_list[i], BUTTON_PULL);
}
}
uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number)
{
uint32_t i;
uint32_t ret = 0xFFFFFFFF;
for (i = 0; i < BUTTONS_NUMBER; ++i)
{
if (m_board_btn_list[i] == pin_number)
{
ret = i;
break;
}
}
return ret;
}
uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx)
{
ASSERT(button_idx < BUTTONS_NUMBER);
return m_board_btn_list[button_idx];
}
#endif //BUTTONS_NUMBER > 0
void bsp_board_init(uint32_t init_flags)
{
#if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
(void) nrf_dfu_trigger_usb_init();
#endif
#if LEDS_NUMBER > 0
if (init_flags & BSP_INIT_LEDS)
{
bsp_board_leds_init();
}
#endif //LEDS_NUMBER > 0
#if BUTTONS_NUMBER > 0
if (init_flags & BSP_INIT_BUTTONS)
{
bsp_board_buttons_init();
}
#endif //BUTTONS_NUMBER > 0
}

View File

@ -0,0 +1,355 @@
/**
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef BOARDS_H
#define BOARDS_H
#include "nrf_gpio.h"
#include "nordic_common.h"
#if defined(BOARD_NRF6310)
#include "nrf6310.h"
#elif defined(BOARD_PCA10000)
#include "pca10000.h"
#elif defined(BOARD_PCA10001)
#include "pca10001.h"
#elif defined(BOARD_PCA10002)
#include "pca10000.h"
#elif defined(BOARD_PCA10003)
#include "pca10003.h"
#elif defined(BOARD_PCA20006)
#include "pca20006.h"
#elif defined(BOARD_PCA10028)
#include "pca10028.h"
#elif defined(BOARD_PCA10031)
#include "pca10031.h"
#elif defined(BOARD_PCA10036)
#include "pca10036.h"
#elif defined(BOARD_PCA10040)
#include "pca10040.h"
#elif defined(BOARD_PCA10056)
#include "pca10056.h"
#elif defined(BOARD_PCA20020)
#include "pca20020.h"
#elif defined(BOARD_PCA10059)
#include "pca10059.h"
#elif defined(BOARD_WT51822)
#include "wt51822.h"
#elif defined(BOARD_N5DK1)
#include "n5_starterkit.h"
#elif defined (BOARD_D52DK1)
#include "d52_starterkit.h"
#elif defined (BOARD_ARDUINO_PRIMO)
#include "arduino_primo.h"
#elif defined (CUSTOM_BOARD_INC)
#include STRINGIFY(CUSTOM_BOARD_INC.h)
#elif defined(BOARD_CUSTOM)
#include "custom_board.h"
#else
#error "Board is not defined"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**@defgroup BSP_BOARD_INIT_FLAGS Board initialization flags.
* @{ */
#define BSP_INIT_NONE 0 /**< No initialization of LEDs or buttons (@ref bsp_board_init).*/
#define BSP_INIT_LEDS (1 << 0) /**< Enable LEDs during initialization (@ref bsp_board_init).*/
#define BSP_INIT_BUTTONS (1 << 1) /**< Enable buttons during initialization (@ref bsp_board_init).*/
/**@} */
/**
* Function for returning the state of an LED.
*
* @param led_idx LED index (starting from 0), as defined in the board-specific header.
*
* @return True if the LED is turned on.
*/
bool bsp_board_led_state_get(uint32_t led_idx);
/**
* Function for turning on an LED.
*
* @param led_idx LED index (starting from 0), as defined in the board-specific header.
*/
void bsp_board_led_on(uint32_t led_idx);
/**
* Function for turning off an LED.
*
* @param led_idx LED index (starting from 0), as defined in the board-specific header.
*/
void bsp_board_led_off(uint32_t led_idx);
/**
* Function for inverting the state of an LED.
*
* @param led_idx LED index (starting from 0), as defined in the board-specific header.
*/
void bsp_board_led_invert(uint32_t led_idx);
/**
* Function for turning off all LEDs.
*/
void bsp_board_leds_off(void);
/**
* Function for turning on all LEDs.
*/
void bsp_board_leds_on(void);
/**
* Function for initializing the BSP handling for the board.
*
* @note This also initializes the USB DFU trigger library if @ref BOARDS_WITH_USB_DFU_TRIGGER is 1.
*
* @param[in] init_flags Flags specifying what to initialize (LEDs/buttons).
* See @ref BSP_BOARD_INIT_FLAGS.
*/
void bsp_board_init(uint32_t init_flags);
/**
* Function for converting pin number to LED index.
*
* @param pin_number Pin number.
*
* @return LED index of the given pin or 0xFFFFFFFF if invalid pin provided.
*/
uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number);
/**
* Function for converting LED index to pin number.
*
* @param led_idx LED index.
*
* @return Pin number.
*/
uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx);
/**
* Function for returning the state of a button.
*
* @param button_idx Button index (starting from 0), as defined in the board-specific header.
*
* @return True if the button is pressed.
*/
bool bsp_board_button_state_get(uint32_t button_idx);
/**
* Function for converting pin number to button index.
*
* @param pin_number Pin number.
*
* @return Button index of the given pin or 0xFFFFFFFF if invalid pin provided.
*/
uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number);
/**
* Function for converting button index to pin number.
*
* @param button_idx Button index.
*
* @return Pin number.
*/
uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx);
#define BSP_BOARD_LED_0 0
#define BSP_BOARD_LED_1 1
#define BSP_BOARD_LED_2 2
#define BSP_BOARD_LED_3 3
#define BSP_BOARD_LED_4 4
#define BSP_BOARD_LED_5 5
#define BSP_BOARD_LED_6 6
#define BSP_BOARD_LED_7 7
#define PIN_MASK(_pin) /*lint -save -e504 */ \
(1u << (uint32_t)((_pin) & (~P0_PIN_NUM))) \
/*lint -restore */
#define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO)
#ifdef BSP_LED_0
#define BSP_LED_0_MASK PIN_MASK(BSP_LED_0)
#define BSP_LED_0_PORT PIN_PORT(BSP_LED_0)
#else
#define BSP_LED_0_MASK 0
#define BSP_LED_0_PORT 0
#endif
#ifdef BSP_LED_1
#define BSP_LED_1_MASK PIN_MASK(BSP_LED_1)
#define BSP_LED_1_PORT PIN_PORT(BSP_LED_1)
#else
#define BSP_LED_1_MASK 0
#define BSP_LED_1_PORT 0
#endif
#ifdef BSP_LED_2
#define BSP_LED_2_MASK PIN_MASK(BSP_LED_2)
#define BSP_LED_2_PORT PIN_PORT(BSP_LED_2)
#else
#define BSP_LED_2_MASK 0
#define BSP_LED_2_PORT 0
#endif
#ifdef BSP_LED_3
#define BSP_LED_3_MASK PIN_MASK(BSP_LED_3)
#define BSP_LED_3_PORT PIN_PORT(BSP_LED_3)
#else
#define BSP_LED_3_MASK 0
#define BSP_LED_3_PORT 0
#endif
#ifdef BSP_LED_4
#define BSP_LED_4_MASK PIN_MASK(BSP_LED_4)
#define BSP_LED_4_PORT PIN_PORT(BSP_LED_4)
#else
#define BSP_LED_4_MASK 0
#define BSP_LED_4_PORT 0
#endif
#ifdef BSP_LED_5
#define BSP_LED_5_MASK PIN_MASK(BSP_LED_5)
#define BSP_LED_5_PORT PIN_PORT(BSP_LED_5)
#else
#define BSP_LED_5_MASK 0
#define BSP_LED_5_PORT 0
#endif
#ifdef BSP_LED_6
#define BSP_LED_6_MASK PIN_MASK(BSP_LED_6)
#define BSP_LED_6_PORT PIN_PORT(BSP_LED_6)
#else
#define BSP_LED_6_MASK 0
#define BSP_LED_6_PORT 0
#endif
#ifdef BSP_LED_7
#define BSP_LED_7_MASK PIN_MASK(BSP_LED_7)
#define BSP_LED_7_PORT PIN_PORT(BSP_LED_7)
#else
#define BSP_LED_7_MASK 0
#define BSP_LED_7_PORT 0
#endif
#define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | \
BSP_LED_2_MASK | BSP_LED_3_MASK | \
BSP_LED_4_MASK | BSP_LED_5_MASK | \
BSP_LED_6_MASK | BSP_LED_7_MASK)
#define BSP_BOARD_BUTTON_0 0
#define BSP_BOARD_BUTTON_1 1
#define BSP_BOARD_BUTTON_2 2
#define BSP_BOARD_BUTTON_3 3
#define BSP_BOARD_BUTTON_4 4
#define BSP_BOARD_BUTTON_5 5
#define BSP_BOARD_BUTTON_6 6
#define BSP_BOARD_BUTTON_7 7
#ifdef BSP_BUTTON_0
#define BSP_BUTTON_0_MASK (1<<BSP_BUTTON_0)
#else
#define BSP_BUTTON_0_MASK 0
#endif
#ifdef BSP_BUTTON_1
#define BSP_BUTTON_1_MASK (1<<BSP_BUTTON_1)
#else
#define BSP_BUTTON_1_MASK 0
#endif
#ifdef BSP_BUTTON_2
#define BSP_BUTTON_2_MASK (1<<BSP_BUTTON_2)
#else
#define BSP_BUTTON_2_MASK 0
#endif
#ifdef BSP_BUTTON_3
#define BSP_BUTTON_3_MASK (1<<BSP_BUTTON_3)
#else
#define BSP_BUTTON_3_MASK 0
#endif
#ifdef BSP_BUTTON_4
#define BSP_BUTTON_4_MASK (1<<BSP_BUTTON_4)
#else
#define BSP_BUTTON_4_MASK 0
#endif
#ifdef BSP_BUTTON_5
#define BSP_BUTTON_5_MASK (1<<BSP_BUTTON_5)
#else
#define BSP_BUTTON_5_MASK 0
#endif
#ifdef BSP_BUTTON_6
#define BSP_BUTTON_6_MASK (1<<BSP_BUTTON_6)
#else
#define BSP_BUTTON_6_MASK 0
#endif
#ifdef BSP_BUTTON_7
#define BSP_BUTTON_7_MASK (1<<BSP_BUTTON_7)
#else
#define BSP_BUTTON_7_MASK 0
#endif
#define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | \
BSP_BUTTON_2_MASK | BSP_BUTTON_3_MASK | \
BSP_BUTTON_4_MASK | BSP_BUTTON_5_MASK | \
BSP_BUTTON_6_MASK | BSP_BUTTON_7_MASK)
#define LEDS_OFF(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) )
#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \
ASSERT(sizeof(leds_mask) == 4); \
NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \
NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0)
#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \
ASSERT(sizeof(leds_mask) == 4); \
for (pin = 0; pin < 32; pin++) \
if ( (leds_mask) & (1 << pin) ) \
nrf_gpio_cfg_output(pin); } while (0)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,163 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef PCA10056_H
#define PCA10056_H
#ifdef __cplusplus
extern "C" {
#endif
#include "nrf_gpio.h"
// LEDs definitions for PCA10056
#define LEDS_NUMBER 4
#define LED_1 NRF_GPIO_PIN_MAP(0,13)
#define LED_2 NRF_GPIO_PIN_MAP(0,14)
#define LED_3 NRF_GPIO_PIN_MAP(0,15)
#define LED_4 NRF_GPIO_PIN_MAP(0,16)
#define LED_START LED_1
#define LED_STOP LED_4
#define LEDS_ACTIVE_STATE 0
#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
#define LEDS_INV_MASK LEDS_MASK
#define BSP_LED_0 13
#define BSP_LED_1 14
#define BSP_LED_2 15
#define BSP_LED_3 16
#define BUTTONS_NUMBER 4
#define BUTTON_1 11
#define BUTTON_2 12
#define BUTTON_3 24
#define BUTTON_4 25
#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
#define BUTTONS_ACTIVE_STATE 0
#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
#define BSP_BUTTON_0 BUTTON_1
#define BSP_BUTTON_1 BUTTON_2
#define BSP_BUTTON_2 BUTTON_3
#define BSP_BUTTON_3 BUTTON_4
#define RX_PIN_NUMBER 8
#define TX_PIN_NUMBER 6
#define CTS_PIN_NUMBER 7
#define RTS_PIN_NUMBER 5
#define HWFC true
#define BSP_QSPI_SCK_PIN 19
#define BSP_QSPI_CSN_PIN 17
#define BSP_QSPI_IO0_PIN 20
#define BSP_QSPI_IO1_PIN 21
#define BSP_QSPI_IO2_PIN 22
#define BSP_QSPI_IO3_PIN 23
// serialization APPLICATION board - temp. setup for running serialized MEMU tests
#define SER_APP_RX_PIN NRF_GPIO_PIN_MAP(1,13) // UART RX pin number.
#define SER_APP_TX_PIN NRF_GPIO_PIN_MAP(1,14) // UART TX pin number.
#define SER_APP_CTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Clear To Send pin number.
#define SER_APP_RTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Request To Send pin number.
#define SER_APP_SPIM0_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI clock GPIO pin number.
#define SER_APP_SPIM0_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI Master Out Slave In GPIO pin number
#define SER_APP_SPIM0_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI Master In Slave Out GPIO pin number
#define SER_APP_SPIM0_SS_PIN NRF_GPIO_PIN_MAP(1,13) // SPI Slave Select GPIO pin number
#define SER_APP_SPIM0_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number
#define SER_APP_SPIM0_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number
// serialization CONNECTIVITY board
#define SER_CON_RX_PIN NRF_GPIO_PIN_MAP(1,14) // UART RX pin number.
#define SER_CON_TX_PIN NRF_GPIO_PIN_MAP(1,13) // UART TX pin number.
#define SER_CON_CTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Clear To Send pin number. Not used if HWFC is set to false.
#define SER_CON_RTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Request To Send pin number. Not used if HWFC is set to false.
#define SER_CON_SPIS_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI SCK signal.
#define SER_CON_SPIS_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI MOSI signal.
#define SER_CON_SPIS_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI MISO signal.
#define SER_CON_SPIS_CSN_PIN NRF_GPIO_PIN_MAP(1,13) // SPI CSN signal.
#define SER_CON_SPIS_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number.
#define SER_CON_SPIS_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number.
#define SER_CONN_CHIP_RESET_PIN NRF_GPIO_PIN_MAP(1,1) // Pin used to reset connectivity chip
// Arduino board mappings
#define ARDUINO_SCL_PIN 27 // SCL signal pin
#define ARDUINO_SDA_PIN 26 // SDA signal pin
#define ARDUINO_AREF_PIN 2 // Aref pin
#define ARDUINO_13_PIN NRF_GPIO_PIN_MAP(1, 15) // Digital pin 13
#define ARDUINO_12_PIN NRF_GPIO_PIN_MAP(1, 14) // Digital pin 12
#define ARDUINO_11_PIN NRF_GPIO_PIN_MAP(1, 13) // Digital pin 11
#define ARDUINO_10_PIN NRF_GPIO_PIN_MAP(1, 12) // Digital pin 10
#define ARDUINO_9_PIN NRF_GPIO_PIN_MAP(1, 11) // Digital pin 9
#define ARDUINO_8_PIN NRF_GPIO_PIN_MAP(1, 10) // Digital pin 8
#define ARDUINO_7_PIN NRF_GPIO_PIN_MAP(1, 8) // Digital pin 7
#define ARDUINO_6_PIN NRF_GPIO_PIN_MAP(1, 7) // Digital pin 6
#define ARDUINO_5_PIN NRF_GPIO_PIN_MAP(1, 6) // Digital pin 5
#define ARDUINO_4_PIN NRF_GPIO_PIN_MAP(1, 5) // Digital pin 4
#define ARDUINO_3_PIN NRF_GPIO_PIN_MAP(1, 4) // Digital pin 3
#define ARDUINO_2_PIN NRF_GPIO_PIN_MAP(1, 3) // Digital pin 2
#define ARDUINO_1_PIN NRF_GPIO_PIN_MAP(1, 2) // Digital pin 1
#define ARDUINO_0_PIN NRF_GPIO_PIN_MAP(1, 1) // Digital pin 0
#define ARDUINO_A0_PIN 3 // Analog channel 0
#define ARDUINO_A1_PIN 4 // Analog channel 1
#define ARDUINO_A2_PIN 28 // Analog channel 2
#define ARDUINO_A3_PIN 29 // Analog channel 3
#define ARDUINO_A4_PIN 30 // Analog channel 4
#define ARDUINO_A5_PIN 31 // Analog channel 5
#ifdef __cplusplus
}
#endif
#endif // PCA10056_H

View File

@ -0,0 +1,95 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/* Header guard */
#ifndef SOFTDEVICE_PRESENT
/**
@defgroup nrf_error Global Error Codes
@{
@brief Global Error definitions
*/
#ifndef NRF_ERROR_H__
#define NRF_ERROR_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
* @{ */
#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
/** @} */
#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit
#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
#ifdef __cplusplus
}
#endif
#endif // NRF_ERROR_H__
/**
@}
*/
#endif // SOFTDEVICE_PRESENT

View File

@ -0,0 +1,80 @@
/**
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_SOC_H__
#define NRF_SOC_H__
#include <stdint.h>
#include "nrf.h"
#ifdef __cplusplus
extern "C" {
#endif
/**@brief Waits for an application event.
*
* An application event is either an application interrupt or a pended interrupt when the
* interrupt is disabled. When the interrupt is enabled it will be taken immediately since
* this function will wait in thread mode, then the execution will return in the application's
* main thread. When an interrupt is disabled and gets pended it will return to the application's
* thread main. The application must ensure that the pended flag is cleared using
* ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for
* disabled interrupts, as the interrupt handler will clear the pending flag automatically for
* enabled interrupts.
*
* In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0
* System Control Register (SCR). @sa CMSIS_SCB
*
* @note If an application interrupt has happened since the last time sd_app_evt_wait was
* called this function will return immediately and not go to sleep. This is to avoid race
* conditions that can occur when a flag is updated in the interrupt handler and processed
* in the main loop.
*
* @post An application interrupt has happened or a interrupt pending flag is set.
*
* @retval ::NRF_SUCCESS
*/
uint32_t sd_app_evt_wait(void);
#ifdef __cplusplus
}
#endif
#endif /* NRF_SOC_H__ */

View File

@ -0,0 +1,449 @@
/**
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "nrf_atomic.h"
#ifndef NRF_ATOMIC_USE_BUILD_IN
#if (defined(__GNUC__) && defined(WIN32))
#define NRF_ATOMIC_USE_BUILD_IN 1
#else
#define NRF_ATOMIC_USE_BUILD_IN 0
#endif
#endif // NRF_ATOMIC_USE_BUILD_IN
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
#define STREX_LDREX_PRESENT
#else
#include "app_util_platform.h"
#endif
#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
#include "nrf_atomic_internal.h"
#endif
uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data = value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
__atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
return value;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data = value;
CRITICAL_REGION_EXIT();
return value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data |= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data |= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data &= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data &= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data ^= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data ^= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data += value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data += value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data -= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data -= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t desired)
{
#if NRF_ATOMIC_USE_BUILD_IN
return __atomic_compare_exchange(p_data,
p_expected,
&desired,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
#elif defined(STREX_LDREX_PRESENT)
return nrf_atomic_internal_cmp_exch(p_data, p_expected, desired);
#else
bool ret;
CRITICAL_REGION_ENTER();
if (*p_data == *p_expected)
{
*p_data = desired;
ret = true;
}
else
{
*p_expected = *p_data;
ret = false;
}
CRITICAL_REGION_EXIT();
return ret;
#endif
}
uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
uint32_t expected = *p_data;
uint32_t new_val;
bool success;
do
{
if (expected >= value)
{
new_val = expected - value;
}
else
{
new_val = expected;
}
success = __atomic_compare_exchange(p_data,
&expected,
&new_val,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
} while(!success);
return expected;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return old_val;
#else
CRITICAL_REGION_ENTER();
uint32_t old_val = *p_data;
*p_data -= value;
CRITICAL_REGION_EXIT();
return old_val;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
{
#if NRF_ATOMIC_USE_BUILD_IN
uint32_t expected = *p_data;
uint32_t new_val;
bool success;
do
{
if (expected >= value)
{
new_val = expected - value;
}
else
{
new_val = expected;
}
success = __atomic_compare_exchange(p_data,
&expected,
&new_val,
1,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
} while(!success);
return new_val;
#elif defined(STREX_LDREX_PRESENT)
uint32_t old_val;
uint32_t new_val;
NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
UNUSED_PARAMETER(old_val);
UNUSED_PARAMETER(new_val);
return new_val;
#else
CRITICAL_REGION_ENTER();
*p_data -= value;
uint32_t new_value = *p_data;
CRITICAL_REGION_EXIT();
return new_value;
#endif //NRF_ATOMIC_USE_BUILD_IN
}
uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_or(p_data, 1);
}
uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_or(p_data, 1);
}
uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_fetch_and(p_data, 0);
}
uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
{
return nrf_atomic_u32_and(p_data, 0);
}

View File

@ -0,0 +1,274 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup nrf_atomic Atomic operations API
* @ingroup app_common
* @{
*
* @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
* Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
*/
#ifndef NRF_ATOMIC_H__
#define NRF_ATOMIC_H__
#include "sdk_common.h"
/**
* @brief Atomic 32 bit unsigned type
* */
typedef volatile uint32_t nrf_atomic_u32_t;
/**
* @brief Atomic 1 bit flag type (technically 32 bit)
* */
typedef volatile uint32_t nrf_atomic_flag_t;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Stores value to an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value to store
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical OR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand OR operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical AND operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand AND operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Logical XOR operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand XOR operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic ADD operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand ADD operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief If value at pointer is equal to expected value, changes value at pointer to desired
*
* Atomically compares the value pointed to by p_data with the value pointed to by p_expected,
* and if those are equal, replaces the former with desired. Otherwise, loads the actual value
* pointed to by p_data into *p_expected.
*
* @param p_data Atomic memory pointer to test and modify.
* @param p_expected Pointer to test value.
* @param desired Value to be stored to atomic memory.
*
* @retval true *p_data was equal to *p_expected
* @retval false *p_data was not equal to *p_expected
*/
bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t desired);
/**
* @brief Arithmetic SUB operation on an atomic object performed if object >= value.
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return Old value stored into atomic object
* */
uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
/**
* @brief Arithmetic SUB operation on an atomic object performed if object >= value.
*
* @param[in] p_data Atomic memory pointer
* @param[in] value Value of second operand SUB operation
*
* @return New value stored into atomic object
* */
uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
/**************************************************************************************************/
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag set operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return Old flag value
* */
uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data);
/**
* @brief Logic one bit flag clear operation on an atomic object
*
* @param[in] p_data Atomic flag memory pointer
*
* @return New flag value
* */
uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data);
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_H__ */
/** @} */

View File

@ -0,0 +1,343 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_ATOMIC_INTERNAL_H__
#define NRF_ATOMIC_INTERNAL_H__
#include "sdk_common.h"
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
*
* @defgroup nrf_atomic_internal Atomic operations internals
* @ingroup nrf_atomic
* @{
*
*/
/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
#error "Unsupported core version"
#endif
#if defined ( __CC_ARM )
static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
/* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
* Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
* allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
* */
push {r4, r5}
mov r4, r0
loop_mov
ldrex r0, [r4]
mov r5, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_mov
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_orr
ldrex r0, [r4]
orr r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_orr
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_and
ldrex r0, [r4]
and r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_and
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_eor
ldrex r0, [r4]
eor r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_eor
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_add
ldrex r0, [r4]
add r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_add
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_sub
ldrex r0, [r4]
sub r5, r0, r1
strex r3, r5, [r4]
cmp r3, #0
bne loop_sub
str r5, [r2]
pop {r4, r5}
bx lr
}
static __asm bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t value)
{
#define RET_REG r0
#define P_EXPC r1
#define VALUE r2
#define STR_RES r3
#define P_DATA r4
#define EXPC_VAL r5
#define ACT_VAL r6
push {r4-r6}
mov P_DATA, r0
mov RET_REG, #0
loop_cmp_exch
ldrex ACT_VAL, [P_DATA]
ldr EXPC_VAL, [P_EXPC]
cmp ACT_VAL, EXPC_VAL
ittee eq
strexeq STR_RES, VALUE, [P_DATA]
moveq RET_REG, #1
strexne STR_RES, ACT_VAL, [P_DATA]
strne ACT_VAL, [P_EXPC]
cmp STR_RES, #0
itt ne
movne RET_REG, #0
bne loop_cmp_exch
pop {r4-r6}
bx lr
#undef RET_REG
#undef P_EXPC
#undef VALUE
#undef STR_RES
#undef P_DATA
#undef EXPC_VAL
#undef ACT_VAL
}
static __asm uint32_t nrf_atomic_internal_sub_hs(nrf_atomic_u32_t * p_ptr,
uint32_t value,
uint32_t * p_new)
{
push {r4, r5}
mov r4, r0
loop_sub_ge
ldrex r0, [r4]
cmp r0, r1
ite hs
subhs r5, r0, r1
movlo r5, r0
strex r3, r5, [r4]
cmp r3, #0
bne loop_sub_ge
str r5, [r2]
pop {r4, r5}
bx lr
}
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
/**
* @brief Atomic operation generic macro
* @param[in] asm_op operation: mov, orr, and, eor, add, sub
* @param[out] old_val atomic object output (uint32_t), value before operation
* @param[out] new_val atomic object output (uint32_t), value after operation
* @param[in] value atomic operation operand
* */
#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
{ \
uint32_t str_res; \
__ASM volatile( \
"1: ldrex %["#old_val"], [%["#ptr"]]\n" \
NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
" strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
" teq %[str_res], #0\n" \
" bne.n 1b" \
: \
[old_val]"=&r" (old_val), \
[new_val]"=&r" (new_val), \
[str_res]"=&r" (str_res) \
: \
[ptr]"r" (ptr), \
[value]"r" (value) \
: "cc"); \
UNUSED_PARAMETER(str_res); \
}
#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
#define NRF_ATOMIC_OP_sub_hs(new_val, old_val, value) \
"cmp %["#old_val"], %["#value"]\n " \
"ite hs\n" \
"subhs %["#new_val"], %["#old_val"], %["#value"]\n" \
"movlo %["#new_val"], %["#old_val"]\n"
static inline bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
uint32_t * p_expected,
uint32_t value)
{
bool res = false;
uint32_t str_res = 0;
uint32_t act_val = 0;
uint32_t exp_val = 0;
UNUSED_VARIABLE(str_res);
UNUSED_VARIABLE(act_val);
UNUSED_VARIABLE(exp_val);
__ASM volatile(
"1: ldrex %[act_val], [%[ptr]]\n"
" ldr %[exp_val], [%[expc]]\n"
" cmp %[act_val], %[exp_val]\n"
" ittee eq\n"
" strexeq %[str_res], %[value], [%[ptr]]\n"
" moveq %[res], #1\n"
" strexne %[str_res], %[act_val], [%[ptr]]\n"
" strne %[act_val], [%[expc]]\n"
" cmp %[str_res], #0\n"
" itt ne\n"
" movne %[res], #0\n"
" bne.n 1b"
:
[res] "=&r" (res),
[exp_val] "=&r" (exp_val),
[act_val] "=&r" (act_val),
[str_res] "=&r" (str_res)
:
"0" (res),
"1" (exp_val),
"2" (act_val),
[expc] "r" (p_expected),
[ptr] "r" (p_data),
[value] "r" (value)
: "cc");
return res;
}
#else
#error "Unsupported compiler"
#endif
#ifdef __cplusplus
}
#endif
#endif /* NRF_ATOMIC_INTERNAL_H__ */
/** @} */

View File

@ -0,0 +1,399 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_BALLOC)
#include "nrf_section.h"
#include "nrf_balloc.h"
#include "app_util_platform.h"
#if NRF_BALLOC_CONFIG_LOG_ENABLED
#define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL
#define NRF_LOG_INITIAL_LEVEL NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
#define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR
#define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR
#else
#define NRF_LOG_LEVEL 0
#endif // NRF_BALLOC_CONFIG_LOG_ENABLED
#include "nrf_log.h"
#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/
#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/
#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
#define POOL_ID(_p_pool) _p_pool->p_name
#define POOL_MARKER "%s"
#else
#define POOL_ID(_p_pool) _p_pool
#define POOL_MARKER "0x%08X"
#endif
NRF_SECTION_DEF(nrf_balloc, nrf_balloc_t);
#if NRF_BALLOC_CLI_CMDS
#include "nrf_cli.h"
static void nrf_balloc_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
{
UNUSED_PARAMETER(argv);
if (nrf_cli_help_requested(p_cli))
{
nrf_cli_help_print(p_cli, NULL, 0);
return;
}
if (argc > 1)
{
nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad argument count");
return;
}
uint32_t num_of_instances = NRF_SECTION_ITEM_COUNT(nrf_balloc, nrf_balloc_t);
uint32_t i;
for (i = 0; i < num_of_instances; i++)
{
const nrf_balloc_t * p_instance = NRF_SECTION_ITEM_GET(nrf_balloc, nrf_balloc_t, i);
uint32_t element_size = NRF_BALLOC_ELEMENT_SIZE(p_instance);
uint32_t dbg_addon = p_instance->block_size - element_size;
uint32_t pool_size = p_instance->p_stack_limit - p_instance->p_stack_base;
uint32_t max_util = nrf_balloc_max_utilization_get(p_instance);
uint32_t util = nrf_balloc_utilization_get(p_instance);
const char * p_name = p_instance->p_name;
nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,
"%s\r\n\t- Element size:\t%d + %d bytes of debug information\r\n"
"\t- Usage:\t%u%% (%u out of %u elements)\r\n"
"\t- Maximum:\t%u%% (%u out of %u elements)\r\n\r\n",
p_name, element_size, dbg_addon,
100ul * util/pool_size, util,pool_size,
100ul * max_util/pool_size, max_util,pool_size);
}
}
// Register "balloc" command and its subcommands in CLI.
NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_balloc_commands)
{
NRF_CLI_CMD(status, NULL, "Print status of balloc instances.", nrf_balloc_status),
NRF_CLI_SUBCMD_SET_END
};
NRF_CLI_CMD_REGISTER(balloc, &nrf_balloc_commands, "Commands for BALLOC management", nrf_balloc_status);
#endif //NRF_BALLOC_CLI_CMDS
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
/**@brief Validate block memory, prepare block guards, and calculate pointer to the element.
*
* @param[in] p_pool Pointer to the memory pool.
* @param[in] p_head Pointer to the beginning of the block.
*
* @return Pointer to the element.
*/
__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head)
{
ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0));
uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
uint32_t * p_element = (uint32_t *)p_head + head_words;
if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
{
for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
{
if (*ptr != FREE_MEM_FILL)
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Detected free memory corruption at 0x%08X (0x%08X != 0x%08X)",
ptr, *ptr, FREE_MEM_FILL);
APP_ERROR_CHECK_BOOL(false);
}
}
}
for (uint32_t * ptr = p_head; ptr < p_element; ptr++)
{
*ptr = HEAD_GUARD_FILL;
}
for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
{
*ptr = TAIL_GUARD_FILL;
}
return p_element;
}
/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free.
*
* @param[in] p_pool Pointer to the memory pool.
* @param[in] p_element Pointer to the element.
*
* @return Pointer to the beginning of the block.
*/
__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element)
{
ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0));
uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
uint32_t * p_head = (uint32_t *)p_element - head_words;
uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++)
{
if (*ptr != HEAD_GUARD_FILL)
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Detected Head Guard corruption at 0x%08X (0x%08X != 0x%08X)",
ptr, *ptr, HEAD_GUARD_FILL);
APP_ERROR_CHECK_BOOL(false);
}
}
for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
{
if (*ptr != TAIL_GUARD_FILL)
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Detected Tail Guard corruption at 0x%08X (0x%08X != 0x%08X)",
ptr, *ptr, TAIL_GUARD_FILL);
APP_ERROR_CHECK_BOOL(false);
}
}
if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
{
for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
{
*ptr = FREE_MEM_FILL;
}
}
return p_head;
}
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
/**@brief Convert block index to a pointer.
*
* @param[in] p_pool Pointer to the memory pool.
* @param[in] idx Index of the block.
*
* @return Pointer to the beginning of the block.
*/
static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx)
{
ASSERT(p_pool != NULL);
return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size);
}
/**@brief Convert block pointer to index.
*
* @param[in] p_pool Pointer to the memory pool.
* @param[in] p_block Pointer to the beginning of the block.
*
* @return Index of the block.
*/
static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block)
{
ASSERT(p_pool != NULL);
return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size;
}
ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool)
{
uint8_t pool_size;
VERIFY_PARAM_NOT_NULL(p_pool);
ASSERT(p_pool->p_cb);
ASSERT(p_pool->p_stack_base);
ASSERT(p_pool->p_stack_limit);
ASSERT(p_pool->p_memory_begin);
ASSERT(p_pool->block_size);
pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
{
for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_memory_end); ptr++)
{
*ptr = FREE_MEM_FILL;
}
}
#endif
NRF_LOG_INST_INFO(p_pool->p_log, "Initialized (size: %u x %u = %u bytes)",
pool_size,
p_pool->block_size,
pool_size * p_pool->block_size);
p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base;
while (pool_size--)
{
*(p_pool->p_cb->p_stack_pointer)++ = pool_size;
}
p_pool->p_cb->max_utilization = 0;
return NRF_SUCCESS;
}
void * nrf_balloc_alloc(nrf_balloc_t const * p_pool)
{
ASSERT(p_pool != NULL);
void * p_block = NULL;
CRITICAL_REGION_ENTER();
if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base)
{
// Allocate block.
p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer));
// Update utilization statistics.
uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer;
if (p_pool->p_cb->max_utilization < utilization)
{
p_pool->p_cb->max_utilization = utilization;
}
}
CRITICAL_REGION_EXIT();
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
if (p_block != NULL)
{
p_block = nrf_balloc_block_unwrap(p_pool, p_block);
}
#endif
NRF_LOG_INST_DEBUG(p_pool->p_log, "Allocating element: 0x%08X", p_block);
return p_block;
}
void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element)
{
ASSERT(p_pool != NULL);
ASSERT(p_element != NULL)
NRF_LOG_INST_DEBUG(p_pool->p_log, "Freeing element: 0x%08X", p_element);
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
void * p_block = nrf_balloc_element_wrap(p_pool, p_element);
// These checks could be done outside critical region as they use only pool configuration data.
if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
{
uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
// Check if the element belongs to this pool.
if ((p_block < p_pool->p_memory_begin) || (p_block >= p_memory_end))
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Attempted to free element (0x%08X) that does not belong to the pool.",
p_element);
APP_ERROR_CHECK_BOOL(false);
}
// Check if the pointer is valid.
if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0)
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Attempted to free corrupted element address (0x%08X).", p_element);
APP_ERROR_CHECK_BOOL(false);
}
}
#else
void * p_block = p_element;
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
CRITICAL_REGION_ENTER();
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
// These checks have to be done in critical region as they use p_pool->p_stack_pointer.
if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
{
// Check for allocated/free ballance.
if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit)
{
NRF_LOG_INST_ERROR(p_pool->p_log,
"Attempted to free an element (0x%08X) while the pool is full.",
p_element);
APP_ERROR_CHECK_BOOL(false);
}
}
if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags))
{
// Check for double free.
for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++)
{
if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block)
{
NRF_LOG_INST_ERROR(p_pool->p_log, "Attempted to double-free an element (0x%08X).",
p_element);
APP_ERROR_CHECK_BOOL(false);
}
}
}
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
// Free the element.
*(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block);
CRITICAL_REGION_EXIT();
}
#endif // NRF_MODULE_ENABLED(NRF_BALLOC)

View File

@ -0,0 +1,351 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**
* @defgroup nrf_balloc Block memory allocator
* @{
* @ingroup app_common
* @brief This module handles block memory allocator features.
*/
#ifndef NRF_BALLOC_H__
#define NRF_BALLOC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "sdk_errors.h"
#include "sdk_config.h"
#include "app_util_platform.h"
#include "app_util.h"
#include "nrf_log_instance.h"
#include "nrf_section.h"
/** @brief Name of the module used for logger messaging.
*/
#define NRF_BALLOC_LOG_NAME balloc
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED || NRF_BALLOC_CLI_CMDS
#define NRF_BALLOC_HAS_NAME 1
#else
#define NRF_BALLOC_HAS_NAME 0
#endif
/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module.
* @{ */
#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0)
#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF)
#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8)
#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF)
#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16)
#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16))
#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17)
#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17))
#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18)
#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18))
/**@} */
/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro.
* Flags can be changed in @ref sdk_config.
*/
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
#define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \
( \
NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \
NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS) | \
NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \
NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \
NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \
)
#else
#define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
/**@brief Block memory allocator control block.*/
typedef struct
{
uint8_t * p_stack_pointer; //!< Current allocation stack pointer.
uint8_t max_utilization; //!< Maximum utilization of the memory pool.
} nrf_balloc_cb_t;
/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */
typedef struct
{
nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block.
uint8_t * p_stack_base; //!< Base of the allocation stack.
/**<
* Stack is used to store handlers to not allocated elements.
*/
uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer.
void * p_memory_begin; //!< Pointer to the start of the memory pool.
/**<
* Memory is used as a heap for blocks.
*/
NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
#if NRF_BALLOC_HAS_NAME
const char * p_name; //!< Pointer to string with pool name.
#endif
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
uint32_t debug_flags; //!< Debugging settings.
/**<
* Debug flag should be created by @ref NRF_BALLOC_DEBUG.
*/
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
uint16_t block_size; //!< Size of the allocated block (including debug overhead).
/**<
* Single block contains user element with header and tail
* words.
*/
} nrf_balloc_t;
/**@brief Get total memory consumed by single block (element size with overhead caused by debug
* flags).
*
* @param[in] _element_size Size of an element.
* @param[in] _debug_flags Debug flags.
*/
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
#define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
( \
(sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \
ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \
(sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \
)
#else
#define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
ALIGN_NUM(sizeof(uint32_t), (_element_size))
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
/**@brief Get element size ( excluding debugging overhead is present)
* flags).
*
* @param[in] _p_balloc Pointer to balloc instance.
*/
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
(ALIGN_NUM(sizeof(uint32_t), (_p_balloc)->block_size) - \
((sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET((_p_balloc)->debug_flags)) + \
(sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET((_p_balloc)->debug_flags))))
#else
#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
(_p_balloc)->block_size
#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) .debug_flags = (_debug_flags),
#else
#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags)
#endif
#if NRF_BALLOC_HAS_NAME
#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
#else
#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name)
#endif
/**@brief Create a block allocator instance with custom debug flags.
*
* @note This macro reserves memory for the given block allocator instance.
*
* @param[in] _name Name of the allocator.
* @param[in] _element_size Size of one element.
* @param[in] _pool_size Size of the pool.
* @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG).
*/
#define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \
STATIC_ASSERT((_pool_size) <= UINT8_MAX); \
static uint8_t CONCAT_2(_name, _nrf_balloc_pool_stack)[(_pool_size)]; \
static uint32_t CONCAT_2(_name,_nrf_balloc_pool_mem) \
[NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \
static nrf_balloc_cb_t CONCAT_2(_name,_nrf_balloc_cb); \
NRF_LOG_INSTANCE_REGISTER(NRF_BALLOC_LOG_NAME, _name, \
NRF_BALLOC_CONFIG_INFO_COLOR, \
NRF_BALLOC_CONFIG_DEBUG_COLOR, \
NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL, \
NRF_BALLOC_CONFIG_LOG_ENABLED ? \
NRF_BALLOC_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
NRF_SECTION_ITEM_REGISTER(nrf_balloc, const nrf_balloc_t _name) = \
{ \
.p_cb = &CONCAT_2(_name,_nrf_balloc_cb), \
.p_stack_base = CONCAT_2(_name,_nrf_balloc_pool_stack), \
.p_stack_limit = CONCAT_2(_name,_nrf_balloc_pool_stack) + (_pool_size), \
.p_memory_begin = CONCAT_2(_name,_nrf_balloc_pool_mem), \
.block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \
\
NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_BALLOC_LOG_NAME, _name) \
__NRF_BALLOC_ASSIGN_POOL_NAME(_name) \
__NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) \
}
/**@brief Create a block allocator instance.
*
* @note This macro reserves memory for the given block allocator instance.
*
* @param[in] _name Name of the allocator.
* @param[in] _element_size Size of one element.
* @param[in] _pool_size Size of the pool.
*/
#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \
NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS)
/**@brief Create a block allocator interface.
*
* @param[in] _type Type which is allocated.
* @param[in] _name Name of the allocator.
*/
#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \
_type * CONCAT_2(_name,_alloc)(void); \
void CONCAT_2(_name,_free)(_type * p_element)
/**@brief Define a custom block allocator interface.
*
* @param[in] _attr Function attribute that will be added to allocator function definition.
* @param[in] _type Type which is allocated.
* @param[in] _name Name of the allocator.
* @param[in] _p_pool Pool from which data will be allocated.
*/
#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \
_attr _type * CONCAT_2(_name,_alloc)(void) \
{ \
GCC_PRAGMA("GCC diagnostic push") \
GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
ASSERT((_p_pool) != NULL); \
ASSERT((_p_pool)->block_size >= \
NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
GCC_PRAGMA("GCC diagnostic pop") \
return (_type *)(nrf_balloc_alloc(_p_pool)); \
} \
\
_attr void CONCAT_2(_name,_free)(_type * p_element) \
{ \
GCC_PRAGMA("GCC diagnostic push") \
GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
ASSERT((_p_pool) != NULL); \
ASSERT((_p_pool)->block_size >= \
NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
GCC_PRAGMA("GCC diagnostic pop") \
nrf_balloc_free((_p_pool), p_element); \
}
/**@brief Define block allocator interface.
*
* @param[in] _type Type which is allocated.
* @param[in] _name Name of the allocator.
* @param[in] _p_pool Pool from which data will be allocated.
*/
#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \
NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool)
/**@brief Define a local block allocator interface.
*
* @param[in] _type Type which is allocated.
* @param[in] _name Name of the allocator.
* @param[in] _p_pool Pool from which data will be allocated.
*/
#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \
NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool)
/**@brief Function for initializing a block memory allocator pool.
*
* @param[out] p_pool Pointer to the pool that is to be initialized.
*
* @return NRF_SUCCESS on success, otherwise error code.
*/
ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool);
/**@brief Function for allocating an element from the pool.
*
* @note This module guarantees that the returned memory is aligned to 4.
*
* @param[in] p_pool Pointer to the memory pool from which the element will be allocated.
*
* @return Allocated element or NULL if the specified pool is empty.
*/
void * nrf_balloc_alloc(nrf_balloc_t const * p_pool);
/**@brief Function for freeing an element back to the pool.
*
* @param[in] p_pool Pointer to the memory pool.
* @param[in] p_element Element to be freed.
*/
void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element);
/**@brief Function for getting maximum memory pool utilization.
*
* @param[in] p_pool Pointer to the memory pool instance.
*
* @return Maximum number of elements allocated from the pool.
*/
__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool)
{
ASSERT(p_pool != NULL);
return p_pool->p_cb->max_utilization;
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
/**@brief Function for getting current memory pool utilization.
*
* @param[in] p_pool Pointer to the memory pool instance.
*
* @return Maximum number of elements allocated from the pool.
*/
__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool)
{
ASSERT(p_pool != NULL);
return (p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer);
}
#endif //SUPPRESS_INLINE_IMPLEMENTATION
#ifdef __cplusplus
}
#endif
#endif // NRF_BALLOC_H__
/** @} */

View File

@ -0,0 +1,638 @@
/**
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "bsp.h"
#include <stddef.h>
#include <stdio.h>
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_gpio.h"
#include "nrf_error.h"
#include "bsp_config.h"
#include "boards.h"
#ifndef BSP_SIMPLE
#include "app_timer.h"
#include "app_button.h"
#endif // BSP_SIMPLE
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE;
static bool m_leds_clear = false;
static uint32_t m_indication_type = 0;
static bool m_alert_on = false;
APP_TIMER_DEF(m_bsp_leds_tmr);
APP_TIMER_DEF(m_bsp_alert_tmr);
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
#if BUTTONS_NUMBER > 0
#ifndef BSP_SIMPLE
static bsp_event_callback_t m_registered_callback = NULL;
static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}};
APP_TIMER_DEF(m_bsp_button_tmr);
static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action);
#endif // BSP_SIMPLE
#ifndef BSP_SIMPLE
static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
{
#ifdef BSP_BUTTON_0
{BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_0
#ifdef BSP_BUTTON_1
{BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_1
#ifdef BSP_BUTTON_2
{BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_2
#ifdef BSP_BUTTON_3
{BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_3
#ifdef BSP_BUTTON_4
{BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_4
#ifdef BSP_BUTTON_5
{BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_5
#ifdef BSP_BUTTON_6
{BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_6
#ifdef BSP_BUTTON_7
{BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},
#endif // BUTTON_7
};
#endif // BSP_SIMPLE
#endif // BUTTONS_NUMBER > 0
#if (BUTTONS_NUMBER > 0)
bool bsp_button_is_pressed(uint32_t button)
{
if (button < BUTTONS_NUMBER)
{
return bsp_board_button_state_get(button);
}
else
{
//If button is not present always return false
return false;
}
}
#endif
#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
/**@brief Function for handling button events.
*
* @param[in] pin_no The pin number of the button pressed.
* @param[in] button_action Action button.
*/
static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
{
bsp_event_t event = BSP_EVENT_NOTHING;
uint32_t button = 0;
uint32_t err_code;
static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */
static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */
button = bsp_board_pin_to_button_idx(pin_no);
if (button < BUTTONS_NUMBER)
{
switch (button_action)
{
case APP_BUTTON_PUSH:
event = m_events_list[button].push_event;
if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
{
err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);
if (err_code == NRF_SUCCESS)
{
current_long_push_pin_no = pin_no;
}
}
release_event_at_push[button] = m_events_list[button].release_event;
break;
case APP_BUTTON_RELEASE:
(void)app_timer_stop(m_bsp_button_tmr);
if (release_event_at_push[button] == m_events_list[button].release_event)
{
event = m_events_list[button].release_event;
}
break;
case BSP_BUTTON_ACTION_LONG_PUSH:
event = m_events_list[button].long_push_event;
}
}
if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
{
m_registered_callback(event);
}
}
/**@brief Handle events from button timer.
*
* @param[in] p_context parameter registered in timer start function.
*/
static void button_timer_handler(void * p_context)
{
bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);
}
#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
static void leds_off(void)
{
if (m_alert_on)
{
uint32_t i;
for (i = 0; i < LEDS_NUMBER; i++)
{
if (i != BSP_LED_ALERT)
{
bsp_board_led_off(i);
}
}
}
else
{
bsp_board_leds_off();
}
}
/**@brief Configure leds to indicate required state.
* @param[in] indicate State to be indicated.
*/
static uint32_t bsp_led_indication(bsp_indication_t indicate)
{
uint32_t err_code = NRF_SUCCESS;
uint32_t next_delay = 0;
if (m_leds_clear)
{
m_leds_clear = false;
leds_off();
}
switch (indicate)
{
case BSP_INDICATE_IDLE:
leds_off();
err_code = app_timer_stop(m_bsp_leds_tmr);
m_stable_state = indicate;
break;
case BSP_INDICATE_SCANNING:
case BSP_INDICATE_ADVERTISING:
// in advertising blink LED_0
if (bsp_board_led_state_get(BSP_LED_INDICATE_INDICATE_ADVERTISING))
{
bsp_board_led_off(BSP_LED_INDICATE_INDICATE_ADVERTISING);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL :
ADVERTISING_SLOW_LED_OFF_INTERVAL;
}
else
{
bsp_board_led_on(BSP_LED_INDICATE_INDICATE_ADVERTISING);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL :
ADVERTISING_SLOW_LED_ON_INTERVAL;
}
m_stable_state = indicate;
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
break;
case BSP_INDICATE_ADVERTISING_WHITELIST:
// in advertising quickly blink LED_0
if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_WHITELIST))
{
bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_WHITELIST ?
ADVERTISING_WHITELIST_LED_OFF_INTERVAL :
ADVERTISING_SLOW_LED_OFF_INTERVAL;
}
else
{
bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_WHITELIST ?
ADVERTISING_WHITELIST_LED_ON_INTERVAL :
ADVERTISING_SLOW_LED_ON_INTERVAL;
}
m_stable_state = indicate;
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
break;
case BSP_INDICATE_ADVERTISING_SLOW:
// in advertising slowly blink LED_0
if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_SLOW))
{
bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_SLOW);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL :
ADVERTISING_SLOW_LED_OFF_INTERVAL;
}
else
{
bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_SLOW);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL :
ADVERTISING_SLOW_LED_ON_INTERVAL;
}
m_stable_state = indicate;
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
break;
case BSP_INDICATE_ADVERTISING_DIRECTED:
// in advertising very quickly blink LED_0
if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_DIRECTED))
{
bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_DIRECTED ?
ADVERTISING_DIRECTED_LED_OFF_INTERVAL :
ADVERTISING_SLOW_LED_OFF_INTERVAL;
}
else
{
bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
next_delay = indicate ==
BSP_INDICATE_ADVERTISING_DIRECTED ?
ADVERTISING_DIRECTED_LED_ON_INTERVAL :
ADVERTISING_SLOW_LED_ON_INTERVAL;
}
m_stable_state = indicate;
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
break;
case BSP_INDICATE_BONDING:
// in bonding fast blink LED_0
bsp_board_led_invert(BSP_LED_INDICATE_BONDING);
m_stable_state = indicate;
err_code =
app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(BONDING_INTERVAL), NULL);
break;
case BSP_INDICATE_CONNECTED:
bsp_board_led_on(BSP_LED_INDICATE_CONNECTED);
m_stable_state = indicate;
break;
case BSP_INDICATE_SENT_OK:
// when sending shortly invert LED_1
m_leds_clear = true;
bsp_board_led_invert(BSP_LED_INDICATE_SENT_OK);
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SENT_OK_INTERVAL), NULL);
break;
case BSP_INDICATE_SEND_ERROR:
// on receving error invert LED_1 for long time
m_leds_clear = true;
bsp_board_led_invert(BSP_LED_INDICATE_SEND_ERROR);
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SEND_ERROR_INTERVAL), NULL);
break;
case BSP_INDICATE_RCV_OK:
// when receving shortly invert LED_1
m_leds_clear = true;
bsp_board_led_invert(BSP_LED_INDICATE_RCV_OK);
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_OK_INTERVAL), NULL);
break;
case BSP_INDICATE_RCV_ERROR:
// on receving error invert LED_1 for long time
m_leds_clear = true;
bsp_board_led_invert(BSP_LED_INDICATE_RCV_ERROR);
err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_ERROR_INTERVAL), NULL);
break;
case BSP_INDICATE_FATAL_ERROR:
// on fatal error turn on all leds
bsp_board_leds_on();
m_stable_state = indicate;
break;
case BSP_INDICATE_ALERT_0:
case BSP_INDICATE_ALERT_1:
case BSP_INDICATE_ALERT_2:
case BSP_INDICATE_ALERT_3:
case BSP_INDICATE_ALERT_OFF:
err_code = app_timer_stop(m_bsp_alert_tmr);
next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate;
// a little trick to find out that if it did not fall through ALERT_OFF
if (next_delay && (err_code == NRF_SUCCESS))
{
if (next_delay > 1)
{
err_code = app_timer_start(m_bsp_alert_tmr,
APP_TIMER_TICKS(((uint16_t)next_delay * ALERT_INTERVAL)),
NULL);
}
bsp_board_led_on(BSP_LED_ALERT);
m_alert_on = true;
}
else
{
bsp_board_led_off(BSP_LED_ALERT);
m_alert_on = false;
}
break;
case BSP_INDICATE_USER_STATE_OFF:
leds_off();
m_stable_state = indicate;
break;
case BSP_INDICATE_USER_STATE_0:
leds_off();
bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
m_stable_state = indicate;
break;
case BSP_INDICATE_USER_STATE_1:
leds_off();
bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
m_stable_state = indicate;
break;
case BSP_INDICATE_USER_STATE_2:
leds_off();
bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
m_stable_state = indicate;
break;
case BSP_INDICATE_USER_STATE_3:
case BSP_INDICATE_USER_STATE_ON:
bsp_board_leds_on();
m_stable_state = indicate;
break;
default:
break;
}
return err_code;
}
/**@brief Handle events from leds timer.
*
* @note Timer handler does not support returning an error code.
* Errors from bsp_led_indication() are not propagated.
*
* @param[in] p_context parameter registered in timer start function.
*/
static void leds_timer_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
if (m_indication_type & BSP_INIT_LEDS)
{
UNUSED_VARIABLE(bsp_led_indication(m_stable_state));
}
}
/**@brief Handle events from alert timer.
*
* @param[in] p_context parameter registered in timer start function.
*/
static void alert_timer_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
bsp_board_led_invert(BSP_LED_ALERT);
}
#endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
/**@brief Configure indicators to required state.
*/
uint32_t bsp_indication_set(bsp_indication_t indicate)
{
uint32_t err_code = NRF_SUCCESS;
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
if (m_indication_type & BSP_INIT_LEDS)
{
err_code = bsp_led_indication(indicate);
}
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
return err_code;
}
uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
{
uint32_t err_code = NRF_SUCCESS;
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
m_indication_type = type;
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
m_registered_callback = callback;
// BSP will support buttons and generate events
if (type & BSP_INIT_BUTTONS)
{
uint32_t num;
for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
{
err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
}
if (err_code == NRF_SUCCESS)
{
err_code = app_button_init((app_button_cfg_t *)app_buttons,
BUTTONS_NUMBER,
APP_TIMER_TICKS(50));
}
if (err_code == NRF_SUCCESS)
{
err_code = app_button_enable();
}
if (err_code == NRF_SUCCESS)
{
err_code = app_timer_create(&m_bsp_button_tmr,
APP_TIMER_MODE_SINGLE_SHOT,
button_timer_handler);
}
}
#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)
bsp_board_init(type);
#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
if (type & BSP_INIT_LEDS)
{
//handle LEDs only. Buttons are already handled.
bsp_board_init(BSP_INIT_LEDS);
// timers module must be already initialized!
if (err_code == NRF_SUCCESS)
{
err_code =
app_timer_create(&m_bsp_leds_tmr, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);
}
if (err_code == NRF_SUCCESS)
{
err_code =
app_timer_create(&m_bsp_alert_tmr, APP_TIMER_MODE_REPEATED, alert_timer_handler);
}
}
#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
return err_code;
}
#ifndef BSP_SIMPLE
/**@brief Assign specific event to button.
*/
uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event)
{
uint32_t err_code = NRF_SUCCESS;
#if BUTTONS_NUMBER > 0
if (button < BUTTONS_NUMBER)
{
if (event == BSP_EVENT_DEFAULT)
{
// Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.
event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;
}
switch (action)
{
case BSP_BUTTON_ACTION_PUSH:
m_events_list[button].push_event = event;
break;
case BSP_BUTTON_ACTION_LONG_PUSH:
m_events_list[button].long_push_event = event;
break;
case BSP_BUTTON_ACTION_RELEASE:
m_events_list[button].release_event = event;
break;
default:
err_code = NRF_ERROR_INVALID_PARAM;
break;
}
}
else
{
err_code = NRF_ERROR_INVALID_PARAM;
}
#else
err_code = NRF_ERROR_INVALID_PARAM;
#endif // BUTTONS_NUMBER > 0
return err_code;
}
#endif // BSP_SIMPLE
uint32_t bsp_buttons_enable()
{
#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
return app_button_enable();
#else
return NRF_ERROR_NOT_SUPPORTED;
#endif
}
uint32_t bsp_buttons_disable()
{
#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
return app_button_disable();
#else
return NRF_ERROR_NOT_SUPPORTED;
#endif
}
static uint32_t wakeup_button_cfg(uint32_t button_idx, bool enable)
{
#if !defined(BSP_SIMPLE)
if (button_idx < BUTTONS_NUMBER)
{
nrf_gpio_pin_sense_t sense = enable ?
(BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW) :
NRF_GPIO_PIN_NOSENSE;
nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), sense);
return NRF_SUCCESS;
}
#else
UNUSED_PARAMETER(button_idx);
UNUSED_PARAMETER(enable);
#endif
return NRF_ERROR_NOT_SUPPORTED;
}
uint32_t bsp_wakeup_button_enable(uint32_t button_idx)
{
return wakeup_button_cfg(button_idx, true);
}
uint32_t bsp_wakeup_button_disable(uint32_t button_idx)
{
return wakeup_button_cfg(button_idx, false);
}

View File

@ -0,0 +1,307 @@
/**
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup bsp Board Support Package
* @{
* @ingroup app_common
*
* @brief BSP module.
* @details This module provides a layer of abstraction from the board.
* It allows the user to indicate certain states on LEDs in a simple way.
* Module functionality can be modified by defining BSP_SIMPLE to reduce
* functionality of this module to enable and read state of the buttons.
*/
#ifndef BSP_H__
#define BSP_H__
#include <stdint.h>
#include <stdbool.h>
#include "boards.h"
#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
#include "app_button.h"
#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
#endif
/* BSP_UART_SUPPORT
* This define enables UART support module.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */
#define BSP_INDICATIONS_LIST { \
"BSP_INDICATE_IDLE", \
"BSP_INDICATE_SCANNING", \
"BSP_INDICATE_ADVERTISING", \
"BSP_INDICATE_ADVERTISING_WHITELIST", \
"BSP_INDICATE_ADVERTISING_SLOW", \
"BSP_INDICATE_ADVERTISING_DIRECTED", \
"BSP_INDICATE_BONDING", \
"BSP_INDICATE_CONNECTED", \
"BSP_INDICATE_SENT_OK", \
"BSP_INDICATE_SEND_ERROR", \
"BSP_INDICATE_RCV_OK", \
"BSP_INDICATE_RCV_ERROR", \
"BSP_INDICATE_FATAL_ERROR", \
"BSP_INDICATE_ALERT_0", \
"BSP_INDICATE_ALERT_1", \
"BSP_INDICATE_ALERT_2", \
"BSP_INDICATE_ALERT_3", \
"BSP_INDICATE_ALERT_OFF", \
"BSP_INDICATE_USER_STATE_OFF", \
"BSP_INDICATE_USER_STATE_0", \
"BSP_INDICATE_USER_STATE_1", \
"BSP_INDICATE_USER_STATE_2", \
"BSP_INDICATE_USER_STATE_3", \
"BSP_INDICATE_USER_STATE_ON" \
} /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/
/**@brief BSP indication states.
*
* @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.
*/
typedef enum
{
BSP_INDICATE_FIRST = 0,
BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/
BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/
BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/
BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/
BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/
BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/
BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/
BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/
BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/
BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/
BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/
BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/
BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/
BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/
BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/
BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/
BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/
BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/
BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/
BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/
BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/
BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/
BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/
BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/
BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON
} bsp_indication_t;
/**@brief BSP events.
*
* @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons.
*/
typedef enum
{
BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */
BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */
BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */
BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */
BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */
BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */
BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */
BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */
BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */
BSP_EVENT_RESET, /**< The device should reset. */
BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */
BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */
BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */
BSP_EVENT_DFU, /**< The device should enter DFU mode. */
BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */
BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */
BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */
BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */
BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */
BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */
BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */
BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */
BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7,
} bsp_event_t;
typedef struct
{
bsp_event_t push_event; /**< The event to fire on regular button press. */
bsp_event_t long_push_event; /**< The event to fire on long button press. */
bsp_event_t release_event; /**< The event to fire on button release. */
} bsp_button_event_cfg_t;
/**@brief BSP module event callback function type.
*
* @details Upon an event in the BSP module, this callback function will be called to notify
* the application about the event.
*
* @param[in] bsp_event_t BSP event type.
*/
typedef void (* bsp_event_callback_t)(bsp_event_t);
/**@brief Function for initializing BSP.
*
* @details The function initializes the board support package to allow state indication and
* button reaction. Default events are assigned to buttons.
* @note Before calling this function, you must initiate the following required modules:
* - @ref app_timer for LED support
* - @ref app_gpiote for button support
*
* @param[in] type Type of peripherals used.
* @param[in] callback Function to be called when button press/event is detected.
*
* @retval NRF_SUCCESS If the BSP module was successfully initialized.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized.
* @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached.
* @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users.
* @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized.
*/
uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback);
/**@brief Function for checking button states.
*
* @details This function checks if the button is pressed. If the button ID is out of range,
* the function returns false.
*
* @param[in] button Button ID to check.
*
* @retval true If the button is pressed.
* @retval false If the button is not pressed.
*/
bool bsp_button_is_pressed(uint32_t button);
/**@brief Function for assigning a specific event to a button.
*
* @details This function allows redefinition of standard events assigned to buttons.
* To unassign events, provide the event @ref BSP_EVENT_NOTHING.
*
* @param[in] button Button ID to be redefined.
* @param[in] action Button action to assign event to.
* @param[in] event Event to be assigned to button.
*
* @retval NRF_SUCCESS If the event was successfully assigned to button.
* @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid.
*/
uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event);
/**@brief Function for configuring indicators to required state.
*
* @details This function indicates the required state by means of LEDs (if enabled).
*
* @note Alerts are indicated independently.
*
* @param[in] indicate State to be indicated.
*
* @retval NRF_SUCCESS If the state was successfully indicated.
* @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized,
* or internal timer has not been created.
*/
uint32_t bsp_indication_set(bsp_indication_t indicate);
/**@brief Function for enabling all buttons.
*
* @details After calling this function, all buttons will generate events when pressed, and
* all buttons will be able to wake the system up from sleep mode.
*
* @retval NRF_SUCCESS If the buttons were successfully enabled.
* @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
* @return A propagated error.
*/
uint32_t bsp_buttons_enable(void);
/**@brief Function for disabling all buttons.
*
* @details After calling this function, no buttons will generate events when pressed, and
* no buttons will be able to wake the system up from sleep mode.
*
* @retval NRF_SUCCESS If the buttons were successfully disabled.
* @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
* @return A propagated error.
*/
uint32_t bsp_buttons_disable(void);
/**@brief Function for enabling wakeup from SYSTEM OFF for given button.
*
* @details After calling this function, button can be used to wake up the chip.
* This function should only be called immediately before going into sleep.
*
* @param[in] button_idx Index of the button.
*
* @retval NRF_SUCCESS If the button was successfully enabled.
* @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
*/
uint32_t bsp_wakeup_button_enable(uint32_t button_idx);
/**@brief Function for disabling wakeup for the given button.
*
* @param[in] button_idx index of the button.
*
* @retval NRF_SUCCESS If the button was successfully disabled.
* @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
*/
uint32_t bsp_wakeup_button_disable(uint32_t button_idx);
#ifdef __cplusplus
}
#endif
#endif // BSP_H__
/** @} */

View File

@ -0,0 +1,135 @@
/**
* Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup bsp Board Support Package
* @{
* @ingroup app_common
*
* @brief BSP module.
* @details This module provides a layer of abstraction from the board.
* It allows the user to indicate certain states on LEDs in a simple way.
* Module functionality can be modified by additional defines:
* - BSP_SIMPLE - reduces functionality of this module to enable
* and read state of the buttons.
* - BSP_UART_SUPPORT - enables support for UART.
*/
#ifndef BSP_CONFIG_H__
#define BSP_CONFIG_H__
#include <stdint.h>
#include <stdbool.h>
#include "boards.h"
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
#include "app_button.h"
#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
#endif
#define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100))
#define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK
#define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK
#define BUTTON_ADVERTISE BSP_BUTTON_0_MASK
#define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK
#define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK
#define BSP_BUTTONS_ALL 0xFFFFFFFF
#define BSP_BUTTONS_NONE 0
#define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */
/**@brief Types of BSP initialization.
*/
#define ADVERTISING_LED_ON_INTERVAL 200
#define ADVERTISING_LED_OFF_INTERVAL 1800
#define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200
#define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200
#define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200
#define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800
#define ADVERTISING_SLOW_LED_ON_INTERVAL 400
#define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000
#define BONDING_INTERVAL 100
#define SENT_OK_INTERVAL 100
#define SEND_ERROR_INTERVAL 500
#define RCV_OK_INTERVAL 100
#define RCV_ERROR_INTERVAL 500
#define ALERT_INTERVAL 200
#define BSP_LED_INDICATE_SENT_OK BSP_BOARD_LED_1
#define BSP_LED_INDICATE_SEND_ERROR BSP_BOARD_LED_1
#define BSP_LED_INDICATE_RCV_OK BSP_BOARD_LED_1
#define BSP_LED_INDICATE_RCV_ERROR BSP_BOARD_LED_1
#define BSP_LED_INDICATE_CONNECTED BSP_BOARD_LED_0
#define BSP_LED_INDICATE_BONDING BSP_BOARD_LED_0
#define BSP_LED_INDICATE_ADVERTISING_DIRECTED BSP_BOARD_LED_0
#define BSP_LED_INDICATE_ADVERTISING_SLOW BSP_BOARD_LED_0
#define BSP_LED_INDICATE_ADVERTISING_WHITELIST BSP_BOARD_LED_0
#define BSP_LED_INDICATE_INDICATE_ADVERTISING BSP_BOARD_LED_0
#define BSP_LED_INDICATE_USER_LED1 BSP_BOARD_LED_0
#define BSP_LED_INDICATE_USER_LED2 BSP_BOARD_LED_1
#define BSP_LED_INDICATE_USER_LED3 BSP_BOARD_LED_2
#define BSP_LED_INDICATE_USER_LED4 BSP_BOARD_LED_3
#define BSP_LED_ALERT BSP_BOARD_LED_2
#ifdef __cplusplus
}
#endif
#endif // BSP_CONFIG_H__
/** @} */

View File

@ -0,0 +1,223 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(BUTTON)
#include "app_button.h"
#include "app_timer.h"
#include "app_error.h"
#include "nrf_drv_gpiote.h"
#include "nrf_assert.h"
static app_button_cfg_t const * mp_buttons = NULL; /**< Button configuration. */
static uint8_t m_button_count; /**< Number of configured buttons. */
static uint32_t m_detection_delay; /**< Delay before a button is reported as pushed. */
APP_TIMER_DEF(m_detection_delay_timer_id); /**< Polling timer id. */
static uint64_t m_pin_state;
static uint64_t m_pin_transition;
/**@brief Function for handling the timeout that delays reporting buttons as pushed.
*
* @details The detection_delay_timeout_handler(...) is a call-back issued from the app_timer
* module. It is called with the p_context parameter. The p_context parameter is
* provided to the app_timer module when a timer is started, using the call
* @ref app_timer_start. On @ref app_timer_start the p_context will be holding the
* currently pressed buttons.
*
* @param[in] p_context Pointer used for passing information app_start_timer() was called.
* In the app_button module the p_context holds information on pressed
* buttons.
*/
static void detection_delay_timeout_handler(void * p_context)
{
uint8_t i;
// Pushed button(s) detected, execute button handler(s).
for (i = 0; i < m_button_count; i++)
{
app_button_cfg_t const * p_btn = &mp_buttons[i];
uint64_t btn_mask = 1ULL << p_btn->pin_no;
if (btn_mask & m_pin_transition)
{
m_pin_transition &= ~btn_mask;
bool pin_is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
if ((m_pin_state & (1ULL << p_btn->pin_no)) == (((uint64_t)pin_is_set) << p_btn->pin_no))
{
uint64_t transition = !(pin_is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
if (p_btn->button_handler)
{
p_btn->button_handler(p_btn->pin_no, transition);
}
}
}
}
}
static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
uint32_t err_code;
uint64_t pin_mask = 1ULL << pin;
// Start detection timer. If timer is already running, the detection period is restarted.
// NOTE: Using the p_context parameter of app_timer_start() to transfer the pin states to the
// timeout handler (by casting event_pins_mask into the equally sized void * p_context
// parameter).
err_code = app_timer_stop(m_detection_delay_timer_id);
if (err_code != NRF_SUCCESS)
{
// The impact in app_button of the app_timer queue running full is losing a button press.
// The current implementation ensures that the system will continue working as normal.
return;
}
if (!(m_pin_transition & pin_mask))
{
if (nrf_drv_gpiote_in_is_set(pin))
{
m_pin_state |= pin_mask;
}
else
{
m_pin_state &= ~(pin_mask);
}
m_pin_transition |= (pin_mask);
err_code = app_timer_start(m_detection_delay_timer_id, m_detection_delay, NULL);
if (err_code != NRF_SUCCESS)
{
// The impact in app_button of the app_timer queue running full is losing a button press.
// The current implementation ensures that the system will continue working as normal.
}
}
else
{
m_pin_transition &= ~pin_mask;
}
}
uint32_t app_button_init(app_button_cfg_t const * p_buttons,
uint8_t button_count,
uint32_t detection_delay)
{
uint32_t err_code;
if (detection_delay < APP_TIMER_MIN_TIMEOUT_TICKS)
{
return NRF_ERROR_INVALID_PARAM;
}
if (!nrf_drv_gpiote_is_init())
{
err_code = nrf_drv_gpiote_init();
VERIFY_SUCCESS(err_code);
}
// Save configuration.
mp_buttons = p_buttons;
m_button_count = button_count;
m_detection_delay = detection_delay;
m_pin_state = 0;
m_pin_transition = 0;
while (button_count--)
{
app_button_cfg_t const * p_btn = &p_buttons[button_count];
#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(p_btn->hi_accuracy);
#else
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
#endif
config.pull = p_btn->pull_cfg;
err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler);
VERIFY_SUCCESS(err_code);
}
// Create polling timer.
return app_timer_create(&m_detection_delay_timer_id,
APP_TIMER_MODE_SINGLE_SHOT,
detection_delay_timeout_handler);
}
uint32_t app_button_enable(void)
{
ASSERT(mp_buttons);
uint32_t i;
for (i = 0; i < m_button_count; i++)
{
nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true);
}
return NRF_SUCCESS;
}
uint32_t app_button_disable(void)
{
ASSERT(mp_buttons);
uint32_t i;
for (i = 0; i < m_button_count; i++)
{
nrf_drv_gpiote_in_event_disable(mp_buttons[i].pin_no);
}
// Make sure polling timer is not running.
return app_timer_stop(m_detection_delay_timer_id);
}
bool app_button_is_pushed(uint8_t button_id)
{
ASSERT(button_id <= m_button_count);
ASSERT(mp_buttons != NULL);
app_button_cfg_t const * p_btn = &mp_buttons[button_id];
bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
return !(is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
}
#endif //NRF_MODULE_ENABLED(BUTTON)

View File

@ -0,0 +1,142 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/** @file
*
* @defgroup app_button Button Handler
* @{
* @ingroup app_common
*
* @brief Buttons handling module.
*
* @details The button handler uses the @ref app_gpiote to detect that a button has been
* pushed. To handle debouncing, it will start a timer in the GPIOTE event handler.
* The button will only be reported as pushed if the corresponding pin is still active when
* the timer expires. If there is a new GPIOTE event while the timer is running, the timer
* is restarted.
*
* @note The app_button module uses the app_timer module. The user must ensure that the queue in
* app_timer is large enough to hold the app_timer_stop() / app_timer_start() operations
* which will be executed on each event from GPIOTE module (2 operations), as well as other
* app_timer operations queued simultaneously in the application.
*
* @note Even if the scheduler is not used, app_button.h will include app_scheduler.h, so when
* compiling, app_scheduler.h must be available in one of the compiler include paths.
*/
#ifndef APP_BUTTON_H__
#define APP_BUTTON_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf.h"
#include "app_error.h"
#include "nrf_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */
#define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */
#define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */
#define APP_BUTTON_ACTIVE_LOW 0 /**< Indicates that a button is active low. */
/**@brief Button event handler type. */
typedef void (*app_button_handler_t)(uint8_t pin_no, uint8_t button_action);
/**@brief Button configuration structure. */
typedef struct
{
uint8_t pin_no; /**< Pin to be used as a button. */
uint8_t active_state; /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */
#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
bool hi_accuracy; /**< True if GPIOTE high accuracy (IN_EVENT) is used. */
#endif
nrf_gpio_pin_pull_t pull_cfg; /**< Pull-up or -down configuration. */
app_button_handler_t button_handler; /**< Handler to be called when button is pushed. */
} app_button_cfg_t;
/**@brief Function for initializing the Buttons.
*
* @details This function will initialize the specified pins as buttons, and configure the Button
* Handler module as a GPIOTE user (but it will not enable button detection).
*
* @note Normally initialization should be done using the APP_BUTTON_INIT() macro
*
* @note app_button_enable() function must be called in order to enable the button detection.
*
* @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!).
* @param[in] button_count Number of buttons.
* @param[in] detection_delay Delay from a GPIOTE event until a button is reported as pushed.
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
uint32_t app_button_init(app_button_cfg_t const * p_buttons,
uint8_t button_count,
uint32_t detection_delay);
/**@brief Function for enabling button detection.
*
* @retval NRF_SUCCESS Module successfully enabled.
*/
uint32_t app_button_enable(void);
/**@brief Function for disabling button detection.
*
* @retval NRF_SUCCESS Button detection successfully disabled. Error code otherwise.
*/
uint32_t app_button_disable(void);
/**@brief Function for checking if a button is currently being pushed.
*
* @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked.
*
* @return Button state.
*/
bool app_button_is_pushed(uint8_t button_id);
#ifdef __cplusplus
}
#endif
#endif // APP_BUTTON_H__
/** @} */

View File

@ -0,0 +1,80 @@
/**
* Copyright (c) 2011 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef _NRF_DELAY_H
#define _NRF_DELAY_H
#include <nrfx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Function for delaying execution for a number of microseconds.
*
* @param us_time Number of microseconds to wait.
*/
#define nrf_delay_us(us_time) NRFX_DELAY_US(us_time)
/**
* @brief Function for delaying execution for a number of milliseconds.
*
* @param ms_time Number of milliseconds to wait.
*/
__STATIC_INLINE void nrf_delay_ms(uint32_t ms_time)
{
if (ms_time == 0)
{
return;
}
do {
nrf_delay_us(1000);
} while (--ms_time);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,191 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_SECTION_H__
#define NRF_SECTION_H__
#include "nordic_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup section_vars Section variables
* @ingroup app_common
* @{
*
* @brief Section variables.
*/
//lint -save -e27 -esym(526,*)
#if defined(__ICCARM__)
// Enable IAR language extensions
#pragma language=extended
#endif
/**@brief Macro for obtaining the address of the beginning of a section.
*
* param[in] section_name Name of the section.
* @hideinitializer
*/
#if defined(__CC_ARM)
#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base)
#elif defined(__GNUC__)
#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name)
#elif defined(__ICCARM__)
#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name))
#endif
/**@brief Macro for obtaining the address of the end of a section.
*
* @param[in] section_name Name of the section.
* @hideinitializer
*/
#if defined(__CC_ARM)
#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit)
#elif defined(__GNUC__)
#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name)
#elif defined(__ICCARM__)
#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name))
#endif
/**@brief Macro for retrieving the length of a given section, in bytes.
*
* @param[in] section_name Name of the section.
* @hideinitializer
*/
#define NRF_SECTION_LENGTH(section_name) \
((size_t)NRF_SECTION_END_ADDR(section_name) - \
(size_t)NRF_SECTION_START_ADDR(section_name))
/**@brief Macro for creating a section.
*
* @param[in] section_name Name of the section.
* @param[in] data_type Data type of the variables to be registered in the section.
*
* @warning Data type must be word aligned to prevent padding.
* @hideinitializer
*/
#if defined(__CC_ARM)
#define NRF_SECTION_DEF(section_name, data_type) \
extern data_type * CONCAT_2(section_name, $$Base); \
extern void * CONCAT_2(section_name, $$Limit)
#elif defined(__GNUC__)
#define NRF_SECTION_DEF(section_name, data_type) \
extern data_type * CONCAT_2(__start_, section_name); \
extern void * CONCAT_2(__stop_, section_name)
#elif defined(__ICCARM__)
#define NRF_SECTION_DEF(section_name, data_type) \
_Pragma(STRINGIFY(section = STRINGIFY(section_name)));
#endif
/**@brief Macro for declaring a variable and registering it in a section.
*
* @details Declares a variable and registers it in a named section. This macro ensures that the
* variable is not stripped away when using optimizations.
*
* @note The order in which variables are placed in a section is dependent on the order in
* which the linker script encounters the variables during linking.
*
* @param[in] section_name Name of the section.
* @param[in] section_var Variable to register in the given section.
* @hideinitializer
*/
#if defined(__CC_ARM)
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used))
#elif defined(__GNUC__)
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))
#elif defined(__ICCARM__)
#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
__root section_var @ STRINGIFY(section_name)
#endif
/**@brief Macro for retrieving a variable from a section.
*
* @warning The stored symbol can only be resolved using this macro if the
* type of the data is word aligned. The operation of acquiring
* the stored symbol relies on the size of the stored type. No
* padding can exist in the named section in between individual
* stored items or this macro will fail.
*
* @param[in] section_name Name of the section.
* @param[in] data_type Data type of the variable.
* @param[in] i Index of the variable in section.
* @hideinitializer
*/
#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \
((data_type*)NRF_SECTION_START_ADDR(section_name) + (i))
/**@brief Macro for getting the number of variables in a section.
*
* @param[in] section_name Name of the section.
* @param[in] data_type Data type of the variables in the section.
* @hideinitializer
*/
#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \
NRF_SECTION_LENGTH(section_name) / sizeof(data_type)
/** @} */
//lint -restore
#ifdef __cplusplus
}
#endif
#endif // NRF_SECTION_H__

View File

@ -0,0 +1,214 @@
/**
* Copyright (c) 2013 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(APP_FIFO)
#include "app_fifo.h"
static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo)
{
uint32_t tmp = p_fifo->read_pos;
return p_fifo->write_pos - tmp;
}
#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */
/**@brief Put one byte to the FIFO. */
static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte)
{
p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte;
p_fifo->write_pos++;
}
/**@brief Look at one byte in the FIFO. */
static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
{
*p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask];
}
/**@brief Get one byte from the FIFO. */
static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
{
fifo_peek(p_fifo, 0, p_byte);
p_fifo->read_pos++;
}
uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size)
{
// Check buffer for null pointer.
if (p_buf == NULL)
{
return NRF_ERROR_NULL;
}
// Check that the buffer size is a power of two.
if (!IS_POWER_OF_TWO(buf_size))
{
return NRF_ERROR_INVALID_LENGTH;
}
p_fifo->p_buf = p_buf;
p_fifo->buf_size_mask = buf_size - 1;
p_fifo->read_pos = 0;
p_fifo->write_pos = 0;
return NRF_SUCCESS;
}
uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
{
if (FIFO_LENGTH() <= p_fifo->buf_size_mask)
{
fifo_put(p_fifo, byte);
return NRF_SUCCESS;
}
return NRF_ERROR_NO_MEM;
}
uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
{
if (FIFO_LENGTH() != 0)
{
fifo_get(p_fifo, p_byte);
return NRF_SUCCESS;
}
return NRF_ERROR_NOT_FOUND;
}
uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
{
if (FIFO_LENGTH() > index)
{
fifo_peek(p_fifo, index, p_byte);
return NRF_SUCCESS;
}
return NRF_ERROR_NOT_FOUND;
}
uint32_t app_fifo_flush(app_fifo_t * p_fifo)
{
p_fifo->read_pos = p_fifo->write_pos;
return NRF_SUCCESS;
}
uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size)
{
VERIFY_PARAM_NOT_NULL(p_fifo);
VERIFY_PARAM_NOT_NULL(p_size);
const uint32_t byte_count = fifo_length(p_fifo);
const uint32_t requested_len = (*p_size);
uint32_t index = 0;
uint32_t read_size = MIN(requested_len, byte_count);
(*p_size) = byte_count;
// Check if the FIFO is empty.
if (byte_count == 0)
{
return NRF_ERROR_NOT_FOUND;
}
// Check if application has requested only the size.
if (p_byte_array == NULL)
{
return NRF_SUCCESS;
}
// Fetch bytes from the FIFO.
while (index < read_size)
{
fifo_get(p_fifo, &p_byte_array[index++]);
}
(*p_size) = read_size;
return NRF_SUCCESS;
}
uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size)
{
VERIFY_PARAM_NOT_NULL(p_fifo);
VERIFY_PARAM_NOT_NULL(p_size);
const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1;
const uint32_t requested_len = (*p_size);
uint32_t index = 0;
uint32_t write_size = MIN(requested_len, available_count);
(*p_size) = available_count;
// Check if the FIFO is FULL.
if (available_count == 0)
{
return NRF_ERROR_NO_MEM;
}
// Check if application has requested only the size.
if (p_byte_array == NULL)
{
return NRF_SUCCESS;
}
//Fetch bytes from the FIFO.
while (index < write_size)
{
fifo_put(p_fifo, p_byte_array[index++]);
}
(*p_size) = write_size;
return NRF_SUCCESS;
}
#endif //NRF_MODULE_ENABLED(APP_FIFO)

View File

@ -0,0 +1,181 @@
/**
* Copyright (c) 2013 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup app_fifo FIFO implementation
* @{
* @ingroup app_common
*
* @brief FIFO implementation.
*/
#ifndef APP_FIFO_H__
#define APP_FIFO_H__
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**@brief A FIFO instance structure.
* @details Keeps track of which bytes to read and write next.
* Also, it keeps the information about which memory is allocated for the buffer
* and its size. This structure must be initialized by app_fifo_init() before use.
*/
typedef struct
{
uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
} app_fifo_t;
/**@brief Function for initializing the FIFO.
*
* @param[out] p_fifo FIFO object.
* @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two.
* @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two.
*
* @retval NRF_SUCCESS If initialization was successful.
* @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer.
* @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two.
*/
uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size);
/**@brief Function for adding an element to the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[in] byte Data byte to add to the FIFO.
*
* @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
* @retval NRF_ERROR_NO_MEM If the FIFO is full.
*/
uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte);
/**@brief Function for getting the next element from the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[out] p_byte Byte fetched from the FIFO.
*
* @retval NRF_SUCCESS If an element was returned.
* @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
*/
uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte);
/**@brief Function for looking at an element in the FIFO, without consuming it.
*
* @param[in] p_fifo Pointer to the FIFO.
* @param[in] index Which element to look at. The lower the index, the earlier it was put.
* @param[out] p_byte Byte fetched from the FIFO.
*
* @retval NRF_SUCCESS If an element was returned.
* @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was
* too large.
*/
uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte);
/**@brief Function for flushing the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO.
*
* @retval NRF_SUCCESS If the FIFO was flushed successfully.
*/
uint32_t app_fifo_flush(app_fifo_t * p_fifo);
/**@brief Function for reading bytes from the FIFO.
*
* This function can also be used to get the number of bytes in the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
* @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO.
* Can be NULL. If NULL, the number of bytes that can be read in the FIFO
* are returned in the p_size parameter.
* @param[inout] p_size Address to memory indicating the maximum number of bytes to be read.
* The provided memory is overwritten with the actual number of bytes
* read if the procedure was successful. This field must not be NULL.
* If p_byte_array is set to NULL by the application, this parameter
* returns the number of bytes in the FIFO.
*
* @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might
* be less than the requested maximum, depending on how many elements exist
* in the FIFO. Even if less bytes are returned, the procedure is considered
* successful.
* @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
* be NULL.
* @retval NRF_ERROR_NOT_FOUND If the FIFO is empty.
*/
uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size);
/**@brief Function for writing bytes to the FIFO.
*
* This function can also be used to get the available size on the FIFO.
*
* @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
* @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO.
* Can be NULL. If NULL, this function returns the number of bytes
* that can be written to the FIFO.
* @param[inout] p_size Address to memory indicating the maximum number of bytes to be written.
* The provided memory is overwritten with the number of bytes that were actually
* written if the procedure is successful. This field must not be NULL.
* If p_byte_array is set to NULL by the application, this parameter
* returns the number of bytes available in the FIFO.
*
* @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might
* be less than the requested maximum, depending on how much room there is in
* the FIFO. Even if less bytes are written, the procedure is considered
* successful. If the write was partial, the application should use
* subsequent calls to attempt writing the data again.
* @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
* be NULL.
* @retval NRF_ERROR_NO_MEM If the FIFO is full.
*
*/
uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size);
#ifdef __cplusplus
}
#endif
#endif // APP_FIFO_H__
/** @} */

View File

@ -0,0 +1,296 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup nrf_log Logger module
* @{
* @ingroup app_common
*
* @brief The nrf_log module interface.
*/
#ifndef NRF_LOG_H_
#define NRF_LOG_H_
#include "sdk_common.h"
#include "nrf_section.h"
#if NRF_MODULE_ENABLED(NRF_LOG)
#include "nrf_strerror.h"
#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code)
#else
#define NRF_LOG_ERROR_STRING_GET(code) ""
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Severity level for the module.
*
* The severity level can be defined in a module to override the default.
*/
#ifndef NRF_LOG_LEVEL
#define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
#endif
/** @brief Initial severity if filtering is enabled.
*/
#ifndef NRF_LOG_INITIAL_LEVEL
#define NRF_LOG_INITIAL_LEVEL NRF_LOG_LEVEL
#endif
#include "nrf_log_internal.h"
/** @def NRF_LOG_ERROR
* @brief Macro for logging error messages. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_WARNING
* @brief Macro for logging error messages. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
*/
/** @def NRF_LOG_INFO
* @brief Macro for logging error messages. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
*/
/** @def NRF_LOG_DEBUG
* @brief Macro for logging error messages. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
*/
#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__)
#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__)
#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
/** @def NRF_LOG_INST_ERROR
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_WARNING
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_INFO
* @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
/** @def NRF_LOG_INST_DEBUG
* @brief Macro for logging error messages for given module instance. It takes a printf-like, formatted
* string with up to seven arguments.
*
* @param p_inst Pointer to the instance with logging support.
*
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*/
#define NRF_LOG_INST_ERROR(p_inst,...) NRF_LOG_INTERNAL_INST_ERROR(p_inst,__VA_ARGS__)
#define NRF_LOG_INST_WARNING(p_inst,...) NRF_LOG_INTERNAL_INST_WARNING(p_inst,__VA_ARGS__)
#define NRF_LOG_INST_INFO(p_inst,...) NRF_LOG_INTERNAL_INST_INFO(p_inst, __VA_ARGS__)
#define NRF_LOG_INST_DEBUG(p_inst,...) NRF_LOG_INTERNAL_INST_DEBUG(p_inst, __VA_ARGS__)
/**
* @brief Macro for logging a formatted string without any prefix or timestamp.
*/
#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__)
/** @def NRF_LOG_HEXDUMP_ERROR
* @brief Macro for logging raw bytes.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_WARNING
* @brief Macro for logging raw bytes.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
*
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INFO
* @brief Macro for logging raw bytes.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
*
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_DEBUG
* @brief Macro for logging raw bytes.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
*
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len)
#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len)
#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len)
#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len)
/** @def NRF_LOG_HEXDUMP_INST_ERROR
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_WARNING
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_INFO
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
/** @def NRF_LOG_HEXDUMP_INST_DEBUG
* @brief Macro for logging raw bytes for a specific module instance.
* @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
*
* @param p_inst Pointer to the instance with logging support.
* @param p_data Pointer to data.
* @param len Data length in bytes.
*/
#define NRF_LOG_HEXDUMP_INST_ERROR(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_WARNING(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_INFO(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len)
#define NRF_LOG_HEXDUMP_INST_DEBUG(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len)
/**
* @brief Macro for logging hexdump without any prefix or timestamp.
*/
#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len)
/**
* @brief Macro for copying a string to internal logger buffer if logs are deferred.
*
* @param _str String.
*/
#define NRF_LOG_PUSH(_str) NRF_LOG_INTERNAL_LOG_PUSH(_str)
/**
* @brief Function for copying a string to the internal logger buffer if logs are deferred.
*
* Use this function to store a string that is volatile (for example allocated
* on stack) or that may change before the deferred logs are processed. Such string is copied
* into the internal logger buffer (see @ref NRF_LOG_STR_PUSH_BUFFER_SIZE).
*
* @note String storing is not reliable. It means that string is copied to the buffer but there is
* no indication when it was used and could be freed. String may be overwritten by another
* @ref nrf_log_push call before being processed. For reliable data dumping use
* hexdump macros (e.g. @ref NRF_LOG_HEXDUMP_INFO).
*
* @note If the logs are not deferred, then this function returns the input parameter.
*
* @param p_str Pointer to the user string.
*
* @return Address to the location where the string is stored in the internal logger buffer.
*/
char const * nrf_log_push(char * const p_str);
/**
* @brief Macro to be used in a formatted string to a pass float number to the log.
*
* Use this macro in a formatted string instead of the %f specifier together with
* @ref NRF_LOG_FLOAT macro.
* Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
*/
#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
/**
* @brief Macro for dissecting a float number into two numbers (integer and residuum).
*/
#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \
(int32_t)(val), \
(int32_t)((((val) > 0) ? (val) - (int32_t)(val) \
: (int32_t)(val) - (val))*100)
/**
* @brief Macro for registering an independent module.
*
* Registration creates set of dynamic (RAM) and constant variables associated with the module.
*/
#define NRF_LOG_MODULE_REGISTER() NRF_LOG_INTERNAL_MODULE_REGISTER()
#ifdef __cplusplus
}
#endif
#endif // NRF_LOG_H_
/** @} */

View File

@ -0,0 +1,271 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_BACKEND_INTERFACE_H
#define NRF_LOG_BACKEND_INTERFACE_H
/**@file
* @addtogroup nrf_log Logger module
* @ingroup app_common
*
* @defgroup nrf_log_backend_interface Logger backend interface
* @{
* @ingroup nrf_log
* @brief The nrf_log backend interface.
*/
#if NRF_MODULE_ENABLED(NRF_LOG)
#include "nrf_memobj.h"
#endif
#include "nrf_section.h"
#include "nordic_common.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief nrf_log entry.
*/
#if NRF_LOG_ENABLED
typedef nrf_memobj_t nrf_log_entry_t;
#else
typedef void nrf_log_entry_t;
#endif
/* Forward declaration of the nrf_log_backend_t type. */
typedef struct nrf_log_backend_s nrf_log_backend_t;
/**
* @brief Logger backend API.
*/
typedef struct
{
/**
* @brief @ref nrf_log_backend_put
*/
void (*put)(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_entry);
/**
* @brief @ref nrf_log_backend_panic_set
*/
void (*panic_set)(nrf_log_backend_t const * p_backend);
/**
* @brief @ref nrf_log_backend_flush
*/
void (*flush)(nrf_log_backend_t const * p_backend);
} nrf_log_backend_api_t;
/**
* @brief Logger backend control block.
*/
typedef struct
{
nrf_log_backend_t const * p_next; //!< Pointer to the next backend in the logger.
uint8_t id; //!< ID of the backend.
bool enabled; //!< Enable flag.
} nrf_log_backend_cb_t;
/**
* @brief Logger backend structure.
*/
struct nrf_log_backend_s
{
nrf_log_backend_api_t const * p_api; //!< Pointer to interface.
void * p_ctx; //!< User context.
char * p_name; //!< Name of the backend.
nrf_log_backend_cb_t * p_cb; //!< Pointer to the backend control block.
};
#define NRF_LOG_BACKEND_SECTION_NAME log_backends
#define NRF_LOG_BACKEND_SUBSECTION_NAME(_name) NRF_LOG_BACKEND_SECTION_NAME
/** @brief Invalid ID value indicating that logger backend is not attached to the logger frontend.*/
#define NRF_LOG_BACKEND_INVALID_ID 0xFF
/** @brief Memory section where backends are located. */
NRF_SECTION_DEF(NRF_LOG_BACKEND_SECTION_NAME, nrf_log_backend_t);
/**
* @brief Macro for creating a logger backend instance.
*
* @param _name Name of the backend instance.
* @param _api Logger backend API.
* @param _p_ctx Pointer to the user context.
*/
#define NRF_LOG_BACKEND_DEF(_name, _api, _p_ctx) \
static nrf_log_backend_cb_t CONCAT_2(log_backend_cb_, _name) = { \
.enabled = false, \
.id = NRF_LOG_BACKEND_INVALID_ID, \
.p_next = NULL \
}; \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_BACKEND_SUBSECTION_NAME(_name), \
static const nrf_log_backend_t _name) = { \
.p_api = &_api, \
.p_ctx = _p_ctx, \
.p_cb = &CONCAT_2(log_backend_cb_, _name), \
.p_name = (char *)STRINGIFY(_name) \
}
/**
* @brief Function for putting message with log entry to the backend.
*
* @param[in] p_backend Pointer to the backend instance.
* @param[in] p_msg Pointer to message with log entry.
*/
__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * const p_backend,
nrf_log_entry_t * p_msg);
/**
* @brief Function for reconfiguring backend to panic mode.
*
* @param[in] p_backend Pointer to the backend instance.
*/
__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * const p_backend);
/**
* @brief Function for flushing backend.
*
* On flushing request backend should release log message(s).
*
* @param[in] p_backend Pointer to the backend instance.
*/
__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * const p_backend);
/**
* @brief Function for setting backend id.
*
* @note It is used internally by the logger.
*
* @param[in] p_backend Pointer to the backend instance.
* @param[in] id Id.
*/
__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t const * const p_backend, uint8_t id);
/**
* @brief Function for getting backend id.
*
* @note It is used internally by the logger.
*
* @param[in] p_backend Pointer to the backend instance.
* @return Id.
*/
__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * const p_backend);
/**
* @brief Function for enabling backend.
*
* @param[in] p_backend Pointer to the backend instance.
*/
__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t const * const p_backend);
/**
* @brief Function for disabling backend.
*
* @param[in] p_backend Pointer to the backend instance.
*/
__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t const * const p_backend);
/**
* @brief Function for checking state of the backend.
*
* @param[in] p_backend Pointer to the backend instance.
*
* @return True if backend is enabled, false otherwise.
*/
__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * const p_backend);
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * const p_backend,
nrf_log_entry_t * p_msg)
{
p_backend->p_api->put(p_backend, p_msg);
}
__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * const p_backend)
{
p_backend->p_api->panic_set(p_backend);
}
__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * const p_backend)
{
p_backend->p_api->flush(p_backend);
}
__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t const * const p_backend, uint8_t id)
{
p_backend->p_cb->id = id;
}
__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * const p_backend)
{
return p_backend->p_cb->id;
}
__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t const * const p_backend)
{
p_backend->p_cb->enabled = true;
}
__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t const * const p_backend)
{
p_backend->p_cb->enabled = false;
}
__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * const p_backend)
{
return p_backend->p_cb->enabled;
}
#endif // SUPPRESS_INLINE_IMPLEMENTATION
#ifdef __cplusplus
}
#endif
#endif //NRF_LOG_BACKEND_INTERFACE_H
/** @} */

View File

@ -0,0 +1,80 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup nrf_log_backend_rtt Log RTT backend
* @{
* @ingroup nrf_log
* @brief Log RTT backend.
*/
#ifndef NRF_LOG_BACKEND_RTT_H
#define NRF_LOG_BACKEND_RTT_H
#include "nrf_log_backend_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const nrf_log_backend_api_t nrf_log_backend_rtt_api;
typedef struct {
nrf_log_backend_t backend;
} nrf_log_backend_rtt_t;
/**
* @brief RTT backend definition
*
* @param _name Name of the instance.
*/
#define NRF_LOG_BACKEND_RTT_DEF(_name) \
NRF_LOG_BACKEND_DEF(_name, nrf_log_backend_rtt_api, NULL)
void nrf_log_backend_rtt_init(void);
#ifdef __cplusplus
}
#endif
#endif //NRF_LOG_BACKEND_RTT_H
/** @} */

View File

@ -0,0 +1,243 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_CTRL_H
#define NRF_LOG_CTRL_H
/**@file
* @addtogroup nrf_log Logger module
* @ingroup app_common
*
* @defgroup nrf_log_ctrl Functions for controlling nrf_log
* @{
* @ingroup nrf_log
* @brief The nrf_log control interface.
*/
#include "sdk_config.h"
#include "sdk_errors.h"
#include <stdint.h>
#include <stdbool.h>
#include "nrf_log_types.h"
#include "nrf_log_ctrl_internal.h"
#include "nrf_log_backend_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Timestamp function prototype.
*
* @return Timestamp value.
*/
typedef uint32_t (*nrf_log_timestamp_func_t)(void);
/**@brief Macro for initializing the logs.
*
* Macro has one or two parameters. First parameter (obligatory) is the timestamp function (@ref nrf_log_timestamp_func_t).
* Additionally, as the second parameter timestamp frequency in Hz can be provided. If not provided then default
* frequency is used (@ref NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY). Frequency is used to format timestamp prefix if
* @ref NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED is set.
*
* @return NRF_SUCCESS after successful initialization, otherwise an error code.
*/
#define NRF_LOG_INIT(...) NRF_LOG_INTERNAL_INIT(__VA_ARGS__)
/**@brief Macro for processing a single log entry from a queue of deferred logs.
*
* You can call this macro from the main context or from the error handler to process
* log entries one by one.
*
* @note If logs are not deferred, this call has no use and is defined as 'false'.
*
* @retval true There are more logs to process in the buffer.
* @retval false No more logs in the buffer.
*/
#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS()
/** @brief Macro for processing all log entries from the buffer.
* It blocks until all buffered entries are processed by the backend.
*
* @note If logs are not deferred, this call has no use and is empty.
*/
#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH()
/** @brief Macro for flushing log data before reset.
*
* @note If logs are not deferred, this call has no use and is empty.
*
* @note If RTT is used, then a breakpoint is hit once flushed.
*/
#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH()
/**
* @brief Function for initializing the frontend and the default backend.
*
* @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend.
* If custom backend is used, then @ref NRF_LOG_INIT should not be called.
* Instead, frontend and user backend should be verbosely initialized.
*
* @param timestamp_func Function for getting a 32-bit timestamp.
* @param timestamp_freq Frequency of the timestamp.
*
* @return Error status.
*
*/
ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq);
/**
* @brief Function for adding new backend interface to the logger.
*
* @param p_backend Pointer to the backend interface.
* @param severity Initial value of severity level for each module forwarded to the backend. This
* option is only applicable if @ref NRF_LOG_FILTERS_ENABLED is set.
* @return -1 if backend cannot be added or positive number (backend ID).
*/
int32_t nrf_log_backend_add(nrf_log_backend_t const * p_backend, nrf_log_severity_t severity);
/**
* @brief Function for removing backend from the logger.
*
* @param p_backend Pointer to the backend interface.
*
*/
void nrf_log_backend_remove(nrf_log_backend_t const * p_backend);
/**
* @brief Function for setting logger backends into panic mode.
*
* When this function is called all attached backends are informed about panic state of the system.
* It is up to the backend to react properly (hold or process logs in blocking mode, etc.)
*/
void nrf_log_panic(void);
/**
* @brief Function for handling a single log entry.
*
* Use this function only if the logs are buffered. It takes a single entry from the
* buffer and attempts to process it.
*
* @retval true If there are more entries to process.
* @retval false If there are no more entries to process.
*/
bool nrf_log_frontend_dequeue(void);
/**
* @brief Function for getting number of independent log modules registered into the logger.
*
* @return Number of registered modules.
*/
uint32_t nrf_log_module_cnt_get(void);
/**
* @brief Function for getting module name.
*
* @param module_id Module ID.
* @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
* @return Pointer to string with module name.
*/
const char * nrf_log_module_name_get(uint32_t module_id, bool is_ordered_idx);
/**
* @brief Function for getting coloring of specific logs.
*
* @param module_id Module ID.
* @param severity Log severity.
*
* @return ID of the color.
*/
uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity);
/**
* @brief Function for configuring filtering ofs logs in the module.
*
* Filtering of logs in modules is independent for each backend.
*
* @param backend_id Backend ID which want to chenge its configuration.
* @param module_id Module ID which logs will be reconfigured.
* @param severity New severity filter.
*/
void nrf_log_module_filter_set(uint32_t backend_id,
uint32_t module_id,
nrf_log_severity_t severity);
/**
* @brief Function for getting module severity level.
*
* @param backend_id Backend ID.
* @param module_id Module ID.
* @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
* @param dynamic It true current filter for given backend is returned. If false then
* compiled-in level is returned (maximum available). If this parameter is
* false then backend_id parameter is not used.
*
* @return Severity.
*/
nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
uint32_t module_id,
bool is_ordered_idx,
bool dynamic);
/**
* @brief Function stores current filtering configuration into non-volatile memory using @ref fds module.
*
* @return NRF_SUCCESS or @ref fds error code.
*/
ret_code_t nrf_log_config_store(void);
/**
* @brief Function loads configuration from non-volatile memory using @ref fds module.
*
* @retval NRF_SUCCESS On successful loading.
* @retval NRF_ERROR_NOT_FOUND Configuration file not found.
* @retval NRF_ERROR_INTERNAL Other @ref fds error on reading configuration file.
*/
ret_code_t nrf_log_config_load(void);
#ifdef __cplusplus
}
#endif
#endif // NRF_LOG_CTRL_H
/**
*@}
**/

View File

@ -0,0 +1,81 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_DEFAULT_BACKENDS_H__
#define NRF_LOG_DEFAULT_BACKENDS_H__
/**@file
* @addtogroup nrf_log Logger module
* @ingroup app_common
*
* @defgroup nrf_log_default_backends Functions for initializing and adding default backends
* @{
* @ingroup nrf_log
* @brief The nrf_log default backends.
*/
#include "sdk_config.h"
#include "sdk_errors.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @def NRF_LOG_DEFAULT_BACKENDS_INIT
* @brief Macro for initializing default backends.
*
* Each backend enabled in configuration is initialized and added as a backend to the logger.
*/
#if NRF_LOG_ENABLED
#define NRF_LOG_DEFAULT_BACKENDS_INIT() nrf_log_default_backends_init()
#else
#define NRF_LOG_DEFAULT_BACKENDS_INIT()
#endif
void nrf_log_default_backends_init(void);
#ifdef __cplusplus
}
#endif
/** @} */
#endif // NRF_LOG_DEFAULT_BACKENDS_H__

View File

@ -0,0 +1,163 @@
/**
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_INSTANCE_H
#define NRF_LOG_INSTANCE_H
#include "sdk_config.h"
#include "nrf_section.h"
#include "nrf_log_types.h"
#include <stdint.h>
/*
* For GCC, sections are sorted in the group by the linker. For IAR and KEIL, it is assumed that linker will sort
* dynamic and const section in the same order (but in different locations). Proper message formatting
* is based on that assumption.
*/
#if defined(__GNUC__)
#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) CONCAT_2(log_dynamic_data_,_module_name)
#define NRF_LOG_FILTER_SECTION_NAME(_module_name) CONCAT_2(log_filter_data_,_module_name)
#define NRF_LOG_CONST_SECTION_NAME(_module_name) CONCAT_2(log_const_data_,_module_name)
#else
#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) log_dynamic_data
#define NRF_LOG_FILTER_SECTION_NAME(_module_name) log_filter_data
#define NRF_LOG_CONST_SECTION_NAME(_module_name) log_const_data
#endif
#define NRF_LOG_ITEM_DATA(_name) CONCAT_3(m_nrf_log_,_name,_logs_data)
#define NRF_LOG_ITEM_DATA_DYNAMIC(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_dynamic)
#define NRF_LOG_ITEM_DATA_FILTER(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_filter)
#define NRF_LOG_ITEM_DATA_CONST(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_const)
#ifdef UNIT_TEST
#define _CONST
#else
#define _CONST const
#endif
/*lint -save -esym(526,log_const_data*) -esym(526,log_dynamic_data*)*/
NRF_SECTION_DEF(log_dynamic_data, nrf_log_module_dynamic_data_t);
NRF_SECTION_DEF(log_filter_data, nrf_log_module_filter_data_t);
NRF_SECTION_DEF(log_const_data, nrf_log_module_const_data_t);
/*lint -restore*/
#define NRF_LOG_INTERNAL_CONST_ITEM_REGISTER( \
_name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(_name), \
_CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(_name)) = { \
.p_module_name = _str_name, \
.info_color_id = (_info_color), \
.debug_color_id = (_debug_color), \
.compiled_lvl = (nrf_log_severity_t)(_compiled_lvl), \
.initial_lvl = (nrf_log_severity_t)(_initial_lvl), \
}
#if NRF_LOG_FILTERS_ENABLED
#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
_name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_LOG_INTERNAL_CONST_ITEM_REGISTER(_name, \
_str_name, \
_info_color, \
_debug_color, \
_initial_lvl, \
_compiled_lvl); \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_DYNAMIC_SECTION_NAME(_name), \
nrf_log_module_dynamic_data_t NRF_LOG_ITEM_DATA_DYNAMIC(_name)); \
NRF_SECTION_ITEM_REGISTER(NRF_LOG_FILTER_SECTION_NAME(_name), \
nrf_log_module_filter_data_t NRF_LOG_ITEM_DATA_FILTER(_name))
#else
#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
_name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_LOG_INTERNAL_CONST_ITEM_REGISTER(_name, \
_str_name, \
_info_color, \
_debug_color, \
_initial_lvl, \
_compiled_lvl)
#endif
/**@file
*
* @defgroup nrf_log_instance Macros for logging on instance level
* @{
* @ingroup nrf_log
*
* @brief Macros for logging on instance level
*/
/** @def NRF_LOG_INSTANCE_PTR_DECLARE
* @brief Macro for declaring a logger instance pointer in the module stucture.
*/
/** @def NRF_LOG_INSTANCE_REGISTER
* @brief Macro for creating an independent module instance.
*
* Module instance provides filtering of logs on instance level instead of module level.
*/
/** @def NRF_LOG_INSTANCE_PTR_INIT
* @brief Macro for initializing a pointer to the logger instance.
*/
/** @} */
#if NRF_LOG_ENABLED && NRF_LOG_FILTERS_ENABLED
#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name) nrf_log_module_dynamic_data_t * _p_name;
#define NRF_LOG_INSTANCE_REGISTER( \
_module_name, _inst_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
NRF_LOG_INTERNAL_ITEM_REGISTER(CONCAT_3(_module_name,_,_inst_name), \
STRINGIFY(_module_name._inst_name), \
_info_color, \
_debug_color, \
_initial_lvl, \
_compiled_lvl)
#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name) \
._p_name = &NRF_LOG_ITEM_DATA_DYNAMIC(CONCAT_3(_module_name,_,_inst_name)),
#else
#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name)
#define NRF_LOG_INSTANCE_REGISTER(_module_name, _inst_name, info_color, debug_color, _initial_lvl, compiled_lvl)
#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name)
#endif
#endif //NRF_LOG_INSTANCE_H

View File

@ -0,0 +1,86 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup nrf_log_str_formatter String formatter for the logger messages
* @{
* @ingroup nrf_log
*/
#ifndef NRF_LOG_STR_FORMATTER_H
#define NRF_LOG_STR_FORMATTER_H
#include <stdint.h>
#include "nrf_fprintf.h"
#include "nrf_log_ctrl.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint32_t timestamp;
uint16_t module_id;
uint16_t dropped;
nrf_log_severity_t severity;
uint8_t use_colors;
} nrf_log_str_formatter_entry_params_t;
void nrf_log_std_entry_process(char const * p_str,
uint32_t const * p_args,
uint32_t nargs,
nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx);
void nrf_log_hexdump_entry_process(uint8_t * p_data,
uint32_t data_len,
nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx);
void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq);
#ifdef __cplusplus
}
#endif
#endif //NRF_LOG_STR_FORMATTER_H
/** @} */

View File

@ -0,0 +1,93 @@
/**
* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_TYPES_H
#define NRF_LOG_TYPES_H
#include <stdint.h>
/**
* @brief Logger severity levels.
*/
typedef enum
{
NRF_LOG_SEVERITY_NONE,
NRF_LOG_SEVERITY_ERROR,
NRF_LOG_SEVERITY_WARNING,
NRF_LOG_SEVERITY_INFO,
NRF_LOG_SEVERITY_DEBUG,
NRF_LOG_SEVERITY_INFO_RAW, /* Artificial level to pass information about skipping string postprocessing.*/
} nrf_log_severity_t;
/**
* @brief Structure holding dynamic data associated with a module.
*
* See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
*/
typedef struct
{
uint16_t order_idx; ///< Ordered index of the module (used for auto-completion).
uint16_t filter; ///< Current highest severity level accepted (redundant to @ref nrf_log_module_filter_data_t::filter_lvls, used for optimization)
} nrf_log_module_dynamic_data_t;
/**
* @brief Structure holding dynamic filters associated with a module or instance if filtering is enabled (@ref NRF_LOG_FILTERS_ENABLED).
*
* @note Backend filters logically are part of @ref nrf_log_module_dynamic_data_t but they are kept separated to enable storing them in non-volatile memory.
*/
typedef struct
{
uint32_t filter_lvls; ///< Current severity levels for each backend (3 bits per backend).
} nrf_log_module_filter_data_t;
/**
* @brief Structure holding constant data associated with a module or instance.
*
* See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
*/
typedef struct
{
const char * p_module_name; ///< Module or instance name.
uint8_t info_color_id; ///< Color code of info messages.
uint8_t debug_color_id; ///< Color code of debug messages.
nrf_log_severity_t compiled_lvl; ///< Compiled highest severity level.
nrf_log_severity_t initial_lvl; ///< Severity level for given module or instance set on backend initialization.
} nrf_log_module_const_data_t;
#endif //NRF_LOG_TYPES_H

View File

@ -0,0 +1,123 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
#include "nrf_log_backend_rtt.h"
#include "nrf_log_backend_serial.h"
#include "nrf_log_str_formatter.h"
#include "nrf_log_internal.h"
#include "nrf_delay.h"
#include <SEGGER_RTT_Conf.h>
#include <SEGGER_RTT.h>
static bool m_host_present;
static uint8_t m_string_buff[NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE];
void nrf_log_backend_rtt_init(void)
{
SEGGER_RTT_Init();
}
static void serial_tx(void const * p_context, char const * buffer, size_t len)
{
if (len)
{
uint32_t idx = 0;
uint32_t processed;
uint32_t watchdog_counter = NRF_LOG_BACKEND_RTT_TX_RETRY_CNT;
do
{
processed = SEGGER_RTT_WriteNoLock(0, &buffer[idx], len);
idx += processed;
len -= processed;
if (processed == 0)
{
/* There are two possible reasons for not writing any data to RTT:
* - The host is not connected and not reading the data.
* - The buffer got full and will be read by the host.
* These two situations are distinguished using the following algorithm.
* At the begining, the module assumes that the host is active,
* so when no data is read, it busy waits and retries.
* If, after retrying, the host reads the data, the module assumes that the host is active.
* If it fails, the module assumes that the host is inactive and stores that information. On next
* call, only one attempt takes place. The host is marked as active if the attempt is successful.
*/
if (!m_host_present)
{
break;
}
else
{
nrf_delay_ms(NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS);
watchdog_counter--;
if (watchdog_counter == 0)
{
m_host_present = false;
break;
}
}
}
m_host_present = true;
} while (len);
}
}
static void nrf_log_backend_rtt_put(nrf_log_backend_t const * p_backend,
nrf_log_entry_t * p_msg)
{
nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff, NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE, serial_tx);
}
static void nrf_log_backend_rtt_flush(nrf_log_backend_t const * p_backend)
{
}
static void nrf_log_backend_rtt_panic_set(nrf_log_backend_t const * p_backend)
{
}
const nrf_log_backend_api_t nrf_log_backend_rtt_api = {
.put = nrf_log_backend_rtt_put,
.flush = nrf_log_backend_rtt_flush,
.panic_set = nrf_log_backend_rtt_panic_set,
};
#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)

View File

@ -0,0 +1,116 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG)
#include "nrf_log_backend_serial.h"
#include "nrf_log_str_formatter.h"
#include "nrf_log_internal.h"
void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
nrf_log_entry_t * p_msg,
uint8_t * p_buffer,
uint32_t length,
nrf_fprintf_fwrite tx_func)
{
nrf_memobj_get(p_msg);
nrf_fprintf_ctx_t fprintf_ctx = {
.p_io_buffer = (char *)p_buffer,
.io_buffer_size = length,
.io_buffer_cnt = 0,
.auto_flush = false,
.p_user_ctx = NULL,
.fwrite = tx_func
};
nrf_log_str_formatter_entry_params_t params;
nrf_log_header_t header;
size_t memobj_offset = 0;
nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
memobj_offset = HEADER_SIZE*sizeof(uint32_t);
params.timestamp = header.timestamp;
params.module_id = header.module_id;
params.dropped = header.dropped;
params.use_colors = NRF_LOG_USES_COLORS;
/*lint -save -e438*/
if (header.base.generic.type == HEADER_TYPE_STD)
{
char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
params.severity = (nrf_log_severity_t)header.base.std.severity;
uint32_t nargs = header.base.std.nargs;
uint32_t args[NRF_LOG_MAX_NUM_OF_ARGS];
nrf_memobj_read(p_msg, args, nargs*sizeof(uint32_t), memobj_offset);
memobj_offset += (nargs*sizeof(uint32_t));
nrf_log_std_entry_process(p_log_str,
args,
nargs,
&params,
&fprintf_ctx);
}
else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
{
uint32_t data_len = header.base.hexdump.len;
params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
uint8_t data_buf[8];
uint32_t chunk_len;
do
{
chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
nrf_memobj_read(p_msg, data_buf, chunk_len, memobj_offset);
memobj_offset += chunk_len;
data_len -= chunk_len;
nrf_log_hexdump_entry_process(data_buf,
chunk_len,
&params,
&fprintf_ctx);
} while (data_len > 0);
}
nrf_memobj_put(p_msg);
/*lint -restore*/
}
#endif //NRF_LOG_ENABLED

View File

@ -0,0 +1,77 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_BACKEND_SERIAL_H
#define NRF_LOG_BACKEND_SERIAL_H
/**@file
* @addtogroup nrf_log Logger module
* @ingroup app_common
*
* @defgroup nrf_log_backend_serial Common part of serial backends
* @{
* @ingroup nrf_log
* @brief The nrf_log serial backend common put function.
*/
#include "nrf_log_backend_interface.h"
#include "nrf_fprintf.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief A function for processing logger entry with simple serial interface as output.
*
*
*/
void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
nrf_log_entry_t * p_msg,
uint8_t * p_buffer,
uint32_t length,
nrf_fprintf_fwrite tx_func);
#endif //NRF_LOG_BACKEND_SERIAL_H
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -0,0 +1,116 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
#include "nrf_log_backend_uart.h"
#include "nrf_log_backend_serial.h"
#include "nrf_log_internal.h"
#include "nrf_drv_uart.h"
#include "app_error.h"
nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
static uint8_t m_string_buff[NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE];
static volatile bool m_xfer_done;
static bool m_async_mode;
static void uart_evt_handler(nrf_drv_uart_event_t * p_event, void * p_context)
{
m_xfer_done = true;
}
static void uart_init(bool async_mode)
{
nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
config.pseltxd = NRF_LOG_BACKEND_UART_TX_PIN;
config.pselrxd = NRF_UART_PSEL_DISCONNECTED;
config.pselcts = NRF_UART_PSEL_DISCONNECTED;
config.pselrts = NRF_UART_PSEL_DISCONNECTED;
config.baudrate = (nrf_uart_baudrate_t)NRF_LOG_BACKEND_UART_BAUDRATE;
ret_code_t err_code = nrf_drv_uart_init(&m_uart, &config, async_mode ? uart_evt_handler : NULL);
APP_ERROR_CHECK(err_code);
m_async_mode = async_mode;
}
void nrf_log_backend_uart_init(void)
{
bool async_mode = NRF_LOG_DEFERRED ? true : false;
uart_init(async_mode);
}
static void serial_tx(void const * p_context, char const * p_buffer, size_t len)
{
uint8_t len8 = (uint8_t)(len & 0x000000FF);
m_xfer_done = false;
ret_code_t err_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)p_buffer, len8);
APP_ERROR_CHECK(err_code);
/* wait for completion since buffer is reused*/
while (m_async_mode && (m_xfer_done == false))
{
}
}
static void nrf_log_backend_uart_put(nrf_log_backend_t const * p_backend,
nrf_log_entry_t * p_msg)
{
nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff,
NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE, serial_tx);
}
static void nrf_log_backend_uart_flush(nrf_log_backend_t const * p_backend)
{
}
static void nrf_log_backend_uart_panic_set(nrf_log_backend_t const * p_backend)
{
nrf_drv_uart_uninit(&m_uart);
uart_init(false);
}
const nrf_log_backend_api_t nrf_log_backend_uart_api = {
.put = nrf_log_backend_uart_put,
.flush = nrf_log_backend_uart_flush,
.panic_set = nrf_log_backend_uart_panic_set,
};
#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)

View File

@ -0,0 +1,91 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_CTRL_INTERNAL_H
#define NRF_LOG_CTRL_INTERNAL_H
/**
* @cond (NODOX)
* @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations
* @{
* @internal
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG)
#define NRF_LOG_LFCLK_FREQ 32768
#ifdef APP_TIMER_CONFIG_RTC_FREQUENCY
#define LOG_TIMESTAMP_DEFAULT_FREQUENCY ((NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY == 0) ? \
(NRF_LOG_LFCLK_FREQ/(APP_TIMER_CONFIG_RTC_FREQUENCY + 1)) : \
NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY)
#else
#define LOG_TIMESTAMP_DEFAULT_FREQUENCY NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY
#endif
#define NRF_LOG_INTERNAL_INIT(...) \
nrf_log_init(GET_VA_ARG_1(__VA_ARGS__), \
GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__, LOG_TIMESTAMP_DEFAULT_FREQUENCY)))
#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue()
#define NRF_LOG_INTERNAL_FLUSH() \
do { \
while (NRF_LOG_INTERNAL_PROCESS()); \
} while (0)
#define NRF_LOG_INTERNAL_FINAL_FLUSH() \
do { \
nrf_log_panic(); \
NRF_LOG_INTERNAL_FLUSH(); \
} while (0)
#else // NRF_MODULE_ENABLED(NRF_LOG)
#define NRF_LOG_INTERNAL_PROCESS() false
#define NRF_LOG_INTERNAL_FLUSH()
#define NRF_LOG_INTERNAL_INIT(...) NRF_SUCCESS
#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \
UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler)
#define NRF_LOG_INTERNAL_FINAL_FLUSH()
#endif // NRF_MODULE_ENABLED(NRF_LOG)
/** @}
* @endcond
*/
#endif // NRF_LOG_CTRL_INTERNAL_H

View File

@ -0,0 +1,76 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG)
#include "nrf_log_default_backends.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_internal.h"
#include "nrf_assert.h"
#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
#include "nrf_log_backend_rtt.h"
NRF_LOG_BACKEND_RTT_DEF(rtt_log_backend);
#endif
#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
#include "nrf_log_backend_uart.h"
NRF_LOG_BACKEND_UART_DEF(uart_log_backend);
#endif
void nrf_log_default_backends_init(void)
{
int32_t backend_id = -1;
(void)backend_id;
#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
nrf_log_backend_rtt_init();
backend_id = nrf_log_backend_add(&rtt_log_backend, NRF_LOG_SEVERITY_DEBUG);
ASSERT(backend_id >= 0);
nrf_log_backend_enable(&rtt_log_backend);
#endif
#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
nrf_log_backend_uart_init();
backend_id = nrf_log_backend_add(&uart_log_backend, NRF_LOG_SEVERITY_DEBUG);
ASSERT(backend_id >= 0);
nrf_log_backend_enable(&uart_log_backend);
#endif
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,516 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_LOG_INTERNAL_H__
#define NRF_LOG_INTERNAL_H__
#include "sdk_common.h"
#include "nrf.h"
#include "nrf_error.h"
#include "app_util.h"
#include <stdint.h>
#include <stdbool.h>
#include "nrf_log_instance.h"
#include "nrf_log_types.h"
#ifndef NRF_LOG_ERROR_COLOR
#define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
#endif
#ifndef NRF_LOG_WARNING_COLOR
#define NRF_LOG_WARNING_COLOR NRF_LOG_COLOR_DEFAULT
#endif
#ifndef NRF_LOG_INFO_COLOR
#define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT
#endif
#ifndef NRF_LOG_DEBUG_COLOR
#define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT
#endif
#ifndef NRF_LOG_COLOR_DEFAULT
#define NRF_LOG_COLOR_DEFAULT 0
#endif
#ifndef NRF_LOG_DEFAULT_LEVEL
#define NRF_LOG_DEFAULT_LEVEL 0
#endif
#ifndef NRF_LOG_USES_COLORS
#define NRF_LOG_USES_COLORS 0
#endif
#ifndef NRF_LOG_USES_TIMESTAMP
#define NRF_LOG_USES_TIMESTAMP 0
#endif
#ifndef NRF_LOG_FILTERS_ENABLED
#define NRF_LOG_FILTERS_ENABLED 0
#endif
#ifndef NRF_LOG_MODULE_NAME
#define NRF_LOG_MODULE_NAME app
#endif
#define NRF_LOG_LEVEL_BITS 3
#define NRF_LOG_LEVEL_MASK ((1UL << NRF_LOG_LEVEL_BITS) - 1)
#define NRF_LOG_MODULE_ID_BITS 16
#define NRF_LOG_MODULE_ID_POS 16
#define NRF_LOG_MAX_NUM_OF_ARGS 6
#if NRF_LOG_FILTERS_ENABLED && NRF_LOG_ENABLED
#define NRF_LOG_FILTER NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).filter
#define NRF_LOG_INST_FILTER(p_inst) (p_inst)->filter
#else
#undef NRF_LOG_FILTER
#define NRF_LOG_FILTER NRF_LOG_SEVERITY_DEBUG
#define NRF_LOG_INST_FILTER(p_inst) NRF_LOG_SEVERITY_DEBUG
#endif
/**
* @brief Macro for calculating module id based on address and section start address
*/
#define NRF_LOG_MODULE_ID_GET_CONST(addr) (((uint32_t)(addr) - \
(uint32_t)NRF_SECTION_START_ADDR(log_const_data)) / \
sizeof(nrf_log_module_const_data_t))
/**
* @brief Macro for calculating module id based on address and section start address
*/
#define NRF_LOG_MODULE_ID_GET_DYNAMIC(addr) (((uint32_t)(addr) - \
(uint32_t)NRF_SECTION_START_ADDR(log_dynamic_data)) / \
sizeof(nrf_log_module_dynamic_data_t))
#if NRF_LOG_ENABLED
#define NRF_LOG_MODULE_ID NRF_LOG_MODULE_ID_GET_CONST(&NRF_LOG_ITEM_DATA_CONST(NRF_LOG_MODULE_NAME))
#if NRF_LOG_FILTERS_ENABLED
#define NRF_LOG_INST_ID(p_inst) NRF_LOG_MODULE_ID_GET_DYNAMIC(p_inst)
#else
#define NRF_LOG_INST_ID(p_inst) NRF_LOG_MODULE_ID
#endif
#else
#define NRF_LOG_MODULE_ID 0
#define NRF_LOG_INST_ID(p_inst) 0
#endif
#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__)
#define LOG_INTERNAL(type, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \
__VA_ARGS__), type, __VA_ARGS__)
#if NRF_LOG_ENABLED
#define NRF_LOG_INTERNAL_LOG_PUSH(_str) nrf_log_push(_str)
#define LOG_INTERNAL_0(type, str) \
nrf_log_frontend_std_0(type, str)
#define LOG_INTERNAL_1(type, str, arg0) \
/*lint -save -e571*/nrf_log_frontend_std_1(type, str, (uint32_t)(arg0))/*lint -restore*/
#define LOG_INTERNAL_2(type, str, arg0, arg1) \
/*lint -save -e571*/nrf_log_frontend_std_2(type, str, (uint32_t)(arg0), \
(uint32_t)(arg1))/*lint -restore*/
#define LOG_INTERNAL_3(type, str, arg0, arg1, arg2) \
/*lint -save -e571*/nrf_log_frontend_std_3(type, str, (uint32_t)(arg0), \
(uint32_t)(arg1), (uint32_t)(arg2))/*lint -restore*/
#define LOG_INTERNAL_4(type, str, arg0, arg1, arg2, arg3) \
/*lint -save -e571*/nrf_log_frontend_std_4(type, str, (uint32_t)(arg0), \
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3))/*lint -restore*/
#define LOG_INTERNAL_5(type, str, arg0, arg1, arg2, arg3, arg4) \
/*lint -save -e571*/nrf_log_frontend_std_5(type, str, (uint32_t)(arg0), \
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4))/*lint -restore*/
#define LOG_INTERNAL_6(type, str, arg0, arg1, arg2, arg3, arg4, arg5) \
/*lint -save -e571*/nrf_log_frontend_std_6(type, str, (uint32_t)(arg0), \
(uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4), (uint32_t)(arg5))/*lint -restore*/
#else //NRF_LOG_ENABLED
#define NRF_LOG_INTERNAL_LOG_PUSH(_str) (void)(_str)
#define LOG_INTERNAL_0(_type, _str) \
(void)(_type); (void)(_str)
#define LOG_INTERNAL_1(_type, _str, _arg0) \
(void)(_type); (void)(_str); (void)(_arg0)
#define LOG_INTERNAL_2(_type, _str, _arg0, _arg1) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1)
#define LOG_INTERNAL_3(_type, _str, _arg0, _arg1, _arg2) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2)
#define LOG_INTERNAL_4(_type, _str, _arg0, _arg1, _arg2, _arg3) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3)
#define LOG_INTERNAL_5(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4)
#define LOG_INTERNAL_6(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4, _arg5) \
(void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4); (void)(_arg5)
#endif //NRF_LOG_ENABLED
#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
#define LOG_SEVERITY_INST_ID(severity,p_inst) ((severity) | NRF_LOG_INST_ID(p_inst) << NRF_LOG_MODULE_ID_POS)
#if NRF_LOG_ENABLED
#define LOG_HEXDUMP(_severity, _p_data, _length) \
nrf_log_frontend_hexdump((_severity), (_p_data), (_length))
#else
#define LOG_HEXDUMP(_severity, _p_data, _length) \
(void)(_severity); (void)(_p_data); (void)_length
#endif
#define NRF_LOG_INTERNAL_INST(level, level_id, p_inst, ...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_INST_FILTER(p_inst) >= level) \
{ \
LOG_INTERNAL(LOG_SEVERITY_INST_ID(level_id, p_inst), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_MODULE(level, level_id, ...) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= level) \
{ \
LOG_INTERNAL(LOG_SEVERITY_MOD_ID(level_id), __VA_ARGS__); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_INST(level, level_id, p_inst, p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_INST_FILTER(p_inst) >= level) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_INST_ID(level_id, p_inst), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_HEXDUMP_MODULE(level, level_id, p_data, len) \
if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
(level <= NRF_LOG_DEFAULT_LEVEL)) \
{ \
if (NRF_LOG_FILTER >= level) \
{ \
LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(level_id), \
(p_data), (len)); \
} \
}
#define NRF_LOG_INTERNAL_INST_ERROR(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_ERROR(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR,__VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_data, len)
#define NRF_LOG_INTERNAL_INST_WARNING(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_WARNING(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING,__VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_data, len)
#define NRF_LOG_INTERNAL_INST_INFO(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_INFO(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, __VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_data, len)
#define NRF_LOG_INTERNAL_RAW_INFO(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, __VA_ARGS__)
#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, p_data, len)
#define NRF_LOG_INTERNAL_INST_DEBUG(p_inst, ...) \
NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, __VA_ARGS__)
#define NRF_LOG_INTERNAL_DEBUG(...) \
NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, __VA_ARGS__)
#define NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, p_data, len)
#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_data, len)
#if NRF_LOG_ENABLED
#ifdef UNIT_TEST
#define COMPILED_LOG_LEVEL 4
#else
#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
#endif
#define NRF_LOG_INTERNAL_MODULE_REGISTER() \
NRF_LOG_INTERNAL_ITEM_REGISTER(NRF_LOG_MODULE_NAME, \
STRINGIFY(NRF_LOG_MODULE_NAME), \
NRF_LOG_INFO_COLOR, \
NRF_LOG_DEBUG_COLOR, \
NRF_LOG_INITIAL_LEVEL, \
COMPILED_LOG_LEVEL)
#else
#define NRF_LOG_INTERNAL_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
#endif
extern nrf_log_module_dynamic_data_t NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME);
extern _CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(NRF_LOG_MODULE_NAME);
/**
* Set of macros for encoding and decoding header for log entries.
* There are 2 types of entries:
* 1. Standard entry (STD)
* An entry consists of header, pointer to string and values. Header contains
* severity leveland determines number of arguments and thus size of the entry.
* Since flash address space starts from 0x00000000 and is limited to kB rather
* than MB 22 bits are used to store the address (4MB). It is used that way to
* save one RAM memory.
*
* --------------------------------
* |TYPE|SEVERITY|NARGS| P_STR |
* |------------------------------|
* | Module_ID (optional) |
* |------------------------------|
* | TIMESTAMP (optional) |
* |------------------------------|
* | ARG0 |
* |------------------------------|
* | .... |
* |------------------------------|
* | ARG(nargs-1) |
* --------------------------------
*
* 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of
* header, optional timestamp, pointer to string and data. A header contains
* length (10bit) and offset which is updated after backend processes part of
* data.
*
* --------------------------------
* |TYPE|SEVERITY|NARGS|OFFSET|LEN|
* |------------------------------|
* | Module_ID (optional) |
* |------------------------------|
* | TIMESTAMP (optional) |
* |------------------------------|
* | P_STR |
* |------------------------------|
* | data |
* |------------------------------|
* | data | dummy |
* --------------------------------
*
*/
#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U)
#define HEADER_TYPE_STD 1U
#define HEADER_TYPE_HEXDUMP 2U
#define HEADER_TYPE_INVALID 3U
typedef struct
{
uint32_t type : 2;
uint32_t in_progress: 1;
uint32_t data : 29;
} nrf_log_generic_header_t;
typedef struct
{
uint32_t type : 2;
uint32_t in_progress: 1;
uint32_t severity : 3;
uint32_t nargs : 4;
uint32_t addr : 22;
} nrf_log_std_header_t;
typedef struct
{
uint32_t type : 2;
uint32_t in_progress: 1;
uint32_t severity : 3;
uint32_t offset : 10;
uint32_t reserved : 6;
uint32_t len : 10;
} nrf_log_hexdump_header_t;
typedef union
{
nrf_log_generic_header_t generic;
nrf_log_std_header_t std;
nrf_log_hexdump_header_t hexdump;
uint32_t raw;
} nrf_log_main_header_t;
typedef struct
{
nrf_log_main_header_t base;
uint16_t module_id;
uint16_t dropped;
uint32_t timestamp;
} nrf_log_header_t;
#define HEADER_SIZE (sizeof(nrf_log_header_t)/sizeof(uint32_t) - \
(NRF_LOG_USES_TIMESTAMP ? 0 : 1))
/**
* @brief A function for logging raw string.
*
* @param severity_mid Severity.
* @param p_str A pointer to a string.
*/
void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str);
/**
* @brief A function for logging a formatted string with one argument.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0 An argument.
*/
void nrf_log_frontend_std_1(uint32_t severity_mid,
char const * const p_str,
uint32_t val0);
/**
* @brief A function for logging a formatted string with 2 arguments.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0, val1 Arguments for formatting string.
*/
void nrf_log_frontend_std_2(uint32_t severity_mid,
char const * const p_str,
uint32_t val0,
uint32_t val1);
/**
* @brief A function for logging a formatted string with 3 arguments.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0, val1, val2 Arguments for formatting string.
*/
void nrf_log_frontend_std_3(uint32_t severity_mid,
char const * const p_str,
uint32_t val0,
uint32_t val1,
uint32_t val2);
/**
* @brief A function for logging a formatted string with 4 arguments.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0, val1, val2, val3 Arguments for formatting string.
*/
void nrf_log_frontend_std_4(uint32_t severity_mid,
char const * const p_str,
uint32_t val0,
uint32_t val1,
uint32_t val2,
uint32_t val3);
/**
* @brief A function for logging a formatted string with 5 arguments.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0, val1, val2, val3, val4 Arguments for formatting string.
*/
void nrf_log_frontend_std_5(uint32_t severity_mid,
char const * const p_str,
uint32_t val0,
uint32_t val1,
uint32_t val2,
uint32_t val3,
uint32_t val4);
/**
* @brief A function for logging a formatted string with 6 arguments.
*
* @param severity_mid Severity.
* @param p_str A pointer to a formatted string.
* @param val0, val1, val2, val3, val4, val5 Arguments for formatting string.
*/
void nrf_log_frontend_std_6(uint32_t severity_mid,
char const * const p_str,
uint32_t val0,
uint32_t val1,
uint32_t val2,
uint32_t val3,
uint32_t val4,
uint32_t val5);
/**
* @brief A function for logging raw data.
*
* @param severity_mid Severity.
* @param p_str A pointer to a string which is prefixing the data.
* @param p_data A pointer to data to be dumped.
* @param length Length of data (in bytes).
*
*/
void nrf_log_frontend_hexdump(uint32_t severity_mid,
const void * const p_data,
uint16_t length);
/**
* @brief A function for reading a byte from log backend.
*
* @return Byte.
*/
uint8_t nrf_log_getchar(void);
#endif // NRF_LOG_INTERNAL_H__

View File

@ -0,0 +1,258 @@
/**
* Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_LOG)
#include "nrf_log_str_formatter.h"
#include "nrf_log_internal.h"
#include "nrf_log_ctrl.h"
#include "nrf_fprintf.h"
#include <ctype.h>
#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m"
#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m"
#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m"
#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m"
#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m"
#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m"
#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m"
#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m"
#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m"
#define NRF_LOG_CHAR_CODE_MAX 0x7E
static const char * severity_names[] = {
NULL,
"error",
"warning",
"info",
"debug"
};
static const char * m_colors[] = {
NRF_LOG_COLOR_CODE_DEFAULT,
NRF_LOG_COLOR_CODE_BLACK,
NRF_LOG_COLOR_CODE_RED,
NRF_LOG_COLOR_CODE_GREEN,
NRF_LOG_COLOR_CODE_YELLOW,
NRF_LOG_COLOR_CODE_BLUE,
NRF_LOG_COLOR_CODE_MAGENTA,
NRF_LOG_COLOR_CODE_CYAN,
NRF_LOG_COLOR_CODE_WHITE,
};
static uint32_t m_freq;
static uint32_t m_timestamp_div;
static void timestamp_print(nrf_fprintf_ctx_t * p_ctx, uint32_t timestamp)
{
if (NRF_LOG_USES_TIMESTAMP)
{
if (NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED)
{
timestamp /= m_timestamp_div;
uint32_t seconds = timestamp/m_freq;
uint32_t hours = seconds/3600;
seconds -= hours * 3600;
uint32_t mins = seconds/60;
seconds -= mins * 60;
uint32_t reminder = timestamp % m_freq;
uint32_t ms = (reminder * 1000)/m_freq;
uint32_t us = (1000*(1000*reminder - (ms * m_freq)))/m_freq;
nrf_fprintf(p_ctx, "[%02d:%02d:%02d.%03d,%03d] ", hours, mins, seconds, ms, us);
}
else
{
nrf_fprintf(p_ctx, "[%08lu] ", timestamp);
}
}
}
static void prefix_process(nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx)
{
if (p_params->dropped)
{
nrf_fprintf(p_ctx,
"%sLogs dropped (%d)%s\r\n",
NRF_LOG_COLOR_CODE_RED,
p_params->dropped,
NRF_LOG_COLOR_CODE_DEFAULT);
}
if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
{
if (p_params->use_colors)
{
nrf_fprintf(p_ctx, "%s",
m_colors[nrf_log_color_id_get( p_params->module_id, p_params->severity)]);
}
timestamp_print(p_ctx, p_params->timestamp);
nrf_fprintf(p_ctx, "<%s> %s: ",
severity_names[p_params->severity], nrf_log_module_name_get(p_params->module_id, false));
}
}
static void postfix_process(nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx,
bool newline)
{
if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
{
if (p_params->use_colors)
{
nrf_fprintf(p_ctx, "%s", m_colors[0]);
}
nrf_fprintf(p_ctx, "\r\n");
}
else if (newline)
{
nrf_fprintf(p_ctx, "\r\n");
}
nrf_fprintf_buffer_flush(p_ctx);
}
void nrf_log_std_entry_process(char const * p_str,
uint32_t const * p_args,
uint32_t nargs,
nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx)
{
bool auto_flush = p_ctx->auto_flush;
p_ctx->auto_flush = false;
prefix_process(p_params, p_ctx);
switch (nargs)
{
case 0:
nrf_fprintf(p_ctx, p_str);
break;
case 1:
nrf_fprintf(p_ctx, p_str, p_args[0]);
break;
case 2:
nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1]);
break;
case 3:
nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2]);
break;
case 4:
nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3]);
break;
case 5:
nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4]);
break;
case 6:
nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5]);
break;
default:
break;
}
postfix_process(p_params, p_ctx, false);
p_ctx->auto_flush = auto_flush;
}
#define HEXDUMP_BYTES_IN_LINE 8
void nrf_log_hexdump_entry_process(uint8_t * p_data,
uint32_t data_len,
nrf_log_str_formatter_entry_params_t * p_params,
nrf_fprintf_ctx_t * p_ctx)
{
if (data_len > HEXDUMP_BYTES_IN_LINE)
{
return;
}
bool auto_flush = p_ctx->auto_flush;
p_ctx->auto_flush = false;
prefix_process(p_params, p_ctx);
uint32_t i;
for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
{
if (i < data_len)
{
nrf_fprintf(p_ctx, " %02x", p_data[i]);
}
else
{
nrf_fprintf(p_ctx, " ");
}
}
nrf_fprintf(p_ctx, "|");
for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
{
if (i < data_len)
{
char c = (char)p_data[i];
nrf_fprintf(p_ctx, "%c", ((c <= NRF_LOG_CHAR_CODE_MAX) && isprint((int)c)) ? c :'.');
}
else
{
nrf_fprintf(p_ctx, " ");
}
}
postfix_process(p_params, p_ctx, true);
p_ctx->auto_flush = auto_flush;
}
void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq)
{
m_timestamp_div = 1;
/* There is no point to have frequency higher than 1MHz (ns are not printed) and too high
* frequency leads to overflows in calculations.
*/
while (freq > 1000000)
{
freq /= 2;
m_timestamp_div *= 2;
}
m_freq = freq;
}
#endif //NRF_LOG_ENABLED

View File

@ -0,0 +1,258 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "nrf_memobj.h"
#include "nrf_atomic.h"
#include "nrf_assert.h"
typedef struct memobj_elem_s memobj_elem_t;
/** @brief Standard chunk header. */
typedef struct
{
memobj_elem_t * p_next; ///< Pointer to the next element.
} memobj_header_t;
/** @brief Head header extension fields. */
typedef struct
{
uint8_t user_cnt; ///< User counter (see @ref nrf_memobj_get and @ref nrf_memobj_put).
uint8_t chunk_cnt; ///< Number of chunks in the object.
uint16_t chunk_size; ///< Single chunk size
} memobj_head_header_fields_t;
/** @brief Head header extension. */
typedef struct
{
union
{
nrf_atomic_u32_t atomic_user_cnt;
memobj_head_header_fields_t fields;
} data;
} memobj_head_header_t;
/** @brief Head chunk structure. */
typedef struct
{
memobj_header_t header; ///< Standard header.
memobj_head_header_t head_header; ///< Head-specific header part.
uint8_t data[1]; ///< Data.
} memobj_head_t;
STATIC_ASSERT(sizeof(memobj_header_t) == NRF_MEMOBJ_STD_HEADER_SIZE);
/** @brief Standard chunk structure. */
struct memobj_elem_s
{
memobj_header_t header; ///< Standard header.
uint8_t data[1]; ///< Data.
};
ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool)
{
return nrf_balloc_init((nrf_balloc_t const *)p_pool);
}
nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
size_t size)
{
uint32_t bsize = (uint32_t)NRF_BALLOC_ELEMENT_SIZE((nrf_balloc_t const *)p_pool) - sizeof(memobj_header_t);
uint8_t num_of_chunks = (uint8_t)CEIL_DIV(size + sizeof(memobj_head_header_t), bsize);
memobj_head_t * p_head = nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
if (p_head == NULL)
{
return NULL;
}
p_head->head_header.data.fields.user_cnt = 0;
p_head->head_header.data.fields.chunk_cnt = 1;
p_head->head_header.data.fields.chunk_size = bsize;
memobj_header_t * p_prev = (memobj_header_t *)p_head;
memobj_header_t * p_curr;
uint32_t i;
uint32_t chunk_less1 = (uint32_t)num_of_chunks - 1;
p_prev->p_next = (memobj_elem_t *)p_pool;
for (i = 0; i < chunk_less1; i++)
{
p_curr = (memobj_header_t *)nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
if (p_curr)
{
(p_head->head_header.data.fields.chunk_cnt)++;
p_prev->p_next = (memobj_elem_t *)p_curr;
p_curr->p_next = (memobj_elem_t *)p_pool;
p_prev = p_curr;
}
else
{
//Could not allocate all requested buffers
nrf_memobj_free((nrf_memobj_t *)p_head);
return NULL;
}
}
return (nrf_memobj_t *)p_head;
}
void nrf_memobj_free(nrf_memobj_t * p_obj)
{
memobj_head_t * p_head = (memobj_head_t *)p_obj;
uint8_t chunk_cnt = p_head->head_header.data.fields.chunk_cnt;
uint32_t i;
memobj_header_t * p_curr = (memobj_header_t *)p_obj;
memobj_header_t * p_next;
uint32_t chunk_less1 = (uint32_t)chunk_cnt - 1;
for (i = 0; i < chunk_less1; i++)
{
p_curr = (memobj_header_t *)p_curr->p_next;
}
nrf_balloc_t const * p_pool2 = (nrf_balloc_t const *)p_curr->p_next;
p_curr = (memobj_header_t *)p_obj;
for (i = 0; i < chunk_cnt; i++)
{
p_next = (memobj_header_t *)p_curr->p_next;
nrf_balloc_free(p_pool2, p_curr);
p_curr = p_next;
}
}
void nrf_memobj_get(nrf_memobj_t const * p_obj)
{
memobj_head_t * p_head = (memobj_head_t *)p_obj;
(void)nrf_atomic_u32_add(&p_head->head_header.data.atomic_user_cnt, 1);
}
void nrf_memobj_put(nrf_memobj_t * p_obj)
{
memobj_head_t * p_head = (memobj_head_t *)p_obj;
uint32_t user_cnt = nrf_atomic_u32_sub(&p_head->head_header.data.atomic_user_cnt, 1);
memobj_head_header_fields_t * p_fields = (memobj_head_header_fields_t *)&user_cnt;
if (p_fields->user_cnt == 0)
{
nrf_memobj_free(p_obj);
}
}
static void memobj_op(nrf_memobj_t * p_obj,
void * p_data,
size_t * p_len,
size_t offset,
bool read)
{
ASSERT(p_obj);
memobj_head_t * p_head = (memobj_head_t *)p_obj;
memobj_elem_t * p_curr_chunk = (memobj_elem_t *)p_obj;
size_t obj_capacity;
size_t chunk_size;
size_t chunk_idx;
size_t chunk_offset;
size_t len;
obj_capacity = (p_head->head_header.data.fields.chunk_size *
p_head->head_header.data.fields.chunk_cnt) -
sizeof(memobj_head_header_fields_t);
ASSERT(offset < obj_capacity);
chunk_size = p_head->head_header.data.fields.chunk_size;
chunk_idx = (offset + sizeof(memobj_head_header_fields_t)) / chunk_size;
chunk_offset = (offset + sizeof(memobj_head_header_fields_t)) % chunk_size;
len = ((*p_len + offset) > obj_capacity) ? obj_capacity - offset : *p_len;
//Return number of available bytes
*p_len = len;
//Move to the first chunk to be used
while (chunk_idx > 0)
{
p_curr_chunk = p_curr_chunk->header.p_next;
chunk_idx--;
}
size_t user_mem_offset = 0;
size_t curr_cpy_size = chunk_size - chunk_offset;
curr_cpy_size = curr_cpy_size > len ? len : curr_cpy_size;
while (len)
{
void * p_user_mem = &((uint8_t *)p_data)[user_mem_offset];
void * p_obj_mem = &p_curr_chunk->data[chunk_offset];
if (read)
{
memcpy(p_user_mem, p_obj_mem, curr_cpy_size);
}
else
{
memcpy(p_obj_mem, p_user_mem, curr_cpy_size);
}
chunk_offset = 0;
p_curr_chunk = p_curr_chunk->header.p_next;
len -= curr_cpy_size;
user_mem_offset += curr_cpy_size;
curr_cpy_size = (chunk_size > len) ? len : chunk_size;
}
}
void nrf_memobj_write(nrf_memobj_t * p_obj,
void * p_data,
size_t len,
size_t offset)
{
size_t op_len = len;
memobj_op(p_obj, p_data, &op_len, offset, false);
ASSERT(op_len == len);
}
void nrf_memobj_read(nrf_memobj_t * p_obj,
void * p_data,
size_t len,
size_t offset)
{
size_t op_len = len;
memobj_op(p_obj, p_data, &op_len, offset, true);
ASSERT(op_len == len);
}

View File

@ -0,0 +1,203 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_MEMOBJ_H
#define NRF_MEMOBJ_H
/**
* @defgroup nrf_memobj Memory Object module
* @{
* @ingroup app_common
* @brief Functions for controlling a memory object.
*/
#include <stdint.h>
#include <stdlib.h>
#include "sdk_errors.h"
#include "nrf_balloc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* A memory object can consist of multiple chunks with the same size. Each object has a header part
* and a data part. The first element in a memory object is memory object head which has a special header.
* The remaining objects have a header of the same size.
*
@verbatim
_____________________ _____________________ _____________________
| | | | | |
|4 B head header | --> |4 B p_next |------->|4 B p_memobj_pool |
|_____________________| | |_____________________| |_____________________|
| | | | | | |
|4 B p_next |--| | | | |
|_____________________| | | .... | |
| | | data | | data |
| | | | | |
| data | | | | |
| | | | | |
|_____________________| |_____________________| |_____________________|
head mid_element last_element
@endverbatim
*
*/
#define NRF_MEMOBJ_STD_HEADER_SIZE sizeof(uint32_t)
/**
* @brief Macro for creating an nrf_memobj pool.
*
* This macro declares an nrf_balloc object. The element in the pool contains a user-defined data part and
* a memory object header.
*
* @param _name Name of the instance.
* @param _chunk_size Size of a single chunk.
* @param _pool_size Number of chunks in the pool.
*/
#define NRF_MEMOBJ_POOL_DEF(_name, _chunk_size, _pool_size) \
STATIC_ASSERT((_chunk_size) > sizeof(uint32_t)); \
NRF_BALLOC_DEF(_name, ((_chunk_size)+NRF_MEMOBJ_STD_HEADER_SIZE), (_pool_size))
/**
* @brief Pool of memory objects.
*/
typedef nrf_balloc_t nrf_memobj_pool_t;
/**
* @brief Memory object handle.
*/
typedef void * nrf_memobj_t;
/**
* @brief Function for initializing the memobj pool instance.
*
* This function initializes the pool.
*
* @param[in] p_pool Pointer to the memobj pool instance structure.
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool);
/**
* @brief Function for allocating a memobj with a requested size.
*
* Fixed length elements in the pool are linked together to provide the amount of memory requested by
* the user. If a memory object is successfully allocated, then the users can use the memory.
* However, it is fragmented into multiple objects so it must be accessed through the API:
* @ref nrf_memobj_write and @ref nrf_memobj_read.
*
* @param[in] p_pool Pointer to the memobj pool instance structure.
* @param[in] size Data size of requested object.
*
* @return Pointer to a memory object or NULL if the requested size cannot be allocated.
*/
nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
size_t size);
/**
* @brief Function for indicating that a memory object is used and cannot be freed.
*
* Memory object can be shared and reused between multiple modules and this mechanism ensures that
* object is freed when no longer used by any module. Memory object has a counter which is incremented
* whenever this function is called. @ref nrf_memobj_put function decrements the counter.
*
* @param[in] p_obj Pointer to memory object.
*/
void nrf_memobj_get(nrf_memobj_t const * p_obj);
/**
* @brief Function for indicated that memory object is no longer used by the module and can be freed
* if no other module is using it.
*
* Memory object is returned to the pool if internal counter reaches 0 after decrementing. It means
* that no other module is needing it anymore.
*
* @note Memory object holds pointer to the pool which was used to allocate it so it does not have
* to be provided explicitly to this function.
*
* @param[in] p_obj Pointer to memory object.
*/
void nrf_memobj_put(nrf_memobj_t * p_obj);
/**
* @brief Function for forcing freeing of the memory object.
*
* @note This function should be use with caution because it can lead to undefined behavior of the
* modules since modules using the memory object are not aware that it has been freed.
*
* @param[in] p_obj Pointer to memory object.
*/
void nrf_memobj_free(nrf_memobj_t * p_obj);
/**
* @brief Function for writing data to the memory object.
*
* @param[in] p_obj Pointer to memory object.
* @param[in] p_data Pointer to data to be written to the memory object.
* @param[in] len Amount of data to be written to the memory object.
* @param[in] offset Offset.
*/
void nrf_memobj_write(nrf_memobj_t * p_obj,
void * p_data,
size_t len,
size_t offset);
/**
* @brief Function for reading data from the memory object.
*
* @param[in] p_obj Pointer to memory object.
* @param[in] p_data Pointer to the destination buffer.
* @param[in] len Amount of data to be read from the memory object.
* @param[in] offset Offset.
*/
void nrf_memobj_read(nrf_memobj_t * p_obj,
void * p_data,
size_t len,
size_t offset);
#ifdef __cplusplus
}
#endif
#endif //NRF_MEMOBJ_H
/** @} */

View File

@ -0,0 +1,237 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "nrf_ringbuf.h"
#include "app_util_platform.h"
#include "nrf_assert.h"
#define WR_OFFSET 0
#define RD_OFFSET 1
void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf)
{
p_ringbuf->p_cb->wr_idx = 0;
p_ringbuf->p_cb->rd_idx = 0;
p_ringbuf->p_cb->tmp_rd_idx = 0;
p_ringbuf->p_cb->tmp_wr_idx = 0;
p_ringbuf->p_cb->rd_flag = 0;
p_ringbuf->p_cb->wr_flag = 0;
}
ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
{
ASSERT(pp_data);
ASSERT(p_length);
if (start)
{
if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
{
return NRF_ERROR_BUSY;
}
}
if (p_ringbuf->p_cb->tmp_wr_idx - p_ringbuf->p_cb->rd_idx == p_ringbuf->bufsize_mask + 1)
{
*p_length = 0;
if (start)
{
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
}
return NRF_SUCCESS;
}
uint32_t wr_idx = p_ringbuf->p_cb->tmp_wr_idx & p_ringbuf->bufsize_mask;
uint32_t rd_idx = p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask;
uint32_t available = (wr_idx >= rd_idx) ? p_ringbuf->bufsize_mask + 1 - wr_idx :
p_ringbuf->p_cb->rd_idx - (p_ringbuf->p_cb->tmp_wr_idx - (p_ringbuf->bufsize_mask + 1));
*p_length = *p_length < available ? *p_length : available;
*pp_data = &p_ringbuf->p_buffer[wr_idx];
p_ringbuf->p_cb->tmp_wr_idx += *p_length;
return NRF_SUCCESS;
}
ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length)
{
uint32_t available = p_ringbuf->bufsize_mask + 1 -
(p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
if (length > available)
{
return NRF_ERROR_NO_MEM;
}
p_ringbuf->p_cb->wr_idx += length;
p_ringbuf->p_cb->tmp_wr_idx = p_ringbuf->p_cb->wr_idx;
if (nrf_atomic_flag_clear_fetch(&p_ringbuf->p_cb->wr_flag) == 0)
{
/* Flag was already cleared. Suggests misuse. */
return NRF_ERROR_INVALID_STATE;
}
return NRF_SUCCESS;
}
ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
uint8_t const * p_data,
size_t * p_length)
{
ASSERT(p_data);
ASSERT(p_length);
if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
{
return NRF_ERROR_BUSY;
}
uint32_t available = p_ringbuf->bufsize_mask + 1 -
(p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
*p_length = available > *p_length ? *p_length : available;
size_t length = *p_length;
uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_wr_idx;
if (length > trail)
{
memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, trail);
length -= trail;
masked_wr_idx = 0;
p_data += trail;
}
memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, length);
p_ringbuf->p_cb->wr_idx += *p_length;
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
return NRF_SUCCESS;
}
ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
{
ASSERT(pp_data);
ASSERT(p_length);
if (start)
{
if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
{
return NRF_ERROR_BUSY;
}
}
uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->tmp_rd_idx;
if (available == 0)
{
*p_length = 0;
if (start)
{
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
}
return NRF_SUCCESS;
}
uint32_t masked_tmp_rd_idx = p_ringbuf->p_cb->tmp_rd_idx & p_ringbuf->bufsize_mask;
uint32_t masked_wr_idx = p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask;
if ((masked_wr_idx > masked_tmp_rd_idx) && (available < *p_length))
{
*p_length = available;
}
else if (masked_wr_idx <= masked_tmp_rd_idx)
{
uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_tmp_rd_idx;
if (*p_length > trail)
{
*p_length = trail;
}
}
*pp_data = &p_ringbuf->p_buffer[masked_tmp_rd_idx];
p_ringbuf->p_cb->tmp_rd_idx += *p_length;
return NRF_SUCCESS;
}
ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
uint8_t * p_data,
size_t * p_length)
{
ASSERT(p_data);
ASSERT(p_length);
if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
{
return NRF_ERROR_BUSY;
}
uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx;
*p_length = available > *p_length ? *p_length : available;
size_t length = *p_length;
uint32_t masked_rd_idx = (p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask);
uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
uint32_t trail = (masked_wr_idx > masked_rd_idx) ? masked_wr_idx - masked_rd_idx :
p_ringbuf->bufsize_mask + 1 - masked_rd_idx;
if (length > trail)
{
memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], trail);
length -= trail;
masked_rd_idx = 0;
p_data += trail;
}
memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], length);
p_ringbuf->p_cb->rd_idx += *p_length;
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
return NRF_SUCCESS;
}
ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length)
{
uint32_t available = (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
if (length > available)
{
return NRF_ERROR_NO_MEM;
}
p_ringbuf->p_cb->rd_idx += length;
p_ringbuf->p_cb->tmp_rd_idx = p_ringbuf->p_cb->rd_idx;
UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
return NRF_SUCCESS;
}

View File

@ -0,0 +1,206 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
#ifndef NRF_RINGBUF_H
#define NRF_RINGBUF_H
/**
* @defgroup nrf_ringbuf Ring buffer
* @{
* @ingroup app_common
* @brief Functions for controlling the ring buffer.
*/
#include <stdint.h>
#include "nrf_atomic.h"
#include "sdk_errors.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Ring buffer instance control block.
* */
typedef struct
{
nrf_atomic_flag_t wr_flag; //!< Protection flag.
nrf_atomic_flag_t rd_flag; //!< Protection flag.
uint32_t wr_idx; //!< Write index (updated when putting).
uint32_t tmp_wr_idx; //!< Temporary write index (updated when allocating).
uint32_t rd_idx; //!< Read index (updated when freeing).
uint32_t tmp_rd_idx; //!< Temporary read index (updated when getting).
} nrf_ringbuf_cb_t;
/**
* @brief Ring buffer instance structure.
* */
typedef struct
{
uint8_t * p_buffer; //!< Pointer to the memory used by the ring buffer.
uint32_t bufsize_mask; //!< Buffer size mask (buffer size must be a power of 2).
nrf_ringbuf_cb_t * p_cb; //!< Pointer to the instance control block.
} nrf_ringbuf_t;
/**
* @brief Macro for defining a ring buffer instance.
*
* @param _name Instance name.
* @param _size Size of the ring buffer (must be a power of 2).
* */
#define NRF_RINGBUF_DEF(_name, _size) \
STATIC_ASSERT(IS_POWER_OF_TWO(_size)); \
static uint8_t CONCAT_2(_name,_buf)[_size]; \
static nrf_ringbuf_cb_t CONCAT_2(_name,_cb); \
static const nrf_ringbuf_t _name = { \
.p_buffer = CONCAT_2(_name,_buf), \
.bufsize_mask = _size - 1, \
.p_cb = &CONCAT_2(_name,_cb), \
}
/**
* @brief Function for initializing a ring buffer instance.
*
* @param p_ringbuf Pointer to the ring buffer instance.
*
* */
void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf);
/**
* @brief Function for allocating memory from a ring buffer.
*
* This function attempts to allocate the amount of memory requested by the user, or a smaller amount if
* the requested amount is not available. If a start flag is set, then exclusive access to allocation
* is established. @ref nrf_ringbuf_put frees access to allocation. If a start flag is not set, then
* exclusive access check is omitted.
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] pp_data Pointer to the pointer to the allocated buffer.
* @param[in, out] p_length Pointer to length. Length is set to the requested amount and filled
* by the function with actually allocated amount.
* @param[in] start Set to true if exclusive access should be controlled.
*
* @retval NRF_SUCCESS Successful allocation (can be smaller amount than requested).
* NRF_ERROR_BUSY Ring buffer allocation process (alloc-put) is ongoing.
*
* */
ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
/**
* @brief Function for commiting data to a ring buffer.
*
* When an allocated buffer (see @ref nrf_ringbuf_alloc) has been filled with data, it must be committed
* to make it available for @ref nrf_ringbuf_get and @ref nrf_ringbuf_cpy_get. This function commits
* the data (can be smaller amount than allocated).
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] length Amount of bytes to put.
* @return NRF_SUCCESS on successful put or error.
* */
ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length);
/**
* @brief Function for copying data directly into the ring buffer.
*
* This function copies a user buffer to the ring buffer.
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] p_data Pointer to the input buffer.
* @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
* @return NRF_SUCCESS on successful put or error.
* */
ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
uint8_t const* p_data,
size_t * p_length);
/**
* Function for getting data from the ring buffer.
*
* This function attempts to get the requested amount of data from the ring buffer. If a start flag is set, then
* exclusive access to getting data from the ring buffer is established. @ref nrf_ringbuf_free frees
* access to getting data from the ring buffer. If a start flag is not set, then
* exclusive access check is omitted.
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] pp_data Pointer to the pointer to the buffer with data.
* @param[in, out] p_length Pointer to length. Length is set to the requested amount and filled
* by the function with the actual amount.
* @param[in] start Set to true if exclusive access should be controlled.
*
* @retval NRF_SUCCESS Successful getting (can be smaller amount than requested).
* NRF_ERROR_BUSY Ring buffer getting process (get-free) is ongoing.
*/
ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
/**
* @brief Function for freeing a buffer back to the ring buffer.
*
* When a buffer with data taken from the ring buffer (see @ref nrf_ringbuf_get) has been processed, it
* must be freed to make it available for further use. This function frees the buffer (can be smaller
* amount than get).
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] length Amount of bytes to free.
* @return NRF_SUCCESS on successful put or error.
* */
ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length);
/**
* @brief Function for copying data directly out of the ring buffer.
*
* This function copies available data from the ring buffer to a user buffer.
*
* @param[in] p_ringbuf Pointer to the ring buffer instance.
* @param[in] p_data Pointer to the input buffer.
* @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
* @return NRF_SUCCESS on successful put or error.
* */
ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
uint8_t * p_data,
size_t * p_length);
#ifdef __cplusplus
}
#endif
#endif //NRF_RINGBUF_H
/** @} */

View File

@ -0,0 +1,288 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(APP_SCHEDULER)
#include "app_scheduler.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "nrf_soc.h"
#include "nrf_assert.h"
#include "app_util_platform.h"
/**@brief Structure for holding a scheduled event header. */
typedef struct
{
app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */
uint16_t event_data_size; /**< Size of event data. */
} event_header_t;
STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */
static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */
static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */
static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */
static uint16_t m_queue_event_size; /**< Maximum event size in queue. */
static uint16_t m_queue_size; /**< Number of queue entries. */
#if APP_SCHEDULER_WITH_PROFILER
static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */
#endif
#if APP_SCHEDULER_WITH_PAUSE
static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
and resuming the scheduler. */
#endif
/**@brief Function for incrementing a queue index, and handle wrap-around.
*
* @param[in] index Old index.
*
* @return New (incremented) index.
*/
static __INLINE uint8_t next_index(uint8_t index)
{
return (index < m_queue_size) ? (index + 1) : 0;
}
static __INLINE uint8_t app_sched_queue_full()
{
uint8_t tmp = m_queue_start_index;
return next_index(m_queue_end_index) == tmp;
}
/**@brief Macro for checking if a queue is full. */
#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
static __INLINE uint8_t app_sched_queue_empty()
{
uint8_t tmp = m_queue_start_index;
return m_queue_end_index == tmp;
}
/**@brief Macro for checking if a queue is empty. */
#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
{
uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);
// Check that buffer is correctly aligned
if (!is_word_aligned(p_event_buffer))
{
return NRF_ERROR_INVALID_PARAM;
}
// Initialize event scheduler
m_queue_event_headers = p_event_buffer;
m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index];
m_queue_end_index = 0;
m_queue_start_index = 0;
m_queue_event_size = event_size;
m_queue_size = queue_size;
#if APP_SCHEDULER_WITH_PROFILER
m_max_queue_utilization = 0;
#endif
return NRF_SUCCESS;
}
uint16_t app_sched_queue_space_get()
{
uint16_t start = m_queue_start_index;
uint16_t end = m_queue_end_index;
uint16_t free_space = m_queue_size - ((end >= start) ?
(end - start) : (m_queue_size + 1 - start + end));
return free_space;
}
#if APP_SCHEDULER_WITH_PROFILER
static void queue_utilization_check(void)
{
uint16_t start = m_queue_start_index;
uint16_t end = m_queue_end_index;
uint16_t queue_utilization = (end >= start) ? (end - start) :
(m_queue_size + 1 - start + end);
if (queue_utilization > m_max_queue_utilization)
{
m_max_queue_utilization = queue_utilization;
}
}
uint16_t app_sched_queue_utilization_get(void)
{
return m_max_queue_utilization;
}
#endif // APP_SCHEDULER_WITH_PROFILER
uint32_t app_sched_event_put(void const * p_event_data,
uint16_t event_data_size,
app_sched_event_handler_t handler)
{
uint32_t err_code;
if (event_data_size <= m_queue_event_size)
{
uint16_t event_index = 0xFFFF;
CRITICAL_REGION_ENTER();
if (!APP_SCHED_QUEUE_FULL())
{
event_index = m_queue_end_index;
m_queue_end_index = next_index(m_queue_end_index);
#if APP_SCHEDULER_WITH_PROFILER
// This function call must be protected with critical region because
// it modifies 'm_max_queue_utilization'.
queue_utilization_check();
#endif
}
CRITICAL_REGION_EXIT();
if (event_index != 0xFFFF)
{
// NOTE: This can be done outside the critical region since the event consumer will
// always be called from the main loop, and will thus never interrupt this code.
m_queue_event_headers[event_index].handler = handler;
if ((p_event_data != NULL) && (event_data_size > 0))
{
memcpy(&m_queue_event_data[event_index * m_queue_event_size],
p_event_data,
event_data_size);
m_queue_event_headers[event_index].event_data_size = event_data_size;
}
else
{
m_queue_event_headers[event_index].event_data_size = 0;
}
err_code = NRF_SUCCESS;
}
else
{
err_code = NRF_ERROR_NO_MEM;
}
}
else
{
err_code = NRF_ERROR_INVALID_LENGTH;
}
return err_code;
}
#if APP_SCHEDULER_WITH_PAUSE
void app_sched_pause(void)
{
CRITICAL_REGION_ENTER();
if (m_scheduler_paused_counter < UINT32_MAX)
{
m_scheduler_paused_counter++;
}
CRITICAL_REGION_EXIT();
}
void app_sched_resume(void)
{
CRITICAL_REGION_ENTER();
if (m_scheduler_paused_counter > 0)
{
m_scheduler_paused_counter--;
}
CRITICAL_REGION_EXIT();
}
#endif //APP_SCHEDULER_WITH_PAUSE
/**@brief Function for checking if scheduler is paused which means that should break processing
* events.
*
* @return Boolean value - true if scheduler is paused, false otherwise.
*/
static __INLINE bool is_app_sched_paused(void)
{
#if APP_SCHEDULER_WITH_PAUSE
return (m_scheduler_paused_counter > 0);
#else
return false;
#endif
}
void app_sched_execute(void)
{
while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY())
{
// Since this function is only called from the main loop, there is no
// need for a critical region here, however a special care must be taken
// regarding update of the queue start index (see the end of the loop).
uint16_t event_index = m_queue_start_index;
void * p_event_data;
uint16_t event_data_size;
app_sched_event_handler_t event_handler;
p_event_data = &m_queue_event_data[event_index * m_queue_event_size];
event_data_size = m_queue_event_headers[event_index].event_data_size;
event_handler = m_queue_event_headers[event_index].handler;
event_handler(p_event_data, event_data_size);
// Event processed, now it is safe to move the queue start index,
// so the queue entry occupied by this event can be used to store
// a next one.
m_queue_start_index = next_index(m_queue_start_index);
}
}
#endif //NRF_MODULE_ENABLED(APP_SCHEDULER)

View File

@ -0,0 +1,211 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/** @file
*
* @defgroup app_scheduler Scheduler
* @{
* @ingroup app_common
*
* @brief The scheduler is used for transferring execution from the interrupt context to the main
* context.
*
* @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
* when using the Scheduler.
*
* @section app_scheduler_req Requirements:
*
* @subsection main_context_logic Logic in main context:
*
* - Define an event handler for each type of event expected.
* - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
* application main loop.
* - Call app_sched_execute() from the main loop each time the application wakes up because of an
* event (typically when sd_app_evt_wait() returns).
*
* @subsection int_context_logic Logic in interrupt context:
*
* - In the interrupt handler, call app_sched_event_put()
* with the appropriate data and event handler. This will insert an event into the
* scheduler's queue. The app_sched_execute() function will pull this event and call its
* handler in the main context.
*
* @if (PERIPHERAL)
* For an example usage of the scheduler, see the implementations of
* @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
* @endif
*
* @image html scheduler_working.svg The high level design of the scheduler
*/
#ifndef APP_SCHEDULER_H__
#define APP_SCHEDULER_H__
#include "sdk_config.h"
#include <stdint.h>
#include "app_error.h"
#include "app_util.h"
#ifdef __cplusplus
extern "C" {
#endif
#define APP_SCHED_EVENT_HEADER_SIZE 8 /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
/**@brief Compute number of bytes required to hold the scheduler buffer.
*
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
* that can be scheduled for execution).
*
* @return Required scheduler buffer size (in bytes).
*/
#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE) \
(((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
/**@brief Scheduler event handler type. */
typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
/**@brief Macro for initializing the event scheduler.
*
* @details It will also handle dimensioning and allocation of the memory buffer required by the
* scheduler, making sure the buffer is correctly aligned.
*
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
* that can be scheduled for execution).
*
* @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
* several times as long as it is from the same location, e.g. to do a reinitialization).
*/
#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE) \
do \
{ \
static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)), \
sizeof(uint32_t))]; \
uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF); \
APP_ERROR_CHECK(ERR_CODE); \
} while (0)
/**@brief Function for initializing the Scheduler.
*
* @details It must be called before entering the main loop.
*
* @param[in] max_event_size Maximum size of events to be passed through the scheduler.
* @param[in] queue_size Number of entries in scheduler queue (i.e. the maximum number of
* events that can be scheduled for execution).
* @param[in] p_evt_buffer Pointer to memory buffer for holding the scheduler queue. It must
* be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
* must be aligned to a 4 byte boundary.
*
* @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
* allocate the scheduler buffer, and also align the buffer correctly.
*
* @retval NRF_SUCCESS Successful initialization.
* @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
* boundary).
*/
uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
/**@brief Function for executing all scheduled events.
*
* @details This function must be called from within the main loop. It will execute all events
* scheduled since the last time it was called.
*/
void app_sched_execute(void);
/**@brief Function for scheduling an event.
*
* @details Puts an event into the event queue.
*
* @param[in] p_event_data Pointer to event data to be scheduled.
* @param[in] event_size Size of event data to be scheduled.
* @param[in] handler Event handler to receive the event.
*
* @return NRF_SUCCESS on success, otherwise an error code.
*/
uint32_t app_sched_event_put(void const * p_event_data,
uint16_t event_size,
app_sched_event_handler_t handler);
/**@brief Function for getting the maximum observed queue utilization.
*
* Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage.
*
* @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality.
*
* @return Maximum number of events in queue observed so far.
*/
uint16_t app_sched_queue_utilization_get(void);
/**@brief Function for getting the current amount of free space in the queue.
*
* @details The real amount of free space may be less if entries are being added from an interrupt.
* To get the sxact value, this function should be called from the critical section.
*
* @return Amount of free space in the queue.
*/
uint16_t app_sched_queue_space_get(void);
/**@brief A function to pause the scheduler.
*
* @details When the scheduler is paused events are not pulled from the scheduler queue for
* processing. The function can be called multiple times. To unblock the scheduler the
* function @ref app_sched_resume has to be called the same number of times.
*
* @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
*/
void app_sched_pause(void);
/**@brief A function to resume a scheduler.
*
* @details To unblock the scheduler this function has to be called the same number of times as
* @ref app_sched_pause function.
*
* @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
*/
void app_sched_resume(void);
#ifdef __cplusplus
}
#endif
#endif // APP_SCHEDULER_H__
/** @} */

View File

@ -0,0 +1,161 @@
/**
* Copyright (c) 2011 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 "sdk_common.h"
#if NRF_MODULE_ENABLED(NRF_STRERROR)
#include "nrf_strerror.h"
/**
* @brief Macro for adding an entity to the description array.
*
* Macro that helps to create a single entity in the description array.
*/
#define NRF_STRERROR_ENTITY(mnemonic) {.code = mnemonic, .name = #mnemonic}
/**
* @brief Array entity element that describes an error.
*/
typedef struct
{
ret_code_t code; /**< Error code. */
char const * name; /**< Descriptive name (the same as the internal error mnemonic). */
}nrf_strerror_desc_t;
/**
* @brief Unknown error code.
*
* The constant string used by @ref nrf_strerror_get when the error description was not found.
*/
static char const m_unknown_str[] = "Unknown error code";
/**
* @brief Array with error codes.
*
* Array that describes error codes.
*
* @note It is required for this array to have error codes placed in ascending order.
* This condition is checked in automatic unit test before the release.
*/
static nrf_strerror_desc_t const nrf_strerror_array[] =
{
NRF_STRERROR_ENTITY(NRF_SUCCESS),
NRF_STRERROR_ENTITY(NRF_ERROR_SVC_HANDLER_MISSING),
NRF_STRERROR_ENTITY(NRF_ERROR_SOFTDEVICE_NOT_ENABLED),
NRF_STRERROR_ENTITY(NRF_ERROR_INTERNAL),
NRF_STRERROR_ENTITY(NRF_ERROR_NO_MEM),
NRF_STRERROR_ENTITY(NRF_ERROR_NOT_FOUND),
NRF_STRERROR_ENTITY(NRF_ERROR_NOT_SUPPORTED),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_PARAM),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_STATE),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_LENGTH),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_FLAGS),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_DATA),
NRF_STRERROR_ENTITY(NRF_ERROR_DATA_SIZE),
NRF_STRERROR_ENTITY(NRF_ERROR_TIMEOUT),
NRF_STRERROR_ENTITY(NRF_ERROR_NULL),
NRF_STRERROR_ENTITY(NRF_ERROR_FORBIDDEN),
NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_ADDR),
NRF_STRERROR_ENTITY(NRF_ERROR_BUSY),
#ifdef NRF_ERROR_CONN_COUNT
NRF_STRERROR_ENTITY(NRF_ERROR_CONN_COUNT),
#endif
#ifdef NRF_ERROR_RESOURCES
NRF_STRERROR_ENTITY(NRF_ERROR_RESOURCES),
#endif
/* SDK Common errors */
NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_NOT_INITIALIZED),
NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_INIT_FAILED),
NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_LOCK_FAILED),
NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_UNLOCK_FAILED),
NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_COND_INIT_FAILED),
NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_ALREADY_INITIALIZED),
NRF_STRERROR_ENTITY(NRF_ERROR_STORAGE_FULL),
NRF_STRERROR_ENTITY(NRF_ERROR_API_NOT_IMPLEMENTED),
NRF_STRERROR_ENTITY(NRF_ERROR_FEATURE_NOT_ENABLED),
NRF_STRERROR_ENTITY(NRF_ERROR_IO_PENDING),
/* TWI error codes */
NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_OVERRUN),
NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_ANACK),
NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_DNACK),
/* IPSP error codes */
NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED),
NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS),
NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED),
NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_PEER_REJECTED)
};
char const * nrf_strerror_get(ret_code_t code)
{
char const * p_ret = nrf_strerror_find(code);
return (p_ret == NULL) ? m_unknown_str : p_ret;
}
char const * nrf_strerror_find(ret_code_t code)
{
nrf_strerror_desc_t const * p_start;
nrf_strerror_desc_t const * p_end;
p_start = nrf_strerror_array;
p_end = nrf_strerror_array + ARRAY_SIZE(nrf_strerror_array);
while (p_start < p_end)
{
nrf_strerror_desc_t const * p_mid = p_start + ((p_end - p_start) / 2);
ret_code_t mid_c = p_mid->code;
if (mid_c > code)
{
p_end = p_mid;
}
else if (mid_c < code)
{
p_start = p_mid + 1;
}
else
{
return p_mid->name;
}
}
return NULL;
}
#endif /* NRF_STRERROR enabled */

View File

@ -0,0 +1,89 @@
/**
* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**
* @defgroup nrf_strerror Error code to string converter
* @ingroup app_common
*
* @brief Module for converting error code into a printable string.
* @{
*/
#ifndef NRF_STRERROR_H__
#define NRF_STRERROR_H__
#include "sdk_errors.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Function for getting a printable error string.
*
* @param code Error code to convert.
*
* @note This function cannot fail.
* For the function that may fail with error translation, see @ref nrf_strerror_find.
*
* @return Pointer to the printable string.
* If the string is not found,
* it returns a simple string that says that the error is unknown.
*/
char const * nrf_strerror_get(ret_code_t code);
/**
* @brief Function for finding a printable error string.
*
* This function gets the error string in the same way as @ref nrf_strerror_get,
* but if the string is not found, it returns NULL.
*
* @param code Error code to convert.
* @return Pointer to the printable string.
* If the string is not found, NULL is returned.
*/
char const * nrf_strerror_find(ret_code_t code);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* NRF_STRERROR_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,313 @@
/**
* Copyright (c) 2012 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/** @file
*
* @defgroup app_timer Application Timer
* @{
* @ingroup app_common
*
* @brief Application timer functionality.
*
* @details This module enables the application to create multiple timer instances based on the RTC1
* peripheral. Checking for time-outs and invocation of user time-out handlers is performed
* in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0).
* Both interrupt handlers are running in APP_LOW priority level.
*
* @details When calling app_timer_start() or app_timer_stop(), the timer operation is just queued,
* and the software interrupt is triggered. The actual timer start/stop operation is
* executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW,
* if the application code calling the timer function is running in APP_LOW or APP_HIGH,
* the timer operation will not be performed until the application handler has returned.
* This will be the case, for example, when stopping a timer from a time-out handler when not using
* the scheduler.
*
* @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the
* @ref app_scheduler should be used or not. Even if the scheduler is
* not used, app_timer.h will include app_scheduler.h, so when
* compiling, app_scheduler.h must be available in one of the compiler include paths.
*/
#ifndef APP_TIMER_H__
#define APP_TIMER_H__
#include "sdk_config.h"
#include "app_error.h"
#include "app_util.h"
#include "compiler_abstraction.h"
#include "nordic_common.h"
#ifdef APP_TIMER_V2
#include "nrf_log_instance.h"
#include "nrf_sortlist.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Name of the module used for logger messaging.
*/
#define APP_TIMER_LOG_NAME app_timer
#define APP_TIMER_CLOCK_FREQ 32768 /**< Clock frequency of the RTC timer used to implement the app timer module. */
#define APP_TIMER_MIN_TIMEOUT_TICKS 5 /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */
#ifdef RTX
#define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (used to allocate data). */
#else
#define APP_TIMER_NODE_SIZE 32 /**< Size of app_timer.timer_node_t (used to allocate data). */
#endif // RTX
#define APP_TIMER_SCHED_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Size of event data when scheduler is used. */
#define APP_TIMER_MAX_CNT_VAL RTC_COUNTER_COUNTER_Msk /**< Maximum counter value that can be returned by @ref app_timer_cnt_get. */
/**@brief Convert milliseconds to timer ticks.
*
* This macro uses 64-bit integer arithmetic, but as long as the macro parameters are
* constants (i.e. defines), the computation will be done by the preprocessor.
*
* @param[in] MS Milliseconds.
*
* @return Number of timer ticks.
*/
#ifndef FREERTOS
#define APP_TIMER_TICKS(MS) \
((uint32_t)ROUNDED_DIV( \
(MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, \
1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1)))
#else
#include "FreeRTOSConfig.h"
#define APP_TIMER_TICKS(MS) (uint32_t)ROUNDED_DIV((MS)*configTICK_RATE_HZ,1000)
#endif
/**
* @brief Create a timer identifier and statically allocate memory for the timer.
*
* @param timer_id Name of the timer identifier variable that will be used to control the timer.
*/
#define APP_TIMER_DEF(timer_id) _APP_TIMER_DEF(timer_id)
/**@brief Application time-out handler type. */
typedef void (*app_timer_timeout_handler_t)(void * p_context);
#ifdef APP_TIMER_V2
/**
* @brief app_timer control block
*/
typedef struct
{
nrf_sortlist_item_t list_item; /**< Token used by sortlist. */
volatile uint32_t end_val; /**< RTC counter value when timer expires. */
uint32_t repeat_period; /**< Repeat period (0 if single shot mode). */
app_timer_timeout_handler_t handler; /**< User handler. */
void * p_context; /**< User context. */
NRF_LOG_INSTANCE_PTR_DECLARE(p_log) /**< Pointer to instance of the logger object (Conditionally compiled). */
volatile bool active; /**< Flag indicating that timer is active. */
} app_timer_t;
/**@brief Timer ID type.
* Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
typedef app_timer_t * app_timer_id_t;
#define _APP_TIMER_DEF(timer_id) \
NRF_LOG_INSTANCE_REGISTER(APP_TIMER_LOG_NAME, timer_id, \
APP_TIMER_CONFIG_INFO_COLOR, \
APP_TIMER_CONFIG_DEBUG_COLOR, \
APP_TIMER_CONFIG_INITIAL_LOG_LEVEL, \
APP_TIMER_CONFIG_LOG_ENABLED ? \
APP_TIMER_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
static app_timer_t CONCAT_2(timer_id,_data) = { \
.active = false, \
NRF_LOG_INSTANCE_PTR_INIT(p_log, APP_TIMER_LOG_NAME, timer_id) \
}; \
static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
#else //APP_TIMER_V2
typedef struct app_timer_t { uint32_t data[CEIL_DIV(APP_TIMER_NODE_SIZE, sizeof(uint32_t))]; } app_timer_t;
/**@brief Timer ID type.
* Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
typedef app_timer_t * app_timer_id_t;
#define _APP_TIMER_DEF(timer_id) \
static app_timer_t CONCAT_2(timer_id,_data) = { {0} }; \
static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
#endif
/**@brief Structure passed to app_scheduler. */
typedef struct
{
app_timer_timeout_handler_t timeout_handler;
void * p_context;
} app_timer_event_t;
/**@brief Timer modes. */
typedef enum
{
APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */
APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */
} app_timer_mode_t;
/**@brief Function for initializing the timer module.
*
* @retval NRF_SUCCESS If the module was initialized successfully.
*/
ret_code_t app_timer_init(void);
/**@brief Function for creating a timer instance.
*
* @param[in] p_timer_id Pointer to timer identifier.
* @param[in] mode Timer mode.
* @param[in] timeout_handler Function to be executed when the timer expires.
*
* @retval NRF_SUCCESS If the timer was successfully created.
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or
* the timer is running.
*
* @note This function does the timer allocation in the caller's context. It is also not protected
* by a critical region. Therefore care must be taken not to call it from several interrupt
* levels simultaneously.
* @note The function can be called again on the timer instance and will re-initialize the instance if
* the timer is not running.
* @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to
* be called on the previously initialized instance.
*/
ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
app_timer_mode_t mode,
app_timer_timeout_handler_t timeout_handler);
/**@brief Function for starting a timer.
*
* @param[in] timer_id Timer identifier.
* @param[in] timeout_ticks Number of ticks (of RTC1, including prescaling) to time-out event
* (minimum 5 ticks).
* @param[in] p_context General purpose pointer. Will be passed to the time-out handler when
* the timer expires.
*
* @retval NRF_SUCCESS If the timer was successfully started.
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
* has not been created.
* @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
*
* @note The minimum timeout_ticks value is 5.
* @note For multiple active timers, time-outs occurring in close proximity to each other (in the
* range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks.
* @note When calling this method on a timer that is already running, the second start operation
* is ignored.
*/
ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
/**@brief Function for stopping the specified timer.
*
* @param[in] timer_id Timer identifier.
*
* @retval NRF_SUCCESS If the timer was successfully stopped.
* @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
* has not been created.
* @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
*/
ret_code_t app_timer_stop(app_timer_id_t timer_id);
/**@brief Function for stopping all running timers.
*
* @retval NRF_SUCCESS If all timers were successfully stopped.
* @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized.
* @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
*/
ret_code_t app_timer_stop_all(void);
/**@brief Function for returning the current value of the RTC1 counter.
*
* @return Current value of the RTC1 counter.
*/
uint32_t app_timer_cnt_get(void);
/**@brief Function for computing the difference between two RTC1 counter values.
*
* @param[in] ticks_to Value returned by app_timer_cnt_get().
* @param[in] ticks_from Value returned by app_timer_cnt_get().
*
* @return Number of ticks from ticks_from to ticks_to.
*/
uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
uint32_t ticks_from);
/**@brief Function for getting the maximum observed operation queue utilization.
*
* Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage.
*
* @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality.
*
* @return Maximum number of events in queue observed so far.
*/
uint8_t app_timer_op_queue_utilization_get(void);
/**
* @brief Function for pausing RTC activity which drives app_timer.
*
* @note This function can be used for debugging purposes to ensure
* that application is halted when entering a breakpoint.
*/
void app_timer_pause(void);
/**
* @brief Function for resuming RTC activity which drives app_timer.
*
* @note This function can be used for debugging purposes to resume
* application activity.
*/
void app_timer_resume(void);
#ifdef __cplusplus
}
#endif
#endif // APP_TIMER_H__
/** @} */

View File

@ -0,0 +1,262 @@
/**
* Copyright (c) 2013 - 2019, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, 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. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
*
*/
/**@file
*
* @defgroup app_uart UART module
* @{
* @ingroup app_common
*
* @brief UART module interface.
*/
#ifndef APP_UART_H__
#define APP_UART_H__
#include <stdint.h>
#include <stdbool.h>
#include "app_util_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
/**@brief UART Flow Control modes for the peripheral.
*/
typedef enum
{
APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */
APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */
} app_uart_flow_control_t;
/**@brief UART communication structure holding configuration settings for the peripheral.
*/
typedef struct
{
uint32_t rx_pin_no; /**< RX pin number. */
uint32_t tx_pin_no; /**< TX pin number. */
uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */
bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
uint32_t baud_rate; /**< Baud rate configuration. */
} app_uart_comm_params_t;
/**@brief UART buffer for transmitting/receiving data.
*/
typedef struct
{
uint8_t * rx_buf; /**< Pointer to the RX buffer. */
uint32_t rx_buf_size; /**< Size of the RX buffer. */
uint8_t * tx_buf; /**< Pointer to the TX buffer. */
uint32_t tx_buf_size; /**< Size of the TX buffer. */
} app_uart_buffers_t;
/**@brief Enumeration which defines events used by the UART module upon data reception or error.
*
* @details The event type is used to indicate the type of additional information in the event
* @ref app_uart_evt_t.
*/
typedef enum
{
APP_UART_DATA_READY, /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */
APP_UART_FIFO_ERROR, /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */
APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
APP_UART_TX_EMPTY, /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */
APP_UART_DATA, /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
} app_uart_evt_type_t;
/**@brief Struct containing events from the UART module.
*
* @details The app_uart_evt_t is used to notify the application of asynchronous events when data
* are received on the UART peripheral or in case an error occured during data reception.
*/
typedef struct
{
app_uart_evt_type_t evt_type; /**< Type of event. */
union
{
uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
uint32_t error_code; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
uint8_t value; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
} data;
} app_uart_evt_t;
/**@brief Function for handling app_uart event callback.
*
* @details Upon an event in the app_uart module this callback function will be called to notify
* the application about the event.
*
* @param[in] p_app_uart_event Pointer to UART event.
*/
typedef void (* app_uart_event_handler_t) (app_uart_evt_t * p_app_uart_event);
/**@brief Macro for safe initialization of the UART module in a single user instance when using
* a FIFO together with UART.
*
* @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
* @param[in] RX_BUF_SIZE Size of desired RX buffer, must be a power of 2 or ZERO (No FIFO).
* @param[in] TX_BUF_SIZE Size of desired TX buffer, must be a power of 2 or ZERO (No FIFO).
* @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
* UART module.
* @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
* @param[out] ERR_CODE The return value of the UART initialization function will be
* written to this parameter.
*
* @note Since this macro allocates a buffer and registers the module as a GPIOTE user when flow
* control is enabled, it must only be called once.
*/
#define APP_UART_FIFO_INIT(P_COMM_PARAMS, RX_BUF_SIZE, TX_BUF_SIZE, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
do \
{ \
app_uart_buffers_t buffers; \
static uint8_t rx_buf[RX_BUF_SIZE]; \
static uint8_t tx_buf[TX_BUF_SIZE]; \
\
buffers.rx_buf = rx_buf; \
buffers.rx_buf_size = sizeof (rx_buf); \
buffers.tx_buf = tx_buf; \
buffers.tx_buf_size = sizeof (tx_buf); \
ERR_CODE = app_uart_init(P_COMM_PARAMS, &buffers, EVT_HANDLER, IRQ_PRIO); \
} while (0)
/**@brief Macro for safe initialization of the UART module in a single user instance.
*
* @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
* @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
* UART module.
* @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
* @param[out] ERR_CODE The return value of the UART initialization function will be
* written to this parameter.
*
* @note Since this macro allocates registers the module as a GPIOTE user when flow control is
* enabled, it must only be called once.
*/
#define APP_UART_INIT(P_COMM_PARAMS, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
do \
{ \
ERR_CODE = app_uart_init(P_COMM_PARAMS, NULL, EVT_HANDLER, IRQ_PRIO); \
} while (0)
/**@brief Function for initializing the UART module. Use this initialization when several instances of the UART
* module are needed.
*
*
* @note Normally single initialization should be done using the APP_UART_INIT() or
* APP_UART_INIT_FIFO() macro depending on whether the FIFO should be used by the UART, as
* that will allocate the buffers needed by the UART module (including aligning the buffer
* correctly).
* @param[in] p_comm_params Pin and communication parameters.
* @param[in] p_buffers RX and TX buffers, NULL is FIFO is not used.
* @param[in] error_handler Function to be called in case of an error.
* @param[in] irq_priority Interrupt priority level.
*
* @retval NRF_SUCCESS If successful initialization.
* @retval NRF_ERROR_INVALID_LENGTH If a provided buffer is not a power of two.
* @retval NRF_ERROR_NULL If one of the provided buffers is a NULL pointer.
*
* The below errors are propagated by the UART module to the caller upon registration when Hardware
* Flow Control is enabled. When Hardware Flow Control is not used, these errors cannot occur.
* @retval NRF_ERROR_INVALID_STATE The GPIOTE module is not in a valid state when registering
* the UART module as a user.
* @retval NRF_ERROR_INVALID_PARAM The UART module provides an invalid callback function when
* registering the UART module as a user.
* Or the value pointed to by *p_uart_uid is not a valid
* GPIOTE number.
* @retval NRF_ERROR_NO_MEM GPIOTE module has reached the maximum number of users.
*/
uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
app_uart_buffers_t * p_buffers,
app_uart_event_handler_t error_handler,
app_irq_priority_t irq_priority);
/**@brief Function for getting a byte from the UART.
*
* @details This function will get the next byte from the RX buffer. If the RX buffer is empty
* an error code will be returned and the app_uart module will generate an event upon
* reception of the first byte which is added to the RX buffer.
*
* @param[out] p_byte Pointer to an address where next byte received on the UART will be copied.
*
* @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided.
* @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module.
*/
uint32_t app_uart_get(uint8_t * p_byte);
/**@brief Function for putting a byte on the UART.
*
* @details This call is non-blocking.
*
* @param[in] byte Byte to be transmitted on the UART.
*
* @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission.
* @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer.
* NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal
* is high for a long period and the buffer fills up.
* @retval NRF_ERROR_INTERNAL If UART driver reported error.
*/
uint32_t app_uart_put(uint8_t byte);
/**@brief Function for flushing the RX and TX buffers (Only valid if FIFO is used).
* This function does nothing if FIFO is not used.
*
* @retval NRF_SUCCESS Flushing completed (Current implementation will always succeed).
*/
uint32_t app_uart_flush(void);
/**@brief Function for closing the UART module.
*
* @retval NRF_SUCCESS If successfully closed.
* @retval NRF_ERROR_INVALID_PARAM If an invalid user id is provided or the user id differs from
* the current active user.
*/
uint32_t app_uart_close(void);
#ifdef __cplusplus
}
#endif
#endif //APP_UART_H__
/** @} */

Some files were not shown because too many files have changed in this diff Show More