From 29bff3c88a29dd8d2a1207c82e1fc09272ea77ac Mon Sep 17 00:00:00 2001 From: "biii.in" Date: Tue, 15 Jun 2021 19:50:38 +0530 Subject: [PATCH 1/7] 0.7.63_rc1 --- .travis.yml | 45 + .../drivers_nrf/clock/nrf_drv_clock.c | 496 +++++++++ .../drivers_nrf/clock/nrf_drv_clock.h | 263 +++++ .../drivers_nrf/common/nrf_drv_common.c | 225 ++++ .../drivers_nrf/common/nrf_drv_common.h | 211 ++++ .../drivers_nrf/config/nrf_drv_config.h | 481 +++++++++ .../config/nrf_drv_config_validation.h | 100 ++ .../SDK/components/drivers_nrf/hal/nrf_adc.c | 95 ++ .../SDK/components/drivers_nrf/hal/nrf_adc.h | 433 ++++++++ .../components/drivers_nrf/hal/nrf_clock.h | 431 ++++++++ .../SDK/components/drivers_nrf/hal/nrf_comp.h | 486 +++++++++ .../SDK/components/drivers_nrf/hal/nrf_ecb.c | 92 ++ .../SDK/components/drivers_nrf/hal/nrf_ecb.h | 85 ++ .../SDK/components/drivers_nrf/hal/nrf_egu.h | 303 ++++++ .../SDK/components/drivers_nrf/hal/nrf_gpio.h | 664 ++++++++++++ .../components/drivers_nrf/hal/nrf_gpiote.h | 408 ++++++++ .../SDK/components/drivers_nrf/hal/nrf_i2s.h | 540 ++++++++++ .../components/drivers_nrf/hal/nrf_lpcomp.h | 384 +++++++ .../SDK/components/drivers_nrf/hal/nrf_nvmc.c | 136 +++ .../SDK/components/drivers_nrf/hal/nrf_nvmc.h | 108 ++ .../SDK/components/drivers_nrf/hal/nrf_pdm.h | 376 +++++++ .../SDK/components/drivers_nrf/hal/nrf_ppi.h | 419 ++++++++ .../SDK/components/drivers_nrf/hal/nrf_pwm.h | 678 ++++++++++++ .../SDK/components/drivers_nrf/hal/nrf_qdec.h | 485 +++++++++ .../SDK/components/drivers_nrf/hal/nrf_rng.h | 228 +++++ .../SDK/components/drivers_nrf/hal/nrf_rtc.h | 321 ++++++ .../components/drivers_nrf/hal/nrf_saadc.c | 48 + .../components/drivers_nrf/hal/nrf_saadc.h | 571 +++++++++++ .../SDK/components/drivers_nrf/hal/nrf_spi.h | 351 +++++++ .../SDK/components/drivers_nrf/hal/nrf_spim.h | 537 ++++++++++ .../SDK/components/drivers_nrf/hal/nrf_spis.h | 529 ++++++++++ .../SDK/components/drivers_nrf/hal/nrf_temp.h | 72 ++ .../components/drivers_nrf/hal/nrf_timer.h | 593 +++++++++++ .../SDK/components/drivers_nrf/hal/nrf_twi.h | 419 ++++++++ .../SDK/components/drivers_nrf/hal/nrf_twim.h | 495 +++++++++ .../SDK/components/drivers_nrf/hal/nrf_twis.h | 693 +++++++++++++ .../SDK/components/drivers_nrf/hal/nrf_uart.h | 488 +++++++++ .../components/drivers_nrf/hal/nrf_uarte.h | 551 ++++++++++ .../SDK/components/drivers_nrf/hal/nrf_wdt.h | 316 ++++++ .../components/libraries/trace/app_trace.c | 60 ++ .../components/libraries/trace/app_trace.h | 84 ++ .../SDK/components/libraries/util/app_error.c | 141 +++ .../SDK/components/libraries/util/app_error.h | 218 ++++ .../libraries/util/app_error_weak.c | 70 ++ .../libraries/util/app_error_weak.h | 68 ++ .../SDK/components/libraries/util/app_util.h | 510 +++++++++ .../components/libraries/util/app_util_bds.h | 430 ++++++++ .../libraries/util/app_util_platform.c | 77 ++ .../libraries/util/app_util_platform.h | 228 +++++ .../SDK/components/libraries/util/common.h | 55 + .../components/libraries/util/nordic_common.h | 126 +++ .../components/libraries/util/nrf_assert.c | 45 + .../components/libraries/util/nrf_assert.h | 80 ++ .../SDK/components/libraries/util/nrf_log.c | 453 ++++++++ .../SDK/components/libraries/util/nrf_log.h | 728 +++++++++++++ .../components/libraries/util/sdk_common.h | 191 ++++ .../components/libraries/util/sdk_errors.h | 132 +++ .../components/libraries/util/sdk_macros.h | 89 ++ .../libraries/util/sdk_mapped_flags.c | 178 ++++ .../libraries/util/sdk_mapped_flags.h | 170 +++ .../SDK/components/libraries/util/sdk_os.h | 57 ++ .../components/libraries/util/sdk_resources.h | 68 ++ .../nfc/ndef/generic/message/nfc_ndef_msg.c | 127 +++ .../nfc/ndef/generic/message/nfc_ndef_msg.h | 165 +++ .../nfc/ndef/generic/record/nfc_ndef_record.c | 157 +++ .../nfc/ndef/generic/record/nfc_ndef_record.h | 283 +++++ .../nfc/ndef/launchapp/nfc_launchapp_msg.c | 135 +++ .../nfc/ndef/launchapp/nfc_launchapp_msg.h | 81 ++ .../nfc/ndef/launchapp/nfc_launchapp_rec.c | 151 +++ .../nfc/ndef/launchapp/nfc_launchapp_rec.h | 82 ++ .../ndef/parser/message/nfc_ndef_msg_parser.c | 76 ++ .../ndef/parser/message/nfc_ndef_msg_parser.h | 104 ++ .../message/nfc_ndef_msg_parser_local.c | 151 +++ .../message/nfc_ndef_msg_parser_local.h | 148 +++ .../parser/record/nfc_ndef_parser_logger.h | 53 + .../parser/record/nfc_ndef_record_parser.c | 266 +++++ .../parser/record/nfc_ndef_record_parser.h | 81 ++ .../components/nfc/ndef/text/nfc_text_rec.c | 91 ++ .../components/nfc/ndef/text/nfc_text_rec.h | 141 +++ .../SDK/components/nfc/ndef/uri/nfc_uri_msg.c | 114 +++ .../SDK/components/nfc/ndef/uri/nfc_uri_msg.h | 76 ++ .../SDK/components/nfc/ndef/uri/nfc_uri_rec.c | 99 ++ .../SDK/components/nfc/ndef/uri/nfc_uri_rec.h | 113 ++ .../nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c | 876 ++++++++++++++++ .../nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h | 173 ++++ .../nfc/t2t_lib/hal_t2t/hal_nfc_t2t_logger.h | 37 + .../nfc/t2t_lib/licence_agreement.txt | 36 + .../SDK/components/nfc/t2t_lib/nfc_fixes.h | 77 ++ .../SDK/components/nfc/t2t_lib/nfc_t2t_lib.h | 251 +++++ .../components/nfc/t2t_lib/nfc_t2t_lib_gcc.a | Bin 0 -> 5566 bytes .../nfc/t2t_parser/nfc_t2t_parser.c | 677 ++++++++++++ .../nfc/t2t_parser/nfc_t2t_parser.h | 176 ++++ .../components/nfc/t2t_parser/nfc_tlv_block.h | 83 ++ .../softdevice/s132/hex/sfe_nrf52832_dfu.hex | 964 ++++++++++++++++++ dist/package_nRF5_b_boards_index.json | 829 +++++++++++++++ libraries/BADC/BADC.cpp | 124 +++ libraries/BADC/BADC.h | 59 ++ libraries/BADC/examples/AdcScan/AdcScan.ino | 45 + .../BADC/examples/tempMonitor/tempMonitor.ino | 24 + .../BADC/examples/vddMonitor/vddMonitor.ino | 37 + libraries/BADC/keywords.txt | 29 + libraries/BADC/library.properties | 9 + libraries/BLPCOMP/BLPCOMP.cpp | 56 + libraries/BLPCOMP/BLPCOMP.h | 72 ++ .../examples/lpcomp_test/lpcomp_test.ino | 33 + libraries/BLPCOMP/keywords.txt | 42 + libraries/BLPCOMP/library.properties | 9 + libraries/BRTC/BRTC.cpp | 220 ++++ libraries/BRTC/BRTC.h | 93 ++ libraries/BRTC/examples/rtc_tick/rtc_tick.ino | 55 + libraries/BRTC/keywords.txt | 24 + libraries/BRTC/library.properties | 9 + libraries/NFC/NFC.cpp | 138 +++ libraries/NFC/NFC.h | 128 +++ libraries/NFC/examples/SendText/SendText.ino | 30 + libraries/NFC/examples/SendURL/SendURL.ino | 62 ++ libraries/NFC/examples/StartApp/StartApp.ino | 46 + libraries/NFC/keywords.txt | 24 + libraries/NFC/library.properties | 9 + variants/I.ONIX_TypeC/pins_arduino.h | 17 + variants/I.ONIX_TypeC/variant.cpp | 55 + variants/I.ONIX_TypeC/variant.h | 87 ++ .../SparkFun_nRF52832_Breakout/pins_arduino.h | 17 + .../SparkFun_nRF52832_Breakout/variant.cpp | 55 + variants/SparkFun_nRF52832_Breakout/variant.h | 116 +++ 125 files changed, 27011 insertions(+) create mode 100644 .travis.yml create mode 100644 cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config_validation.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_clock.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_comp.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_egu.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpio.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpiote.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_i2s.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_lpcomp.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pdm.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ppi.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pwm.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_qdec.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rng.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rtc.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.c create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spi.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spim.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spis.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_temp.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_timer.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twi.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twim.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twis.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uart.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uarte.h create mode 100644 cores/nRF5/SDK/components/drivers_nrf/hal/nrf_wdt.h create mode 100644 cores/nRF5/SDK/components/libraries/trace/app_trace.c create mode 100644 cores/nRF5/SDK/components/libraries/trace/app_trace.h create mode 100644 cores/nRF5/SDK/components/libraries/util/app_error.c create mode 100644 cores/nRF5/SDK/components/libraries/util/app_error.h create mode 100644 cores/nRF5/SDK/components/libraries/util/app_error_weak.c create mode 100644 cores/nRF5/SDK/components/libraries/util/app_error_weak.h create mode 100644 cores/nRF5/SDK/components/libraries/util/app_util.h create mode 100644 cores/nRF5/SDK/components/libraries/util/app_util_bds.h create mode 100644 cores/nRF5/SDK/components/libraries/util/app_util_platform.c create mode 100644 cores/nRF5/SDK/components/libraries/util/app_util_platform.h create mode 100644 cores/nRF5/SDK/components/libraries/util/common.h create mode 100644 cores/nRF5/SDK/components/libraries/util/nordic_common.h create mode 100644 cores/nRF5/SDK/components/libraries/util/nrf_assert.c create mode 100644 cores/nRF5/SDK/components/libraries/util/nrf_assert.h create mode 100644 cores/nRF5/SDK/components/libraries/util/nrf_log.c create mode 100644 cores/nRF5/SDK/components/libraries/util/nrf_log.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_common.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_errors.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_macros.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.c create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_os.h create mode 100644 cores/nRF5/SDK/components/libraries/util/sdk_resources.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_parser_logger.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.h create mode 100644 cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.c create mode 100644 cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t_logger.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/licence_agreement.txt create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/nfc_fixes.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a create mode 100644 cores/nRF5/SDK/components/nfc/t2t_parser/nfc_t2t_parser.c create mode 100644 cores/nRF5/SDK/components/nfc/t2t_parser/nfc_t2t_parser.h create mode 100644 cores/nRF5/SDK/components/nfc/t2t_parser/nfc_tlv_block.h create mode 100644 cores/nRF5/SDK/components/softdevice/s132/hex/sfe_nrf52832_dfu.hex create mode 100644 dist/package_nRF5_b_boards_index.json create mode 100644 libraries/BADC/BADC.cpp create mode 100644 libraries/BADC/BADC.h create mode 100644 libraries/BADC/examples/AdcScan/AdcScan.ino create mode 100644 libraries/BADC/examples/tempMonitor/tempMonitor.ino create mode 100644 libraries/BADC/examples/vddMonitor/vddMonitor.ino create mode 100644 libraries/BADC/keywords.txt create mode 100644 libraries/BADC/library.properties create mode 100644 libraries/BLPCOMP/BLPCOMP.cpp create mode 100644 libraries/BLPCOMP/BLPCOMP.h create mode 100644 libraries/BLPCOMP/examples/lpcomp_test/lpcomp_test.ino create mode 100644 libraries/BLPCOMP/keywords.txt create mode 100644 libraries/BLPCOMP/library.properties create mode 100644 libraries/BRTC/BRTC.cpp create mode 100644 libraries/BRTC/BRTC.h create mode 100644 libraries/BRTC/examples/rtc_tick/rtc_tick.ino create mode 100644 libraries/BRTC/keywords.txt create mode 100644 libraries/BRTC/library.properties create mode 100644 libraries/NFC/NFC.cpp create mode 100644 libraries/NFC/NFC.h create mode 100644 libraries/NFC/examples/SendText/SendText.ino create mode 100644 libraries/NFC/examples/SendURL/SendURL.ino create mode 100644 libraries/NFC/examples/StartApp/StartApp.ino create mode 100644 libraries/NFC/keywords.txt create mode 100644 libraries/NFC/library.properties create mode 100644 variants/I.ONIX_TypeC/pins_arduino.h create mode 100644 variants/I.ONIX_TypeC/variant.cpp create mode 100644 variants/I.ONIX_TypeC/variant.h create mode 100644 variants/SparkFun_nRF52832_Breakout/pins_arduino.h create mode 100644 variants/SparkFun_nRF52832_Breakout/variant.cpp create mode 100644 variants/SparkFun_nRF52832_Breakout/variant.h diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..c576ed57 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,45 @@ +language: generic +addons: + apt: + packages: + - libc6:i386 + - libstdc++6:i386 +env: + global: + - IDE_VERSION=1.8.5 +before_install: + - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz + - tar xf arduino-$IDE_VERSION-linux64.tar.xz + - mv arduino-$IDE_VERSION $HOME/arduino-ide + - export PATH=$PATH:$HOME/arduino-ide + - arduino --pref "boardsmanager.additional.urls=https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json" --install-boards sandeepmistry:nRF5 > /dev/null + - buildExampleSketch() { arduino --verbose-build --verify --board $1 $HOME/arduino-ide/examples/$2/$3/$3.ino; } +install: + - mkdir -p $HOME/Arduino/hardware/sandeepmistry + - ln -s $PWD $HOME/Arduino/hardware/sandeepmistry/nRF5 +script: + - buildExampleSketch sandeepmistry:nRF5:nRF52DK 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:BluzDK 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:BLENano:version=1_0 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:RedBearLab_nRF51822:version=1_0 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:BBCmicrobit 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:CalliopeMini 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Generic_nRF51822:chip=xxac 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Generic_nRF52832 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:OSHChip 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:STCT_nRF52_minidev 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:PCA1000X:board_variant=pca10000 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:PCA1000X:board_variant=pca10001 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:PCA1000X:board_variant=nrf6310 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:nRF51Dongle:version=1_1_0 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Blend2 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:BLENano2 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:TinyBLE 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:bluey 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:hackaBLE 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:hackaBLE_v2 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Sinobit 01.Basics BareMinimum + - buildExampleSketch sandeepmistry:nRF5:DWM1001-DEV 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:SeeedArchLink 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:Generic_nRF52833 01.Basics Blink + - buildExampleSketch sandeepmistry:nRF5:BBCmicrobitV2 01.Basics Blink diff --git a/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.c b/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.c new file mode 100644 index 00000000..929eae2e --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.c @@ -0,0 +1,496 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_drv_clock.h" +#include "nrf_error.h" +#include "nordic_common.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#include "nrf_soc.h" +#include "app_util_platform.h" +#else +#include "app_util_platform.h" +#endif // SOFTDEVICE_PRESENT + +/*lint -save -e652 */ +#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC +#define NRF_CLOCK_LFCLK_Xtal CLOCK_LFCLKSRC_SRC_Xtal +#define NRF_CLOCK_LFCLK_Synth CLOCK_LFCLKSRC_SRC_Synth +/*lint -restore */ + +#define INT_MAX 0xFFFFFFFF + +#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC) && !defined(SOFTDEVICE_PRESENT) +#define CALIBRATION_SUPPORT 1 +#else +#define CALIBRATION_SUPPORT 0 +#endif +typedef enum +{ + CAL_STATE_IDLE, + CAL_STATE_CT, + CAL_STATE_HFCLK_REQ, + CAL_STATE_CAL, + CAL_STATE_ABORT, +} nrf_drv_clock_cal_state_t; + +/**@brief CLOCK control block. */ +typedef struct +{ + volatile uint32_t hfclk_requests; /*< High-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_hf_head; + bool module_initialized; /*< Indicate the state of module */ + volatile bool hfclk_on; /*< High-frequency clock state. */ +#ifndef SOFTDEVICE_PRESENT + volatile bool lfclk_on; /*< Low-frequency clock state. */ + uint32_t lfclk_requests; /*< Low-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_lf_head; +#if CALIBRATION_SUPPORT + nrf_drv_clock_handler_item_t cal_hfclk_started_handler_item; + nrf_drv_clock_event_handler_t cal_done_handler; + volatile nrf_drv_clock_cal_state_t cal_state; +#endif //CALIBRATION_SUPPORT +#endif //SOFTDEVICE_PRESENT +}nrf_drv_clock_cb_t; + +static nrf_drv_clock_cb_t m_clock_cb; + +#ifndef SOFTDEVICE_PRESENT +/**@brief Function for starting LFCLK. This function will return immediately without waiting for start. + */ +static void lfclk_start(void) +{ + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); +} + +/**@brief Function for stopping LFCLK and calibration (if it was set up). + */ +static void lfclk_stop(void) +{ +#if CALIBRATION_SUPPORT + (void)nrf_drv_clock_calibration_abort(); +#endif //CALIBRATION_SUPPORT + + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); + while (nrf_clock_lf_is_running()) + {} +} +#endif +static void hfclk_start(void) +{ +#ifndef SOFTDEVICE_PRESENT + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +#else + UNUSED_VARIABLE(sd_clock_hfclk_request()); +#endif +} + +static void hfclk_stop(void) +{ +#ifndef SOFTDEVICE_PRESENT + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); + while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY)) + {} +#else + UNUSED_VARIABLE(sd_clock_hfclk_release()); +#endif +} + +ret_code_t nrf_drv_clock_init(void) +{ + uint32_t result = NRF_SUCCESS; + + if (m_clock_cb.module_initialized) + { + return MODULE_ALREADY_INITIALIZED; + } + + m_clock_cb.p_hf_head = NULL; + m_clock_cb.hfclk_requests = 0; +#ifndef SOFTDEVICE_PRESENT + m_clock_cb.p_lf_head = NULL; + m_clock_cb.lfclk_requests = 0; + nrf_clock_xtalfreq_set(CLOCK_CONFIG_XTAL_FREQ); + nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC); + nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY); +#if CALIBRATION_SUPPORT + m_clock_cb.cal_state = CAL_STATE_IDLE; +#endif // CALIBRATION_SUPPORT +#else // SOFTDEVICE_PRESENT + uint8_t is_enabled; + result = sd_softdevice_is_enabled(&is_enabled); + if((result == NRF_SUCCESS) && !is_enabled) + { + result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED; + } +#endif // SOFTDEVICE_PRESENT + m_clock_cb.module_initialized = true; + return result; +} + +void nrf_drv_clock_uninit(void) +{ + ASSERT(m_clock_cb.module_initialized); +#ifndef SOFTDEVICE_PRESENT + nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); + nrf_clock_int_disable(0xFFFFFFFF); + lfclk_stop(); +#endif + hfclk_stop(); + m_clock_cb.module_initialized = false; +} + +static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head, + nrf_drv_clock_handler_item_t * p_item) +{ + if (*p_head) + { + p_item->p_next = *p_head; + *p_head = p_item; + } + else + { + p_item->p_next = NULL; + *p_head = p_item; + } +} + +static nrf_drv_clock_handler_item_t * item_dequeue(nrf_drv_clock_handler_item_t ** p_head) +{ + nrf_drv_clock_handler_item_t * p_item = *p_head; + if (p_item) + { + *p_head = p_item->p_next; + } + + return p_item; +} + +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) +{ + ASSERT(m_clock_cb.module_initialized); +#ifndef SOFTDEVICE_PRESENT + ASSERT(m_clock_cb.lfclk_requests != INT_MAX); + CRITICAL_REGION_ENTER(); + if (m_clock_cb.lfclk_on) + { + if (p_handler_item) + { + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); + } + } + else + { + + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, p_handler_item); + } + if (m_clock_cb.lfclk_requests == 0) + { + lfclk_start(); + } + } + m_clock_cb.lfclk_requests++; + CRITICAL_REGION_EXIT(); +#else + if (p_handler_item) + { + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); + } +#endif // SOFTDEVICE_PRESENT +} + + +void nrf_drv_clock_lfclk_release(void) +{ + ASSERT(m_clock_cb.module_initialized); +#ifndef SOFTDEVICE_PRESENT + ASSERT(m_clock_cb.lfclk_requests > 0); + + CRITICAL_REGION_ENTER(); + m_clock_cb.lfclk_requests--; + if (m_clock_cb.lfclk_requests == 0) + { + lfclk_stop(); + m_clock_cb.lfclk_on = false; + m_clock_cb.p_lf_head = NULL; + } + CRITICAL_REGION_EXIT(); +#endif // SOFTDEVICE_PRESENT +} + + +bool nrf_drv_clock_lfclk_is_running(void) +{ + ASSERT(m_clock_cb.module_initialized); + bool result; +#ifndef SOFTDEVICE_PRESENT + result = nrf_clock_lf_is_running(); +#else + result = true; +#endif + return result; +} + +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) +{ + ASSERT(m_clock_cb.module_initialized); + ASSERT(m_clock_cb.hfclk_requests != INT_MAX); + + CRITICAL_REGION_ENTER(); + if (m_clock_cb.hfclk_on) + { + if (p_handler_item) + { + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } + } + else + { + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, p_handler_item); + } + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_start(); + } + } + m_clock_cb.hfclk_requests++; + CRITICAL_REGION_EXIT(); +} + +void nrf_drv_clock_hfclk_release(void) +{ + ASSERT(m_clock_cb.module_initialized); + ASSERT(m_clock_cb.hfclk_requests > 0); + + //disable interrupts CLOCK or SoftDevice events + CRITICAL_REGION_ENTER(); + m_clock_cb.hfclk_requests--; + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_stop(); + m_clock_cb.hfclk_on = false; + m_clock_cb.p_hf_head = NULL; + } + CRITICAL_REGION_EXIT(); + //enable interrupts CLOCK or SoftDevice events +} + +bool nrf_drv_clock_hfclk_is_running(void) +{ + bool result; + ASSERT(m_clock_cb.module_initialized); +#ifndef SOFTDEVICE_PRESENT + result = nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +#else + uint32_t is_running; + UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running)); + result = is_running ? true : false; +#endif + return result; +} + +#if CALIBRATION_SUPPORT +static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event) +{ + if (m_clock_cb.cal_state == CAL_STATE_ABORT) + { + nrf_drv_clock_hfclk_release(); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + } + else + { + nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK); + m_clock_cb.cal_state = CAL_STATE_CAL; + nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); + } +} +#endif + +ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event_handler_t handler) +{ +#if CALIBRATION_SUPPORT + ASSERT(m_clock_cb.cal_state == CAL_STATE_IDLE); + ret_code_t ret = NRF_SUCCESS; + if (m_clock_cb.lfclk_on == false) + { + ret = NRF_ERROR_INVALID_STATE; + } + else if (m_clock_cb.cal_state == CAL_STATE_IDLE) + { + m_clock_cb.cal_done_handler = handler; + m_clock_cb.cal_hfclk_started_handler_item.event_handler = clock_calibration_hf_started; + if (interval == 0) + { + m_clock_cb.cal_state = CAL_STATE_HFCLK_REQ; + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } + else + { + m_clock_cb.cal_state = CAL_STATE_CT; + nrf_clock_cal_timer_timeout_set(interval); + nrf_clock_int_enable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART); + } + } + else + { + ret = NRF_ERROR_BUSY; + } + return ret; +#else //CALIBRATION_SUPPORT + return NRF_ERROR_FORBIDDEN; +#endif +} + + +ret_code_t nrf_drv_clock_calibration_abort(void) +{ +#if CALIBRATION_SUPPORT + CRITICAL_REGION_ENTER(); + switch(m_clock_cb.cal_state) + { + case CAL_STATE_CT: + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + break; + case CAL_STATE_HFCLK_REQ: + /* fall through. */ + case CAL_STATE_CAL: + m_clock_cb.cal_state = CAL_STATE_ABORT; + break; + default: + break; + } + CRITICAL_REGION_EXIT(); + return NRF_SUCCESS; +#else //CALIBRATION_SUPPORT + return NRF_ERROR_FORBIDDEN; +#endif +} + +ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating) +{ +#if CALIBRATION_SUPPORT + ASSERT(m_clock_cb.module_initialized); + *p_is_calibrating = (m_clock_cb.cal_state != CAL_STATE_IDLE); + return NRF_SUCCESS; +#else //CALIBRATION_SUPPORT + return NRF_ERROR_FORBIDDEN; +#endif +} + +static __INLINE void clock_clk_started_notify(nrf_drv_clock_handler_item_t **p_head, + nrf_drv_clock_evt_type_t evt_type) +{ + while(1) + { + nrf_drv_clock_handler_item_t * p_item = item_dequeue(p_head); + if (p_item) + { + p_item->event_handler(evt_type); + } + else + { + break; + } + } +} + +#ifndef SOFTDEVICE_PRESENT +void POWER_CLOCK_IRQHandler(void) +{ + if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); + m_clock_cb.hfclk_on = true; + clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } + if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); + m_clock_cb.lfclk_on = true; + clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, NRF_DRV_CLOCK_EVT_LFCLK_STARTED); + } +#if CALIBRATION_SUPPORT + if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } + + if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); + nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK); + + nrf_drv_clock_hfclk_release(); + nrf_drv_clock_evt_type_t evt_type = (m_clock_cb.cal_state == CAL_STATE_ABORT) ? + NRF_DRV_CLOCK_EVT_CAL_ABORTED : NRF_DRV_CLOCK_EVT_CAL_DONE; + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(evt_type); + } + } +#endif //CALIBRATION_SUPPORT +} +#else +void nrf_drv_clock_on_soc_event(uint32_t evt_id) +{ + if (evt_id == NRF_EVT_HFCLKSTARTED) + { + clock_clk_started_notify((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } +} +#endif // SOFTDEVICE_PRESENT + +#undef NRF_CLOCK_LFCLK_RC +#undef NRF_CLOCK_LFCLK_Xtal +#undef NRF_CLOCK_LFCLK_Synth diff --git a/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.h b/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.h new file mode 100644 index 00000000..1ee25951 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/clock/nrf_drv_clock.h @@ -0,0 +1,263 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_DRV_CLOCK_H__ +#define NRF_DRV_CLOCK_H__ + +#include +#include +#include "sdk_errors.h" +#include "nrf_assert.h" +#include "nrf_clock.h" +#include "nrf_drv_config.h" +#include "nrf_drv_common.h" + +/** + * + * @addtogroup nrf_clock Clock HAL and driver + * @ingroup nrf_drivers + * @brief Clock APIs. + * @details The clock HAL provides basic APIs for accessing the registers of the clock. + * The clock driver provides APIs on a higher level. + * + * @defgroup nrf_clock_drv Clock driver + * @{ + * @ingroup nrf_clock + * @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK). + */ + +/** + * @brief Clock events. + */ +typedef enum +{ + NRF_DRV_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started. + NRF_DRV_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started. + NRF_DRV_CLOCK_EVT_CAL_DONE, ///< Calibration is done. + NRF_DRV_CLOCK_EVT_CAL_ABORTED, ///< Calibration has been aborted. +} nrf_drv_clock_evt_type_t; + +/** + * @brief Clock event handler. + * + * @param[in] event Event. + */ +typedef void (*nrf_drv_clock_event_handler_t)(nrf_drv_clock_evt_type_t event); + +// Forward declaration of the nrf_drv_clock_handler_item_t type. +typedef struct nrf_drv_clock_handler_item_s nrf_drv_clock_handler_item_t; + +struct nrf_drv_clock_handler_item_s +{ + nrf_drv_clock_handler_item_t * p_next; ///< A pointer to the next handler that should be called when the clock is started. + nrf_drv_clock_event_handler_t event_handler; ///< Function to be called when the clock is started. +}; + +/** + * @brief Function for initializing the nrf_drv_clock module. + * + * After initialization, the module is in power off state (clocks are not requested). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval MODULE_ALREADY_INITIALIZED If the driver was already initialized. + * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED If the SoftDevice was not enabled. + */ +ret_code_t nrf_drv_clock_init(void); + +/** + * @brief Function for uninitializing the clock module. + * + */ +void nrf_drv_clock_uninit(void); + +/** + * @brief Function for requesting the LFCLK. + * + * The low-frequency clock can be requested by different modules + * or contexts. The driver ensures that the clock will be started only when it is requested + * the first time. If the clock is not ready but it was already started, the handler item that is + * provided as an input parameter is added to the list of handlers that will be notified + * when the clock is started. If the clock is already enabled, user callback is called from the + * current context. + * + * The first request will start the selected LFCLK source. If an event handler is + * provided, it will be called once the LFCLK is started. If the LFCLK was already started at this + * time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_lfclk_is_running function can be polled to check if the clock has started. + * + * @note When a SoftDevice is enabled, the LFCLK is always running and the driver cannot control it. + * + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. + */ +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); + +/** + * @brief Function for releasing the LFCLK. + * + * If there are no more requests, the LFCLK source will be stopped. + * + * @note When a SoftDevice is enabled, the LFCLK is always running. + */ +void nrf_drv_clock_lfclk_release(void); + +/** + * @brief Function for checking the LFCLK state. + * + * @retval true If the LFCLK is running. + * @retval false If the LFCLK is not running. + */ +bool nrf_drv_clock_lfclk_is_running(void); + +/** + * @brief Function for requesting the high-accuracy source HFCLK. + * + * The high-accuracy source + * can be requested by different modules or contexts. The driver ensures that the high-accuracy + * clock will be started only when it is requested the first time. If the clock is not ready + * but it was already started, the handler item that is provided as an input parameter is added + * to the list of handlers that will be notified when the clock is started. + * + * If an event handler is provided, it will be called once the clock is started. If the clock was already + * started at this time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_hfclk_is_running function can be polled to check if the clock has started. + * + * @note If a SoftDevice is running, the clock is managed by the SoftDevice and all requests are handled by + * the SoftDevice. This function cannot be called from all interrupt priority levels in that case. + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. + */ +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); + +/** + * @brief Function for releasing the high-accuracy source HFCLK. + * + * If there are no more requests, the high-accuracy source will be released. + */ +void nrf_drv_clock_hfclk_release(void); + +/** + * @brief Function for checking the HFCLK state. + * + * @retval true If the HFCLK is running (for \nRFXX XTAL source). + * @retval false If the HFCLK is not running. + */ +bool nrf_drv_clock_hfclk_is_running(void); + +/** + * @brief Function for starting a single calibration process. + * + * This function can also delay the start of calibration by a user-specified value. The delay will use + * a low-power timer that is part of the CLOCK module. @ref nrf_drv_clock_is_calibrating can be called to + * check if calibration is still in progress. If a handler is provided, the user can be notified when + * calibration is completed. The ext calibration can be started from the handler context. + * + * The calibration process consists of three phases: + * - Delay (optional) + * - Requesting the high-accuracy HFCLK + * - Hardware-supported calibration + * + * @param[in] delay Time after which the calibration will be started (in 0.25 s units). + * @param[in] handler NULL or user function to be called when calibration is completed or aborted. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + * @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off. + * @retval NRF_ERROR_BUSY If calibration is in progress. + */ +ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_handler_t handler); + +/** + * @brief Function for aborting calibration. + * + * This function aborts on-going calibration. If calibration was started, it cannot be stopped. If a handler + * was provided by @ref nrf_drv_clock_calibration_start, this handler will be called once + * aborted calibration is completed. @ref nrf_drv_clock_is_calibrating can also be used to check + * if the system is calibrating. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + */ +ret_code_t nrf_drv_clock_calibration_abort(void); + +/** + * @brief Function for checking if calibration is in progress. + * + * This function indicates that the system is + * in calibration if it is in any of the calibration process phases (see @ref nrf_drv_clock_calibration_start). + * + * @param[out] p_is_calibrating True if calibration is in progress, false if not. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + */ +ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating); + +/**@brief Function for returning a requested task address for the clock driver module. + * + * @param[in] task One of the peripheral tasks. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task); + +/**@brief Function for returning a requested event address for the clock driver module. + * + * @param[in] event One of the peripheral events. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event); + +/** + * @brief Function called by the SoftDevice handler if an @ref nrf_soc event is received from the SoftDevice. + */ +#ifdef SOFTDEVICE_PRESENT +void nrf_drv_clock_on_soc_event(uint32_t evt_id); +#endif +/** + *@} + **/ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task) +{ + return nrf_clock_task_address_get(task); +} + +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event) +{ + return nrf_clock_event_address_get(event); +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION + +/*lint --flb "Leave library region" */ +#endif // NRF_CLOCK_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.c b/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.c new file mode 100644 index 00000000..c98f0685 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.c @@ -0,0 +1,225 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nrf_drv_common.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif + + +#if PERIPHERAL_RESOURCE_SHARING_ENABLED + +typedef struct { + nrf_drv_irq_handler_t handler; + bool acquired; +} shared_resource_t; + +// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0 +#if (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED) + #define SERIAL_BOX_0_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_0 + #define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0) + #endif + + static shared_resource_t m_serial_box_0 = { .acquired = false }; + void SPI0_TWI0_IRQHandler(void) + { + ASSERT(m_serial_box_0.handler); + m_serial_box_0.handler(); + } +#endif // (SPI0_ENABLED || SPIS0_ENABLED || TWI0_ENABLED || TWIS0_ENABLED) + +// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1 +#if (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED) + #define SERIAL_BOX_1_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_1 + #define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1) + #endif + + static shared_resource_t m_serial_box_1 = { .acquired = false }; + void SPI1_TWI1_IRQHandler(void) + { + ASSERT(m_serial_box_1.handler); + m_serial_box_1.handler(); + } +#endif // (SPI1_ENABLED || SPIS1_ENABLED || TWI1_ENABLED || TWIS1_ENABLED) + +// SPIM2, SPIS2, SPI2 +#if (SPI2_ENABLED || SPIS2_ENABLED) + #define SERIAL_BOX_2_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_2 + #define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2) + #endif + + static shared_resource_t m_serial_box_2 = { .acquired = false }; + void SPIM2_SPIS2_SPI2_IRQHandler(void) + { + ASSERT(m_serial_box_2.handler); + m_serial_box_2.handler(); + } +#endif // (SPI2_ENABLED || SPIS2_ENABLED) + +// COMP, LPCOMP +#if (COMP_ENABLED || LPCOMP_ENABLED) + #define COMP_LPCOMP_IN_USE + + #ifndef IS_COMP_LPCOMP + #define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP) + #endif + + static shared_resource_t m_comp_lpcomp = { .acquired = false }; + void LPCOMP_IRQHandler(void) + { + ASSERT(m_comp_lpcomp.handler); + m_comp_lpcomp.handler(); + } +#endif // (COMP_ENABLED || LPCOMP_ENABLED) + +#if defined(SERIAL_BOX_0_IN_USE) || \ + defined(SERIAL_BOX_1_IN_USE) || \ + defined(SERIAL_BOX_2_IN_USE) || \ + defined(COMP_LPCOMP_IN_USE) +static ret_code_t acquire_shared_resource(shared_resource_t * p_resource, + nrf_drv_irq_handler_t handler) +{ + bool busy = false; + + CRITICAL_REGION_ENTER(); + if (p_resource->acquired) + { + busy = true; + } + else + { + p_resource->acquired = true; + } + CRITICAL_REGION_EXIT(); + + if (busy) + { + return NRF_ERROR_BUSY; + } + + p_resource->handler = handler; + return NRF_SUCCESS; +} +#endif + +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_0, handler); + } +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_1, handler); + } +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_2, handler); + } +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + return acquire_shared_resource(&m_comp_lpcomp, handler); + } +#endif + + return NRF_ERROR_INVALID_PARAM; +} + +void nrf_drv_common_per_res_release(void const * p_per_base) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + m_serial_box_0.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + m_serial_box_1.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + m_serial_box_2.acquired = false; + } + else +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + m_comp_lpcomp.acquired = false; + } + else +#endif + + {} +} + +#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED + + +void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority) +{ + +#ifdef SOFTDEVICE_PRESENT + ASSERT((priority == APP_IRQ_PRIORITY_LOW) || (priority == APP_IRQ_PRIORITY_HIGH)); +#endif + + NVIC_SetPriority(IRQn, priority); + NVIC_ClearPendingIRQ(IRQn); + NVIC_EnableIRQ(IRQn); +} diff --git a/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.h b/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.h new file mode 100644 index 00000000..ccdaf51c --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/common/nrf_drv_common.h @@ -0,0 +1,211 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_DRV_COMMON_H__ +#define NRF_DRV_COMMON_H__ + +#include +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "nrf_drv_config.h" + + +/** + * @brief Offset of event registers in every peripheral instance + * + * This is the offset where event registers start in the every peripheral. + */ +#define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U + +/** + * @brief Driver state. + */ +typedef enum +{ + NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */ + NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */ + NRF_DRV_STATE_POWERED_ON +} nrf_drv_state_t; + +/** + * @brief Driver power state selection. + */ +typedef enum +{ + NRF_DRV_PWR_CTRL_ON, /**< Power on request. */ + NRF_DRV_PWR_CTRL_OFF /**< Power off request. */ +} nrf_drv_pwr_ctrl_t; + +/** + * @brief IRQ handler type. + */ +typedef void (*nrf_drv_irq_handler_t)(void); + + +#if PERIPHERAL_RESOURCE_SHARING_ENABLED + +/** + * @brief Function for acquiring shared peripheral resources associated with + * the specified peripheral. + * + * Certain resources and registers are shared among peripherals that have + * the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0). + * Only one of them can be utilized at a given time. This function reserves + * proper resources to be used by the specified peripheral. + * If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ + * handlers for peripherals that are sharing resources with others are + * implemented by the nrf_drv_common module instead of individual drivers. + * The drivers must then specify their interrupt handling routines and + * register them by using this function. + * + * @param[in] p_per_base Requested peripheral base pointer. + * @param[in] handler Interrupt handler to register. May be NULL + * if interrupts are not used for the peripheral. + * + * @retval NRF_SUCCESS If resources were acquired successfully. + * @retval NRF_ERROR_BUSY If resources were already acquired. + * @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled + * or the peripheral does not share resources + * with other peripherals. + */ +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler); + +/** + * @brief Function for releasing shared resources reserved previously by + * @ref nrf_drv_common_per_res_acquire() for the specified peripheral. + * + * @param[in] p_per_base Requested peripheral base pointer. + */ +void nrf_drv_common_per_res_release(void const * p_per_base); + +#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED + + +/** + * @brief Function sets priority and enables NVIC interrupt + * + * @note Function checks if correct priority is used when softdevice is present + * + * @param[in] IRQn Interrupt id + * @param[in] priority Interrupt priority + */ +void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority); + +/** + * @brief Function disables NVIC interrupt + * + * @param[in] IRQn Interrupt id + */ +__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn); + +/** + * @brief Convert bit position to event code + * + * Function for converting the bit position in INTEN register to event code + * that is equivalent to the offset of the event register from the beginning + * of peripheral instance. + * + * For example the result of this function can be casted directly to + * the types like @ref nrf_twis_event_t or @ref nrf_rng_events_t... + * + * @param bit Bit position in INTEN register + * @return Event code to be casted to the right enum type or to be used in functions like + * @ref nrf_rng_event_get + * + * @sa nrf_drv_event_to_bitpos + */ +__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit); + +/** + * @brief Convert event code to bit position + * + * This function can be used to get bit position in INTEN register from event code. + * + * @param event Event code that may be casted from enum values from types like + * @ref nrf_twis_event_t or @ref nrf_rng_events_t + * @return Bit position in INTEN register that corresponds to the given code. + * + * @sa nrf_drv_bitpos_to_event + */ +__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event); + +/** + * @brief Get interrupt number connected with given instance + * + * Function returns interrupt number for a given instance of any peripheral. + * @param[in] pinst Pointer to peripheral registry + * @return Interrupt number + */ +__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst); + +/** + * @brief Check if given object is in RAM + * + * Function for analyzing if given location is placed in RAM. + * This function is used to determine if we have address that can be supported by EasyDMA. + * @param[in] ptr Pointer to the object + * @retval true Object is located in RAM + * @retval false Object is not located in RAM + */ +__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn) +{ + NVIC_DisableIRQ(IRQn); +} + +__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit) +{ + return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t); +} + +__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event) +{ + return (event - NRF_DRV_COMMON_EVREGS_OFFSET) / sizeof(uint32_t); +} + +__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst) +{ + uint8_t ret = (uint8_t)((uint32_t)pinst>>12U); + return (IRQn_Type) ret; +} + +__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr) +{ + return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_DRV_COMMON_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config.h b/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config.h new file mode 100644 index 00000000..801a9d83 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config.h @@ -0,0 +1,481 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_DRV_CONFIG_H +#define NRF_DRV_CONFIG_H + +/** + * Provide a non-zero value here in applications that need to use several + * peripherals with the same ID that are sharing certain resources + * (for example, SPI0 and TWI0). Obviously, such peripherals cannot be used + * simultaneously. Therefore, this definition allows to initialize the driver + * for another peripheral from a given group only after the previously used one + * is uninitialized. Normally, this is not possible, because interrupt handlers + * are implemented in individual drivers. + * This functionality requires a more complicated interrupt handling and driver + * initialization, hence it is not always desirable to use it. + */ +#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 + +/* CLOCK */ +#define CLOCK_ENABLED 1//0 + +#if (CLOCK_ENABLED == 1) +#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default +#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LFCLK_Xtal +#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* GPIOTE */ +#define GPIOTE_ENABLED 0 + +#if (GPIOTE_ENABLED == 1) +#define GPIOTE_CONFIG_USE_SWI_EGU false +#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#endif + +/* TIMER */ +#define TIMER0_ENABLED 0 + +#if (TIMER0_ENABLED == 1) +#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit +#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER0_INSTANCE_INDEX 0 +#endif + +#define TIMER1_ENABLED 0 + +#if (TIMER1_ENABLED == 1) +#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) +#endif + +#define TIMER2_ENABLED 0 + +#if (TIMER2_ENABLED == 1) +#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) +#endif + +#define TIMER3_ENABLED 0 + +#if (TIMER3_ENABLED == 1) +#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) +#endif + +#define TIMER4_ENABLED 0 + +#if (TIMER4_ENABLED == 1) +#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz +#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer +#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit +#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) +#endif + + +#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) + +/* RTC */ +#define RTC0_ENABLED 0 + +#if (RTC0_ENABLED == 1) +#define RTC0_CONFIG_FREQUENCY 32678 +#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC0_CONFIG_RELIABLE false + +#define RTC0_INSTANCE_INDEX 0 +#endif + +#define RTC1_ENABLED 0 + +#if (RTC1_ENABLED == 1) +#define RTC1_CONFIG_FREQUENCY 32768 +#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC1_CONFIG_RELIABLE false + +#define RTC1_INSTANCE_INDEX (RTC0_ENABLED) +#endif + +#define RTC2_ENABLED 0 + +#if (RTC2_ENABLED == 1) +#define RTC2_CONFIG_FREQUENCY 32768 +#define RTC2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define RTC2_CONFIG_RELIABLE false + +#define RTC2_INSTANCE_INDEX (RTC0_ENABLED+RTC1_ENABLED) +#endif + + +#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED+RTC2_ENABLED) + +#define NRF_MAXIMUM_LATENCY_US 2000 + +/* RNG */ +#define RNG_ENABLED 0 + +#if (RNG_ENABLED == 1) +#define RNG_CONFIG_ERROR_CORRECTION true +#define RNG_CONFIG_POOL_SIZE 8 +#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* PWM */ + +#define PWM0_ENABLED 0 + +#if (PWM0_ENABLED == 1) +#define PWM0_CONFIG_OUT0_PIN 2 +#define PWM0_CONFIG_OUT1_PIN 3 +#define PWM0_CONFIG_OUT2_PIN 4 +#define PWM0_CONFIG_OUT3_PIN 5 +#define PWM0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM0_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz +#define PWM0_CONFIG_COUNT_MODE NRF_PWM_MODE_UP +#define PWM0_CONFIG_TOP_VALUE 1000 +#define PWM0_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON +#define PWM0_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO + +#define PWM0_INSTANCE_INDEX 0 +#endif + +#define PWM1_ENABLED 0 + +#if (PWM1_ENABLED == 1) +#define PWM1_CONFIG_OUT0_PIN 2 +#define PWM1_CONFIG_OUT1_PIN 3 +#define PWM1_CONFIG_OUT2_PIN 4 +#define PWM1_CONFIG_OUT3_PIN 5 +#define PWM1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM1_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz +#define PWM1_CONFIG_COUNT_MODE NRF_PWM_MODE_UP +#define PWM1_CONFIG_TOP_VALUE 1000 +#define PWM1_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON +#define PWM1_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO + +#define PWM1_INSTANCE_INDEX (PWM0_ENABLED) +#endif + +#define PWM2_ENABLED 0 + +#if (PWM2_ENABLED == 1) +#define PWM2_CONFIG_OUT0_PIN 2 +#define PWM2_CONFIG_OUT1_PIN 3 +#define PWM2_CONFIG_OUT2_PIN 4 +#define PWM2_CONFIG_OUT3_PIN 5 +#define PWM2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define PWM2_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz +#define PWM2_CONFIG_COUNT_MODE NRF_PWM_MODE_UP +#define PWM2_CONFIG_TOP_VALUE 1000 +#define PWM2_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON +#define PWM2_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO + +#define PWM2_INSTANCE_INDEX (PWM0_ENABLED + PWM1_ENABLED) +#endif + +#define PWM_COUNT (PWM0_ENABLED + PWM1_ENABLED + PWM2_ENABLED) + +/* SPI */ +#define SPI0_ENABLED 0 + +#if (SPI0_ENABLED == 1) +#define SPI0_USE_EASY_DMA 0 + +#define SPI0_CONFIG_SCK_PIN 2 +#define SPI0_CONFIG_MOSI_PIN 3 +#define SPI0_CONFIG_MISO_PIN 4 +#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI0_INSTANCE_INDEX 0 +#endif + +#define SPI1_ENABLED 0 + +#if (SPI1_ENABLED == 1) +#define SPI1_USE_EASY_DMA 0 + +#define SPI1_CONFIG_SCK_PIN 2 +#define SPI1_CONFIG_MOSI_PIN 3 +#define SPI1_CONFIG_MISO_PIN 4 +#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI1_INSTANCE_INDEX (SPI0_ENABLED) +#endif + +#define SPI2_ENABLED 0 + +#if (SPI2_ENABLED == 1) +#define SPI2_USE_EASY_DMA 0 + +#define SPI2_CONFIG_SCK_PIN 2 +#define SPI2_CONFIG_MOSI_PIN 3 +#define SPI2_CONFIG_MISO_PIN 4 +#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) +#endif + +#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) + +/* SPIS */ +#define SPIS0_ENABLED 0 + +#if (SPIS0_ENABLED == 1) +#define SPIS0_CONFIG_SCK_PIN 2 +#define SPIS0_CONFIG_MOSI_PIN 3 +#define SPIS0_CONFIG_MISO_PIN 4 +#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPIS0_INSTANCE_INDEX 0 +#endif + +#define SPIS1_ENABLED 0 + +#if (SPIS1_ENABLED == 1) +#define SPIS1_CONFIG_SCK_PIN 2 +#define SPIS1_CONFIG_MOSI_PIN 3 +#define SPIS1_CONFIG_MISO_PIN 4 +#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPIS1_INSTANCE_INDEX SPIS0_ENABLED +#endif + +#define SPIS2_ENABLED 0 + +#if (SPIS2_ENABLED == 1) +#define SPIS2_CONFIG_SCK_PIN 2 +#define SPIS2_CONFIG_MOSI_PIN 3 +#define SPIS2_CONFIG_MISO_PIN 4 +#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED) +#endif + +#define SPIS_COUNT (SPIS0_ENABLED + SPIS1_ENABLED + SPIS2_ENABLED) + +/* UART */ +#define UART0_ENABLED 1 + +#if (UART0_ENABLED == 1) +#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED +#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED +#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_115200 +#define UART0_CONFIG_PSEL_TXD 0 +#define UART0_CONFIG_PSEL_RXD 0 +#define UART0_CONFIG_PSEL_CTS 0 +#define UART0_CONFIG_PSEL_RTS 0 +#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#ifdef NRF52 +#define UART0_CONFIG_USE_EASY_DMA false +//Compile time flag +#define UART_EASY_DMA_SUPPORT 1 +#define UART_LEGACY_SUPPORT 1 +#endif //NRF52 +#endif + +#define TWI0_ENABLED 0 + +#if (TWI0_ENABLED == 1) +#define TWI0_USE_EASY_DMA 0 + +#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI0_CONFIG_SCL 0 +#define TWI0_CONFIG_SDA 1 +#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TWI0_INSTANCE_INDEX 0 +#endif + +#define TWI1_ENABLED 0 + +#if (TWI1_ENABLED == 1) +#define TWI1_USE_EASY_DMA 0 + +#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K +#define TWI1_CONFIG_SCL 0 +#define TWI1_CONFIG_SDA 1 +#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + +#define TWI1_INSTANCE_INDEX (TWI0_ENABLED) +#endif + +#define TWI_COUNT (TWI0_ENABLED + TWI1_ENABLED) + +/* TWIS */ +#define TWIS0_ENABLED 0 + +#if (TWIS0_ENABLED == 1) + #define TWIS0_CONFIG_ADDR0 0 + #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS0_CONFIG_SCL 0 + #define TWIS0_CONFIG_SDA 1 + #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + + #define TWIS0_INSTANCE_INDEX 0 +#endif + +#define TWIS1_ENABLED 0 + +#if (TWIS1_ENABLED == 1) + #define TWIS1_CONFIG_ADDR0 0 + #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ + #define TWIS1_CONFIG_SCL 0 + #define TWIS1_CONFIG_SDA 1 + #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW + + #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) +#endif + +#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +/* For more documentation see nrf_drv_twis.h file */ +#define TWIS_NO_SYNC_MODE 0 + +/* QDEC */ +#define QDEC_ENABLED 0 + +#if (QDEC_ENABLED == 1) +#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 +#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us +#define QDEC_CONFIG_PIO_A 1 +#define QDEC_CONFIG_PIO_B 2 +#define QDEC_CONFIG_PIO_LED 3 +#define QDEC_CONFIG_LEDPRE 511 +#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH +#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define QDEC_CONFIG_DBFEN false +#define QDEC_CONFIG_SAMPLE_INTEN false +#endif + +/* ADC */ +#define ADC_ENABLED 0 + +#if (ADC_ENABLED == 1) +#define ADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + + +/* SAADC */ +#define SAADC_ENABLED 0 + +#if (SAADC_ENABLED == 1) +#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT +#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED +#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* PDM */ +#define PDM_ENABLED 0 + +#if (PDM_ENABLED == 1) +#define PDM_CONFIG_MODE NRF_PDM_MODE_MONO +#define PDM_CONFIG_EDGE NRF_PDM_EDGE_LEFTFALLING +#define PDM_CONFIG_CLOCK_FREQ NRF_PDM_FREQ_1032K +#define PDM_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#endif + +/* COMP */ +#define COMP_ENABLED 0 + +#if (COMP_ENABLED == 1) +#define COMP_CONFIG_REF NRF_COMP_REF_Int1V8 +#define COMP_CONFIG_MAIN_MODE NRF_COMP_MAIN_MODE_SE +#define COMP_CONFIG_SPEED_MODE NRF_COMP_SP_MODE_High +#define COMP_CONFIG_HYST NRF_COMP_HYST_NoHyst +#define COMP_CONFIG_ISOURCE NRF_COMP_ISOURCE_Off +#define COMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define COMP_CONFIG_INPUT NRF_COMP_INPUT_0 +#endif + +/* LPCOMP */ +#define LPCOMP_ENABLED 0 + +#if (LPCOMP_ENABLED == 1) +#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 +#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN +#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW +#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 +#endif + +/* WDT */ +#define WDT_ENABLED 0 + +#if (WDT_ENABLED == 1) +#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP +#define WDT_CONFIG_RELOAD_VALUE 2000 +#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#endif + +/* SWI EGU */ +#ifdef NRF52 + #define EGU_ENABLED 0 +#endif + +/* I2S */ +#define I2S_ENABLED 0 + +#if (I2S_ENABLED == 1) +#define I2S_CONFIG_SCK_PIN 22 +#define I2S_CONFIG_LRCK_PIN 23 +#define I2S_CONFIG_MCK_PIN NRF_DRV_I2S_PIN_NOT_USED +#define I2S_CONFIG_SDOUT_PIN 24 +#define I2S_CONFIG_SDIN_PIN 25 +#define I2S_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH +#define I2S_CONFIG_MASTER NRF_I2S_MODE_MASTER +#define I2S_CONFIG_FORMAT NRF_I2S_FORMAT_I2S +#define I2S_CONFIG_ALIGN NRF_I2S_ALIGN_LEFT +#define I2S_CONFIG_SWIDTH NRF_I2S_SWIDTH_16BIT +#define I2S_CONFIG_CHANNELS NRF_I2S_CHANNELS_STEREO +#define I2S_CONFIG_MCK_SETUP NRF_I2S_MCK_32MDIV8 +#define I2S_CONFIG_RATIO NRF_I2S_RATIO_256X +#endif + +#include "nrf_drv_config_validation.h" + +#endif // NRF_DRV_CONFIG_H diff --git a/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config_validation.h b/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config_validation.h new file mode 100644 index 00000000..6862bb7b --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/config/nrf_drv_config_validation.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_DRV_CONFIG_VALIDATION_H +#define NRF_DRV_CONFIG_VALIDATION_H + +#ifdef NRF52 + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((SPI0_ENABLED + SPIS0_ENABLED + TWI0_ENABLED + TWIS0_ENABLED) > 1) +#error "Peripherals overlap. SPI0, SPIS0, TWI0, TWIS0 - only one of these can be enabled." +#endif + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((SPI1_ENABLED + SPIS1_ENABLED + TWI1_ENABLED + TWIS1_ENABLED) > 1) +#error "Peripherals overlap. SPI1, SPIS1, TWI1, TWIS1 - only one of these can be enabled." +#endif + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1) +#error "Peripherals overlap. SPI2, SPIS2 - only one of these can be enabled." +#endif + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((COMP_ENABLED + LPCOMP_ENABLED) > 1) +#error "COMP and LPCOMP cannot be enabled together. Peripherals overlap." +#endif + +#else //NRF51 + +#if (TWIS0_ENABLED + TWIS1_ENABLED) > 0 +#error "TWIS not present in nRF51." +#endif + +#if SPIS0_ENABLED > 0 +#error "SPIS0 instance not present in nRF51." +#endif + +#if (SPI2_ENABLED + SPIS2_ENABLED) > 0 +#error "SPI2/SPIS2 instance not present in nRF51." +#endif + +#if RTC2_ENABLED +#error "RTC2 not present in NRF51." +#endif + +#if (TIMER3_ENABLED + TIMER4_ENABLED) > 0 +#error "TIMER3 and TIMER4 not present in nRF51." +#endif + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((SPI0_ENABLED + TWI0_ENABLED) > 1) +#error "Peripherals overlap. SPI0, TWI0 - only one of these can be enabled." +#endif + +#if (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((SPI1_ENABLED + SPIS1_ENABLED + TWI1_ENABLED) > 1) +#error "Peripherals overlap. SPI1, SPIS1, TWI1 - only one of these can be enabled." +#endif + +#if SAADC_ENABLED > 0 +#error "SAADC not present in nRF51." +#endif + +#if I2S_ENABLED > 0 +#error "I2S not present in nRF51." +#endif +#if COMP_ENABLED > 0 +#error "COMP not present in nRF51." +#endif + +#endif //NRF51 + +#endif // NRF_DRV_CONFIG_VALIDATION_H diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.c b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.c new file mode 100644 index 00000000..ef1f9b48 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.c @@ -0,0 +1,95 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief ADC HAL implementation + */ + +#include "nrf_adc.h" + +#ifndef NRF52 + +/** + * @brief Function for configuring ADC. + * + * This function powers on ADC and configures it. ADC is in DISABLE state after configuration, + * so it should be enabled before using it. + * + * @param[in] config Requested configuration. + */ +void nrf_adc_configure(nrf_adc_config_t * config) +{ + uint32_t config_reg = 0; + + config_reg |= ((uint32_t)config->resolution << ADC_CONFIG_RES_Pos) & ADC_CONFIG_RES_Msk; + config_reg |= ((uint32_t)config->scaling << ADC_CONFIG_INPSEL_Pos) & ADC_CONFIG_INPSEL_Msk; + config_reg |= ((uint32_t)config->reference << ADC_CONFIG_REFSEL_Pos) & ADC_CONFIG_REFSEL_Msk; + + if (config->reference & ADC_CONFIG_EXTREFSEL_Msk) + { + config_reg |= config->reference & ADC_CONFIG_EXTREFSEL_Msk; + } + + /* select input */ + nrf_adc_input_select(NRF_ADC_CONFIG_INPUT_DISABLED); + + /* set new configuration keeping selected input */ + NRF_ADC->CONFIG = config_reg | (NRF_ADC->CONFIG & ADC_CONFIG_PSEL_Msk); +} + + +/** + * @brief Blocking function for executing single ADC conversion. + * + * This function selects the desired input, starts a single conversion, + * waits for it to finish, and returns the result. + * ADC is left in STOP state, the given input is selected. + * This function does not check if ADC is initialized and powered. + * + * @param[in] input Requested input to be selected. + * + * @return Conversion result + */ +int32_t nrf_adc_convert_single(nrf_adc_config_input_t input) +{ + int32_t val; + + nrf_adc_input_select(input); + nrf_adc_start(); + + while (!nrf_adc_conversion_finished()) + { + } + nrf_adc_conversion_event_clean(); + val = nrf_adc_result_get(); + nrf_adc_stop(); + return val; +} +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.h new file mode 100644 index 00000000..0410ea35 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_adc.h @@ -0,0 +1,433 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_ADC_H_ +#define NRF_ADC_H_ + +/** + * @defgroup nrf_adc_hal ADC HAL + * @{ + * @ingroup nrf_adc + * @brief @tagAPI51 Hardware access layer for managing the analog-to-digital converter (ADC). + */ + +#include +#include + +#include "nrf.h" + +#ifndef NRF52 +/** + * @enum nrf_adc_config_resolution_t + * @brief Resolution of the analog-to-digital converter. + */ + +/** + * @brief ADC interrupts. + */ +typedef enum +{ + NRF_ADC_INT_END_MASK = ADC_INTENSET_END_Msk, /**< ADC interrupt on END event. */ +} nrf_adc_int_mask_t; + +typedef enum +{ + NRF_ADC_CONFIG_RES_8BIT = ADC_CONFIG_RES_8bit, /**< 8 bit resolution. */ + NRF_ADC_CONFIG_RES_9BIT = ADC_CONFIG_RES_9bit, /**< 9 bit resolution. */ + NRF_ADC_CONFIG_RES_10BIT = ADC_CONFIG_RES_10bit, /**< 10 bit resolution. */ +} nrf_adc_config_resolution_t; + + +/** + * @enum nrf_adc_config_scaling_t + * @brief Scaling factor of the analog-to-digital conversion. + */ +typedef enum +{ + NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE = ADC_CONFIG_INPSEL_AnalogInputNoPrescaling, /**< Full scale input. */ + NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS = ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling, /**< 2/3 scale input. */ + NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD = ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling, /**< 1/3 scale input. */ + NRF_ADC_CONFIG_SCALING_SUPPLY_TWO_THIRDS = ADC_CONFIG_INPSEL_SupplyTwoThirdsPrescaling, /**< 2/3 of supply. */ + NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD = ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling /**< 1/3 of supply. */ +} nrf_adc_config_scaling_t; + +/** + * @enum nrf_adc_config_reference_t + * @brief Reference selection of the analog-to-digital converter. + */ +typedef enum +{ + NRF_ADC_CONFIG_REF_VBG = ADC_CONFIG_REFSEL_VBG, /**< 1.2 V reference. */ + NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF = ADC_CONFIG_REFSEL_SupplyOneHalfPrescaling, /**< 1/2 of power supply. */ + NRF_ADC_CONFIG_REF_SUPPLY_ONE_THIRD = ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling, /**< 1/3 of power supply. */ + NRF_ADC_CONFIG_REF_EXT_REF0 = ADC_CONFIG_REFSEL_External | + ADC_CONFIG_EXTREFSEL_AnalogReference0 << + ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */ + NRF_ADC_CONFIG_REF_EXT_REF1 = ADC_CONFIG_REFSEL_External | + ADC_CONFIG_EXTREFSEL_AnalogReference1 << ADC_CONFIG_EXTREFSEL_Pos, /**< External reference 0. */ +} nrf_adc_config_reference_t; + +/** + * @enum nrf_adc_config_input_t + * @brief Input selection of the analog-to-digital converter. + */ +typedef enum +{ + NRF_ADC_CONFIG_INPUT_DISABLED = ADC_CONFIG_PSEL_Disabled, /**< No input selected. */ + NRF_ADC_CONFIG_INPUT_0 = ADC_CONFIG_PSEL_AnalogInput0, /**< Input 0. */ + NRF_ADC_CONFIG_INPUT_1 = ADC_CONFIG_PSEL_AnalogInput1, /**< Input 1. */ + NRF_ADC_CONFIG_INPUT_2 = ADC_CONFIG_PSEL_AnalogInput2, /**< Input 2. */ + NRF_ADC_CONFIG_INPUT_3 = ADC_CONFIG_PSEL_AnalogInput3, /**< Input 3. */ + NRF_ADC_CONFIG_INPUT_4 = ADC_CONFIG_PSEL_AnalogInput4, /**< Input 4. */ + NRF_ADC_CONFIG_INPUT_5 = ADC_CONFIG_PSEL_AnalogInput5, /**< Input 5. */ + NRF_ADC_CONFIG_INPUT_6 = ADC_CONFIG_PSEL_AnalogInput6, /**< Input 6. */ + NRF_ADC_CONFIG_INPUT_7 = ADC_CONFIG_PSEL_AnalogInput7, /**< Input 7. */ +} nrf_adc_config_input_t; + +/** + * @enum nrf_adc_task_t + * @brief Analog-to-digital converter tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_ADC_TASK_START = offsetof(NRF_ADC_Type, TASKS_START), /**< ADC start sampling task. */ + NRF_ADC_TASK_STOP = offsetof(NRF_ADC_Type, TASKS_STOP) /**< ADC stop sampling task. */ + /*lint -restore*/ +} nrf_adc_task_t; + +/** + * @enum nrf_adc_event_t + * @brief Analog-to-digital converter events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + /*lint -save -e30*/ + NRF_ADC_EVENT_END = offsetof(NRF_ADC_Type, EVENTS_END) /**< End of conversion event. */ + /*lint -restore*/ +} nrf_adc_event_t; + +/**@brief Analog-to-digital converter configuration. */ +typedef struct +{ + nrf_adc_config_resolution_t resolution; /**< ADC resolution. */ + nrf_adc_config_scaling_t scaling; /**< ADC scaling factor. */ + nrf_adc_config_reference_t reference; /**< ADC reference. */ +} nrf_adc_config_t; + +/** Default ADC configuration. */ +#define NRF_ADC_CONFIG_DEFAULT { NRF_ADC_CONFIG_RES_10BIT, \ + NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD, \ + NRF_ADC_CONFIG_REF_VBG } + +/** + * @brief Function for configuring ADC. + * + * This function powers on the analog-to-digital converter and configures it. + * After the configuration, the ADC is in DISABLE state and must be + * enabled before using it. + * + * @param[in] config Configuration parameters. + */ +void nrf_adc_configure(nrf_adc_config_t * config); + +/** + * @brief Blocking function for executing a single ADC conversion. + * + * This function selects the desired input, starts a single conversion, + * waits for it to finish, and returns the result. + * After the input is selected, the analog-to-digital converter + * is left in STOP state. + * The function does not check if the ADC is initialized and powered. + * + * @param[in] input Input to be selected. + * + * @return Conversion result. + */ +int32_t nrf_adc_convert_single(nrf_adc_config_input_t input); + +/** + * @brief Function for selecting ADC input. + * + * This function selects the active input of ADC. Ensure that + * the ADC is powered on and in IDLE state before calling this function. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_adc_input_select(nrf_adc_config_input_t input) +{ + NRF_ADC->CONFIG = + ((uint32_t)input << ADC_CONFIG_PSEL_Pos) | (NRF_ADC->CONFIG & ~ADC_CONFIG_PSEL_Msk); + + if (input != NRF_ADC_CONFIG_INPUT_DISABLED) + { + NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled << ADC_ENABLE_ENABLE_Pos; + } + else + { + NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled << ADC_ENABLE_ENABLE_Pos; + } +} + + +/** + * @brief Function for retrieving the ADC conversion result. + * + * This function retrieves and returns the last analog-to-digital conversion result. + * + * @return Last conversion result. + */ +__STATIC_INLINE int32_t nrf_adc_result_get(void) +{ + return (int32_t)NRF_ADC->RESULT; +} + + +/** + * @brief Function for checking whether the ADC is busy. + * + * This function checks whether the analog-to-digital converter is busy with a conversion. + * + * @retval true If the ADC is busy. + * @retval false If the ADC is not busy. + */ +__STATIC_INLINE bool nrf_adc_is_busy(void) +{ + return ( (NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == ADC_BUSY_BUSY_Msk); +} + +/** + * @brief Function for getting the ADC's enabled interrupts. + * + * @param[in] mask Mask of interrupts to check. + * + * @return State of the interrupts selected by the mask. + * + * @sa nrf_adc_int_enable() + * @sa nrf_adc_int_disable() + */ +__STATIC_INLINE uint32_t nrf_adc_int_get(uint32_t mask) +{ + return (NRF_ADC->INTENSET & mask); // when read this register will return the value of INTEN. +} + + +/** + * @brief Function for starting conversion. + * + * @sa nrf_adc_stop() + * + */ +__STATIC_INLINE void nrf_adc_start(void) +{ + NRF_ADC->TASKS_START = 1; +} + + +/** + * @brief Function for stopping conversion. + * + * If the analog-to-digital converter is in inactive state, power consumption is reduced. + * + * @sa nrf_adc_start() + * + */ +__STATIC_INLINE void nrf_adc_stop(void) +{ + NRF_ADC->TASKS_STOP = 1; +} + + +/** + * @brief Function for checking if the requested ADC conversion has ended. + * + * @retval true If the task has finished. + * @retval false If the task is still running. + */ +__STATIC_INLINE bool nrf_adc_conversion_finished(void) +{ + return ((bool)NRF_ADC->EVENTS_END); +} + +/** + * @brief Function for clearing the conversion END event. + */ +__STATIC_INLINE void nrf_adc_conversion_event_clean(void) +{ + NRF_ADC->EVENTS_END = 0; +} + +/** + * @brief Function for getting the address of an ADC task register. + * + * @param[in] adc_task ADC task. + * + * @return Address of the specified ADC task. + */ +__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task); + +/** + * @brief Function for getting the address of a specific ADC event register. + * + * @param[in] adc_event ADC event. + * + * @return Address of the specified ADC event. + */ +__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event); + +/** + * @brief Function for setting the CONFIG register in ADC. + * + * @param[in] configuration Value to be written to the CONFIG register. + */ +__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration); + +/** + * @brief Function for clearing an ADC event. + * + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event); + +/** + * @brief Function for checking state of an ADC event. + * + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask); + +/** + * @brief Function for activating a specific ADC task. + * + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task); + +/** + * @brief Function for enabling ADC. + * + */ +__STATIC_INLINE void nrf_adc_enable(void); + +/** + * @brief Function for disabling ADC. + * + */ +__STATIC_INLINE void nrf_adc_disable(void); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task) +{ + return (uint32_t)((uint8_t *)NRF_ADC + adc_task); +} + +__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event) +{ + return (uint32_t)((uint8_t *)NRF_ADC + adc_event); +} + +__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration) +{ + NRF_ADC->CONFIG = configuration; +} + +__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event); +} + +__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask) +{ + NRF_ADC->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask) +{ + NRF_ADC->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask) +{ + return (bool)(NRF_ADC->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE void nrf_adc_enable(void) +{ + NRF_ADC->ENABLE = 1; +} + +__STATIC_INLINE void nrf_adc_disable(void) +{ + NRF_ADC->ENABLE = 0; +} +#endif +#endif /* NRF52 */ +/** + *@} + **/ + +#endif /* NRF_ADC_H_ */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_clock.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_clock.h new file mode 100644 index 00000000..b7a1e19e --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_clock.h @@ -0,0 +1,431 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_CLOCK_H__ +#define NRF_CLOCK_H__ + +#include +#include + +#include "nrf.h" + +/** + * @defgroup nrf_clock_hal Clock HAL + * @{ + * @ingroup nrf_clock + * @brief Hardware access layer for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK). + */ + +#define NRF_CLOCK_TASK_TRIGGER (1UL) +#define NRF_CLOCK_EVENT_CLEAR (0UL) + +/** + * @brief Low-frequency clock sources. + * @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers. + */ +typedef enum +{ + NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */ + NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */ + NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */ +} nrf_clock_lfclk_t; + +/** + * @brief High-frequency clock sources. + */ +typedef enum +{ + NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */ + NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */ +} nrf_clock_hfclk_t; + +/** + * @brief Trigger status of task LFCLKSTART/HFCLKSTART. + * @details Used by LFCLKRUN and HFCLKRUN registers. + */ +typedef enum +{ + NRF_CLOCK_START_TASK_NOT_TRIGGERED = CLOCK_LFCLKRUN_STATUS_NotTriggered, /**< Task LFCLKSTART/HFCLKSTART has not been triggered. */ + NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */ +} nrf_clock_start_task_status_t; + +/** + * @brief Crystal frequency selection. + */ +typedef enum +{ +#ifdef NRF51 + NRF_CLOCK_XTALFREQ_Default = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< Default. 32 MHz. */ + NRF_CLOCK_XTALFREQ_16MHz = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< 16 MHz crystal. */ + NRF_CLOCK_XTALFREQ_32MHz = CLOCK_XTALFREQ_XTALFREQ_32MHz /**< 32 MHz crystal. */ +#elif defined NRF52 + NRF_CLOCK_XTALFREQ_Default, /**< Default. 64MHz. */ +#endif +} nrf_clock_xtalfreq_t; + +/** + * @brief Interrupts. + */ +typedef enum +{ + NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */ + NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */ + NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */ + NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk /**< Interrupt on CTTO event. */ +} nrf_clock_int_mask_t; + +/** + * @brief Tasks. + * + * @details The NRF_CLOCK_TASK_LFCLKSTOP task cannot be set when the low-frequency clock is not running. + * The NRF_CLOCK_TASK_HFCLKSTOP task cannot be set when the high-frequency clock is not running. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/ + NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/ + NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/ + NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/ + NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/ + NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/ + NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/ +} nrf_clock_task_t; /*lint -restore */ + +/** + * @brief Events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/ + NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started.*/ + NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/ + NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO) /**< Calibration timer time-out.*/ +} nrf_clock_event_t; /*lint -restore */ + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask); + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a specific interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask); + +/** + * @brief Function for retrieving the address of a specific task. + * @details This function can be used by the PPI module. + * + * @param[in] task Task. + * + * @return Address of the requested task register. + */ +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task); + +/** + * @brief Function for setting a specific task. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task); + +/** + * @brief Function for retrieving the address of a specific event. + * @details This function can be used by the PPI module. + * + * @param[in] event Event. + * + * @return Address of the requested event register. + */ +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event); + +/** + * @brief Function for clearing a specific event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event); + +/** + * @brief Function for retrieving the state of a specific event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event); + +/** + * @brief Function for changing the low-frequency clock source. + * @details This function cannot be called when the low-frequency clock is running. + * + * @param[in] source New low-frequency clock source. + * + */ +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source); + +/** + * @brief Function for retrieving the selected source for the low-frequency clock. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void); + +/** + * @brief Function for retrieving the active source of the low-frequency clock. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void); + +/** + * @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void); + +/** + * @brief Function for retrieving the state of the LFCLK clock. + * + * @retval false If the LFCLK clock is not running. + * @retval true If the LFCLK clock is running. + */ +__STATIC_INLINE bool nrf_clock_lf_is_running(void); + +/** + * @brief Function for retrieving the trigger status of the task LFCLKSTART. + * + * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered. + * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered. + */ +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void); + +/** + * @brief Function for retrieving the active source of the high-frequency clock. + * + * @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock. + * @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock. + */ +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void); + +/** + * @brief Function for retrieving the state of the HFCLK clock. + * + * @param[in] clk_src Clock source to be checked. + * + * @retval false If the HFCLK clock is not running. + * @retval true If the HFCLK clock is running. + */ +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src); + +/** + * @brief Function for retrieving the trigger status of the task HFCLKSTART. + * + * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered. + * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered. + */ +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void); + +/** + * @brief Function for retrieving the frequency selection of the external crystal. + * + * @retval NRF_CLOCK_XTALFREQ_16MHz If a 16 MHz crystal is used as source for the HFCLK oscillator. + * @retval NRF_CLOCK_XTALFREQ_32MHz If a 32 MHz crystal is used as source for the HFCLK oscillator. + */ +__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void); + +/** + * @brief Function for changing the frequency selection of the external crystal. + * + * @param[in] xtalfreq New frequency selection for the external crystal. + */ +__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq); + +/** + * @brief Function for changing the calibration timer interval. + * + * @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds). + */ +__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask) +{ + NRF_CLOCK->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask) +{ + NRF_CLOCK->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask) +{ + return (bool)(NRF_CLOCK->INTENCLR & int_mask); +} + +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task) +{ + return ((uint32_t )NRF_CLOCK + task); +} + +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER; +} + +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event) +{ + return ((uint32_t)NRF_CLOCK + event); +} + +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); +} + +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source) +{ + NRF_CLOCK->LFCLKSRC = + (uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC & + CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY & + CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_lf_is_running(void) +{ + return ((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN & + CLOCK_LFCLKRUN_STATUS_Msk) >> + CLOCK_LFCLKRUN_STATUS_Pos); +} + +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void) +{ + return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT & + CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src) +{ + return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) == + (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN & + CLOCK_HFCLKRUN_STATUS_Msk) >> + CLOCK_HFCLKRUN_STATUS_Pos); +} + +__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void) +{ +#ifdef NRF51 + return (nrf_clock_xtalfreq_t)((NRF_CLOCK->XTALFREQ & + CLOCK_XTALFREQ_XTALFREQ_Msk) >> CLOCK_XTALFREQ_XTALFREQ_Pos); +#elif defined NRF52 + return NRF_CLOCK_XTALFREQ_Default; +#endif +} + +__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq) +{ +#ifdef NRF51 + NRF_CLOCK->XTALFREQ = + (uint32_t)((xtalfreq << CLOCK_XTALFREQ_XTALFREQ_Pos) & CLOCK_XTALFREQ_XTALFREQ_Msk); +#elif defined NRF52 + return; +#endif +} + +__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval) +{ + NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** + *@} + **/ +#endif // NRF_CLOCK_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_comp.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_comp.h new file mode 100644 index 00000000..6a66b24e --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_comp.h @@ -0,0 +1,486 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief COMP HAL API. + */ + +#ifndef NRF_COMP_H_ +#define NRF_COMP_H_ + +/** + * @defgroup nrf_comp_hal COMP HAL + * @{ + * @ingroup nrf_comp + * @brief @tagAPI52 Hardware access layer for managing the Comparator (COMP). + */ + +#include "nrf.h" + +#include +#include +#include + +/** + * @enum nrf_comp_input_t + * @brief COMP analog pin selection. + */ +typedef enum +{ + NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */ + NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */ + NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */ + NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */ + NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */ + NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */ + NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */ + NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7 /*!< AIN7 selected as analog input. */ +}nrf_comp_input_t; + +/** + * @enum nrf_comp_ref_t + * @brief COMP reference selection. + */ +typedef enum +{ + NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */ + NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */ + NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */ +}nrf_comp_ref_t; + +/** + * @enum nrf_comp_ext_ref_t + * @brief COMP external analog reference selection. + */ +typedef enum +{ + NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */ + NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */ +}nrf_comp_ext_ref_t; + +/** + * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP. + */ +typedef struct +{ + uint8_t th_down; /*!< THDOWN value. */ + uint8_t th_up; /*!< THUP value. */ +}nrf_comp_th_t; + +/** + * @enum nrf_comp_main_mode_t + * @brief COMP main operation mode. + */ +typedef enum +{ + NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */ + NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */ +}nrf_comp_main_mode_t; + +/** + * @enum nrf_comp_sp_mode_t + * @brief COMP speed and power mode. + */ +typedef enum +{ + NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */ + NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */ + NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */ +}nrf_comp_sp_mode_t; + +/** + * @enum nrf_comp_hyst_t + * @brief COMP comparator hysteresis. + */ +typedef enum +{ + NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */ + NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */ +}nrf_comp_hyst_t; + +/** + * @brief COMP current source selection on analog input. + */ +typedef enum +{ + NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */ + NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */ + NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */ + NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */ +}nrf_isource_t; + +/** + * @enum nrf_comp_task_t + * @brief COMP tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */ + NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */ + NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */ + /*lint -restore*/ +}nrf_comp_task_t; + +/** + * @enum nrf_comp_event_t + * @brief COMP events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */ + NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */ + NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */ + NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */ + /*lint -restore*/ +}nrf_comp_event_t; + +/** + * @brief COMP reference configuration. + */ +typedef struct +{ + nrf_comp_ref_t reference; /*!< COMP reference selection. */ + nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */ +}nrf_comp_ref_conf_t; + + +/** + * @brief Function for enabling the COMP peripheral. + */ +__STATIC_INLINE void nrf_comp_enable(void); + + +/** + * @brief Function for disabling the COMP peripheral. + */ + +__STATIC_INLINE void nrf_comp_disable(void); + +/** + * @brief Function for checking if the COMP peripheral is enabled. + * + * @retval true If the COMP peripheral is enabled. + * @retval false If the COMP peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_comp_enable_check(void); + +/** + * @brief Function for setting the reference source. + * + * @param[in] reference COMP reference selection. + */ +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference); + + +/** + * @brief Function for setting the external analog reference source. + * + * @param[in] ext_ref COMP external analog reference selection. + */ +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref); + + +/** + * @brief Function for setting threshold voltages. + * + * @param[in] threshold COMP VDOWN and VUP thresholds. + */ +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold); + + +/** + * @brief Function for setting the main mode. + * + * @param[in] main_mode COMP main operation mode. + */ +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode); + + +/** + * @brief Function for setting the speed mode. + * + * @param[in] speed_mode COMP speed and power mode. + */ +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode); + + +/** + * @brief Function for setting the hysteresis. + * + * @param[in] hyst COMP comparator hysteresis. + */ +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst); + + +/** + * @brief Function for setting the current source on the analog input. + * + * @param[in] isource COMP current source selection on analog input. + */ +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource); + + +/** + * @brief Function for selecting the active input of the COMP. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input); + + +/** + * @brief Function for getting the last COMP compare result. + * + * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-. + * + * @note If VIN+ == VIN-, the return value depends on the previous result. + */ +__STATIC_INLINE uint32_t nrf_comp_result_get(void); + + +/** + * @brief Function for enabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be enabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask); + +/** + * @brief Function for disabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be disabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask); + + +/** + * @brief Function for getting the enabled interrupts of COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be checked. + * + * @retval true If any interrupts of the specified mask are enabled. + */ +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask); + + + +/** + * @brief Function for getting the address of a specific COMP task register. + * + * @param[in] comp_task COMP task. + * + * @return Address of the specified COMP task. + */ +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task); + + +/** + * @brief Function for getting the address of a specific COMP event register. + * + * @param[in] comp_event COMP event. + * + * @return Address of the specified COMP event. + */ +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event); + + +/** + * @brief Function for setting COMP shorts. + * + * @param[in] comp_short_mask COMP shorts by mask. + * + */ +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask); + + +/** + * @brief Function for clearing COMP shorts by mask. + * + * @param[in] comp_short_mask COMP shorts to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask); + + +/** + * @brief Function for setting a specific COMP task. + * + * @param[in] comp_task COMP task to be set. + * + */ +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task); + + +/** + * @brief Function for clearing a specific COMP event. + * + * @param[in] comp_event COMP event to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event); + + +/** + * @brief Function for getting the state of a specific COMP event. + * + * @retval true If the specified COMP event is active. + * + */ +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_comp_enable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_comp_disable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE bool nrf_comp_enable_check(void) +{ + return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled); +} + +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference) +{ + NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref) +{ + NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold) +{ + NRF_COMP->TH = + ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) | + ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk); +} + +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode) +{ + NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos); +} + +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode) +{ + NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos); +} + +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst) +{ + NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk; +} + +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource) +{ + NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk; +} + +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input) +{ + NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos); +} + +__STATIC_INLINE uint32_t nrf_comp_result_get(void) +{ + return (uint32_t)NRF_COMP->RESULT; +} + +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENSET = comp_int_mask; +} + +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENCLR = comp_int_mask; +} + +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask) +{ + return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN. +} + +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task); +} + +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event); +} + +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS |= comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS &= ~comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1; +} + +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0; +} + +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event) +{ + return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** + *@} + **/ + +#endif // NRF_COMP_H_ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.c b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.c new file mode 100644 index 00000000..cd62b175 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.c @@ -0,0 +1,92 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + * + * $LastChangedRevision: 25419 $ +*/ + +/** + * @file + * @brief Implementation of AES ECB driver + */ + + +//lint -e438 + +#include +#include +#include +#include "nrf.h" +#include "nrf_ecb.h" + +static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access. +static uint8_t* ecb_key; ///< Key: Starts at ecb_data +static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes. +static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes. + +bool nrf_ecb_init(void) +{ + ecb_key = ecb_data; + ecb_cleartext = ecb_data + 16; + ecb_ciphertext = ecb_data + 32; + + NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data; + return true; +} + + +bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf) +{ + uint32_t counter = 0x1000000; + if(src_buf != ecb_cleartext) + { + memcpy(ecb_cleartext,src_buf,16); + } + NRF_ECB->EVENTS_ENDECB = 0; + NRF_ECB->TASKS_STARTECB = 1; + while(NRF_ECB->EVENTS_ENDECB == 0) + { + counter--; + if(counter == 0) + { + return false; + } + } + NRF_ECB->EVENTS_ENDECB = 0; + if(dest_buf != ecb_ciphertext) + { + memcpy(dest_buf,ecb_ciphertext,16); + } + return true; +} + +void nrf_ecb_set_key(const uint8_t * key) +{ + memcpy(ecb_key,key,16); +} + + diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.h new file mode 100644 index 00000000..30d8449e --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ecb.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + * + * + * $LastChangedRevision: 13999 $ + */ + +/** + * @file + * @brief ECB driver API. + */ + +#ifndef NRF_ECB_H__ +#define NRF_ECB_H__ + +/** + * @defgroup nrf_ecb AES ECB encryption + * @{ + * @ingroup nrf_drivers + * @brief Driver for the AES Electronic Code Book (ECB) peripheral. + * + * To encrypt and decrypt data, the peripheral must first be powered on + * using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key. + */ + +#include + +/** + * @brief Function for initializing and powering on the ECB peripheral. + * + * This function allocates memory for the ECBDATAPTR. + * @retval true If initialization was successful. + * @retval false If powering on failed. + */ +bool nrf_ecb_init(void); + +/** + * @brief Function for encrypting and decrypting 16-byte data using current key. + * + * This function avoids unnecessary copying of data if the parameters point to the + * correct locations in the ECB data structure. + * + * @param dst Result of encryption/decryption. 16 bytes will be written. + * @param src Source with 16-byte data to be encrypted/decrypted. + * + * @retval true If the encryption operation completed. + * @retval false If the encryption operation did not complete. + */ +bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src); + +/** + * @brief Function for setting the key to be used for encryption and decryption. + * + * @param key Pointer to the key. 16 bytes will be read. + */ +void nrf_ecb_set_key(const uint8_t * key); + +#endif // NRF_ECB_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_egu.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_egu.h new file mode 100644 index 00000000..6c8d5e3c --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_egu.h @@ -0,0 +1,303 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_EGU_H__ +#define NRF_EGU_H__ + +#ifndef NRF52 + #error EGU is not supported on your chip. +#endif + +/** +* @defgroup nrf_egu EGU (Event Generator Unit) abstraction +* @{ +* @ingroup nrf_drivers +* @brief @tagAPI52 EGU (Event Generator Unit) module functions. +* +*/ + +#include +#include +#include +#include "nrf_assert.h" +#include "nrf.h" + +#define NRF_EGU_COUNT 6 /**< Number of EGU instances. */ +#define NRF_EGU_CHANNEL_COUNT 16 /**< Number of channels per EGU instance. */ + +/** + * @enum nrf_egu_task_t + * @brief EGU tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */ + NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */ + NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */ + NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */ + NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */ + NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */ + NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */ + NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */ + NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */ + NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */ + NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */ + NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */ + NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */ + NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */ + NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */ + NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */ + /*lint -restore*/ +} nrf_egu_task_t; + + +/** + * @enum nrf_egu_event_t + * @brief EGU events. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */ + NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */ + NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */ + NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */ + NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */ + NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */ + NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */ + NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */ + NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */ + NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */ + NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */ + NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */ + NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */ + NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */ + NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */ + NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */ + /*lint -restore*/ +} nrf_egu_event_t; + + +/** + * @enum nrf_egu_int_mask_t + * @brief EGU interrupts. + */ +typedef enum +{ + NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */ + NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */ + NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */ + NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */ + NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */ + NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */ + NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */ + NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */ + NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */ + NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */ + NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */ + NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */ + NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */ + NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */ + NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */ + NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */ + NRF_EGU_INT_ALL = 0xFFFFuL +} nrf_egu_int_mask_t; + + +/** + * @brief Function for triggering a specific EGU task. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL; +} + + +/** + * @brief Function for returning the address of a specific EGU task register. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_task_t egu_task) +{ + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGER task register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_trigger_addres_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGER task. + * + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(uint8_t channel) +{ + ASSERT(channel <= NRF_EGU_CHANNEL_COUNT); + return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for returning the state of a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to check. + */ +__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for clearing a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to clear. + */ +__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL; +} + + +/** + * @brief Function for returning the address of a specific EGU event register. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGERED event register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_triggered_addres_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGERED event. + * + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(uint8_t channel) +{ + ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for enabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + NRF_EGUx->INTENSET = egu_int_mask; +} + + +/** + * @brief Function for retrieving the state of one or more EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to check. + * + * @retval true If all of the specified interrupts are enabled. + * @retval false If at least one of the specified interrupts is disabled. + */ +__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + return (bool)(NRF_EGUx->INTENSET & egu_int_mask); +} + + +/** + * @brief Function for disabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + NRF_EGUx->INTENCLR = egu_int_mask; +} + +/** + * @brief Function for retrieving one or more specific EGU interrupts. + * + * @param channel Channel number. + * + * @returns EGU interrupt mask. + */ +__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(uint8_t channel) +{ + ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel)); +} + +/** @} */ + +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpio.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpio.h new file mode 100644 index 00000000..5178b1f3 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpio.h @@ -0,0 +1,664 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_GPIO_H__ +#define NRF_GPIO_H__ + +#include "nrf.h" +#include + +/** + * @defgroup nrf_gpio GPIO abstraction + * @{ + * @ingroup nrf_drivers + * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports. + * + * Here, the GPIO ports are defined as follows: + * - Port 0 -> pin 0-7 + * - Port 1 -> pin 8-15 + * - Port 2 -> pin 16-23 + * - Port 3 -> pin 24-31 + */ + +#define NUMBER_OF_PINS 32 + +/** + * @brief Enumerator used for selecting between port 0 - 3. + */ +typedef enum +{ + NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7) + NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15) + NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23) + NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31) +} nrf_gpio_port_select_t; + +/** + * @brief Enumerator used for setting the direction of a GPIO port. + */ +typedef enum +{ + NRF_GPIO_PORT_DIR_OUTPUT, ///< Output + NRF_GPIO_PORT_DIR_INPUT ///< Input +} nrf_gpio_port_dir_t; + +/** + * @brief Pin direction definitions. + */ +typedef enum +{ + NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input + NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output +} nrf_gpio_pin_dir_t; + +/** + * @brief Connection of input buffer + */ +typedef enum +{ + NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer + NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer +} nrf_gpio_pin_input_t; + +/** + * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration + */ +typedef enum +{ + NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled + NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled + NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled +} nrf_gpio_pin_pull_t; + +/** + * @brief Enumerator used for selecting output drive mode + */ +typedef enum +{ + NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1' + NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1' + NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1' + NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1'' + NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1' + NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1' + NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1' + NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1' +} nrf_gpio_pin_drive_t; + +/** + * @brief Enumerator used for selecting the pin to sense high or low level on the pin input. + */ +typedef enum +{ + NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled. + NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level. + NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level. +} nrf_gpio_pin_sense_t; + + +/** + * @brief Function for configuring the GPIO pin range as outputs with normal drive strength. + * This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * + * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * + * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * + * @note For configuring only one pin as output use @ref nrf_gpio_cfg_output + * Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. + */ +__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end); + +/** + * @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details. + * This function can be used to configure pin range as simple input. + * + * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * + * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * + * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high) + * + * @note For configuring only one pin as input use @ref nrf_gpio_cfg_input + * Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable + */ +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config); + +/** + * @brief Pin configuration function + * + * The main pin configuration function. + * This function allows to set any aspect in PIN_CNF register. + * @param pin_number Specifies the pin number (allowed values 0-31). + * @param dir Pin direction + * @param input Connect or disconnect input buffer + * @param pull Pull configuration + * @param drive Drive configuration + * @param sense Pin sensing mechanism + */ +__STATIC_INLINE void nrf_gpio_cfg( + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense); + +/** + * @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details. + * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * + * @param pin_number specifies the pin number (allowed values 0-31) + * + * @note Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. + */ +__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. + * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * + * @param pin_number Specifies the pin number (allowed values 0-30). + * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high). + * + * @note Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable + */ +__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config); + +/** + * @brief Function for reseting pin configuration to its default state. + * + * @param pin_number Specifies the pin number (allowed values 0-31). + */ +__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected. + * + * @param pin_number Specifies the pin number (allowed values 0-31). + * + */ +__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number); + +/** + * @brief Function for disconnecting input for the given GPIO. + * + * @param pin_number Specifies the pin number (allowed values 0-31). + * + */ +__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. + * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable. + * + * @param pin_number Specifies the pin number (allowed values 0-30). + * @param pull_config State of the pin pull resistor (no pull, pulled down or pulled high). + * @param sense_config Sense level of the pin (no sense, sense low or sense high). + */ +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config); + +/** + * @brief Function for configuring sense level for the given GPIO. + * + * @param pin_number Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30). + * @param sense_config Sense configuration. + * + */ +__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config); + +/** + * @brief Function for setting the direction for a GPIO pin. + * + * @param pin_number specifies the pin number (0-31) for which to + * set the direction. + * + * @param direction specifies the direction + */ +__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction); + +/** + * @brief Function for setting a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number (0-31) to set. + */ +__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number); + +/** + * @brief Function for setting GPIO pins. + * + * Note that the pins must be configured as outputs for this + * function to have any effect. + * + * @param pin_mask Specifies the pins to set. + */ +__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask); + +/** + * @brief Function for clearing a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number (0-31) to clear. + */ +__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number); + +/** + * @brief Function for clearing GPIO pins. + * + * Note that the pins must be configured as outputs for this + * function to have any effect. + * + * @param pin_mask Specifies the pins to clear. + */ +__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask); + +/** + * @brief Function for toggling a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number (0-31) to toggle. + */ +__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number); + +/** + * @brief Function for toggling GPIO pins. + * + * Note that the pins must be configured as outputs for this + * function to have any effect. + * + * @param pin_mask Specifies the pins to toggle. + */ +__STATIC_INLINE void nrf_gpio_pins_toggle(uint32_t pin_mask); + +/** + * @brief Function for writing a value to a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number specifies the pin number (0-31) to + * write. + * + * @param value specifies the value to be written to the pin. + * @arg 0 clears the pin + * @arg >=1 sets the pin. + */ +__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value); + +/** + * @brief Function for reading the input level of a GPIO pin. + * + * Note that the pin must have input connected for the value + * returned from this function to be valid. + * + * @param pin_number specifies the pin number (0-31) to + * read. + * + * @return + * @retval 0 if the pin input level is low. + * @retval 1 if the pin input level is high. + * @retval > 1 should never occur. + */ +__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number); + +/** + * @brief Function for reading the input level of all GPIO pins. + * + * Note that the pin must have input connected for the value + * returned from this function to be valid. + * + * @retval Status of input of all pins + */ +__STATIC_INLINE uint32_t nrf_gpio_pins_read(void); + +/** + * @brief Function for reading the sense configuration of a GPIO pin. + * + * @param pin_number specifies the pin number (0-31) to + * read. + * + * @retval Sense configuration + */ +__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number); + +/** + * @brief Generic function for writing a single byte of a 32 bit word at a given + * address. + * + * This function should not be called from outside the nrf_gpio + * abstraction layer. + * + * @param word_address is the address of the word to be written. + * + * @param byte_no is the word byte number (0-3) to be written. + * + * @param value is the value to be written to byte "byte_no" of word + * at address "word_address" + */ +__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value); + +/** + * @brief Generic function for reading a single byte of a 32 bit word at a given + * address. + * + * This function should not be called from outside the nrf_gpio + * abstraction layer. + * + * @param word_address is the address of the word to be read. + * + * @param byte_no is the byte number (0-3) of the word to be read. + * + * @return byte "byte_no" of word at address "word_address". + */ +__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no); + +/** + * @brief Function for setting the direction of a port. + * + * @param port is the port for which to set the direction. + * + * @param dir direction to be set for this port. + */ +__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir); + +/** + * @brief Function for reading a GPIO port. + * + * @param port is the port to read. + * + * @return the input value on this port. + */ +__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port); + +/** + * @brief Function for writing to a GPIO port. + * + * @param port is the port to write. + * + * @param value is the value to write to this port. + * + * @sa nrf_gpio_port_dir_set() + */ +__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value); + +/** + * @brief Function for setting individual pins on GPIO port. + * + * @param port is the port for which to set the pins. + * + * @param set_mask is a mask specifying which pins to set. A bit + * set to 1 indicates that the corresponding port pin shall be + * set. + * + * @sa nrf_gpio_port_dir_set() + */ +__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask); + +/** + * @brief Function for clearing individual pins on GPIO port. + * + * @param port is the port for which to clear the pins. + * + * @param clr_mask is a mask specifying which pins to clear. A bit + * set to 1 indicates that the corresponding port pin shall be + * cleared. + * + * @sa nrf_gpio_port_dir_set() + */ +__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + for (; pin_range_start <= pin_range_end; pin_range_start++) + { + nrf_gpio_cfg_output(pin_range_start); + } +} + +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + for (; pin_range_start <= pin_range_end; pin_range_start++) + { + nrf_gpio_cfg_input(pin_range_start, pull_config); + } +} + +__STATIC_INLINE void nrf_gpio_cfg( + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense) +{ + NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos); +} + +__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + +__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + +__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + +__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); +} + +__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); +} + +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + sense_config); +} + +__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + //uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk; + NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk; + NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos); +} + +__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction) +{ + if(direction == NRF_GPIO_PIN_DIR_INPUT) + { + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + } + else + { + NRF_GPIO->DIRSET = (1UL << pin_number); + } +} + +__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number) +{ + NRF_GPIO->OUTSET = (1UL << pin_number); +} + +__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask) +{ + NRF_GPIO->OUTSET = pin_mask; +} + +__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number) +{ + NRF_GPIO->OUTCLR = (1UL << pin_number); +} + +__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask) +{ + NRF_GPIO->OUTCLR = pin_mask; +} + +__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number) +{ + nrf_gpio_pins_toggle(1UL << pin_number); +} + +__STATIC_INLINE void nrf_gpio_pins_toggle(uint32_t pin_mask) +{ + uint32_t pins_state = NRF_GPIO->OUT; + NRF_GPIO->OUTSET = (~pins_state & pin_mask); + NRF_GPIO->OUTCLR = ( pins_state & pin_mask); +} + +__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) +{ + if (value == 0) + { + nrf_gpio_pin_clear(pin_number); + } + else + { + nrf_gpio_pin_set(pin_number); + } +} + +__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number) +{ + return ((NRF_GPIO->IN >> pin_number) & 1UL); +} + +__STATIC_INLINE uint32_t nrf_gpio_pins_read(void) +{ + return NRF_GPIO->IN; +} + +__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number) +{ + return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos); +} + +__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value) +{ + *((volatile uint8_t*)(word_address) + byte_no) = value; +} + +__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no) +{ + return (*((const volatile uint8_t*)(word_address) + byte_no)); +} + +__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir) +{ + if (dir == NRF_GPIO_PORT_DIR_OUTPUT) + { + nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF); + } + else + { + nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL); + } +} + +__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port) +{ + return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port); +} + +__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value) +{ + nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value); +} + +__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask) +{ + nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask); +} + +__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask) +{ + nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask); +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ + +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpiote.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpiote.h new file mode 100644 index 00000000..08c5d7cb --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_gpiote.h @@ -0,0 +1,408 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_GPIOTE_H__ +#define NRF_GPIOTE_H__ + +#include "nrf.h" +#include +#include +#include + +/** +* @defgroup nrf_gpiote_abs GPIOTE abstraction +* @{ +* @ingroup nrf_gpiote +* @brief GPIOTE abstraction for configuration of channels. +*/ +#ifdef NRF51 +#define NUMBER_OF_GPIO_TE 4 +#elif defined(NRF52) +#define NUMBER_OF_GPIO_TE 8 +#else +#error "Chip family not specified" +#endif + + /** + * @enum nrf_gpiote_polarity_t + * @brief Polarity for the GPIOTE channel. + */ +typedef enum +{ + NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi, ///< Low to high. + NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo, ///< High to low. + NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle ///< Toggle. +} nrf_gpiote_polarity_t; + + + /** + * @enum nrf_gpiote_outinit_t + * @brief Initial output value for the GPIOTE channel. + */ +typedef enum +{ + NRF_GPIOTE_INITIAL_VALUE_LOW = GPIOTE_CONFIG_OUTINIT_Low, ///< Low to high. + NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High ///< High to low. +} nrf_gpiote_outinit_t; + +/** + * @brief Tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_GPIOTE_TASKS_OUT_0 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/ + NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/ + NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/ + NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/ +#if (NUMBER_OF_GPIO_TE == 8) + NRF_GPIOTE_TASKS_OUT_4 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/ + NRF_GPIOTE_TASKS_OUT_5 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/ + NRF_GPIOTE_TASKS_OUT_6 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/ + NRF_GPIOTE_TASKS_OUT_7 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/ +#endif +#ifdef NRF52 + NRF_GPIOTE_TASKS_SET_0 = offsetof(NRF_GPIOTE_Type, TASKS_SET[0]), /**< Set task 0.*/ + NRF_GPIOTE_TASKS_SET_1 = offsetof(NRF_GPIOTE_Type, TASKS_SET[1]), /**< Set task 1.*/ + NRF_GPIOTE_TASKS_SET_2 = offsetof(NRF_GPIOTE_Type, TASKS_SET[2]), /**< Set task 2.*/ + NRF_GPIOTE_TASKS_SET_3 = offsetof(NRF_GPIOTE_Type, TASKS_SET[3]), /**< Set task 3.*/ + NRF_GPIOTE_TASKS_SET_4 = offsetof(NRF_GPIOTE_Type, TASKS_SET[4]), /**< Set task 4.*/ + NRF_GPIOTE_TASKS_SET_5 = offsetof(NRF_GPIOTE_Type, TASKS_SET[5]), /**< Set task 5.*/ + NRF_GPIOTE_TASKS_SET_6 = offsetof(NRF_GPIOTE_Type, TASKS_SET[6]), /**< Set task 6.*/ + NRF_GPIOTE_TASKS_SET_7 = offsetof(NRF_GPIOTE_Type, TASKS_SET[7]), /**< Set task 7.*/ + NRF_GPIOTE_TASKS_CLR_0 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[0]), /**< Clear task 0.*/ + NRF_GPIOTE_TASKS_CLR_1 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[1]), /**< Clear task 1.*/ + NRF_GPIOTE_TASKS_CLR_2 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[2]), /**< Clear task 2.*/ + NRF_GPIOTE_TASKS_CLR_3 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[3]), /**< Clear task 3.*/ + NRF_GPIOTE_TASKS_CLR_4 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[4]), /**< Clear task 4.*/ + NRF_GPIOTE_TASKS_CLR_5 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[5]), /**< Clear task 5.*/ + NRF_GPIOTE_TASKS_CLR_6 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[6]), /**< Clear task 6.*/ + NRF_GPIOTE_TASKS_CLR_7 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[7]), /**< Clear task 7.*/ +#endif + /*lint -restore*/ +} nrf_gpiote_tasks_t; + +/** + * @brief Events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_GPIOTE_EVENTS_IN_0 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/ + NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/ + NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/ + NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/ +#if (NUMBER_OF_GPIO_TE == 8) + NRF_GPIOTE_EVENTS_IN_4 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[4]), /**< In event 4.*/ + NRF_GPIOTE_EVENTS_IN_5 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[5]), /**< In event 5.*/ + NRF_GPIOTE_EVENTS_IN_6 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[6]), /**< In event 6.*/ + NRF_GPIOTE_EVENTS_IN_7 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[7]), /**< In event 7.*/ +#endif + NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/ + /*lint -restore*/ +} nrf_gpiote_events_t; + +/** + * @enum nrf_gpiote_int_t + * @brief GPIOTE interrupts. + */ +typedef enum +{ + NRF_GPIOTE_INT_IN0_MASK = GPIOTE_INTENSET_IN0_Msk, /**< GPIOTE interrupt from IN0. */ + NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */ + NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */ + NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */ +#if (NUMBER_OF_GPIO_TE == 8) + NRF_GPIOTE_INT_IN4_MASK = GPIOTE_INTENSET_IN4_Msk, /**< GPIOTE interrupt from IN4. */ + NRF_GPIOTE_INT_IN5_MASK = GPIOTE_INTENSET_IN5_Msk, /**< GPIOTE interrupt from IN5. */ + NRF_GPIOTE_INT_IN6_MASK = GPIOTE_INTENSET_IN6_Msk, /**< GPIOTE interrupt from IN6. */ + NRF_GPIOTE_INT_IN7_MASK = GPIOTE_INTENSET_IN7_Msk, /**< GPIOTE interrupt from IN7. */ +#endif + NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */ +} nrf_gpiote_int_t; + +#if (NUMBER_OF_GPIO_TE == 4) +#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ + NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK) +#elif (NUMBER_OF_GPIO_TE == 8) +#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ + NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK |\ + NRF_GPIOTE_INT_IN4_MASK | NRF_GPIOTE_INT_IN5_MASK |\ + NRF_GPIOTE_INT_IN6_MASK | NRF_GPIOTE_INT_IN7_MASK) +#else +#error "Unexpected number of GPIO Tasks and Events" +#endif +/** + * @brief Function for activating a specific GPIOTE task. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task); + +/** + * @brief Function for getting the address of a specific GPIOTE task. + * + * @param[in] task Task. + * + * @returns Address. + */ +__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task); + +/** + * @brief Function for getting the state of a specific GPIOTE event. + * + * @param[in] event Event. + */ +__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event); + +/** + * @brief Function for clearing a specific GPIOTE event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event); + +/** + * @brief Function for getting the address of a specific GPIOTE event. + * + * @param[in] event Event. + * + * @return Address + */ +__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event); + +/**@brief Function for enabling interrupts. + * + * @param[in] mask Interrupt mask to be enabled. + */ +__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask); + +/**@brief Function for disabling interrupts. + * + * @param[in] mask Interrupt mask to be disabled. + */ +__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask); + +/**@brief Function for checking if interrupts are enabled. + * + * @param[in] mask Mask of interrupt flags to check. + * + * @return Mask with enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask); + +/**@brief Function for enabling a GPIOTE event. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx); + +/**@brief Function for disabling a GPIOTE event. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx); + +/**@brief Function for configuring a GPIOTE event. + * + * @param[in] idx Task-Event index. + * @param[in] pin Pin associated with event. + * @param[in] polarity Transition that should generate an event. + */ +__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity); + +/**@brief Function for getting the pin associated with a GPIOTE event. + * + * @param[in] idx Task-Event index. + * + * @return Pin number. + */ +__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx); + +/**@brief Function for getting the polarity associated with a GPIOTE event. + * + * @param[in] idx Task-Event index. + * + * @return Polarity. + */ +__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx); + +/**@brief Function for enabling a GPIOTE task. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx); + +/**@brief Function for disabling a GPIOTE task. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx); + +/**@brief Function for configuring a GPIOTE task. + * @note Function is not configuring mode field so task is disabled after this function is called. + * + * @param[in] idx Task-Event index. + * @param[in] pin Pin associated with event. + * @param[in] polarity Transition that should generate an event. + * @param[in] init_val Initial value of pin. + */ +__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity, + nrf_gpiote_outinit_t init_val); + +/**@brief Function for forcing a specific state on the pin connected to GPIOTE. + * + * @param[in] idx Task-Event index. + * @param[in] init_val Pin state. + */ +__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val); + +/**@brief Function for resetting a GPIOTE task event configuration to the default state. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task) +{ + *(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task) +{ + return ((uint32_t)NRF_GPIOTE + task); +} + +__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event) +{ + return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false; +} + +__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event) +{ + *(uint32_t *)nrf_gpiote_event_addr_get(event) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event)); + (void)dummy; +#endif +} + +__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event) +{ + return ((uint32_t)NRF_GPIOTE + event); +} + +__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask) +{ + NRF_GPIOTE->INTENSET = mask; +} + +__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask) +{ + NRF_GPIOTE->INTENCLR = mask; +} + +__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask) +{ + return (NRF_GPIOTE->INTENSET & mask); +} + +__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event; +} + +__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event; +} + +__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity) +{ + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk); + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) | + ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk); +} + +__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx) +{ + return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PSEL_Msk) >> GPIOTE_CONFIG_PSEL_Pos); +} + +__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx) +{ + return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos); +} + +__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx) +{ + uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task; + /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens + on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the + correct state in GPIOTE but not in the OUT register. */ + /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */ + NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk); + __NOP(); + __NOP(); + __NOP(); + NRF_GPIOTE->CONFIG[idx] = final_config; +} + +__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task; +} + +__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity, + nrf_gpiote_outinit_t init_val) +{ + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | + GPIOTE_CONFIG_POLARITY_Msk | + GPIOTE_CONFIG_OUTINIT_Msk); + + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) | + ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) | + ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); +} + +__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val) +{ + NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) + | ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); +} + +__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] = 0; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ + +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_i2s.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_i2s.h new file mode 100644 index 00000000..6291b00f --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_i2s.h @@ -0,0 +1,540 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_i2s_hal I2S HAL + * @{ + * @ingroup nrf_i2s + * + * @brief @tagAPI52 Hardware access layer for managing the Inter-IC Sound (I2S) peripheral. + */ + +#ifndef NRF_I2S_H__ +#define NRF_I2S_H__ + +#include +#include +#include + +#include "nrf.h" + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set + * function call to specify that a given I2S signal (SDOUT, SDIN, or MCK) + * shall not be connected to a physical pin. + */ +#define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief I2S tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled. + NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator. + /*lint -restore*/ +} nrf_i2s_task_t; + +/** + * @brief I2S events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped. + /*lint -restore*/ +} nrf_i2s_event_t; + +/** + * @brief I2S interrupts. + */ +typedef enum +{ + NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event. + NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event. + NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event. +} nrf_i2s_int_mask_t; + +/** + * @brief I2S modes of operation. + */ +typedef enum +{ + NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode. + NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode. +} nrf_i2s_mode_t; + +/** + * @brief I2S master clock generator settings. + */ +typedef enum +{ + NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz. + NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz. + NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz. + NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz. + NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz. + NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz. + NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz. + NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz. + NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz. + NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz. + NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz. + NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz. + NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz. + NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz. + NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz. + NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz. +} nrf_i2s_mck_t; + +/** + * @brief I2S MCK/LRCK ratios. + */ +typedef enum +{ + NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32. + NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48. + NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64. + NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96. + NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128. + NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192. + NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256. + NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384. + NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512. +} nrf_i2s_ratio_t; + +/** + * @brief I2S sample widths. + */ +typedef enum +{ + NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit. + NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit. + NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit. +} nrf_i2s_swidth_t; + +/** + * @brief I2S alignments of sample within a frame. + */ +typedef enum +{ + NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned. + NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned. +} nrf_i2s_align_t; + +/** + * @brief I2S frame formats. + */ +typedef enum +{ + NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format. + NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format. +} nrf_i2s_format_t; + +/** + * @brief I2S enabled channels. + */ +typedef enum +{ + NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo. + NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only. + NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only. +} nrf_i2s_channels_t; + + +/** + * @brief Function for activating a specific I2S task. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for getting the address of a specific I2S task register. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for clearing a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for checking the state of a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for getting the address of a specific I2S event register. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_i2s I2S instance. + * @param[in] i2s_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int); + +/** + * @brief Function for enabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for disabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for configuring I2S pins. + * + * Usage of the SDOUT, SDIN, and MCK signals is optional. + * If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_i2s I2S instance. + * @param[in] sck_pin SCK pin number. + * @param[in] lrck_pin LRCK pin number. + * @param[in] mck_pin MCK pin number. + * @param[in] sdout_pin SDOUT pin number. + * @param[in] sdin_pin SDIN pin number. + */ +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin); + +/** + * @brief Function for setting the I2S peripheral configuration. + * + * @param[in] p_i2s I2S instance. + * @param[in] mode Mode of operation (master or slave). + * @param[in] format I2S frame format. + * @param[in] alignment Alignment of sample within a frame. + * @param[in] sample_width Sample width. + * @param[in] channels Enabled channels. + * @param[in] mck_setup Master clock generator setup. + * @param[in] ratio MCK/LRCK ratio. + * + * @retval true If the configuration has been set successfully. + * @retval false If the requested configuration is not allowed. + */ +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio); + +/** + * @brief Function for setting up the I2S transfer. + * + * This function sets up the RX and TX buffers and enables reception and/or + * transmission accordingly. If the transfer in a given direction is not + * required, pass NULL instead of the pointer to the corresponding buffer. + * + * @param[in] p_i2s I2S instance. + * @param[in] size Size of the buffers (in 32-bit words). + * @param[in] p_rx_buffer Pointer to the receive buffer. + * Pass NULL to disable reception. + * @param[in] p_tx_buffer Pointer to the transmit buffer. + * Pass NULL to disable transmission. + */ +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_rx_buffer, + uint32_t const * p_tx_buffer); + +/** + * @brief Function for setting the pointer to the receive buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the receive buffer. + */ +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer); + +/** + * @brief Function for getting the pointer to the receive buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the receive buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s); + +/** + * @brief Function for setting the pointer to the transmit buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the transmit buffer. + */ +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer); + +/** + * @brief Function for getting the pointer to the transmit buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the transmit buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task) +{ + return ((uint32_t)p_i2s + (uint32_t)task); +} + +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return ((uint32_t)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENSET = mask; +} + +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENCLR = mask; +} + +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int) +{ + return (bool)(p_i2s->INTENSET & i2s_int); +} + +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin) +{ + p_i2s->PSEL.SCK = sck_pin; + p_i2s->PSEL.LRCK = lrck_pin; + p_i2s->PSEL.MCK = mck_pin; + p_i2s->PSEL.SDOUT = sdout_pin; + p_i2s->PSEL.SDIN = sdin_pin; +} + +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio) +{ + if (mode == NRF_I2S_MODE_MASTER) + { + // The MCK/LRCK ratio shall be a multiple of 2 * sample width. + if (((sample_width == NRF_I2S_SWIDTH_16BIT) && + (ratio == NRF_I2S_RATIO_48X)) + || + ((sample_width == NRF_I2S_SWIDTH_24BIT) && + ((ratio == NRF_I2S_RATIO_32X) || + (ratio == NRF_I2S_RATIO_64X) || + (ratio == NRF_I2S_RATIO_128X) || + (ratio == NRF_I2S_RATIO_256X) || + (ratio == NRF_I2S_RATIO_512X)))) + { + return false; + } + } + + p_i2s->CONFIG.MODE = mode; + p_i2s->CONFIG.FORMAT = format; + p_i2s->CONFIG.ALIGN = alignment; + p_i2s->CONFIG.SWIDTH = sample_width; + p_i2s->CONFIG.CHANNELS = channels; + p_i2s->CONFIG.RATIO = ratio; + + if (mck_setup == NRF_I2S_MCK_DISABLED) + { + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + else + { + p_i2s->CONFIG.MCKFREQ = mck_setup; + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + + return true; +} + +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_buffer_rx, + uint32_t const * p_buffer_tx) +{ + p_i2s->RXTXD.MAXCNT = size; + + nrf_i2s_rx_buffer_set(p_i2s, p_buffer_rx); + p_i2s->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0; + + nrf_i2s_tx_buffer_set(p_i2s, p_buffer_tx); + p_i2s->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0; +} + +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer) +{ + p_i2s->RXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->RXD.PTR); +} + +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer) +{ + p_i2s->TXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->TXD.PTR); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_I2S_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_lpcomp.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_lpcomp.h new file mode 100644 index 00000000..3d68a7b8 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_lpcomp.h @@ -0,0 +1,384 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief LPCOMP HAL API. + */ + +#ifndef NRF_LPCOMP_H_ +#define NRF_LPCOMP_H_ + +/** + * @defgroup nrf_lpcomp_hal LPCOMP HAL + * @{ + * @ingroup nrf_lpcomp + * @brief Hardware access layer for managing the Low Power Comparator (LPCOMP). + */ + +#include "nrf.h" + +#include +#include +#include + +/** + * @enum nrf_lpcomp_ref_t + * @brief LPCOMP reference selection. + */ +typedef enum +{ +#ifdef NRF51 + NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */ +#elif defined NRF52 + NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */ +#endif + NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef | + (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */ + NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef | + (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */ +} nrf_lpcomp_ref_t; + +/** + * @enum nrf_lpcomp_input_t + * @brief LPCOMP input selection. + */ +typedef enum +{ + NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */ + NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */ + NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */ + NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */ + NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */ + NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */ + NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */ + NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */ +} nrf_lpcomp_input_t; + +/** + * @enum nrf_lpcomp_detect_t + * @brief LPCOMP detection type selection. + */ +typedef enum +{ + NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */ + NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */ + NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */ +} nrf_lpcomp_detect_t; + +/** + * @enum nrf_lpcomp_task_t + * @brief LPCOMP tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_LPCOMP_TASK_START = offsetof(NRF_LPCOMP_Type, TASKS_START), /**< LPCOMP start sampling task. */ + NRF_LPCOMP_TASK_STOP = offsetof(NRF_LPCOMP_Type, TASKS_STOP), /**< LPCOMP stop sampling task. */ + NRF_LPCOMP_TASK_SAMPLE = offsetof(NRF_LPCOMP_Type, TASKS_SAMPLE) /**< Sample comparator value. */ +} nrf_lpcomp_task_t; /*lint -restore*/ + + +/** + * @enum nrf_lpcomp_event_t + * @brief LPCOMP events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_LPCOMP_EVENT_READY = offsetof(NRF_LPCOMP_Type, EVENTS_READY), /**< LPCOMP is ready and output is valid. */ + NRF_LPCOMP_EVENT_DOWN = offsetof(NRF_LPCOMP_Type, EVENTS_DOWN), /**< Input voltage crossed the threshold going down. */ + NRF_LPCOMP_EVENT_UP = offsetof(NRF_LPCOMP_Type, EVENTS_UP), /**< Input voltage crossed the threshold going up. */ + NRF_LPCOMP_EVENT_CROSS = offsetof(NRF_LPCOMP_Type, EVENTS_CROSS) /**< Input voltage crossed the threshold in any direction. */ +} nrf_lpcomp_event_t; /*lint -restore*/ + +/** + * @enum nrf_lpcomp_short_mask_t + * @brief LPCOMP shorts masks. + */ +typedef enum +{ + NRF_LPCOMP_SHORT_CROSS_STOP_MASK = LPCOMP_SHORTS_CROSS_STOP_Msk, /*!< Short between CROSS event and STOP task. */ + NRF_LPCOMP_SHORT_UP_STOP_MASK = LPCOMP_SHORTS_UP_STOP_Msk, /*!< Short between UP event and STOP task. */ + NRF_LPCOMP_SHORT_DOWN_STOP_MASK = LPCOMP_SHORTS_DOWN_STOP_Msk, /*!< Short between DOWN event and STOP task. */ + NRF_LPCOMP_SHORT_READY_STOP_MASK = LPCOMP_SHORTS_READY_STOP_Msk, /*!< Short between READY event and STOP task. */ + NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */ +} nrf_lpcomp_short_mask_t; + + +/** @brief LPCOMP configuration. */ +typedef struct +{ + nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */ + nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */ +} nrf_lpcomp_config_t; + +/** Default LPCOMP configuration. */ +#define NRF_LPCOMP_CONFIG_DEFAULT { NRF_LPCOMP_REF_SUPPLY_FOUR_EIGHT, NRF_LPCOMP_DETECT_DOWN } + +/** + * @brief Function for configuring LPCOMP. + * + * This function powers on LPCOMP and configures it. LPCOMP is in DISABLE state after configuration, + * so it must be enabled before using it. All shorts are inactive, events are cleared, and LPCOMP is stopped. + * + * @param[in] p_config Configuration. + */ +__STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config) +{ + NRF_LPCOMP->TASKS_STOP = 1; + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->REFSEL = + (p_config->reference << LPCOMP_REFSEL_REFSEL_Pos) & LPCOMP_REFSEL_REFSEL_Msk; + + //If external source is choosen extract analog reference index. + if ((p_config->reference & LPCOMP_REFSEL_REFSEL_ARef)==LPCOMP_REFSEL_REFSEL_ARef) + { + uint32_t extref = p_config->reference >> 16; + NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk; + } + + NRF_LPCOMP->ANADETECT = + (p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk; + NRF_LPCOMP->SHORTS = 0; + NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | + LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; +} + + +/** + * @brief Function for selecting the LPCOMP input. + * + * This function selects the active input of LPCOMP. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_lpcomp_input_select(nrf_lpcomp_input_t input) +{ + uint32_t lpcomp_enable_state = NRF_LPCOMP->ENABLE; + + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->PSEL = + ((uint32_t)input << LPCOMP_PSEL_PSEL_Pos) | (NRF_LPCOMP->PSEL & ~LPCOMP_PSEL_PSEL_Msk); + NRF_LPCOMP->ENABLE = lpcomp_enable_state; +} + + +/** + * @brief Function for enabling the Low Power Comparator. + * + * This function enables LPCOMP. + * + */ +__STATIC_INLINE void nrf_lpcomp_enable(void) +{ + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->EVENTS_READY = 0; + NRF_LPCOMP->EVENTS_DOWN = 0; + NRF_LPCOMP->EVENTS_UP = 0; + NRF_LPCOMP->EVENTS_CROSS = 0; +} + + +/** + * @brief Function for disabling the Low Power Comparator. + * + * This function disables LPCOMP. + * + */ +__STATIC_INLINE void nrf_lpcomp_disable(void) +{ + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; +} + + +/** + * @brief Function for getting the last LPCOMP compare result. + * + * @return The last compare result. If 0 then VIN+ < VIN-, if 1 then the opposite. + */ +__STATIC_INLINE uint32_t nrf_lpcomp_result_get(void) +{ + return (uint32_t)NRF_LPCOMP->RESULT; +} + + +/** + * @brief Function for enabling interrupts from LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be enabled. + * + * @sa nrf_lpcomp_int_disable() + * @sa nrf_lpcomp_int_enable_check() + */ +__STATIC_INLINE void nrf_lpcomp_int_enable(uint32_t lpcomp_int_mask) +{ + NRF_LPCOMP->INTENSET = lpcomp_int_mask; +} + + +/** + * @brief Function for disabling interrupts from LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be disabled. + * + * @sa nrf_lpcomp_int_enable() + * @sa nrf_lpcomp_int_enable_check() + */ +__STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask) +{ + NRF_LPCOMP->INTENCLR = lpcomp_int_mask; +} + + +/** + * @brief Function for getting the enabled interrupts of LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be checked. + * + * @retval true If any of interrupts of the specified mask are enabled. + * + * @sa nrf_lpcomp_int_enable() + * @sa nrf_lpcomp_int_disable() + */ +__STATIC_INLINE bool nrf_lpcomp_int_enable_check(uint32_t lpcomp_int_mask) +{ + return (NRF_LPCOMP->INTENSET & lpcomp_int_mask); // when read this register will return the value of INTEN. +} + + +/** + * @brief Function for getting the address of a specific LPCOMP task register. + * + * @param[in] lpcomp_task LPCOMP task. + * + * @return The address of the specified LPCOMP task. + */ +__STATIC_INLINE uint32_t * nrf_lpcomp_task_address_get(nrf_lpcomp_task_t lpcomp_task) +{ + return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_task); +} + + +/** + * @brief Function for getting the address of a specific LPCOMP event register. + * + * @param[in] lpcomp_event LPCOMP event. + * + * @return The address of the specified LPCOMP event. + */ +__STATIC_INLINE uint32_t * nrf_lpcomp_event_address_get(nrf_lpcomp_event_t lpcomp_event) +{ + return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event); +} + + +/** + * @brief Function for setting LPCOMP shorts. + * + * @param[in] lpcomp_short_mask LPCOMP shorts by mask. + * + */ +__STATIC_INLINE void nrf_lpcomp_shorts_enable(uint32_t lpcomp_short_mask) +{ + NRF_LPCOMP->SHORTS |= lpcomp_short_mask; +} + + +/** + * @brief Function for clearing LPCOMP shorts by mask. + * + * @param[in] lpcomp_short_mask LPCOMP shorts to be cleared. + * + */ +__STATIC_INLINE void nrf_lpcomp_shorts_disable(uint32_t lpcomp_short_mask) +{ + NRF_LPCOMP->SHORTS &= ~lpcomp_short_mask; +} + + +/** + * @brief Function for setting a specific LPCOMP task. + * + * @param[in] lpcomp_task LPCOMP task to be set. + * + */ +__STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_task) ) = 1; +} + + +/** + * @brief Function for clearing a specific LPCOMP event. + * + * @param[in] lpcomp_event LPCOMP event to be cleared. + * + */ +__STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0; +} + + +/** + * @brief Function for getting the state of a specific LPCOMP event. + * + * @retval true If the specified LPCOMP event is active. + * + */ +__STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event) +{ + return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event)); +} + + +/** + *@} + **/ + +#endif /* NRF_LPCOMP_H_ */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.c b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.c new file mode 100644 index 00000000..c9f8cbab --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.c @@ -0,0 +1,136 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + * + * + * $LastChangedRevision: 17685 $ + */ + +/** + *@file + *@brief NMVC driver implementation + */ + +#include +#include "nrf.h" +#include "nrf_nvmc.h" + + +void nrf_nvmc_page_erase(uint32_t address) +{ + // Enable erase. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + // Erase the page + NRF_NVMC->ERASEPAGE = address; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + + +void nrf_nvmc_write_byte(uint32_t address, uint8_t value) +{ + uint32_t byte_shift = address & (uint32_t)0x03; + uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. + uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); + value32 = value32 + ((uint32_t)value << (byte_shift << 3)); + + // Enable write. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + *(uint32_t*)address32 = value32; + while(NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + { + } +} + +void nrf_nvmc_write_word(uint32_t address, uint32_t value) +{ + // Enable write. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + *(uint32_t*)address = value; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes) +{ + uint32_t i; + for(i=0;iCONFIG = NVMC_CONFIG_WEN_Wen; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + for(i=0;iREADY == NVMC_READY_READY_Busy) + { + } + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.h new file mode 100644 index 00000000..ac9af6cd --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_nvmc.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + * + * $LastChangedRevision: 17685 $ + */ + +/** + * @file + * @brief NMVC driver API. + */ + +#ifndef NRF_NVMC_H__ +#define NRF_NVMC_H__ + +#include + + +/** + * @defgroup nrf_nvmc Non-volatile memory controller + * @{ + * @ingroup nrf_drivers + * @brief Driver for the NVMC peripheral. + * + * This driver allows writing to the non-volatile memory (NVM) regions + * of the chip. In order to write to NVM the controller must be powered + * on and the relevant page must be erased. + * + */ + + +/** + * @brief Erase a page in flash. This is required before writing to any + * address in the page. + * + * @param address Start address of the page. + */ +void nrf_nvmc_page_erase(uint32_t address); + + +/** + * @brief Write a single byte to flash. + * + * The function reads the word containing the byte, and then + * rewrites the entire word. + * + * @param address Address to write to. + * @param value Value to write. + */ +void nrf_nvmc_write_byte(uint32_t address , uint8_t value); + + +/** + * @brief Write a 32-bit word to flash. + * @param address Address to write to. + * @param value Value to write. + */ +void nrf_nvmc_write_word(uint32_t address, uint32_t value); + + +/** + * @brief Write consecutive bytes to flash. + * + * @param address Address to write to. + * @param src Pointer to data to copy from. + * @param num_bytes Number of bytes in src to write. + */ +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes); + + +/** + * @brief Write consecutive words to flash. + * + * @param address Address to write to. + * @param src Pointer to data to copy from. + * @param num_words Number of bytes in src to write. + */ +void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words); + + +#endif // NRF_NVMC_H__ +/** @} */ + + diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pdm.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pdm.h new file mode 100644 index 00000000..511cb0c0 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pdm.h @@ -0,0 +1,376 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_PDM_H_ +#define NRF_PDM_H_ + +/** + * @defgroup nrf_pdm_hal PDM HAL + * @{ + * @ingroup nrf_pdm + * + * @brief @tagAPI52 Hardware abstraction layer for accessing the pulse density modulation (PDM) peripheral. + */ + +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + + +#define NRF_PDM_GAIN_MINIMUM 0x00 +#define NRF_PDM_GAIN_DEFAULT 0x28 +#define NRF_PDM_GAIN_MAXIMUM 0x50 + +typedef uint8_t nrf_pdm_gain_t; + + +/** + * @brief PDM tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START), ///< Starts continuous PDM transfer. + NRF_PDM_TASK_STOP = offsetof(NRF_PDM_Type, TASKS_STOP) ///< Stops PDM transfer. +} nrf_pdm_task_t; + + +/** + * @brief PDM events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer has started. + NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer has finished. + NRF_PDM_EVENT_END = offsetof(NRF_PDM_Type, EVENTS_END) ///< The PDM has written the last sample specified by SAMPLE.MAXCNT (or the last sample after a STOP task has been received) to Data RAM. +} nrf_pdm_event_t; + + +/** + * @brief PDM interrupt masks. + */ +typedef enum +{ + NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_PDM_INT_END = PDM_INTENSET_END_Msk ///< Interrupt on EVENTS_END event. +} nrf_pdm_int_mask_t; + +/** + * @brief PDM clock frequency. + */ +typedef enum +{ + NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K, ///< PDM_CLK = 1.000 MHz. + NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz. + NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K ///< PDM_CLK = 1.067 MHz. +} nrf_pdm_freq_t; + + +/** + * @brief PDM operation mode. + */ +typedef enum +{ + NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo, ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word. + NRF_PDM_MODE_MONO = PDM_MODE_OPERATION_Mono ///< Sample and store two successive Left samples (16 bit each) per RAM word. +} nrf_pdm_mode_t; + + +/** + * @brief PDM sampling mode. + */ +typedef enum +{ + NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling, ///< Left (or mono) is sampled on falling edge of PDM_CLK. + NRF_PDM_EDGE_LEFTRISING = PDM_MODE_EDGE_LeftRising ///< Left (or mono) is sampled on rising edge of PDM_CLK. +} nrf_pdm_edge_t; + + +/** + * @brief Function for triggering a PDM task. + * + * @param[in] pdm_task PDM task. + */ +__STATIC_INLINE void nrf_pdm_task_trigger(nrf_pdm_task_t pdm_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_task)) = 0x1UL; +} + + +/** + * @brief Function for getting the address of a PDM task register. + * + * @param[in] pdm_task PDM task. + * + * @return Address of the specified PDM task. + */ +__STATIC_INLINE uint32_t nrf_pdm_task_address_get(nrf_pdm_task_t pdm_task) +{ + return (uint32_t)((uint8_t *)NRF_PDM + (uint32_t)pdm_task); +} + + +/** + * @brief Function for getting the state of a PDM event. + * + * @param[in] pdm_event PDM event. + * + * @return State of the specified PDM event. + */ +__STATIC_INLINE bool nrf_pdm_event_check(nrf_pdm_event_t pdm_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for clearing a PDM event. + * + * @param[in] pdm_event PDM event. + */ +__STATIC_INLINE void nrf_pdm_event_clear(nrf_pdm_event_t pdm_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)) = 0x0UL; +} + + +/** + * @brief Function for getting the address of a PDM event register. + * + * @param[in] pdm_event PDM event. + * + * @return Address of the specified PDM event. + */ +__STATIC_INLINE volatile uint32_t * nrf_pdm_event_address_get(nrf_pdm_event_t pdm_event) +{ + return (volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for enabling PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pdm_int_enable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENSET = pdm_int_mask; +} + + +/** + * @brief Function for retrieving the state of PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to check. + * + * @retval true If all specified interrupts are enabled. + * @retval false If at least one of the given interrupts is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_int_enable_check(uint32_t pdm_int_mask) +{ + return (bool)(NRF_PDM->INTENSET & pdm_int_mask); +} + + +/** + * @brief Function for disabling interrupts. + * + * @param pdm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pdm_int_disable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENCLR = pdm_int_mask; +} + + +/** + * @brief Function for enabling the PDM peripheral. + * + * The PDM peripheral must be enabled before use. + */ +__STATIC_INLINE void nrf_pdm_enable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for disabling the PDM peripheral. + */ +__STATIC_INLINE void nrf_pdm_disable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for checking if the PDM peripheral is enabled. + * + * @retval true If the PDM peripheral is enabled. + * @retval false If the PDM peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_enable_check(void) +{ + return (NRF_PDM->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos)); +} + + +/** + * @brief Function for setting the PDM operation mode. + * + * @param[in] pdm_mode PDM operation mode. + * @param[in] pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_set(nrf_pdm_mode_t pdm_mode, nrf_pdm_edge_t pdm_edge) +{ + NRF_PDM->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk) + | ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk); +} + + +/** + * @brief Function for getting the PDM operation mode. + * + * @param[out] p_pdm_mode PDM operation mode. + * @param[out] p_pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_get(nrf_pdm_mode_t * p_pdm_mode, nrf_pdm_edge_t * p_pdm_edge) +{ + uint32_t mode = NRF_PDM->MODE; + *p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos); + *p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos); +} + + +/** + * @brief Function for setting the PDM clock frequency. + * + * @param[in] pdm_freq PDM clock frequency. + */ +__STATIC_INLINE void nrf_pdm_clock_set(nrf_pdm_freq_t pdm_freq) +{ + NRF_PDM->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for getting the PDM clock frequency. + */ +__STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(void) +{ + return (nrf_pdm_freq_t) ((NRF_PDM->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for setting up the PDM pins. + * + * @param[in] psel_clk CLK pin number. + * @param[in] psel_din DIN pin number. + */ +__STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din) +{ + NRF_PDM->PSEL.CLK = ((psel_clk << PDM_PSEL_CLK_PIN_Pos) & PDM_PSEL_CLK_PIN_Msk) + | ((PDM_PSEL_CLK_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_CLK_CONNECT_Msk); + NRF_PDM->PSEL.DIN = ((psel_din << PDM_PSEL_DIN_PIN_Pos) & PDM_PSEL_DIN_PIN_Msk) + | ((PDM_PSEL_DIN_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_DIN_CONNECT_Msk); +} + +/** + * @brief Function for disconnecting the PDM pins. + */ +__STATIC_INLINE void nrf_pdm_psel_disconnect() +{ + NRF_PDM->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos) + & PDM_PSEL_CLK_CONNECT_Msk); + NRF_PDM->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos) + & PDM_PSEL_DIN_CONNECT_Msk); +} + + +/** + * @brief Function for setting the PDM gain. + * + * @param[in] gain_l Left channel gain. + * @param[in] gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_set(nrf_pdm_gain_t gain_l, nrf_pdm_gain_t gain_r) +{ + NRF_PDM->GAINL = gain_l; + NRF_PDM->GAINR = gain_r; +} + + +/** + * @brief Function for getting the PDM gain. + * + * @param[out] p_gain_l Left channel gain. + * @param[out] p_gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_get(nrf_pdm_gain_t * p_gain_l, nrf_pdm_gain_t * p_gain_r) +{ + *p_gain_l = NRF_PDM->GAINL; + *p_gain_r = NRF_PDM->GAINR; +} + + +/** + * @brief Function for setting the PDM sample buffer. + * + * @param[in] p_buffer Pointer to the RAM address where samples should be written with EasyDMA. + * @param[in] num Number of samples to allocate memory for in EasyDMA mode. + * + * The amount of allocated RAM depends on the operation mode. + * - For stereo mode: N 32-bit words. + * - For mono mode: Ceil(N/2) 32-bit words. + */ +__STATIC_INLINE void nrf_pdm_buffer_set(uint32_t * p_buffer, uint32_t num) +{ + NRF_PDM->SAMPLE.PTR = (uint32_t)p_buffer; + NRF_PDM->SAMPLE.MAXCNT = num; +} + +/** + * @brief Function for getting the current PDM sample buffer address. + * + * @return Pointer to the current sample buffer. + */ +__STATIC_INLINE uint32_t * nrf_pdm_buffer_get() +{ + return (uint32_t *)NRF_PDM->SAMPLE.PTR; +} + + +/** + *@} + **/ + +#endif /* NRF_PDM_H_ */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ppi.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ppi.h new file mode 100644 index 00000000..74cea745 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_ppi.h @@ -0,0 +1,419 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_PPI_H__ +#define NRF_PPI_H__ + +#include +#include "nrf.h" + +/** + * @defgroup nrf_ppi_hal PPI HAL + * @{ + * @ingroup nrf_ppi + * @brief Hardware access layer for setting up Programmable Peripheral Interconnect (PPI) channels. + */ + +#define NRF_PPI_TASK_SET (1UL) + +/** + * @enum nrf_ppi_channel_t + * @brief PPI channels. + */ +typedef enum +{ + NRF_PPI_CHANNEL0 = PPI_CHEN_CH0_Pos, /**< Channel 0. */ + NRF_PPI_CHANNEL1 = PPI_CHEN_CH1_Pos, /**< Channel 1. */ + NRF_PPI_CHANNEL2 = PPI_CHEN_CH2_Pos, /**< Channel 2. */ + NRF_PPI_CHANNEL3 = PPI_CHEN_CH3_Pos, /**< Channel 3. */ + NRF_PPI_CHANNEL4 = PPI_CHEN_CH4_Pos, /**< Channel 4. */ + NRF_PPI_CHANNEL5 = PPI_CHEN_CH5_Pos, /**< Channel 5. */ + NRF_PPI_CHANNEL6 = PPI_CHEN_CH6_Pos, /**< Channel 6. */ + NRF_PPI_CHANNEL7 = PPI_CHEN_CH7_Pos, /**< Channel 7. */ + NRF_PPI_CHANNEL8 = PPI_CHEN_CH8_Pos, /**< Channel 8. */ + NRF_PPI_CHANNEL9 = PPI_CHEN_CH9_Pos, /**< Channel 9. */ + NRF_PPI_CHANNEL10 = PPI_CHEN_CH10_Pos, /**< Channel 10. */ + NRF_PPI_CHANNEL11 = PPI_CHEN_CH11_Pos, /**< Channel 11. */ + NRF_PPI_CHANNEL12 = PPI_CHEN_CH12_Pos, /**< Channel 12. */ + NRF_PPI_CHANNEL13 = PPI_CHEN_CH13_Pos, /**< Channel 13. */ + NRF_PPI_CHANNEL14 = PPI_CHEN_CH14_Pos, /**< Channel 14. */ + NRF_PPI_CHANNEL15 = PPI_CHEN_CH15_Pos, /**< Channel 15. */ +#ifdef NRF52 + NRF_PPI_CHANNEL16 = PPI_CHEN_CH16_Pos, /**< Channel 16. */ + NRF_PPI_CHANNEL17 = PPI_CHEN_CH17_Pos, /**< Channel 17. */ + NRF_PPI_CHANNEL18 = PPI_CHEN_CH18_Pos, /**< Channel 18. */ + NRF_PPI_CHANNEL19 = PPI_CHEN_CH19_Pos, /**< Channel 19. */ +#endif + NRF_PPI_CHANNEL20 = PPI_CHEN_CH20_Pos, /**< Channel 20. */ + NRF_PPI_CHANNEL21 = PPI_CHEN_CH21_Pos, /**< Channel 21. */ + NRF_PPI_CHANNEL22 = PPI_CHEN_CH22_Pos, /**< Channel 22. */ + NRF_PPI_CHANNEL23 = PPI_CHEN_CH23_Pos, /**< Channel 23. */ + NRF_PPI_CHANNEL24 = PPI_CHEN_CH24_Pos, /**< Channel 24. */ + NRF_PPI_CHANNEL25 = PPI_CHEN_CH25_Pos, /**< Channel 25. */ + NRF_PPI_CHANNEL26 = PPI_CHEN_CH26_Pos, /**< Channel 26. */ + NRF_PPI_CHANNEL27 = PPI_CHEN_CH27_Pos, /**< Channel 27. */ + NRF_PPI_CHANNEL28 = PPI_CHEN_CH28_Pos, /**< Channel 28. */ + NRF_PPI_CHANNEL29 = PPI_CHEN_CH29_Pos, /**< Channel 29. */ + NRF_PPI_CHANNEL30 = PPI_CHEN_CH30_Pos, /**< Channel 30. */ + NRF_PPI_CHANNEL31 = PPI_CHEN_CH31_Pos /**< Channel 31. */ +} nrf_ppi_channel_t; + +/** + * @enum nrf_ppi_channel_group_t + * @brief PPI channel groups. + */ +typedef enum +{ + NRF_PPI_CHANNEL_GROUP0 = 0, /**< Channel group 0. */ + NRF_PPI_CHANNEL_GROUP1 = 1, /**< Channel group 1. */ + NRF_PPI_CHANNEL_GROUP2 = 2, /**< Channel group 2. */ + NRF_PPI_CHANNEL_GROUP3 = 3, /**< Channel group 3. */ +#ifdef NRF52 + NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */ + NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */ +#endif +} nrf_ppi_channel_group_t; + +/** + * @enum nrf_ppi_channel_include_t + * @brief Definition of which PPI channels belong to a group. + */ +typedef enum +{ + NRF_PPI_CHANNEL_EXCLUDE = PPI_CHG_CH0_Excluded, /**< Channel excluded from a group. */ + NRF_PPI_CHANNEL_INCLUDE = PPI_CHG_CH0_Included /**< Channel included in a group. */ +} nrf_ppi_channel_include_t; + +/** + * @enum nrf_ppi_channel_enable_t + * @brief Definition if a PPI channel is enabled. + */ +typedef enum +{ + NRF_PPI_CHANNEL_DISABLED = PPI_CHEN_CH0_Disabled, /**< Channel disabled. */ + NRF_PPI_CHANNEL_ENABLED = PPI_CHEN_CH0_Enabled /**< Channel enabled. */ +} nrf_ppi_channel_enable_t; + +/** + * @enum nrf_ppi_task_t + * @brief PPI tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_PPI_TASK_CHG0_EN = offsetof(NRF_PPI_Type, TASKS_CHG[0].EN), /**< Task for enabling channel group 0 */ + NRF_PPI_TASK_CHG0_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[0].DIS), /**< Task for disabling channel group 0 */ + NRF_PPI_TASK_CHG1_EN = offsetof(NRF_PPI_Type, TASKS_CHG[1].EN), /**< Task for enabling channel group 1 */ + NRF_PPI_TASK_CHG1_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[1].DIS), /**< Task for disabling channel group 1 */ + NRF_PPI_TASK_CHG2_EN = offsetof(NRF_PPI_Type, TASKS_CHG[2].EN), /**< Task for enabling channel group 2 */ + NRF_PPI_TASK_CHG2_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[2].DIS), /**< Task for disabling channel group 2 */ + NRF_PPI_TASK_CHG3_EN = offsetof(NRF_PPI_Type, TASKS_CHG[3].EN), /**< Task for enabling channel group 3 */ + NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS), /**< Task for disabling channel group 3 */ +#ifdef NRF52 + NRF_PPI_TASK_CHG4_EN = offsetof(NRF_PPI_Type, TASKS_CHG[4].EN), /**< Task for enabling channel group 4 */ + NRF_PPI_TASK_CHG4_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[4].DIS), /**< Task for disabling channel group 4 */ + NRF_PPI_TASK_CHG5_EN = offsetof(NRF_PPI_Type, TASKS_CHG[5].EN), /**< Task for enabling channel group 5 */ + NRF_PPI_TASK_CHG5_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[5].DIS) /**< Task for disabling channel group 5 */ +#endif + /*lint -restore*/ +} nrf_ppi_task_t; + +/** + * @brief Function for enabling a given PPI channel. + * + * @details This function enables only one channel. + * + * @param[in] channel Channel to enable. + * + * */ +__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel) +{ + NRF_PPI->CHENSET = PPI_CHENSET_CH0_Set << ((uint32_t) channel); +} + + +/** + * @brief Function for disabling a given PPI channel. + * + * @details This function disables only one channel. + * + * @param[in] channel Channel to disable. + */ +__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_t channel) +{ + NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Clear << ((uint32_t) channel); +} + + +/** + * @brief Function for checking if a given PPI channel is enabled. + * + * @details This function checks only one channel. + * + * @param[in] channel Channel to check. + * + * @retval NRF_PPI_CHANNEL_ENABLED If the channel is enabled. + * @retval NRF_PPI_CHANNEL_DISABLED If the channel is not enabled. + * + */ +__STATIC_INLINE nrf_ppi_channel_enable_t nrf_ppi_channel_enable_get(nrf_ppi_channel_t channel) +{ + if (NRF_PPI->CHEN & (PPI_CHEN_CH0_Msk << ((uint32_t) channel))) + { + return NRF_PPI_CHANNEL_ENABLED; + } + else + { + return NRF_PPI_CHANNEL_DISABLED; + } +} + + +/** + * @brief Function for disabling all PPI channels. + */ +__STATIC_INLINE void nrf_ppi_channel_disable_all(void) +{ + NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL); +} + +/** + * @brief Function for disabling multiple PPI channels. + * + * @param[in] mask Channel mask. + */ +__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask) +{ + NRF_PPI->CHENCLR = mask; +} + +/** + * @brief Function for setting up event and task endpoints for a given PPI channel. + * + * @param[in] eep Event register address. + * + * @param[in] tep Task register address. + * + * @param[in] channel Channel to which the given endpoints are assigned. + */ +__STATIC_INLINE void nrf_ppi_channel_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t eep, + uint32_t tep) +{ + NRF_PPI->CH[(uint32_t) channel].EEP = eep; + NRF_PPI->CH[(uint32_t) channel].TEP = tep; +} + +#ifdef NRF52 +/** + * @brief Function for setting up task endpoint for a given PPI fork. + * + * @param[in] fork_tep Task register address. + * + * @param[in] channel Channel to which the given fork endpoint is assigned. + */ +__STATIC_INLINE void nrf_ppi_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t fork_tep) +{ + NRF_PPI->FORK[(uint32_t) channel].TEP = fork_tep; +} + +/** + * @brief Function for setting up event and task endpoints for a given PPI channel and fork. + * + * @param[in] eep Event register address. + * + * @param[in] tep Task register address. + * + * @param[in] fork_tep Fork task register address (register value). + * + * @param[in] channel Channel to which the given endpoints are assigned. + */ +__STATIC_INLINE void nrf_ppi_channel_and_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t eep, + uint32_t tep, + uint32_t fork_tep) +{ + nrf_ppi_channel_endpoint_setup(channel, eep, tep); + nrf_ppi_fork_endpoint_setup(channel, fork_tep); +} +#endif + +/** + * @brief Function for including a PPI channel in a channel group. + * + * @details This function adds only one channel to the group. + * + * @param[in] channel Channel to be included in the group. + * + * @param[in] channel_group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channel_include_in_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] | (PPI_CHG_CH0_Included << ((uint32_t) channel)); +} + +/** + * @brief Function for including multiple PPI channels in a channel group. + * + * @details This function adds all specified channels to the group. + * + * @param[in] channel_mask Channels to be included in the group. + * + * @param[in] channel_group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channels_include_in_group(uint32_t channel_mask, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] | (channel_mask); +} + + +/** + * @brief Function for removing a PPI channel from a channel group. + * + * @details This function removes only one channel from the group. + * + * @param[in] channel Channel to be removed from the group. + * + * @param[in] channel_group Channel group. + */ +__STATIC_INLINE void nrf_ppi_channel_remove_from_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] & ~(PPI_CHG_CH0_Included << ((uint32_t) channel)); +} + +/** + * @brief Function for removing multiple PPI channels from a channel group. + * + * @details This function removes all specified channels from the group. + * + * @param[in] channel_mask Channels to be removed from the group. + * + * @param[in] channel_group Channel group. + */ +__STATIC_INLINE void nrf_ppi_channels_remove_from_group(uint32_t channel_mask, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] & ~(channel_mask); +} + + +/** + * @brief Function for removing all PPI channels from a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channel_group_clear(nrf_ppi_channel_group_t group) +{ + NRF_PPI->CHG[(uint32_t) group] = 0; +} + + +/** + * @brief Function for enabling a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_group_enable(nrf_ppi_channel_group_t group) +{ + NRF_PPI->TASKS_CHG[(uint32_t) group].EN = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for disabling a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_group_disable(nrf_ppi_channel_group_t group) +{ + NRF_PPI->TASKS_CHG[(uint32_t) group].DIS = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for setting a PPI task. + * + * @param[in] ppi_task PPI task to set. + */ +__STATIC_INLINE void nrf_ppi_task_trigger(nrf_ppi_task_t ppi_task) +{ + *((volatile uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task)) = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for returning the address of a specific PPI task register. + * + * @param[in] ppi_task PPI task. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_address_get(nrf_ppi_task_t ppi_task) +{ + return (uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task); +} + +/** + * @brief Function for returning the PPI enable task address of a specific group. + * + * @param[in] group PPI group. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_group_enable_address_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].EN; +} + +/** + * @brief Function for returning the PPI disable task address of a specific group. + * + * @param[in] group PPI group. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].DIS; +} + + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ +#endif // NRF_PPI_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pwm.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pwm.h new file mode 100644 index 00000000..8eabb5c0 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_pwm.h @@ -0,0 +1,678 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_pwm_hal PWM HAL + * @{ + * @ingroup nrf_pwm + * + * @brief @tagAPI52 Hardware access layer for managing the Pulse Width Modulation (PWM) + * peripheral. + */ + +#ifndef NRF_PWM_H__ +#define NRF_PWM_H__ + +#include +#include +#include + +#include "nrf.h" +#include "nrf_assert.h" + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set + * function call to specify that a given output channel shall not be + * connected to a physical pin. + */ +#define NRF_PWM_PIN_NOT_CONNECTED 0xFFFFFFFF + +/** + * @brief Number of channels in each PWM instance. + */ +#define NRF_PWM_CHANNEL_COUNT 4 + + +/** + * @brief PWM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_TASK_STOP = offsetof(NRF_PWM_Type, TASKS_STOP), ///< Stops PWM pulse generation on all channels at the end of the current PWM period, and stops the sequence playback. + NRF_PWM_TASK_SEQSTART0 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[0]), ///< Starts playback of sequence 0. + NRF_PWM_TASK_SEQSTART1 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[1]), ///< Starts playback of sequence 1. + NRF_PWM_TASK_NEXTSTEP = offsetof(NRF_PWM_Type, TASKS_NEXTSTEP) ///< Steps by one value in the current sequence if the decoder is set to @ref NRF_PWM_STEP_TRIGGERED mode. + /*lint -restore*/ +} nrf_pwm_task_t; + +/** + * @brief PWM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_EVENT_STOPPED = offsetof(NRF_PWM_Type, EVENTS_STOPPED), ///< Response to STOP task, emitted when PWM pulses are no longer generated. + NRF_PWM_EVENT_SEQSTARTED0 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[0]), ///< First PWM period started on sequence 0. + NRF_PWM_EVENT_SEQSTARTED1 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[1]), ///< First PWM period started on sequence 1. + NRF_PWM_EVENT_SEQEND0 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[0]), ///< Emitted at the end of every sequence 0 when its last value has been read from RAM. + NRF_PWM_EVENT_SEQEND1 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[1]), ///< Emitted at the end of every sequence 1 when its last value has been read from RAM. + NRF_PWM_EVENT_PWMPERIODEND = offsetof(NRF_PWM_Type, EVENTS_PWMPERIODEND), ///< Emitted at the end of each PWM period. + NRF_PWM_EVENT_LOOPSDONE = offsetof(NRF_PWM_Type, EVENTS_LOOPSDONE) ///< Concatenated sequences have been played the requested number of times. + /*lint -restore*/ +} nrf_pwm_event_t; + +/** + * @brief PWM interrupts. + */ +typedef enum +{ + NRF_PWM_INT_STOPPED_MASK = PWM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_PWM_INT_SEQSTARTED0_MASK = PWM_INTENSET_SEQSTARTED0_Msk, ///< Interrupt on SEQSTARTED[0] event. + NRF_PWM_INT_SEQSTARTED1_MASK = PWM_INTENSET_SEQSTARTED1_Msk, ///< Interrupt on SEQSTARTED[1] event. + NRF_PWM_INT_SEQEND0_MASK = PWM_INTENSET_SEQEND0_Msk, ///< Interrupt on SEQEND[0] event. + NRF_PWM_INT_SEQEND1_MASK = PWM_INTENSET_SEQEND1_Msk, ///< Interrupt on SEQEND[1] event. + NRF_PWM_INT_PWMPERIODEND_MASK = PWM_INTENSET_PWMPERIODEND_Msk, ///< Interrupt on PWMPERIODEND event. + NRF_PWM_INT_LOOPSDONE_MASK = PWM_INTENSET_LOOPSDONE_Msk ///< Interrupt on LOOPSDONE event. +} nrf_pwm_int_mask_t; + +/** + * @brief PWM shortcuts. + */ +typedef enum +{ + NRF_PWM_SHORT_SEQEND0_STOP_MASK = PWM_SHORTS_SEQEND0_STOP_Msk, ///< Shortcut between SEQEND[0] event and STOP task. + NRF_PWM_SHORT_SEQEND1_STOP_MASK = PWM_SHORTS_SEQEND1_STOP_Msk, ///< Shortcut between SEQEND[1] event and STOP task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[0] task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[1] task. + NRF_PWM_SHORT_LOOPSDONE_STOP_MASK = PWM_SHORTS_LOOPSDONE_STOP_Msk ///< Shortcut between LOOPSDONE event and STOP task. +} nrf_pwm_short_mask_t; + +/** + * @brief PWM modes of operation. + */ +typedef enum +{ + NRF_PWM_MODE_UP = PWM_MODE_UPDOWN_Up, ///< Up counter (edge-aligned PWM duty cycle). + NRF_PWM_MODE_UP_AND_DOWN = PWM_MODE_UPDOWN_UpAndDown, ///< Up and down counter (center-aligned PWM duty cycle). +} nrf_pwm_mode_t; + +/** + * @brief PWM base clock frequencies. + */ +typedef enum +{ + NRF_PWM_CLK_16MHz = PWM_PRESCALER_PRESCALER_DIV_1, ///< 16 MHz / 1 = 16 MHz. + NRF_PWM_CLK_8MHz = PWM_PRESCALER_PRESCALER_DIV_2, ///< 16 MHz / 2 = 8 MHz. + NRF_PWM_CLK_4MHz = PWM_PRESCALER_PRESCALER_DIV_4, ///< 16 MHz / 4 = 4 MHz. + NRF_PWM_CLK_2MHz = PWM_PRESCALER_PRESCALER_DIV_8, ///< 16 MHz / 8 = 2 MHz. + NRF_PWM_CLK_1MHz = PWM_PRESCALER_PRESCALER_DIV_16, ///< 16 MHz / 16 = 1 MHz. + NRF_PWM_CLK_500kHz = PWM_PRESCALER_PRESCALER_DIV_32, ///< 16 MHz / 32 = 500 kHz. + NRF_PWM_CLK_250kHz = PWM_PRESCALER_PRESCALER_DIV_64, ///< 16 MHz / 64 = 250 kHz. + NRF_PWM_CLK_125kHz = PWM_PRESCALER_PRESCALER_DIV_128 ///< 16 MHz / 128 = 125 kHz. +} nrf_pwm_clk_t; + +/** + * @brief PWM decoder load modes. + * + * The selected mode determines how the sequence data is read from RAM and + * spread to the compare registers. + */ +typedef enum +{ + NRF_PWM_LOAD_COMMON = PWM_DECODER_LOAD_Common, ///< 1st half word (16-bit) used in all PWM channels (0-3). + NRF_PWM_LOAD_GROUPED = PWM_DECODER_LOAD_Grouped, ///< 1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3. + NRF_PWM_LOAD_INDIVIDUAL = PWM_DECODER_LOAD_Individual, ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3. + NRF_PWM_LOAD_WAVE_FORM = PWM_DECODER_LOAD_WaveForm ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter. +} nrf_pwm_dec_load_t; + +/** + * @brief PWM decoder next step modes. + * + * The selected mode determines when the next value from the active sequence + * is loaded. + */ +typedef enum +{ + NRF_PWM_STEP_AUTO = PWM_DECODER_MODE_RefreshCount, ///< Automatically after the current value is played and repeated the requested number of times. + NRF_PWM_STEP_TRIGGERED = PWM_DECODER_MODE_NextStep ///< When the @ref NRF_PWM_TASK_NEXTSTEP task is triggered. +} nrf_pwm_dec_step_t; + + +/** + * @brief Type used for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_COMMON mode. + */ +typedef uint16_t nrf_pwm_values_common_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_GROUPED mode. + */ +typedef struct { + uint16_t group_0; ///< Duty cycle value for group 0 (channels 0 and 1). + uint16_t group_1; ///< Duty cycle value for group 1 (channels 2 and 3). +} nrf_pwm_values_grouped_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + */ +typedef struct +{ + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t channel_3; ///< Duty cycle value for channel 3. +} nrf_pwm_values_individual_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_WAVE_FORM mode. + */ +typedef struct { + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t counter_top; ///< Top value for the pulse generator counter. +} nrf_pwm_values_wave_form_t; + +/** + * @brief Union grouping pointers to arrays of duty cycle values applicable to + * various loading modes. + */ +typedef union { + nrf_pwm_values_common_t const * p_common; ///< Pointer to be used in @ref NRF_PWM_LOAD_COMMON mode. + nrf_pwm_values_grouped_t const * p_grouped; ///< Pointer to be used in @ref NRF_PWM_LOAD_GROUPED mode. + nrf_pwm_values_individual_t const * p_individual; ///< Pointer to be used in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + nrf_pwm_values_wave_form_t const * p_wave_form; ///< Pointer to be used in @ref NRF_PWM_LOAD_WAVE_FORM mode. + uint16_t const * p_raw; ///< Pointer providing raw access to the values. +} nrf_pwm_values_t; + +/** + * @brief Structure for defining a sequence of PWM duty cycles. + * + * When the sequence is set (by a call to @ref nrf_pwm_sequence_set), the + * provided duty cycle values are not copied. The @p values pointer is stored + * in the peripheral's internal register, and the values are loaded from RAM + * during the sequence playback. Therefore, you must ensure that the values + * do not change before and during the sequence playback (for example, + * the values cannot be placed in a local variable that is allocated on stack). + * If the sequence is played in a loop and the values should be updated + * before the next iteration, it is safe to modify them when the corresponding + * event signaling the end of sequence occurs (@ref NRF_PWM_EVENT_SEQEND0 + * or @ref NRF_PWM_EVENT_SEQEND1, respectively). + * + * @note The @p repeats and @p end_delay values (which are written to the + * SEQ[n].REFRESH and SEQ[n].ENDDELAY registers in the peripheral, + * respectively) are ignored at the end of a complex sequence + * playback, indicated by the LOOPSDONE event. + * See the @linkProductSpecification52 for more information. + */ +typedef struct +{ + nrf_pwm_values_t values; ///< Pointer to an array with duty cycle values. This array must be in Data RAM. + /**< This field is defined as an union of pointers + * to provide a convenient way to define duty + * cycle values in various loading modes + * (see @ref nrf_pwm_dec_load_t). + * In each value, the most significant bit (15) + * determines the polarity of the output and the + * others (14-0) compose the 15-bit value to be + * compared with the pulse generator counter. */ + uint16_t length; ///< Number of 16-bit values in the array pointed by @p values. + uint32_t repeats; ///< Number of times that each duty cycle should be repeated (after being played once). Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. + uint32_t end_delay; ///< Additional time (in PWM periods) that the last duty cycle is to be kept after the sequence is played. Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. +} nrf_pwm_sequence_t; + +/** + * @brief Helper macro for calculating the number of 16-bit values in specified + * array of duty cycle values. + */ +#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array)/sizeof(uint16_t)) + + +/** + * @brief Function for activating a specific PWM task. + * + * @param[in] p_pwm PWM instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_pwm, + nrf_pwm_task_t task); + +/** + * @brief Function for getting the address of a specific PWM task register. + * + * @param[in] p_pwm PWM instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_pwm, + nrf_pwm_task_t task); + +/** + * @brief Function for clearing a specific PWM event. + * + * @param[in] p_pwm PWM instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_pwm, + nrf_pwm_event_t event); + +/** + * @brief Function for checking the state of a specific PWM event. + * + * @param[in] p_pwm PWM instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_pwm, + nrf_pwm_event_t event); + +/** + * @brief Function for getting the address of a specific PWM event register. + * + * @param[in] p_pwm PWM instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_pwm, + nrf_pwm_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for setting the configuration of PWM shortcuts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_shorts_mask Shortcuts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask); + +/** + * @brief Function for setting the configuration of PWM interrupts. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_int_mask Interrupts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_pwm PWM instance. + * @param[in] pwm_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_pwm, + nrf_pwm_int_mask_t pwm_int); + +/** + * @brief Function for enabling the PWM peripheral. + * + * @param[in] p_pwm PWM instance. + */ +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_pwm); + +/** + * @brief Function for disabling the PWM peripheral. + * + * @param[in] p_pwm PWM instance. + */ +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_pwm); + +/** + * @brief Function for assigning pins to PWM output channels. + * + * Usage of all PWM output channels is optional. If a given channel is not + * needed, pass the @ref NRF_PWM_PIN_NOT_CONNECTED value instead of its pin + * number. + * + * @param[in] p_pwm PWM instance. + * @param[in] out_pins Array with pin numbers for individual PWM output channels. + */ +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_pwm, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]); + +/** + * @brief Function for configuring the PWM peripheral. + * + * @param[in] p_pwm PWM instance. + * @param[in] base_clock Base clock frequency. + * @param[in] mode Operating mode of the pulse generator counter. + * @param[in] top_value Value up to which the pulse generator counter counts. + */ +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value); + +/** + * @brief Function for defining a sequence of PWM duty cycles. + * + * @param[in] p_pwm PWM instance. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_seq Pointer to the sequence definition. + */ +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq); + +/** + * @brief Function for modifying the pointer to the duty cycle values + * in the specified sequence. + * + * @param[in] p_pwm PWM instance. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_values Pointer to an array with duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint16_t const * p_values); + +/** + * @brief Function for modifying the total number of duty cycle values + * in the specified sequence. + * + * @param[in] p_pwm PWM instance. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] length Number of duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint16_t length); + +/** + * @brief Function for modifying the additional number of PWM periods spent + * on each duty cycle value in the specified sequence. + * + * @param[in] p_pwm PWM instance. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] refresh Number of additional PWM periods for each duty cycle value. + */ +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint32_t refresh); + +/** + * @brief Function for modifying the additional time added after the sequence + * is played. + * + * @param[in] p_pwm PWM instance. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] end_delay Number of PWM periods added at the end of the sequence. + */ +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint32_t end_delay); + +/** + * @brief Function for setting the mode of loading sequence data from RAM + * and advancing the sequence. + * + * @param[in] p_pwm PWM instance. + * @param[in] dec_load Mode of loading sequence data from RAM. + * @param[in] dec_step Mode of advancing the active sequence. + */ +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_pwm, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step); + +/** + * @brief Function for setting the number of times the sequence playback + * should be performed. + * + * This function applies to two-sequence playback (concatenated sequence 0 and 1). + * A single sequence can be played back only once. + * + * @param[in] p_pwm PWM instance. + * @param[in] loop_count Number of times to perform the sequence playback. + */ +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_pwm, + uint16_t loop_count); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_pwm, + nrf_pwm_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_pwm, + nrf_pwm_task_t task) +{ + return ((uint32_t)p_pwm + (uint32_t)task); +} + +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_pwm, + nrf_pwm_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_pwm, + nrf_pwm_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_pwm + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_pwm, + nrf_pwm_event_t event) +{ + return ((uint32_t)p_pwm + (uint32_t)event); +} + +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask) +{ + p_pwm->SHORTS |= pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask) +{ + p_pwm->SHORTS &= ~(pwm_shorts_mask); +} + +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_pwm, + uint32_t pwm_shorts_mask) +{ + p_pwm->SHORTS = pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask) +{ + p_pwm->INTENSET = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask) +{ + p_pwm->INTENCLR = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_pwm, + uint32_t pwm_int_mask) +{ + p_pwm->INTEN = pwm_int_mask; +} + +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_pwm, + nrf_pwm_int_mask_t pwm_int) +{ + return (bool)(p_pwm->INTENSET & pwm_int); +} + +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_pwm) +{ + p_pwm->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_pwm) +{ + p_pwm->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_pwm, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]) +{ + uint8_t i; + for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i) + { + p_pwm->PSEL.OUT[i] = out_pins[i]; + } +} + +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_pwm, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value) +{ + ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk); + + p_pwm->PRESCALER = base_clock; + p_pwm->MODE = mode; + p_pwm->COUNTERTOP = top_value; +} + +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq) +{ + ASSERT(p_seq != NULL); + + nrf_pwm_seq_ptr_set( p_pwm, seq_id, p_seq->values.p_raw); + nrf_pwm_seq_cnt_set( p_pwm, seq_id, p_seq->length); + nrf_pwm_seq_refresh_set( p_pwm, seq_id, p_seq->repeats); + nrf_pwm_seq_end_delay_set(p_pwm, seq_id, p_seq->end_delay); +} + +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint16_t const * p_values) +{ + ASSERT(seq_id <= 1); + ASSERT(p_values != NULL); + p_pwm->SEQ[seq_id].PTR = (uint32_t)p_values; +} + +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint16_t length) +{ + ASSERT(seq_id <= 1); + ASSERT(length != 0); + ASSERT(length <= PWM_SEQ_CNT_CNT_Msk); + p_pwm->SEQ[seq_id].CNT = length; +} + +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint32_t refresh) +{ + ASSERT(seq_id <= 1); + ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk); + p_pwm->SEQ[seq_id].REFRESH = refresh; +} + +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_pwm, + uint8_t seq_id, + uint32_t end_delay) +{ + ASSERT(seq_id <= 1); + ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk); + p_pwm->SEQ[seq_id].ENDDELAY = end_delay; +} + +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_pwm, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step) +{ + p_pwm->DECODER = ((uint32_t)dec_load << PWM_DECODER_LOAD_Pos) | + ((uint32_t)dec_step << PWM_DECODER_MODE_Pos); +} + +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_pwm, + uint16_t loop_count) +{ + p_pwm->LOOP = loop_count; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_PWM_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_qdec.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_qdec.h new file mode 100644 index 00000000..7bbbdc68 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_qdec.h @@ -0,0 +1,485 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_QDEC_H__ +#define NRF_QDEC_H__ + +#include +#include "nrf_error.h" +#include "nrf.h" + +/*lint ++flb "Enter library region" */ + +/** + * @defgroup nrf_qdec_hal QDEC HAL + * @{ + * @ingroup nrf_qdec + * @brief Hardware access layer for accessing the quadrature decoder (QDEC) peripheral. + */ + +/** + * @enum nrf_qdec_task_t + * @brief QDEC tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_QDEC_TASK_START = offsetof(NRF_QDEC_Type, TASKS_START), /**< Starting the quadrature decoder. */ + NRF_QDEC_TASK_STOP = offsetof(NRF_QDEC_Type, TASKS_STOP), /**< Stopping the quadrature decoder. */ + NRF_QDEC_TASK_READCLRACC = offsetof(NRF_QDEC_Type, TASKS_READCLRACC) /**< Reading and clearing ACC and ACCDBL registers. */ +} nrf_qdec_task_t; + +/** + * @enum nrf_qdec_event_t + * @brief QDEC events. + */ +typedef enum +{ + NRF_QDEC_EVENT_SAMPLERDY = offsetof(NRF_QDEC_Type, EVENTS_SAMPLERDY), /**< Event generated for every new sample. */ + NRF_QDEC_EVENT_REPORTRDY = offsetof(NRF_QDEC_Type, EVENTS_REPORTRDY), /**< Event generated for every new report. */ + NRF_QDEC_EVENT_ACCOF = offsetof(NRF_QDEC_Type, EVENTS_ACCOF) /**< Event generated for every accumulator overflow. */ +} nrf_qdec_event_t; /*lint -restore */ + +/** + * @enum nrf_qdec_short_mask_t + * @brief QDEC shortcuts. + */ +typedef enum +{ + NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK = QDEC_SHORTS_REPORTRDY_READCLRACC_Msk, /**< Shortcut between REPORTRDY event and READCLRACC task. */ + NRF_QDEC_SHORT_SAMPLERDY_STOP_MASK = QDEC_SHORTS_SAMPLERDY_STOP_Msk /**< Shortcut between SAMPLERDY event and STOP task. */ +} nrf_qdec_short_mask_t; + +/** + * @enum nrf_qdec_int_mask_t + * @brief QDEC interrupts. + */ +typedef enum +{ + NRF_QDEC_INT_SAMPLERDY_MASK = QDEC_INTENSET_SAMPLERDY_Msk, /**< Mask for enabling or disabling an interrupt on SAMPLERDY event. */ + NRF_QDEC_INT_REPORTRDY_MASK = QDEC_INTENSET_REPORTRDY_Msk, /**< Mask for enabling or disabling an interrupt on REPORTRDY event. */ + NRF_QDEC_INT_ACCOF_MASK = QDEC_INTENSET_ACCOF_Msk /**< Mask for enabling or disabling an interrupt on ACCOF event. */ +} nrf_qdec_int_mask_t; + +/** + * @enum nrf_qdec_enable_t + * @brief States of the enable bit. + */ +typedef enum +{ + NRF_QDEC_DISABLE = QDEC_ENABLE_ENABLE_Disabled, /**< Mask for disabling the QDEC periperal. When disabled, the QDEC decoder pins are not active. */ + NRF_QDEC_ENABLE = QDEC_ENABLE_ENABLE_Enabled /**< Mask for enabling the QDEC periperal. When enabled, the QDEC pins are active. */ +} nrf_qdec_enable_t; + + +/** + * @enum nrf_qdec_dbfen_t + * @brief States of the debounce filter enable bit. + */ +typedef enum +{ + NRF_QDEC_DBFEN_DISABLE = QDEC_DBFEN_DBFEN_Disabled, /**< Mask for disabling the debounce filter. */ + NRF_QDEC_DBFEN_ENABLE = QDEC_DBFEN_DBFEN_Enabled /**< Mask for enabling the debounce filter. */ +} nrf_qdec_dbfen_t; + +/** + * @enum nrf_qdec_ledpol_t + * @brief Active LED polarity. + */ +typedef enum +{ + NRF_QDEC_LEPOL_ACTIVE_LOW = QDEC_LEDPOL_LEDPOL_ActiveLow, /**< QDEC LED active on output pin low. */ + NRF_QDEC_LEPOL_ACTIVE_HIGH = QDEC_LEDPOL_LEDPOL_ActiveHigh /**< QDEC LED active on output pin high. */ +} nrf_qdec_ledpol_t; + + +/** + * @enum nrf_qdec_sampleper_t + * @brief Available sampling periods. + */ +typedef enum +{ + NRF_QDEC_SAMPLEPER_128us = QDEC_SAMPLEPER_SAMPLEPER_128us, /**< QDEC sampling period 128 microseconds. */ + NRF_QDEC_SAMPLEPER_256us = QDEC_SAMPLEPER_SAMPLEPER_256us, /**< QDEC sampling period 256 microseconds. */ + NRF_QDEC_SAMPLEPER_512us = QDEC_SAMPLEPER_SAMPLEPER_512us, /**< QDEC sampling period 512 microseconds. */ + NRF_QDEC_SAMPLEPER_1024us = QDEC_SAMPLEPER_SAMPLEPER_1024us, /**< QDEC sampling period 1024 microseconds. */ + NRF_QDEC_SAMPLEPER_2048us = QDEC_SAMPLEPER_SAMPLEPER_2048us, /**< QDEC sampling period 2048 microseconds. */ + NRF_QDEC_SAMPLEPER_4096us = QDEC_SAMPLEPER_SAMPLEPER_4096us, /**< QDEC sampling period 4096 microseconds. */ + NRF_QDEC_SAMPLEPER_8192us = QDEC_SAMPLEPER_SAMPLEPER_8192us, /**< QDEC sampling period 8192 microseconds. */ + NRF_QDEC_SAMPLEPER_16384us = QDEC_SAMPLEPER_SAMPLEPER_16384us /**< QDEC sampling period 16384 microseconds. */ +} nrf_qdec_sampleper_t; + +/** + * @enum nrf_qdec_reportper_t + * @brief Available report periods. + */ +typedef enum +{ + NRF_QDEC_REPORTPER_10 = QDEC_REPORTPER_REPORTPER_10Smpl, /**< QDEC report period 10 samples. */ + NRF_QDEC_REPORTPER_40 = QDEC_REPORTPER_REPORTPER_40Smpl, /**< QDEC report period 40 samples. */ + NRF_QDEC_REPORTPER_80 = QDEC_REPORTPER_REPORTPER_80Smpl, /**< QDEC report period 80 samples. */ + NRF_QDEC_REPORTPER_120 = QDEC_REPORTPER_REPORTPER_120Smpl, /**< QDEC report period 120 samples. */ + NRF_QDEC_REPORTPER_160 = QDEC_REPORTPER_REPORTPER_160Smpl, /**< QDEC report period 160 samples. */ + NRF_QDEC_REPORTPER_200 = QDEC_REPORTPER_REPORTPER_200Smpl, /**< QDEC report period 200 samples. */ + NRF_QDEC_REPORTPER_240 = QDEC_REPORTPER_REPORTPER_240Smpl, /**< QDEC report period 240 samples. */ + NRF_QDEC_REPORTPER_280 = QDEC_REPORTPER_REPORTPER_280Smpl, /**< QDEC report period 280 samples. */ + NRF_QDEC_REPORTPER_DISABLED /**< QDEC reporting disabled. */ +} nrf_qdec_reportper_t; + +/** + * @brief Function for enabling QDEC. + */ +__STATIC_INLINE void nrf_qdec_enable(void) +{ + NRF_QDEC->ENABLE = NRF_QDEC_ENABLE; +} + + +/** + * @brief Function for disabling QDEC. + */ +__STATIC_INLINE void nrf_qdec_disable(void) +{ + NRF_QDEC->ENABLE = NRF_QDEC_DISABLE; +} + + +/** + * @brief Function for returning the enable state of QDEC. + * @return State of the register. + */ +__STATIC_INLINE uint32_t nrf_qdec_enable_get(void) +{ + return NRF_QDEC->ENABLE; +} + + +/** + * @brief Function for enabling QDEC interrupts by mask. + * @param[in] qdec_int_mask Sources of the interrupts to enable. + */ +__STATIC_INLINE void nrf_qdec_int_enable(uint32_t qdec_int_mask) +{ + NRF_QDEC->INTENSET = qdec_int_mask; // writing 0 has no effect +} + + +/** + * @brief Function for disabling QDEC interrupts by mask. + * @param[in] qdec_int_mask Sources of the interrupts to disable. + * + */ +__STATIC_INLINE void nrf_qdec_int_disable(uint32_t qdec_int_mask) +{ + NRF_QDEC->INTENCLR = qdec_int_mask; // writing 0 has no effect +} + + +/** + * @brief Function for getting the enabled interrupts of the QDEC. + */ +__STATIC_INLINE uint32_t nrf_qdec_int_enable_check(nrf_qdec_int_mask_t qdec_int_mask) +{ + return NRF_QDEC->INTENSET & qdec_int_mask; // when read this register will return the value of INTEN. +} + + +/** + * @brief Function for enabling the debouncing filter of the QED. + */ +__STATIC_INLINE void nrf_qdec_dbfen_enable(void) +{ + NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_ENABLE; +} + + +/** + * @brief Function for disabling the debouncing filter of the QED. + */ +__STATIC_INLINE void nrf_qdec_dbfen_disable(void) +{ + NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_DISABLE; +} + + +/** + * @brief Function for getting the state of the QDEC's debouncing filter. + * @retval NRF_QDEC_DBFEN_DISABLE If the debouncing filter is disabled. + * @retval NRF_QDEC_DBFEN_ENABLE If the debouncing filter is enabled. + */ +__STATIC_INLINE uint32_t nrf_qdec_dbfen_get(void) +{ + return NRF_QDEC->DBFEN; +} + + +/** + * @brief Function for assigning QDEC pins. + * @param[in] psela Pin number. + * @param[in] pselb Pin number. + * @param[in] pselled Pin number. + */ +__STATIC_INLINE void nrf_qdec_pio_assign( uint32_t psela, uint32_t pselb, uint32_t pselled) +{ +#ifdef NRF51 + NRF_QDEC->PSELA = psela; + NRF_QDEC->PSELB = pselb; + NRF_QDEC->PSELLED = pselled; +#elif defined NRF52 + NRF_QDEC->PSEL.A = psela; + NRF_QDEC->PSEL.B = pselb; + NRF_QDEC->PSEL.LED = pselled; +#endif +} + +/** + * @brief Function for setting a specific QDEC task. + * @param[in] qdec_task QDEC task to be set. + */ +__STATIC_INLINE void nrf_qdec_task_trigger(nrf_qdec_task_t qdec_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task) ) = 1; +} + + +/** + * @brief Function for retrieving the address of a QDEC task register. + * @param[in] qdec_task QDEC task. + */ +__STATIC_INLINE uint32_t * nrf_qdec_task_address_get(nrf_qdec_task_t qdec_task) +{ + return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task); +} + + +/** + * @brief Function for clearing a specific QDEC event. + * @param[in] qdec_event QDEC event to clear. + */ +__STATIC_INLINE void nrf_qdec_event_clear(nrf_qdec_event_t qdec_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event) ) = 0; +} + + +/** + * @brief Function for retrieving the state of a specific QDEC event. + * @return State of the QDEC event. + */ +__STATIC_INLINE uint32_t nrf_qdec_event_check(nrf_qdec_event_t qdec_event) +{ + return *(volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event); +} + + +/** + * @brief Function for retrieving the address of a specific QDEC event register. + * @param[in] qdec_event QDEC event. + * @return Address of the specified QDEC event. + */ +__STATIC_INLINE uint32_t * nrf_qdec_event_address_get(nrf_qdec_event_t qdec_event) +{ + return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event); +} + + +/** + * @brief Function for setting QDEC shortcuts. + * @param[in] qdec_short_mask QDEC shortcut by mask. + */ +__STATIC_INLINE void nrf_qdec_shorts_enable(uint32_t qdec_short_mask) +{ + NRF_QDEC->SHORTS |= qdec_short_mask; +} + + +/** + * @brief Function for clearing shortcuts of the QDEC by mask. + * @param[in] qdec_short_mask QDEC shortcute to be cleared. + */ +__STATIC_INLINE void nrf_qdec_shorts_disable(uint32_t qdec_short_mask) +{ + NRF_QDEC->SHORTS &= ~qdec_short_mask; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLEPER register. + * @return Value of the SAMPLEPER register. + */ +__STATIC_INLINE int32_t nrf_qdec_sampleper_reg_get(void) +{ + return NRF_QDEC->SAMPLEPER; +} + + +/** + * @brief Function for converting the value of QDEC's SAMPLE PERIOD to microseconds. + * @retval sampling period in microseconds. + */ +__STATIC_INLINE uint32_t nrf_qdec_sampleper_to_value(uint32_t sampleper) +{ + return (1 << (7+sampleper)); +} + +/** + * @brief Function for setting the value of QDEC's SAMPLEPER register. + * @param[in] sample_per Sampling period. + */ +__STATIC_INLINE void nrf_qdec_sampleper_set(nrf_qdec_sampleper_t sample_per) +{ + NRF_QDEC->SAMPLEPER = sample_per; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLE register. + * @return Value of the SAMPLE register. + */ +__STATIC_INLINE int32_t nrf_qdec_sample_get(void) +{ + return NRF_QDEC->SAMPLE; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACC register. + * @return Value of the ACC register. + */ +__STATIC_INLINE int32_t nrf_qdec_acc_get(void) +{ + return NRF_QDEC->ACC; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCREAD register. + * @return Value of the ACCREAD register. + */ +__STATIC_INLINE int32_t nrf_qdec_accread_get(void) +{ + return NRF_QDEC->ACCREAD; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCDBL register. + * @return Value of the ACCDBL register. + */ +__STATIC_INLINE uint32_t nrf_qdec_accdbl_get(void) +{ + return NRF_QDEC->ACCDBL; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCDBLREAD register. + * @return Value of the ACCDBLREAD register. + */ +__STATIC_INLINE uint32_t nrf_qdec_accdblread_get(void) +{ + return NRF_QDEC->ACCDBLREAD; +} + + +/** + * @brief Function for setting how long the LED is switched on before sampling. + * @param[in] time_us Time (in microseconds) how long the LED is switched on before sampling. + */ +__STATIC_INLINE void nrf_qdec_ledpre_set(uint32_t time_us) +{ + NRF_QDEC->LEDPRE = time_us; +} + + +/** + * @brief Function for retrieving how long the LED is switched on before sampling. + * @retval time_us Time (in microseconds) how long the LED is switched on before sampling. + */ +__STATIC_INLINE uint32_t nrf_qdec_ledpre_get(void) +{ + return NRF_QDEC->LEDPRE; +} + + +/** + * @brief Function for setting the report period (in samples). + * @param[in] reportper Number of samples. + */ +__STATIC_INLINE void nrf_qdec_reportper_set(nrf_qdec_reportper_t reportper) +{ + NRF_QDEC->REPORTPER = reportper; +} + + +/** + * @brief Function for retrieving the report period. + * @retval reportper Number of samples as encoded in the register. + */ +__STATIC_INLINE uint32_t nrf_qdec_reportper_reg_get(void) +{ + return NRF_QDEC->REPORTPER; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLEPER register. + * @param [in] reportper Reportper to be converted to amount of samples per report. + + */ +__STATIC_INLINE uint32_t nrf_qdec_reportper_to_value(uint32_t reportper) +{ + return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper*40; +} + + +/** + * @brief Function for setting the active level for the LED. + * @param[in] pol Active level for the LED. + */ +__STATIC_INLINE void nrf_qdec_ledpol_set(nrf_qdec_ledpol_t pol) +{ + NRF_QDEC->LEDPOL = pol; +} + + +/** + * @brief Function for retrieving the active level for the LED. + * @return Active level for the LED. + */ +__STATIC_INLINE uint32_t nrf_qdec_ledpol_get(void) +{ + return NRF_QDEC->LEDPOL; +} + + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rng.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rng.h new file mode 100644 index 00000000..aac323b9 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rng.h @@ -0,0 +1,228 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief RNG HAL API. + */ + +#ifndef NRF_RNG_H__ +#define NRF_RNG_H__ +/** + * @defgroup nrf_rng_hal RNG HAL + * @{ + * @ingroup nrf_rng + * @brief Hardware access layer for managing the random number generator (RNG). + */ + +#include +#include +#include +#include "nrf.h" + +#define NRF_RNG_TASK_SET (1UL) +#define NRF_RNG_EVENT_CLEAR (0UL) +/** + * @enum nrf_rng_task_t + * @brief RNG tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */ + NRF_RNG_TASK_STOP = offsetof(NRF_RNG_Type, TASKS_STOP) /**< Stop the random number generator. */ +} nrf_rng_task_t; /*lint -restore */ + +/** + * @enum nrf_rng_event_t + * @brief RNG events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */ +} nrf_rng_event_t; /*lint -restore */ + +/** + * @enum nrf_rng_int_mask_t + * @brief RNG interrupts. + */ +typedef enum +{ + NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */ +} nrf_rng_int_mask_t; + +/** + * @enum nrf_rng_short_mask_t + * @brief Types of RNG shortcuts. + */ +typedef enum +{ + NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */ +} nrf_rng_short_mask_t; + +/** + * @brief Function for enabling interrupts. + * + * @param[in] rng_int_mask Mask of interrupts. + */ +__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENSET = rng_int_mask; +} + +/** + * @brief Function for disabling interrupts. + * + * @param[in] rng_int_mask Mask of interrupts. + */ +__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENCLR = rng_int_mask; +} + +/** + * @brief Function for getting the state of a specific interrupt. + * + * @param[in] rng_int_mask Interrupt. + * + * @retval true If the interrupt is not enabled. + * @retval false If the interrupt is enabled. + */ +__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) +{ + return (bool)(NRF_RNG->INTENCLR & rng_int_mask); +} + +/** + * @brief Function for getting the address of a specific task. + * + * This function can be used by the PPI module. + * + * @param[in] rng_task Task. + */ +__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_task); +} + +/** + * @brief Function for setting a specific task. + * + * @param[in] rng_task Task. + */ +__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET; +} + +/** + * @brief Function for getting address of a specific event. + * + * This function can be used by the PPI module. + * + * @param[in] rng_event Event. + */ +__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_event); +} + +/** + * @brief Function for clearing a specific event. + * + * @param[in] rng_event Event. + */ +__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR; +} + +/** + * @brief Function for getting the state of a specific event. + * + * @param[in] rng_event Event. + * + * @retval true If the event is not set. + * @retval false If the event is set. + */ +__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); +} + +/** + * @brief Function for setting shortcuts. + * + * @param[in] rng_short_mask Mask of shortcuts. + * + */ +__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS |= rng_short_mask; +} + +/** + * @brief Function for clearing shortcuts. + * + * @param[in] rng_short_mask Mask of shortcuts. + * + */ +__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS &= ~rng_short_mask; +} + +/** + * @brief Function for getting the previously generated random value. + * + * @return Previously generated random value. + */ +__STATIC_INLINE uint8_t nrf_rng_random_value_get(void) +{ + return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk); +} + +/** + * @brief Function for enabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_enable(void) +{ + NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk; +} + +/** + * @brief Function for disabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_disable(void) +{ + NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk; +} +/** + *@} + **/ +#endif /* NRF_RNG_H__ */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rtc.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rtc.h new file mode 100644 index 00000000..3c2d7afd --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_rtc.h @@ -0,0 +1,321 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief RTC HAL API. + */ + +#ifndef NRF_RTC_H +#define NRF_RTC_H + +/** + * @defgroup nrf_rtc_hal RTC HAL + * @{ + * @ingroup nrf_rtc + * @brief Hardware access layer for managing the real time counter (RTC). + */ + +#include +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + +/** + * @brief Macro for getting the number of compare channels available + * in a given RTC instance. + */ +#ifdef NRF51 + #define NRF_RTC_CC_CHANNEL_COUNT(id) 4 +#else + #define NRF_RTC_CC_CHANNEL_COUNT(id) ((id) == 0 ? 3 : 4) +#endif + +#define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */ + +/**< Macro for wrapping values to RTC capacity. */ +#define RTC_WRAP(val) (val & RTC_COUNTER_COUNTER_Msk) + +#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)NRF_RTC_INT_COMPARE0_MASK << ch) +#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch*sizeof(uint32_t)) +/** + * @enum nrf_rtc_task_t + * @brief RTC tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */ + NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */ + NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */ + NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW),/**< Trigger overflow. */ + /*lint -restore*/ +} nrf_rtc_task_t; + +/** + * @enum nrf_rtc_event_t + * @brief RTC events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */ + NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */ + NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */ + NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */ + NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */ + NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */ + /*lint -restore*/ +} nrf_rtc_event_t; + +/** + * @enum nrf_rtc_int_t + * @brief RTC interrupts. + */ +typedef enum +{ + NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */ + NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */ + NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */ + NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */ + NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */ + NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */ +} nrf_rtc_int_t; + +/**@brief Function for setting a compare value for a channel. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] ch Channel. + * @param[in] cc_val Compare value to set. + */ +__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val); + +/**@brief Function for returning the compare value for a channel. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] ch Channel. + * + * @return COMPARE[ch] value. + */ +__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch); + +/**@brief Function for enabling interrupts. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] mask Interrupt mask to be enabled. + */ +__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for disabling interrupts. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] mask Interrupt mask to be disabled. + */ +__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for checking if interrupts are enabled. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] mask Mask of interrupt flags to check. + * + * @return Mask with enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for returning the status of currently enabled interrupts. + * + * @param[in] p_rtc Pointer to the instance register structure. + * + * @return Value in INTEN register. + */ +__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc); + +/**@brief Function for checking if an event is pending. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] event Address of the event. + * + * @return Mask of pending events. + */ +__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for clearing an event. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for returning a counter value. + * + * @param[in] p_rtc Pointer to the instance register structure. + * + * @return Counter value. + */ +__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc); + +/**@brief Function for setting a prescaler value. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] val Value to set the prescaler to. + */ +__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val); + +/**@brief Function for returning the address of an event. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] event Requested event. + * + * @return Address of the requested event register. + */ +__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for returning the address of a task. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] task Requested task. + * + * @return Address of the requested task register. + */ +__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task); + +/**@brief Function for starting a task. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] task Requested task. + */ +__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task); + +/**@brief Function for enabling events. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] mask Mask of event flags to enable. + */ +__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for disabling an event. + * + * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] event Requested event. + */ +__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event); + +/** + *@} + **/ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val) +{ + p_rtc->CC[ch] = cc_val; +} + +__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch) +{ + return p_rtc->CC[ch]; +} + +__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->INTENSET = mask; +} + +__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->INTENCLR = mask; +} + +__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + return (p_rtc->INTENSET & mask); +} + +__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->INTENSET; +} + +__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + return *(volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event); +} + +__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->COUNTER; +} + +__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val) +{ + ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos)); + p_rtc->PRESCALER = val; +} +__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->PRESCALER; +} + +__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + return (uint32_t)p_rtc + event; +} + +__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task) +{ + return (uint32_t)p_rtc + task; +} + +__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task) +{ + *(__IO uint32_t *)((uint32_t)p_rtc + task) = 1; +} + +__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->EVTENSET = mask; +} +__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->EVTENCLR = mask; +} +#endif + +#endif /* NRF_RTC_H */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.c b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.c new file mode 100644 index 00000000..c2f0ae34 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief SAADC HAL implementation + */ + +#include "nrf_saadc.h" + +void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config) +{ + NRF_SAADC->CH[channel].CONFIG = + ((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) + | ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) + | ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) + | ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) + | ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) + | ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); + nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n); + return; +} diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.h new file mode 100644 index 00000000..231aa9f2 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_saadc.h @@ -0,0 +1,571 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_SAADC_H_ +#define NRF_SAADC_H_ + +/** + * @defgroup nrf_saadc_hal SAADC HAL + * @{ + * @ingroup nrf_saadc + * + * @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral. + */ + +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + +#define NRF_SAADC_CHANNEL_COUNT 8 + +/** + * @brief Resolution of the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_RESOLUTION_8BIT = SAADC_RESOLUTION_VAL_8bit, ///< 8 bit resolution. + NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///< 10 bit resolution. + NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///< 12 bit resolution. + NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit ///< 14 bit resolution. +} nrf_saadc_resolution_t; + + +/** + * @brief Input selection for the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC, ///< Not connected. + NRF_SAADC_INPUT_AIN0 = SAADC_CH_PSELP_PSELP_AnalogInput0, ///< Analog input 0 (AIN0). + NRF_SAADC_INPUT_AIN1 = SAADC_CH_PSELP_PSELP_AnalogInput1, ///< Analog input 1 (AIN1). + NRF_SAADC_INPUT_AIN2 = SAADC_CH_PSELP_PSELP_AnalogInput2, ///< Analog input 2 (AIN2). + NRF_SAADC_INPUT_AIN3 = SAADC_CH_PSELP_PSELP_AnalogInput3, ///< Analog input 3 (AIN3). + NRF_SAADC_INPUT_AIN4 = SAADC_CH_PSELP_PSELP_AnalogInput4, ///< Analog input 4 (AIN4). + NRF_SAADC_INPUT_AIN5 = SAADC_CH_PSELP_PSELP_AnalogInput5, ///< Analog input 5 (AIN5). + NRF_SAADC_INPUT_AIN6 = SAADC_CH_PSELP_PSELP_AnalogInput6, ///< Analog input 6 (AIN6). + NRF_SAADC_INPUT_AIN7 = SAADC_CH_PSELP_PSELP_AnalogInput7, ///< Analog input 7 (AIN7). + NRF_SAADC_INPUT_VDD = SAADC_CH_PSELP_PSELP_VDD ///< VDD as input. +} nrf_saadc_input_t; + + +/** + * @brief Analog-to-digital converter oversampling mode. + */ +typedef enum +{ + NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass, ///< No oversampling. + NRF_SAADC_OVERSAMPLE_2X = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, ///< Oversample 2x. + NRF_SAADC_OVERSAMPLE_4X = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x, ///< Oversample 4x. + NRF_SAADC_OVERSAMPLE_8X = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x, ///< Oversample 8x. + NRF_SAADC_OVERSAMPLE_16X = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x, ///< Oversample 16x. + NRF_SAADC_OVERSAMPLE_32X = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x, ///< Oversample 32x. + NRF_SAADC_OVERSAMPLE_64X = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x, ///< Oversample 64x. + NRF_SAADC_OVERSAMPLE_128X = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///< Oversample 128x. + NRF_SAADC_OVERSAMPLE_256X = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x ///< Oversample 256x. +} nrf_saadc_oversample_t; + + +/** + * @brief Analog-to-digital converter channel resistor control. + */ +typedef enum +{ + NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass, ///< Bypass resistor ladder. + NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///< Pull-down to GND. + NRF_SAADC_RESISTOR_PULLUP = SAADC_CH_CONFIG_RESP_Pullup, ///< Pull-up to VDD. + NRF_SAADC_RESISTOR_VDD1_2 = SAADC_CH_CONFIG_RESP_VDD1_2 ///< Set input at VDD/2. +} nrf_saadc_resistor_t; + + +/** + * @brief Gain factor of the analog-to-digital converter input. + */ +typedef enum +{ + NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///< Gain factor 1/6. + NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///< Gain factor 1/5. + NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///< Gain factor 1/4. + NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///< Gain factor 1/3. + NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///< Gain factor 1/2. + NRF_SAADC_GAIN1 = SAADC_CH_CONFIG_GAIN_Gain1, ///< Gain factor 1. + NRF_SAADC_GAIN2 = SAADC_CH_CONFIG_GAIN_Gain2, ///< Gain factor 2. + NRF_SAADC_GAIN4 = SAADC_CH_CONFIG_GAIN_Gain4, ///< Gain factor 4. +} nrf_saadc_gain_t; + + +/** + * @brief Reference selection for the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///< Internal reference (0.6 V). + NRF_SAADC_REFERENCE_VDD4 = SAADC_CH_CONFIG_REFSEL_VDD1_4 ///< VDD/4 as reference. +} nrf_saadc_reference_t; + + +/** + * @brief Analog-to-digital converter acquisition time. + */ +typedef enum +{ + NRF_SAADC_ACQTIME_3US = SAADC_CH_CONFIG_TACQ_3us, ///< 3 us. + NRF_SAADC_ACQTIME_5US = SAADC_CH_CONFIG_TACQ_5us, ///< 5 us. + NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///< 10 us. + NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///< 15 us. + NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///< 20 us. + NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us ///< 40 us. +} nrf_saadc_acqtime_t; + + +/** + * @brief Analog-to-digital converter channel mode. + */ +typedef enum +{ + NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE, ///< Single ended, PSELN will be ignored, negative input to ADC shorted to GND. + NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///< Differential mode. +} nrf_saadc_mode_t; + + +/** + * @brief Analog-to-digital converter tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_SAADC_TASK_START = offsetof(NRF_SAADC_Type, TASKS_START), ///< Start the ADC and prepare the result buffer in RAM. + NRF_SAADC_TASK_SAMPLE = offsetof(NRF_SAADC_Type, TASKS_SAMPLE), ///< Take one ADC sample. If scan is enabled, all channels are sampled. + NRF_SAADC_TASK_STOP = offsetof(NRF_SAADC_Type, TASKS_STOP), ///< Stop the ADC and terminate any on-going conversion. + NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration. +} nrf_saadc_task_t; + + +/** + * @brief Analog-to-digital converter events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_SAADC_EVENT_STARTED = offsetof(NRF_SAADC_Type, EVENTS_STARTED), ///< The ADC has started. + NRF_SAADC_EVENT_END = offsetof(NRF_SAADC_Type, EVENTS_END), ///< The ADC has filled up the result buffer. + NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete. + NRF_SAADC_EVENT_STOPPED = offsetof(NRF_SAADC_Type, EVENTS_STOPPED), ///< The ADC has stopped. + NRF_SAADC_EVENT_CH0_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH), ///< Last result is equal or above CH[0].LIMIT.HIGH. + NRF_SAADC_EVENT_CH0_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL), ///< Last result is equal or below CH[0].LIMIT.LOW. + NRF_SAADC_EVENT_CH1_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH), ///< Last result is equal or above CH[1].LIMIT.HIGH. + NRF_SAADC_EVENT_CH1_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL), ///< Last result is equal or below CH[1].LIMIT.LOW. + NRF_SAADC_EVENT_CH2_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH), ///< Last result is equal or above CH[2].LIMIT.HIGH. + NRF_SAADC_EVENT_CH2_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL), ///< Last result is equal or below CH[2].LIMIT.LOW. + NRF_SAADC_EVENT_CH3_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH), ///< Last result is equal or above CH[3].LIMIT.HIGH. + NRF_SAADC_EVENT_CH3_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL), ///< Last result is equal or below CH[3].LIMIT.LOW. + NRF_SAADC_EVENT_CH4_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH), ///< Last result is equal or above CH[4].LIMIT.HIGH. + NRF_SAADC_EVENT_CH4_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL), ///< Last result is equal or below CH[4].LIMIT.LOW. + NRF_SAADC_EVENT_CH5_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH), ///< Last result is equal or above CH[5].LIMIT.HIGH. + NRF_SAADC_EVENT_CH5_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL), ///< Last result is equal or below CH[5].LIMIT.LOW. + NRF_SAADC_EVENT_CH6_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH), ///< Last result is equal or above CH[6].LIMIT.HIGH. + NRF_SAADC_EVENT_CH6_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL), ///< Last result is equal or below CH[6].LIMIT.LOW. + NRF_SAADC_EVENT_CH7_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH), ///< Last result is equal or above CH[7].LIMIT.HIGH. + NRF_SAADC_EVENT_CH7_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL) ///< Last result is equal or below CH[7].LIMIT.LOW. +} nrf_saadc_event_t; + + +/** + * @brief Analog-to-digital converter interrupt masks. + */ +typedef enum +{ + NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event. + NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event. + NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event. + NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event. + NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event. + NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event. + NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event. + NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event. + NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event. + NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event. + NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event. + NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event. + NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event. + NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event. + NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event. + NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event. + NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event. + NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts. +} nrf_saadc_int_mask_t; + + +/** + * @brief Analog-to-digital converter value limit type. + */ +typedef enum +{ + NRF_SAADC_LIMIT_LOW = 0, + NRF_SAADC_LIMIT_HIGH = 1 +} nrf_saadc_limit_t; + + +typedef int16_t nrf_saadc_value_t; ///< Type of a single ADC conversion result. + + +/** + * @brief Analog-to-digital converter configuration structure. + */ +typedef struct +{ + nrf_saadc_resolution_t resolution; + nrf_saadc_oversample_t oversample; + nrf_saadc_value_t * buffer; + uint32_t buffer_size; +} nrf_saadc_config_t; + + +/** + * @brief Analog-to-digital converter channel configuration structure. + */ +typedef struct +{ + nrf_saadc_resistor_t resistor_p; + nrf_saadc_resistor_t resistor_n; + nrf_saadc_gain_t gain; + nrf_saadc_reference_t reference; + nrf_saadc_acqtime_t acq_time; + nrf_saadc_mode_t mode; + nrf_saadc_input_t pin_p; + nrf_saadc_input_t pin_n; +} nrf_saadc_channel_config_t; + + +/** + * @brief Function for triggering a specific SAADC task. + * + * @param[in] saadc_task SAADC task. + */ +__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL; +} + + +/** + * @brief Function for getting the address of a specific SAADC task register. + * + * @param[in] saadc_task SAADC task. + * + * @return Address of the specified SAADC task. + */ +__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task) +{ + return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task); +} + + +/** + * @brief Function for getting the state of a specific SAADC event. + * + * @param[in] saadc_event SAADC event. + * + * @return State of the specified SAADC event. + */ +__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); +} + + +/** + * @brief Function for clearing the specific SAADC event. + * + * @param[in] saadc_event SAADC event. + */ +__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL; +} + + +/** + * @brief Function for getting the address of a specific SAADC event register. + * + * @param[in] saadc_event SAADC event. + * + * @return Address of the specified SAADC event. + */ +__STATIC_INLINE volatile uint32_t * nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event) +{ + return (volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); +} + + +/** + * @brief Function for getting the address of a specific SAADC limit event register. + * + * @param[in] channel Channel number. + * @param[in] limit_type Low limit or high limit. + * + * @return Address of the specified SAADC limit event. + */ +__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + if (limit_type == NRF_SAADC_LIMIT_HIGH) + { + return &NRF_SAADC->EVENTS_CH[channel].LIMITH; + } + else + { + return &NRF_SAADC->EVENTS_CH[channel].LIMITL; + } +} + + +/** + * @brief Function for getting the SAADC channel monitoring limit events. + * + * @param[in] channel Channel number. + * @param[in] limit_type Low limit or high limit. + */ +__STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + if (limit_type == NRF_SAADC_LIMIT_HIGH) + { + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH + + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH) + * (uint32_t) channel ); + } + else + { + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL + + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL) + * (uint32_t) channel ); + } +} + + +/** + * @brief Function for configuring the input pins for a specific SAADC channel. + * + * @param[in] channel Channel number. + * @param[in] pselp Positive input. + * @param[in] pseln Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode. + */ +__STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel, + nrf_saadc_input_t pselp, + nrf_saadc_input_t pseln) +{ + NRF_SAADC->CH[channel].PSELN = pseln; + NRF_SAADC->CH[channel].PSELP = pselp; +} + + +/** + * @brief Function for setting the SAADC channel monitoring limits. + * + * @param[in] channel Channel number. + * @param[in] low Low limit. + * @param[in] high High limit. + */ +__STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high) +{ + NRF_SAADC->CH[channel].LIMIT = ( + (((uint32_t) low << SAADC_CH_LIMIT_LOW_Pos) & SAADC_CH_LIMIT_LOW_Msk) + | (((uint32_t) high << SAADC_CH_LIMIT_HIGH_Pos) & SAADC_CH_LIMIT_HIGH_Msk)); +} + + +/** + * @brief Function for enabling specified SAADC interrupts. + * + * @param[in] saadc_int_mask Interrupt(s) to enable. + */ +__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask) +{ + NRF_SAADC->INTENSET = saadc_int_mask; +} + + +/** + * @brief Function for retrieving the state of specified SAADC interrupts. + * + * @param[in] saadc_int_mask Interrupt(s) to check. + * + * @retval true If all specified interrupts are enabled. + * @retval false If at least one of the given interrupts is not enabled. + */ +__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask) +{ + return (bool)(NRF_SAADC->INTENSET & saadc_int_mask); +} + + +/** + * @brief Function for disabling specified interrupts. + * + * @param saadc_int_mask Interrupt(s) to disable. + */ +__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask) +{ + NRF_SAADC->INTENCLR = saadc_int_mask; +} + + +/** + * @brief Function for generating masks for SAADC channel limit interrupts. + * + * @param[in] channel SAADC channel number. + * @param[in] limit_type Limit type. + * + * @returns Interrupt mask. + */ +__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH; + return mask << (channel * 2); +} + + +/** + * @brief Function for checking whether the SAADC is busy. + * + * This function checks whether the analog-to-digital converter is busy with a conversion. + * + * @retval true If the SAADC is busy. + * @retval false If the SAADC is not busy. + */ +__STATIC_INLINE bool nrf_saadc_busy_check(void) +{ + //return ((NRF_SAADC->STATUS & SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk); + //simplified for performance + return NRF_SAADC->STATUS; +} + + +/** + * @brief Function for enabling the SAADC. + * + * The analog-to-digital converter must be enabled before use. + */ +__STATIC_INLINE void nrf_saadc_enable(void) +{ + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for disabling the SAADC. + */ +__STATIC_INLINE void nrf_saadc_disable(void) +{ + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for checking if the SAADC is enabled. + * + * @retval true If the SAADC is enabled. + * @retval false If the SAADC is not enabled. + */ +__STATIC_INLINE bool nrf_saadc_enable_check(void) +{ + //simplified for performance + return NRF_SAADC->ENABLE; +} + + +/** + * @brief Function for initializing the SAADC result buffer. + * + * @param[in] buffer Pointer to the result buffer. + * @param[in] num Size of buffer in words. + */ +__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num) +{ + NRF_SAADC->RESULT.PTR = (uint32_t)buffer; + NRF_SAADC->RESULT.MAXCNT = num; +} + +/** + * @brief Function for getting the number of buffer words transferred since last START operation. + * + * @returns Number of words transferred. + */ +__STATIC_INLINE uint16_t nrf_saadc_amount_get(void) +{ + return NRF_SAADC->RESULT.AMOUNT; +} + + +/** + * @brief Function for setting the SAADC sample resolution. + * + * @param[in] resolution Bit resolution. + */ +__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution) +{ + NRF_SAADC->RESOLUTION = resolution; +} + + +/** + * @brief Function for configuring the oversampling feature. + * + * @param[in] oversample Oversampling mode. + */ +__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample) +{ + NRF_SAADC->OVERSAMPLE = oversample; +} + +/** + * @brief Function for getting the oversampling feature configuration. + * + * @return Oversampling configuration. + */ +__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void) +{ + return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE; +} + +/** + * @brief Function for initializing the SAADC channel. + * + * @param[in] channel Channel number. + * @param[in] config Pointer to the channel configuration structure. + */ +void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config); + +/** + *@} + **/ + +#endif /* NRF_SAADC_H_ */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spi.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spi.h new file mode 100644 index 00000000..f35c026b --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spi.h @@ -0,0 +1,351 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_spi_hal SPI HAL + * @{ + * @ingroup nrf_spi_master + * + * @brief Hardware access layer for accessing the SPI peripheral. + */ + +#ifndef NRF_SPI_H__ +#define NRF_SPI_H__ + +#include +#include +#include + +#include "nrf.h" + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spi_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPI_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPI_EVENT_READY = offsetof(NRF_SPI_Type, EVENTS_READY) ///< TXD byte sent and RXD byte received. + /*lint -restore*/ +} nrf_spi_event_t; + +/** + * @brief SPI interrupts. + */ +typedef enum +{ + NRF_SPI_INT_READY_MASK = SPI_INTENSET_READY_Msk ///< Interrupt on READY event. +} nrf_spi_int_mask_t; + +/** + * @brief SPI data rates. + */ +typedef enum +{ + NRF_SPI_FREQ_125K = SPI_FREQUENCY_FREQUENCY_K125, ///< 125 kbps. + NRF_SPI_FREQ_250K = SPI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_SPI_FREQ_500K = SPI_FREQUENCY_FREQUENCY_K500, ///< 500 kbps. + NRF_SPI_FREQ_1M = SPI_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps. + NRF_SPI_FREQ_2M = SPI_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps. + NRF_SPI_FREQ_4M = SPI_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_SPI_FREQ_8M = (int)SPI_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps. +} nrf_spi_frequency_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spi_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPI_BIT_ORDER_MSB_FIRST = SPI_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPI_BIT_ORDER_LSB_FIRST = SPI_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spi_bit_order_t; + + +/** + * @brief Function for clearing a specific SPI event. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_event Event to clear. + */ +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event); + +/** + * @brief Function for checking the state of a specific SPI event. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event); + +/** + * @brief Function for getting the address of a specific SPI event register. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi, + uint32_t spi_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi, + uint32_t spi_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi, + nrf_spi_int_mask_t spi_int); + +/** + * @brief Function for enabling the SPI peripheral. + * + * @param[in] p_spi SPI instance. + */ +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi); + +/** + * @brief Function for disabling the SPI peripheral. + * + * @param[in] p_spi SPI instance. + */ +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi); + +/** + * @brief Function for configuring SPI pins. + * + * If a given signal is not needed, pass the @ref NRF_SPI_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_spi SPI instance. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + */ +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin); + +/** + * @brief Function for writing data to the SPI transmitter register. + * + * @param[in] p_spi SPI instance. + * @param[in] data TX data to send. + */ +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data); + +/** + * @brief Function for reading data from the SPI receiver register. + * + * @param[in] p_spi SPI instance. + * + * @return RX data received. + */ +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi); + +/** + * @brief Function for setting the SPI master data rate. + * + * @param[in] p_spi SPI instance. + * @param[in] frequency SPI frequency. + */ +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi, + nrf_spi_frequency_t frequency); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_spi SPI instance. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi, + nrf_spi_mode_t spi_mode, + nrf_spi_bit_order_t spi_bit_order); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event) +{ + *((volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event); +} + +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi, + nrf_spi_event_t spi_event) +{ + return (uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event); +} + +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi, + uint32_t spi_int_mask) +{ + p_spi->INTENSET = spi_int_mask; +} + +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi, + uint32_t spi_int_mask) +{ + p_spi->INTENCLR = spi_int_mask; +} + +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi, + nrf_spi_int_mask_t spi_int) +{ + return (bool)(p_spi->INTENSET & spi_int); +} + +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi) +{ + p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi) +{ + p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin) +{ + p_spi->PSELSCK = sck_pin; + p_spi->PSELMOSI = mosi_pin; + p_spi->PSELMISO = miso_pin; +} + +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data) +{ + p_spi->TXD = data; +} + +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi) +{ + return p_spi->RXD; +} + +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi, + nrf_spi_frequency_t frequency) +{ + p_spi->FREQUENCY = frequency; +} + +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi, + nrf_spi_mode_t spi_mode, + nrf_spi_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPI_BIT_ORDER_MSB_FIRST ? + SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst); + switch (spi_mode) + { + default: + case NRF_SPI_MODE_0: + config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_1: + config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_2: + config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_3: + config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); + break; + } + p_spi->CONFIG = config; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_SPI_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spim.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spim.h new file mode 100644 index 00000000..58d28b95 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spim.h @@ -0,0 +1,537 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_spim_hal SPIM HAL + * @{ + * @ingroup nrf_spi_master + * + * @brief Hardware access layer for accessing the SPIM peripheral. + */ + +#ifndef NRF_SPIM_H__ +#define NRF_SPIM_H__ + +#include +#include +#include + +#include "nrf.h" + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPIM_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPIM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIM_TASK_START = offsetof(NRF_SPIM_Type, TASKS_START), ///< Start SPI transaction. + NRF_SPIM_TASK_STOP = offsetof(NRF_SPIM_Type, TASKS_STOP), ///< Stop SPI transaction. + NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction. + NRF_SPIM_TASK_RESUME = offsetof(NRF_SPIM_Type, TASKS_RESUME) ///< Resume SPI transaction. + /*lint -restore*/ +} nrf_spim_task_t; + +/** + * @brief SPIM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped. + NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached. +#ifdef NRF52 + NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached. +#endif + NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached. + NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started. + /*lint -restore*/ +} nrf_spim_event_t; + +#ifdef NRF52 +/** + * @brief SPIM shortcuts. + */ +typedef enum +{ + NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task. +} nrf_spim_short_mask_t; +#endif + +/** + * @brief SPIM interrupts. + */ +typedef enum +{ + NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event. +#ifdef NRF52 + NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event. +#endif + NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event. + NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event. +} nrf_spim_int_mask_t; + +/** + * @brief SPI master data rates. + */ +typedef enum +{ + NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125, ///< 125 kbps. + NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500, ///< 500 kbps. + NRF_SPIM_FREQ_1M = SPIM_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps. + NRF_SPIM_FREQ_2M = SPIM_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps. + NRF_SPIM_FREQ_4M = SPIM_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_SPIM_FREQ_8M = (int)SPIM_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps. +} nrf_spim_frequency_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPIM_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spim_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spim_bit_order_t; + + +/** + * @brief Function for activating a specific SPIM task. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_task Task to activate. + */ +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim, + nrf_spim_task_t spim_task); + +/** + * @brief Function for getting the address of a specific SPIM task register. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim, + nrf_spim_task_t spim_task); + +/** + * @brief Function for clearing a specific SPIM event. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_event Event to clear. + */ +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event); + +/** + * @brief Function for checking the state of a specific SPIM event. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event); + +/** + * @brief Function for getting the address of a specific SPIM event register. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event); +#ifdef NRF52 +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim, + uint32_t spim_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim, + uint32_t spim_shorts_mask); + +/** + * @brief Function for getting shorts setting. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim); +#endif +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim, + uint32_t spim_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim, + uint32_t spim_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_spim SPIM instance. + * @param[in] spim_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim, + nrf_spim_int_mask_t spim_int); + +/** + * @brief Function for enabling the SPIM peripheral. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim); + +/** + * @brief Function for disabling the SPIM peripheral. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim); + +/** + * @brief Function for configuring SPIM pins. + * + * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_spim SPIM instance. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + */ +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin); + +/** + * @brief Function for setting the SPI master data rate. + * + * @param[in] p_spim SPIM instance. + * @param[in] frequency SPI frequency. + */ +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim, + nrf_spim_frequency_t frequency); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_spim SPIM instance. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_spim SPIM instance. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_spim SPIM instance. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim, + nrf_spim_mode_t spi_mode, + nrf_spim_bit_order_t spi_bit_order); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_spim SPIM instance. + * @param[in] orc Over-read character that is clocked out in case of + * an over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim, + uint8_t orc); + +#ifdef NRF52 +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_spim SPIM instance. + */ +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim); +#endif +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim, + nrf_spim_task_t spim_task) +{ + *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim, + nrf_spim_task_t spim_task) +{ + return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_task); +} + +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event) +{ + *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event); +} + +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim, + nrf_spim_event_t spim_event) +{ + return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_event); +} + +#ifdef NRF52 +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim, + uint32_t spim_shorts_mask) +{ + p_spim->SHORTS |= spim_shorts_mask; +} + +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim, + uint32_t spim_shorts_mask) +{ + p_spim->SHORTS &= ~(spim_shorts_mask); +} + +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim) +{ + return p_spim->SHORTS; +} +#endif +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim, + uint32_t spim_int_mask) +{ + p_spim->INTENSET = spim_int_mask; +} + +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim, + uint32_t spim_int_mask) +{ + p_spim->INTENCLR = spim_int_mask; +} + +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim, + nrf_spim_int_mask_t spim_int) +{ + return (bool)(p_spim->INTENSET & spim_int); +} + +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim) +{ + p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim) +{ + p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin) +{ + p_spim->PSEL.SCK = sck_pin; + p_spim->PSEL.MOSI = mosi_pin; + p_spim->PSEL.MISO = miso_pin; +} + +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim, + nrf_spim_frequency_t frequency) +{ + p_spim->FREQUENCY = frequency; +} + +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim, + uint8_t const * p_buffer, + uint8_t length) +{ + p_spim->TXD.PTR = (uint32_t)p_buffer; + p_spim->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim, + uint8_t * p_buffer, + uint8_t length) +{ + p_spim->RXD.PTR = (uint32_t)p_buffer; + p_spim->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim, + nrf_spim_mode_t spi_mode, + nrf_spim_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ? + SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst); + switch (spi_mode) + { + default: + case NRF_SPIM_MODE_0: + config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_1: + config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_2: + config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_3: + config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + } + p_spim->CONFIG = config; +} + +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim, + uint8_t orc) +{ + p_spim->ORC = orc; +} + +#ifdef NRF52 +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim) +{ + p_spim->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim) +{ + p_spim->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim) +{ + p_spim->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim) +{ + p_spim->RXD.LIST = 0; +} +#endif +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_SPIM_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spis.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spis.h new file mode 100644 index 00000000..c56da950 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_spis.h @@ -0,0 +1,529 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_spis_hal SPIS HAL + * @{ + * @ingroup nrf_spis + * + * @brief Hardware access layer for accessing the SPIS peripheral. + */ + +#ifndef NRF_SPIS_H__ +#define NRF_SPIS_H__ + +#include +#include +#include + +#include "nrf.h" + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spis_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPIS_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPIS tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIS_TASK_ACQUIRE = offsetof(NRF_SPIS_Type, TASKS_ACQUIRE), ///< Acquire SPI semaphore. + NRF_SPIS_TASK_RELEASE = offsetof(NRF_SPIS_Type, TASKS_RELEASE), ///< Release SPI semaphore, enabling the SPI slave to acquire it. + /*lint -restore*/ +} nrf_spis_task_t; + +/** + * @brief SPIS events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIS_EVENT_END = offsetof(NRF_SPIS_Type, EVENTS_END), ///< Granted transaction completed. + NRF_SPIS_EVENT_ACQUIRED = offsetof(NRF_SPIS_Type, EVENTS_ACQUIRED) ///< Semaphore acquired. + /*lint -restore*/ +} nrf_spis_event_t; + +/** + * @brief SPIS shortcuts. + */ +typedef enum +{ + NRF_SPIS_SHORT_END_ACQUIRE = SPIS_SHORTS_END_ACQUIRE_Msk ///< Shortcut between END event and ACQUIRE task. +} nrf_spis_short_mask_t; + +/** + * @brief SPIS interrupts. + */ +typedef enum +{ + NRF_SPIS_INT_END_MASK = SPIS_INTENSET_END_Msk, ///< Interrupt on END event. + NRF_SPIS_INT_ACQUIRED_MASK = SPIS_INTENSET_ACQUIRED_Msk ///< Interrupt on ACQUIRED event. +} nrf_spis_int_mask_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPIS_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPIS_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPIS_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPIS_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spis_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPIS_BIT_ORDER_MSB_FIRST = SPIS_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPIS_BIT_ORDER_LSB_FIRST = SPIS_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spis_bit_order_t; + +/** + * @brief SPI semaphore status. + */ +typedef enum +{ + NRF_SPIS_SEMSTAT_FREE = 0, ///< Semaphore is free. + NRF_SPIS_SEMSTAT_CPU = 1, ///< Semaphore is assigned to the CPU. + NRF_SPIS_SEMSTAT_SPIS = 2, ///< Semaphore is assigned to the SPI slave. + NRF_SPIS_SEMSTAT_CPUPENDING = 3 ///< Semaphore is assigned to the SPI, but a handover to the CPU is pending. +} nrf_spis_semstat_t; + +/** + * @brief SPIS status. + */ +typedef enum +{ + NRF_SPIS_STATUS_OVERREAD = SPIS_STATUS_OVERREAD_Msk, ///< TX buffer over-read detected and prevented. + NRF_SPIS_STATUS_OVERFLOW = SPIS_STATUS_OVERFLOW_Msk ///< RX buffer overflow detected and prevented. +} nrf_spis_status_mask_t; + +/** + * @brief Function for activating a specific SPIS task. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_task Task to activate. + */ +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis, + nrf_spis_task_t spis_task); + +/** + * @brief Function for getting the address of a specific SPIS task register. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis, + nrf_spis_task_t spis_task); + +/** + * @brief Function for clearing a specific SPIS event. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_event Event to clear. + */ +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis, + nrf_spis_event_t spis_event); + +/** + * @brief Function for checking the state of a specific SPIS event. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis, + nrf_spis_event_t spis_event); + +/** + * @brief Function for getting the address of a specific SPIS event register. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis, + nrf_spis_event_t spis_event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis, + uint32_t spis_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis, + uint32_t spis_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis, + uint32_t spis_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis, + uint32_t spis_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_spis SPIS instance. + * @param[in] spis_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis, + nrf_spis_int_mask_t spis_int); + +/** + * @brief Function for enabling the SPIS peripheral. + * + * @param[in] p_spis SPIS instance. + */ +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis); + +/** + * @brief Function for disabling the SPIS peripheral. + * + * @param[in] p_spis SPIS instance. + */ +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis); + +/** + * @brief Function for retrieving the SPIS semaphore status. + * + * @param[in] p_spis SPIS instance. + * + * @returns Current semaphore status. + */ +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis); + +/** + * @brief Function for retrieving the SPIS status. + * + * @param[in] p_spis SPIS instance. + * + * @returns Current SPIS status. + */ +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis); + +/** + * @brief Function for configuring SPIS pins. + * + * If a given signal is not needed, pass the @ref NRF_SPIS_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_spis SPIS instance. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + * @param[in] csn_pin CSN pin number. + */ +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin, + uint32_t csn_pin); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_spis SPIS instance. + * @param[in] p_buffer Pointer to the buffer that contains the data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_spis SPIS instance. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for getting the number of bytes transmitted + * in the last granted transaction. + * + * @param[in] p_spis SPIS instance. + * + * @returns Number of bytes transmitted. + */ +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis); + +/** + * @brief Function for getting the number of bytes received + * in the last granted transaction. + * + * @param[in] p_spis SPIS instance. + * + * @returns Number of bytes received. + */ +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_spis SPIS instance. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis, + nrf_spis_mode_t spi_mode, + nrf_spis_bit_order_t spi_bit_order); + +/** + * @brief Function for setting the default character. + * + * @param[in] p_spis SPIS instance. + * @param[in] def Default character that is clocked out in case of + * an overflow of the RXD buffer. + */ +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis, + uint8_t def); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_spis SPIS instance. + * @param[in] orc Over-read character that is clocked out in case of + * an over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis, + uint8_t orc); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis, + nrf_spis_task_t spis_task) +{ + *((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis, + nrf_spis_task_t spis_task) +{ + return (uint32_t)p_spis + (uint32_t)spis_task; +} + +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis, + nrf_spis_event_t spis_event) +{ + *((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis, + nrf_spis_event_t spis_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event); +} + +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis, + nrf_spis_event_t spis_event) +{ + return (uint32_t)p_spis + (uint32_t)spis_event; +} + +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis, + uint32_t spis_shorts_mask) +{ + p_spis->SHORTS |= spis_shorts_mask; +} + +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis, + uint32_t spis_shorts_mask) +{ + p_spis->SHORTS &= ~(spis_shorts_mask); +} + +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis, + uint32_t spis_int_mask) +{ + p_spis->INTENSET = spis_int_mask; +} + +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis, + uint32_t spis_int_mask) +{ + p_spis->INTENCLR = spis_int_mask; +} + +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis, + nrf_spis_int_mask_t spis_int) +{ + return (bool)(p_spis->INTENSET & spis_int); +} + +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis) +{ + p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis) +{ + p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis) +{ + return (nrf_spis_semstat_t) ((p_spis->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk) + >> SPIS_SEMSTAT_SEMSTAT_Pos); +} + +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis) +{ + return (nrf_spis_status_mask_t) p_spis->STATUS; +} + +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin, + uint32_t csn_pin) +{ + p_spis->PSELSCK = sck_pin; + p_spis->PSELMOSI = mosi_pin; + p_spis->PSELMISO = miso_pin; + p_spis->PSELCSN = csn_pin; +} + +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis, + uint8_t const * p_buffer, + uint8_t length) +{ + p_spis->TXDPTR = (uint32_t)p_buffer; + p_spis->MAXTX = length; +} + +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis, + uint8_t * p_buffer, + uint8_t length) +{ + p_spis->RXDPTR = (uint32_t)p_buffer; + p_spis->MAXRX = length; +} + +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis) +{ + return (uint8_t) p_spis->AMOUNTRX; +} + +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis) +{ + return (uint8_t) p_spis->AMOUNTTX; +} + +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis, + nrf_spis_mode_t spi_mode, + nrf_spis_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPIS_BIT_ORDER_MSB_FIRST ? + SPIS_CONFIG_ORDER_MsbFirst : SPIS_CONFIG_ORDER_LsbFirst); + + switch (spi_mode) + { + default: + case NRF_SPIS_MODE_0: + config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_1: + config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_2: + config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_3: + config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); + break; + } + p_spis->CONFIG = config; +} + +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis, + uint8_t orc) +{ + p_spis->ORC = orc; +} + +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis, + uint8_t def) +{ + p_spis->DEF = def; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_SPIS_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_temp.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_temp.h new file mode 100644 index 00000000..7a4f6d47 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_temp.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_TEMP_H__ +#define NRF_TEMP_H__ + +#include "nrf.h" + +/** +* @defgroup nrf_temperature TEMP (temperature) abstraction +* @{ +* @ingroup nrf_drivers temperature_example +* @brief Temperature module init and read functions. +* +*/ + +/**@cond NO_DOXYGEN */ +#define MASK_SIGN (0x00000200UL) +#define MASK_SIGN_EXTENSION (0xFFFFFC00UL) + +/** + * @brief Function for preparing the temp module for temperature measurement. + * + * This function initializes the TEMP module and writes to the hidden configuration register. + */ +static __INLINE void nrf_temp_init(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */ + *(uint32_t *) 0x4000C504 = 0; +} + +/** + * @brief Function for reading temperature measurement. + * + * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value. + */ +static __INLINE int32_t nrf_temp_read(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */ + return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP); +} +/**@endcond */ + +/** @} */ + +#endif diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_timer.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_timer.h new file mode 100644 index 00000000..9c4b078b --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_timer.h @@ -0,0 +1,593 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_timer_hal Timer HAL + * @{ + * @ingroup nrf_timer + * + * @brief Hardware access layer for accessing the timer peripheral. + */ + +#ifndef NRF_TIMER_H__ +#define NRF_TIMER_H__ + +#include +#include +#include + +#include "nrf.h" +#include "nrf_assert.h" + + +/** + * @brief Macro for validating the correctness of the BIT_WIDTH setting. + */ +#ifdef NRF51 + /** + * In the nRF51 Series, timer instance 0 supports all available bit widths. + * The other two instances support only 8 and 16 bits. + */ + #define NRF_TIMER_IS_BIT_WIDTH_VALID(p_timer, bit_width) \ + ((p_timer == NRF_TIMER0) || (bit_width <= NRF_TIMER_BIT_WIDTH_16)) +#else + /** + * In the nRF52 Series, all timer instances support all available bit widths. + */ + #define NRF_TIMER_IS_BIT_WIDTH_VALID(p_timer, bit_width) true +#endif + +/** + * @brief Macro for getting the number of capture/compare channels available + * in a given timer instance. + */ +#ifdef NRF51 + #define NRF_TIMER_CC_CHANNEL_COUNT(id) 4 +#else + #define NRF_TIMER_CC_CHANNEL_COUNT(id) ((id) <= 2 ? 4 : 6) +#endif + + +/** + * @brief Timer tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer. + NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer. + NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode). + NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value. + NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. + NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0. + NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1. + NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2. + NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3. +#ifdef NRF52 + NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4. + NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5. +#endif + /*lint -restore*/ +} nrf_timer_task_t; + +/** + * @brief Timer events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0. + NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1. + NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2. + NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3. +#ifdef NRF52 + NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4. + NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5. +#endif + /*lint -restore*/ +} nrf_timer_event_t; + +/** + * @brief Types of timer shortcuts. + */ +typedef enum +{ + NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3. +#ifdef NRF52 + NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5. +#endif + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3. +#ifdef NRF52 + NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5. +#endif +} nrf_timer_short_mask_t; + +/** + * @brief Timer modes. + */ +typedef enum +{ + NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer. + NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter. +#ifdef NRF52 + NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter. +#endif +} nrf_timer_mode_t; + +/** + * @brief Timer bit width. + */ +typedef enum +{ + NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit. + NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit. + NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit. + NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit. +} nrf_timer_bit_width_t; + +/** + * @brief Timer prescalers. + */ +typedef enum +{ + NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz. + NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz. + NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz. + NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz. + NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz. + NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz. + NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz. + NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz. + NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. + NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. +} nrf_timer_frequency_t; + +/** + * @brief Timer capture/compare channels. + */ +typedef enum +{ + NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0. + NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1. + NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2. + NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3. +#ifdef NRF52 + NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4. + NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5. +#endif +} nrf_timer_cc_channel_t; + +/** + * @brief Timer interrupts. + */ +typedef enum +{ + NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0. + NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1. + NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2. + NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3. +#ifdef NRF52 + NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4. + NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5. +#endif +} nrf_timer_int_mask_t; + + +/** + * @brief Function for activating a specific timer task. + * + * @param[in] p_timer Timer instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_timer, + nrf_timer_task_t task); + +/** + * @brief Function for getting the address of a specific timer task register. + * + * @param[in] p_timer Timer instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_timer, + nrf_timer_task_t task); + +/** + * @brief Function for clearing a specific timer event. + * + * @param[in] p_timer Timer instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event); + +/** + * @brief Function for checking the state of a specific timer event. + * + * @param[in] p_timer Timer instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event); + +/** + * @brief Function for getting the address of a specific timer event register. + * + * @param[in] p_timer Timer instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_timer Timer instance. + * @param[in] timer_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_timer, + uint32_t timer_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_timer Timer instance. + * @param[in] timer_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_timer, + uint32_t timer_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_timer Timer instance. + * @param[in] timer_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_timer, + uint32_t timer_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_timer Timer instance. + * @param[in] timer_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_timer, + uint32_t timer_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_timer Timer instance. + * @param[in] timer_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_timer, + uint32_t timer_int); + +/** + * @brief Function for setting the timer mode. + * + * @param[in] p_timer Timer instance. + * @param[in] mode Timer mode. + */ +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_timer, + nrf_timer_mode_t mode); + +/** + * @brief Function for retrieving the timer mode. + * + * @param[in] p_timer Timer instance. + * + * @return Timer mode. + */ +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_timer); + +/** + * @brief Function for setting the timer bit width. + * + * @param[in] p_timer Timer instance. + * @param[in] bit_width Timer bit width. + */ +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_timer, + nrf_timer_bit_width_t bit_width); + +/** + * @brief Function for retrieving the timer bit width. + * + * @param[in] p_timer Timer instance. + * + * @return Timer bit width. + */ +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_timer); + +/** + * @brief Function for setting the timer frequency. + * + * @param[in] p_timer Timer instance. + * @param[in] frequency Timer frequency. + */ +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_timer, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for retrieving the timer frequency. + * + * @param[in] p_timer Timer instance. + * + * @return Timer frequency. + */ +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_timer); + +/** + * @brief Function for writing the capture/compare register for a specified channel. + * + * @param[in] p_timer Timer instance. + * @param[in] cc_channel Requested capture/compare channel. + * @param[in] cc_value Value to write to the capture/compare register. + */ +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_timer, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value); + +/** + * @brief Function for retrieving the capture/compare value for a specified channel. + * + * @param[in] p_timer Timer instance. + * @param[in] cc_channel Requested capture/compare channel. + * + * @return Value from the requested capture/compare register. + */ +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_timer, + nrf_timer_cc_channel_t cc_channel); + +/** + * @brief Function for getting a specific timer capture task. + * + * @param[in] channel Capture channel. + * + * @return Capture task. + */ +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare event. + * + * @param[in] channel Compare channel. + * + * @return Compare event. + */ +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare interrupt. + * + * @param[in] channel Compare channel. + * + * @return Compare interrupt. + */ +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in microseconds) and timer frequency. + * + * @param[in] time_us Time in microseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in milliseconds) and timer frequency. + * + * @param[in] time_ms Time in milliseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_timer, + nrf_timer_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_timer, + nrf_timer_task_t task) +{ + return (uint32_t *)((uint8_t *)p_timer + (uint32_t)task); +} + +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_timer + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_timer, + nrf_timer_event_t event) +{ + return (uint32_t *)((uint8_t *)p_timer + (uint32_t)event); +} + +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_timer, + uint32_t timer_shorts_mask) +{ + p_timer->SHORTS |= timer_shorts_mask; +} + +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_timer, + uint32_t timer_shorts_mask) +{ + p_timer->SHORTS &= ~(timer_shorts_mask); +} + +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_timer, + uint32_t timer_int_mask) +{ + p_timer->INTENSET = timer_int_mask; +} + +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_timer, + uint32_t timer_int_mask) +{ + p_timer->INTENCLR = timer_int_mask; +} + +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_timer, + uint32_t timer_int) +{ + return (bool)(p_timer->INTENSET & timer_int); +} + +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_timer, + nrf_timer_mode_t mode) +{ + p_timer->MODE = (p_timer->MODE & ~TIMER_MODE_MODE_Msk) | + ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); +} + +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_timer) +{ + return (nrf_timer_mode_t)(p_timer->MODE); +} + +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_timer, + nrf_timer_bit_width_t bit_width) +{ + p_timer->BITMODE = (p_timer->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | + ((bit_width << TIMER_BITMODE_BITMODE_Pos) & + TIMER_BITMODE_BITMODE_Msk); +} + +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_timer) +{ + return (nrf_timer_bit_width_t)(p_timer->BITMODE); +} + +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_timer, + nrf_timer_frequency_t frequency) +{ + p_timer->PRESCALER = (p_timer->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | + ((frequency << TIMER_PRESCALER_PRESCALER_Pos) & + TIMER_PRESCALER_PRESCALER_Msk); +} + +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_timer) +{ + return (nrf_timer_frequency_t)(p_timer->PRESCALER); +} + +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_timer, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value) +{ + p_timer->CC[cc_channel] = cc_value; +} + +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_timer, + nrf_timer_cc_channel_t cc_channel) +{ + return (uint32_t)p_timer->CC[cc_channel]; +} + +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel) +{ + return (nrf_timer_task_t) + ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel) +{ + return (nrf_timer_event_t) + ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel) +{ + return (nrf_timer_int_mask_t) + ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel); +} + +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16 MHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_us <= (UINT32_MAX / 16UL)); + return ((time_us * 16UL) >> prescaler); +} + +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16000 kHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_ms <= (UINT32_MAX / 16000UL)); + return ((time_ms * 16000UL) >> prescaler); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_TIMER_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twi.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twi.h new file mode 100644 index 00000000..fbbd0bf6 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twi.h @@ -0,0 +1,419 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_TWI_H__ +#define NRF_TWI_H__ + +/** + * @defgroup nrf_twi_hal TWI HAL + * @{ + * @ingroup nrf_twi_master + * + * @brief Hardware access layer for managing the TWI peripheral. + */ + +#include +#include +#include + +#include "nrf.h" + +/** + * @brief TWI tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWI_TASK_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWI_TASK_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) ///< Resume TWI transaction. + /*lint -restore*/ +} nrf_twi_task_t; + +/** + * @brief TWI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWI_EVENT_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWI_EVENT_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received. + NRF_TWI_EVENT_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), ///< TWI TXD byte sent. + NRF_TWI_EVENT_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWI_EVENT_BB = offsetof(NRF_TWI_Type, EVENTS_BB), ///< TWI byte boundary, generated before each byte that is sent or received. + NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state. + /*lint -restore*/ +} nrf_twi_event_t; + +/** + * @brief TWI shortcuts. + */ +typedef enum +{ + NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, ///< Shortcut between BB event and SUSPEND task. + NRF_TWI_SHORT_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, ///< Shortcut between BB event and STOP task. +} nrf_twi_short_mask_t; + +/** + * @brief TWI interrupts. + */ +typedef enum +{ + NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, ///< Interrupt on RXDREADY event. + NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, ///< Interrupt on TXDSENT event. + NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, ///< Interrupt on BB event. + NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk ///< Interrupt on SUSPENDED event. +} nrf_twi_int_mask_t; + +/** + * @brief TWI error source. + */ +typedef enum +{ + NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte. + NRF_TWI_ERROR_OVERRUN = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error. + /**< A new byte was received before the previous byte was read + * from the RXD register (previous data is lost). */ +} nrf_twi_error_t; + +/** + * @brief TWI master clock frequency. + */ +typedef enum +{ + NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twi_frequency_t; + + +/** + * @brief Function for activating a specific TWI task. + * + * @param[in] p_twi TWI instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_twi, + nrf_twi_task_t task); + +/** + * @brief Function for getting the address of a specific TWI task register. + * + * @param[in] p_twi TWI instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi, + nrf_twi_task_t task); + +/** + * @brief Function for clearing a specific TWI event. + * + * @param[in] p_twi TWI instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi, + nrf_twi_event_t event); + +/** + * @brief Function for checking the state of a specific event. + * + * @param[in] p_twi TWI instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_twi, + nrf_twi_event_t event); + +/** + * @brief Function for getting the address of a specific TWI event register. + * + * @param[in] p_twi TWI instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi, + nrf_twi_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_twi TWI instance. + * @param[in] shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_twi, + uint32_t shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_twi TWI instance. + * @param[in] shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_twi, + uint32_t shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_twi TWI instance. + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi, + uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_twi TWI instance. + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi, + uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_twi TWI instance. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_twi, + nrf_twi_int_mask_t int_mask); + +/** + * @brief Function for enabling the TWI peripheral. + * + * @param[in] p_twi TWI instance. + */ +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi); + +/** + * @brief Function for disabling the TWI peripheral. + * + * @param[in] p_twi TWI instance. + */ +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi); + +/** + * @brief Function for configuring TWI pins. + * + * + * @param[in] p_twi TWI instance. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. + */ +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi, + uint32_t scl_pin, + uint32_t sda_pin); + +/** + * @brief Function for setting the TWI master clock frequency. + * + * @param[in] p_twi TWI instance. + * @param[in] frequency TWI frequency. + */ +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi, + nrf_twi_frequency_t frequency); + +/** + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. + * + * @param[in] p_twi TWI instance. + * + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_twi); + +/** + * @brief Function for setting the address to be used in TWI transfers. + * + * @param[in] p_twi TWI instance. + * @param[in] address Address to be used in transfers. + */ +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t address); + +/** + * @brief Function for reading data received by TWI. + * + * @param[in] p_twi TWI instance. + * + * @return Received data. + */ +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi); + +/** + * @brief Function for writing data to be transmitted by TWI. + * + * @param[in] p_twi TWI instance. + * @param[in] data Data to be transmitted. + */ +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data); + +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi, + uint32_t shorts_mask); + +/** + * @} + */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_twi, + nrf_twi_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi, + nrf_twi_task_t task) +{ + return (uint32_t *)((uint8_t *)p_twi + (uint32_t)task); +} + +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi, + nrf_twi_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_twi, + nrf_twi_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi, + nrf_twi_event_t event) +{ + return (uint32_t *)((uint8_t *)p_twi + (uint32_t)event); +} + +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_twi, + uint32_t shorts_mask) +{ + p_twi->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_twi, + uint32_t shorts_mask) +{ + p_twi->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi, + uint32_t int_mask) +{ + p_twi->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi, + uint32_t int_mask) +{ + p_twi->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_twi, + nrf_twi_int_mask_t int_mask) +{ + return (bool)(p_twi->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi) +{ + p_twi->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi) +{ + p_twi->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi, + uint32_t scl_pin, + uint32_t sda_pin) +{ + p_twi->PSELSCL = scl_pin; + p_twi->PSELSDA = sda_pin; +} + +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi, + nrf_twi_frequency_t frequency) +{ + p_twi->FREQUENCY = frequency; +} + +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_twi) +{ + uint32_t error_source = p_twi->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_twi->ERRORSRC = error_source; + + return error_source; +} + +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t address) +{ + p_twi->ADDRESS = address; +} + +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi) +{ + return (uint8_t)p_twi->RXD; +} + +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data) +{ + p_twi->TXD = data; +} + +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi, + uint32_t shorts_mask) +{ + p_twi->SHORTS = shorts_mask; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_TWI_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twim.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twim.h new file mode 100644 index 00000000..8f89be37 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twim.h @@ -0,0 +1,495 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_TWIM_H__ +#define NRF_TWIM_H__ + +/** + * @defgroup nrf_twim_hal TWIM HAL + * @{ + * @ingroup nrf_twi_master + * + * @brief Hardware access layer for managing the TWIM peripheral. + */ + +#include +#include +#include + +#include "nrf.h" + +/** + * @brief TWIM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_TASK_STARTRX = offsetof(NRF_TWIM_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWIM_TASK_STARTTX = offsetof(NRF_TWIM_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWIM_TASK_STOP = offsetof(NRF_TWIM_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWIM_TASK_SUSPEND = offsetof(NRF_TWIM_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWIM_TASK_RESUME = offsetof(NRF_TWIM_Type, TASKS_RESUME) ///< Resume TWI transaction. + /*lint -restore*/ +} nrf_twim_task_t; + +/** + * @brief TWIM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_EVENT_STOPPED = offsetof(NRF_TWIM_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWIM_EVENT_ERROR = offsetof(NRF_TWIM_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWIM_EVENT_SUSPENDED = 0x148, ///< TWI suspended. + NRF_TWIM_EVENT_RXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_RXSTARTED), ///< Receive sequence started. + NRF_TWIM_EVENT_TXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_TXSTARTED), ///< Transmit sequence started. + NRF_TWIM_EVENT_LASTRX = offsetof(NRF_TWIM_Type, EVENTS_LASTRX), ///< Byte boundary, starting to receive the last byte. + NRF_TWIM_EVENT_LASTTX = offsetof(NRF_TWIM_Type, EVENTS_LASTTX) ///< Byte boundary, starting to transmit the last byte. + /*lint -restore*/ +} nrf_twim_event_t; + +/** + * @brief TWIM shortcuts. + */ +typedef enum +{ + NRF_TWIM_SHORT_LASTTX_STARTRX_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk, ///< Shortcut between LASTTX event and STARTRX task. + NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK = TWIM_SHORTS_LASTTX_SUSPEND_Msk, ///< Shortcut between LASTTX event and SUSPEND task. + NRF_TWIM_SHORT_LASTTX_STOP_MASK = TWIM_SHORTS_LASTTX_STOP_Msk, ///< Shortcut between LASTTX event and STOP task. + NRF_TWIM_SHORT_LASTRX_STARTTX_MASK = TWIM_SHORTS_LASTRX_STARTTX_Msk, ///< Shortcut between LASTRX event and STARTTX task. + NRF_TWIM_SHORT_LASTRX_STOP_MASK = TWIM_SHORTS_LASTRX_STOP_Msk ///< Shortcut between LASTRX event and STOP task. +} nrf_twim_short_mask_t; + +/** + * @brief TWIM interrupts. + */ +typedef enum +{ + NRF_TWIM_INT_STOPPED_MASK = TWIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWIM_INT_ERROR_MASK = TWIM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWIM_INT_SUSPENDED_MASK = (1 << 18), ///< Interrupt on SUSPENDED event. + NRF_TWIM_INT_RXSTARTED_MASK = TWIM_INTENSET_RXSTARTED_Msk, ///< Interrupt on RXSTARTED event. + NRF_TWIM_INT_TXSTARTED_MASK = TWIM_INTENSET_TXSTARTED_Msk, ///< Interrupt on TXSTARTED event. + NRF_TWIM_INT_LASTRX_MASK = TWIM_INTENSET_LASTRX_Msk, ///< Interrupt on LASTRX event. + NRF_TWIM_INT_LASTTX_MASK = TWIM_INTENSET_LASTTX_Msk ///< Interrupt on LASTTX event. +} nrf_twim_int_mask_t; + +/** + * @brief TWIM master clock frequency. + */ +typedef enum +{ + NRF_TWIM_FREQ_100K = TWIM_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWIM_FREQ_250K = TWIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWIM_FREQ_400K = TWIM_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twim_frequency_t; + +/** + * @brief TWIM error source. + */ +typedef enum +{ + NRF_TWIM_ERROR_ADDRESS_NACK = TWIM_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWIM_ERROR_DATA_NACK = TWIM_ERRORSRC_DNACK_Msk ///< NACK received after sending a data byte. +} nrf_twim_error_t; + + +/** + * @brief Function for activating a specific TWIM task. + * + * @param[in] p_twim TWIM instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_twim, + nrf_twim_task_t task); + +/** + * @brief Function for getting the address of a specific TWIM task register. + * + * @param[in] p_twim TWIM instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_twim, + nrf_twim_task_t task); + +/** + * @brief Function for clearing a specific TWIM event. + * + * @param[in] p_twim TWIM instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event); + +/** + * @brief Function for checking the state of a specific TWIM event. + * + * @param[in] p_twim TWIM instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event); + +/** + * @brief Function for getting the address of a specific TWIM event register. + * + * @param[in] p_twim TWIM instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_twim TWIM instance. + * @param[in] shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_twim TWIM instance. + * @param[in] shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_twim TWIM instance. + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_twim, + uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_twim TWIM instance. + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_twim, + uint32_t int_mask); + +/** + * @brief Function for checking the state of a given interrupt. + * + * @param[in] p_twim TWIM instance. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_twim, + nrf_twim_int_mask_t int_mask); + +/** + * @brief Function for enabling the TWIM peripheral. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for disabling the TWIM peripheral. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for configuring TWI pins. + * + * + * @param[in] p_twim TWIM instance. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. + */ +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_twim, + uint32_t scl_pin, + uint32_t sda_pin); + +/** + * @brief Function for setting the TWI master clock frequency. + * + * @param[in] p_twim TWIM instance. + * @param[in] frequency TWI frequency. + */ +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_twim, + nrf_twim_frequency_t frequency); + +/** + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. + * + * @param[in] p_twim TWIM instance. + * + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for setting the address to be used in TWI transfers. + * + * @param[in] p_twim TWIM instance. + * @param[in] address Address to be used in transfers. + */ +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_twim, + uint8_t address); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_twim TWIM instance. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_twim, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_twim TWIM instance. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_twim, + uint8_t * p_buffer, + uint8_t length); + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask); + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_twim); + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_twim); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_twim TWIM instance. + */ +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_twim); + +/** + * @} + */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_twim, + nrf_twim_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_twim, + nrf_twim_task_t task) +{ + return (uint32_t *)((uint8_t *)p_twim + (uint32_t)task); +} + +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_twim + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_twim, + nrf_twim_event_t event) +{ + return (uint32_t *)((uint8_t *)p_twim + (uint32_t)event); +} + +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask) +{ + p_twim->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask) +{ + p_twim->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_twim, + uint32_t int_mask) +{ + p_twim->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_twim, + uint32_t int_mask) +{ + p_twim->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_twim, + nrf_twim_int_mask_t int_mask) +{ + return (bool)(p_twim->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_twim) +{ + p_twim->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_twim) +{ + p_twim->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_twim, + uint32_t scl_pin, + uint32_t sda_pin) +{ + p_twim->PSEL.SCL = scl_pin; + p_twim->PSEL.SDA = sda_pin; +} + +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_twim, + nrf_twim_frequency_t frequency) +{ + p_twim->FREQUENCY = frequency; +} + +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_twim) +{ + uint32_t error_source = p_twim->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_twim->ERRORSRC = error_source; + + return error_source; +} + +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_twim, + uint8_t address) +{ + p_twim->ADDRESS = address; +} + +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_twim, + uint8_t const * p_buffer, + uint8_t length) +{ + p_twim->TXD.PTR = (uint32_t)p_buffer; + p_twim->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_twim, + uint8_t * p_buffer, + uint8_t length) +{ + p_twim->RXD.PTR = (uint32_t)p_buffer; + p_twim->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_twim, + uint32_t shorts_mask) +{ + p_twim->SHORTS = shorts_mask; +} + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_twim) +{ + return p_twim->TXD.AMOUNT; +} + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_twim) +{ + return p_twim->RXD.AMOUNT; +} + +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_twim) +{ + p_twim->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_twim) +{ + p_twim->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_twim) +{ + p_twim->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_twim) +{ + p_twim->RXD.LIST = 0; +} +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_TWIM_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twis.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twis.h new file mode 100644 index 00000000..79153554 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_twis.h @@ -0,0 +1,693 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + */ + +/** + * @ingroup nrf_twis + * @defgroup nrf_twis_hal TWIS HAL + * @{ + * + * @brief @tagAPI52 Hardware access layer for Two Wire Interface Slave with EasyDMA + * (TWIS) peripheral. + */ +#ifndef NRF_TWIS_H__ +#define NRF_TWIS_H__ + +#include "nrf.h" +#include "nrf_drv_config.h" +#include +#include +#include + +/** + * @brief TWIS tasks + */ +typedef enum +{ + /*lint -save -e30*/ +#ifndef NRF52_PAN_30 /* STOP task is not functional in MPW3 (PAN-30) */ + /* Stop task is not working properly for first release */ + NRF_TWIS_TASK_STOP = offsetof(NRF_TWIS_Type, TASKS_STOP), /**< Stop TWIS transaction */ +#endif + NRF_TWIS_TASK_SUSPEND = offsetof(NRF_TWIS_Type, TASKS_SUSPEND), /**< Suspend TWIS transaction */ + NRF_TWIS_TASK_RESUME = offsetof(NRF_TWIS_Type, TASKS_RESUME), /**< Resume TWIS transaction */ + NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), /**< Prepare the TWIS slave to respond to a write command */ + NRF_TWIS_TASK_PREPARETX = offsetof(NRF_TWIS_Type, TASKS_PREPARETX) /**< Prepare the TWIS slave to respond to a read command */ + /*lint -restore*/ +} nrf_twis_task_t; + +/** + * @brief TWIS events + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIS_EVENT_STOPPED = offsetof(NRF_TWIS_Type, EVENTS_STOPPED), /**< TWIS stopped */ + NRF_TWIS_EVENT_ERROR = offsetof(NRF_TWIS_Type, EVENTS_ERROR), /**< TWIS error */ + NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_RXSTARTED), /**< Receive sequence started */ + NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_TXSTARTED), /**< Transmit sequence started */ + NRF_TWIS_EVENT_WRITE = offsetof(NRF_TWIS_Type, EVENTS_WRITE), /**< Write command received */ + NRF_TWIS_EVENT_READ = offsetof(NRF_TWIS_Type, EVENTS_READ) /**< Read command received */ + /*lint -restore*/ +} nrf_twis_event_t; + +/** + * @brief TWIS shortcuts + */ +typedef enum +{ + NRF_TWIS_SHORT_WRITE_SUSPEND_MASK = TWIS_SHORTS_WRITE_SUSPEND_Msk, /**< Shortcut between WRITE event and SUSPEND task */ + NRF_TWIS_SHORT_READ_SUSPEND_MASK = TWIS_SHORTS_READ_SUSPEND_Msk, /**< Shortcut between READ event and SUSPEND task */ +} nrf_twis_short_mask_t; + +/** + * @brief TWIS interrupts + */ +typedef enum +{ + NRF_TWIS_INT_STOPPED_MASK = TWIS_INTEN_STOPPED_Msk, /**< Interrupt on STOPPED event */ + NRF_TWIS_INT_ERROR_MASK = TWIS_INTEN_ERROR_Msk, /**< Interrupt on ERROR event */ + NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_RXSTARTED_Msk, /**< Interrupt on RXSTARTED event */ + NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_TXSTARTED_Msk, /**< Interrupt on TXSTARTED event */ + NRF_TWIS_INT_WRITE_MASK = TWIS_INTEN_WRITE_Msk, /**< Interrupt on WRITE event */ + NRF_TWIS_INT_READ_MASK = TWIS_INTEN_READ_Msk, /**< Interrupt on READ event */ +} nrf_twis_int_mask_t; + +/** + * @brief TWIS error source + */ +typedef enum +{ + NRF_TWIS_ERROR_OVERFLOW = TWIS_ERRORSRC_OVERFLOW_Msk, /**< RX buffer overflow detected, and prevented */ +#ifdef NRF52_PAN_29 + /* Patched version of bit positions in ERRORSRC register (PAN-29) */ + NRF_TWIS_ERROR_DATA_NACK = 1U << 1, /**< NACK sent after receiving a data byte */ + NRF_TWIS_ERROR_OVERREAD = 1U << 2 /**< TX buffer over-read detected, and prevented */ +#else + /* Code that meets current documentation */ + NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk, /**< NACK sent after receiving a data byte */ + NRF_TWIS_ERROR_OVERREAD = TWIS_ERRORSRC_OVERREAD_Msk /**< TX buffer over-read detected, and prevented */ +#endif +} nrf_twis_error_t; + +/** + * @brief TWIS address matching configuration + */ +typedef enum +{ + NRF_TWIS_CONFIG_ADDRESS0_MASK = TWIS_CONFIG_ADDRESS0_Msk, /**< Enable or disable address matching on ADDRESS[0] */ + NRF_TWIS_CONFIG_ADDRESS1_MASK = TWIS_CONFIG_ADDRESS1_Msk, /**< Enable or disable address matching on ADDRESS[1] */ + NRF_TWIS_CONFIG_ADDRESS01_MASK = TWIS_CONFIG_ADDRESS0_Msk | TWIS_CONFIG_ADDRESS1_Msk /**< Enable both address matching */ +} nrf_twis_config_addr_mask_t; + +/** + * @brief Variable type to hold amount of data for EasyDMA + * + * Variable of the minimum size that can hold the amount of data to transfer. + * + * @note + * Defined to make it simple to change if EasyDMA would be updated to support more data in + * the future devices to. + */ +typedef uint8_t nrf_twis_amount_t; + +/** + * @brief Smallest variable type to hold TWI address + * + * Variable of the minimum size that can hold single TWI address. + * + * @note + * Defined to make it simple to change if new TWI would support for example + * 10 bit addressing mode. + */ +typedef uint8_t nrf_twis_address_t; + + +/** + * @brief Function for activating a specific TWIS task. + * + * @param[in] p_twis TWIS instance. + * @param task Task. + */ +__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task); + +/** + * @brief Function for returning the address of a specific TWIS task register. + * + * @param[in] p_twis TWIS instance. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_twis_task_address_get( + NRF_TWIS_Type const * const p_twis, + nrf_twis_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param[in] p_twis TWIS instance. + * @param event Event. + */ +__STATIC_INLINE void nrf_twis_event_clear( + NRF_TWIS_Type * const p_twis, + nrf_twis_event_t event); +/** + * @brief Function for returning the state of a specific event. + * + * @param[in] p_twis TWIS instance. + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twis_event_check( + NRF_TWIS_Type const * const p_twis, + nrf_twis_event_t event); + + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * @param[in,out] p_twis TWIS instance + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_twis_event_get_and_clear( + NRF_TWIS_Type * const p_twis, + nrf_twis_event_t event); + + +/** + * @brief Function for returning the address of a specific TWIS event register. + * + * @param[in] p_twis TWIS instance. + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_twis_event_address_get( + NRF_TWIS_Type const * const p_twis, + nrf_twis_event_t event); + +/** + * @brief Function for setting a shortcut. + * + * @param[in] p_twis TWIS instance. + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask); + +/** + * @brief Function for clearing shortcuts. + * + * @param[in] p_twis TWIS instance. + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask); + +/** + * @brief Get the shorts mask + * + * Function returns shorts register. + * @param[in] p_twis TWIS instance. + * @return Flags of currently enabled shortcuts + */ +__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis); + +/** + * @brief Function for enabling selected interrupts. + * + * @param[in] p_twis TWIS instance. + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param[in] p_twis TWIS instance. + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask); + +/** + * @brief Function for disabling selected interrupts. + * + * @param[in] p_twis TWIS instance. + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask); + +/** + * @brief Function for retrieving and clearing the TWIS error source. + * + * @attention Error sources are cleared after read. + * @param[in] p_twis TWIS instance + * @return Error source mask with values from @ref nrf_twis_error_t. + */ +__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis); + +/** + * @brief Get information which of addresses matched + * + * Function returns index in the address table + * that points to the address that already matched. + * @param[in] p_twis TWIS instance + * @return Index of matched address + */ +__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis); + +/** + * @brief Function for enabling TWIS. + * + * @param[in] p_twis TWIS instance. + */ +__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_twis); + +/** + * @brief Function for disabling TWIS. + * + * @param[in] p_twis TWIS instance. + */ +__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_twis); + +/** + * @brief Function for configuring TWIS pins. + * + * @param[in] p_twis TWIS instance. + * @param scl SCL pin number. + * @param sda SDA pin number. + */ +__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_twis TWIS instance. + * @param p_buf Pointer to the buffer for received data. + * @param length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twis_rx_buffer_set( + NRF_TWIS_Type * const p_twis, + uint8_t * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function that prepares TWIS for receiving + * + * This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task. + * @param[in] p_twis TWIS instance. + * @param p_buf Pointer to the buffer for received data. + * @param length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twis_rx_prepare( + NRF_TWIS_Type * const p_twis, + uint8_t * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function for getting number of bytes received in the last transaction. + * + * @param[in] p_twis TWIS instance. + * @return Amount of bytes received. + * */ +__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_twis TWIS instance. + * @param p_buf Pointer to the buffer with data to send. + * @param length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twis_tx_buffer_set( + NRF_TWIS_Type * const p_twis, + uint8_t const * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function that prepares TWIS for transmitting + * + * This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task. + * @param[in] p_twis TWIS instance. + * @param p_buf Pointer to the buffer with data to send. + * @param length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twis_tx_prepare( + NRF_TWIS_Type * const p_twis, + uint8_t const * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function for getting number of bytes transmitted in the last transaction. + * + * @param[in] p_twis TWIS instance. + * @return Amount of bytes transmitted. + */ +__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis); + +/** + * @brief Function for setting slave address + * + * Function sets the selected address for this TWI interface. + * @param[in] p_twis TWIS instance. + * @param n Index of address to set + * @param addr Addres to set + * @sa nrf_twis_config_address_set + * @sa nrf_twis_config_address_get + */ +__STATIC_INLINE void nrf_twis_address_set( + NRF_TWIS_Type * const p_twis, + uint_fast8_t n, + nrf_twis_address_t addr); + +/** + * @brief Function for retrieving configured slave address + * + * Function gets the selected address for this TWI interface. + * @param[in] p_twis TWIS instance. + * @param n Index of address to get + */ +__STATIC_INLINE nrf_twis_address_t nrf_twis_address_get( + NRF_TWIS_Type const * const p_twis, + uint_fast8_t n); + +/** + * @brief Function for setting the device address configuration. + * + * @param[in] p_twis TWIS instance. + * @param addr_mask Mask of address indexes of what device should answer to. + * + * @sa nrf_twis_address_set + */ +__STATIC_INLINE void nrf_twis_config_address_set( + NRF_TWIS_Type * const p_twis, + nrf_twis_config_addr_mask_t addr_mask); + +/** + * @brief Function for retrieving the device address configuration. + * + * @param[in] p_twis TWIS instance. + * + * @return Mask of address indexes of what device should answer to. + */ +__STATIC_INLINE nrf_twis_config_addr_mask_t nrf_twis_config_address_get( + NRF_TWIS_Type const * const p_twis); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_twis TWIS instance. + * @param[in] orc Over-read character. Character clocked out in case of + * over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_twis_orc_set( + NRF_TWIS_Type * const p_twis, + uint8_t orc); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_twis TWIS instance. + * + * @return Over-read character configured for selected instance. + */ +__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis); + + +/** @} */ /* End of nrf_twis_hal */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @param[in] p_twis TWIS instance. + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_twis, uint32_t offset) +{ + return (volatile uint32_t*)((uint8_t *)p_twis + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @param[in] p_twis TWIS instance. + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_twis, uint32_t offset) +{ + return (volatile const uint32_t*)((uint8_t *)p_twis + (uint32_t)offset); +} + + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + + +void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task) +{ + *(nrf_twis_getRegPtr(p_twis, (uint32_t)task)) = 1UL; +} + +uint32_t nrf_twis_task_address_get( + NRF_TWIS_Type const * const p_twis, + nrf_twis_task_t task) +{ + return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)task); +} + +void nrf_twis_event_clear( + NRF_TWIS_Type * const p_twis, + nrf_twis_event_t event) +{ + *(nrf_twis_getRegPtr(p_twis, (uint32_t)event)) = 0UL; +} + +bool nrf_twis_event_check( + NRF_TWIS_Type const * const p_twis, + nrf_twis_event_t event) +{ + return (bool)*nrf_twis_getRegPtr_c(p_twis, (uint32_t)event); +} + +bool nrf_twis_event_get_and_clear( + NRF_TWIS_Type * const p_twis, + nrf_twis_event_t event) +{ + bool ret = nrf_twis_event_check(p_twis, event); + if(ret) + { + nrf_twis_event_clear(p_twis, event); + } + return ret; +} + +uint32_t nrf_twis_event_address_get( + NRF_TWIS_Type const * const p_twis, + nrf_twis_event_t event) +{ + return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)event); +} + +void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask) +{ + p_twis->SHORTS |= short_mask; +} + +void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask) +{ + if(~0U == short_mask) + { + /* Optimized version for "disable all" */ + p_twis->SHORTS = 0; + } + else + { + p_twis->SHORTS &= ~short_mask; + } +} + +uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis) +{ + return p_twis->SHORTS; +} + +void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask) +{ + p_twis->INTENSET = int_mask; +} + +bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask) +{ + return (bool)(p_twis->INTENSET & int_mask); +} + +void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask) +{ + p_twis->INTENCLR = int_mask; +} + +uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis) +{ + uint32_t ret = p_twis->ERRORSRC; + p_twis->ERRORSRC = ret; + return ret; +} + +uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis) +{ + return (uint_fast8_t)p_twis->MATCH; +} + +void nrf_twis_enable(NRF_TWIS_Type * const p_twis) +{ + p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos); +} + +void nrf_twis_disable(NRF_TWIS_Type * const p_twis) +{ + p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos); +} + +void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda) +{ + p_twis->PSEL.SCL = scl; + p_twis->PSEL.SDA = sda; +} + +void nrf_twis_rx_buffer_set( + NRF_TWIS_Type * const p_twis, + uint8_t * p_buf, + nrf_twis_amount_t length) +{ + p_twis->RXD.PTR = (uint32_t)p_buf; + p_twis->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twis_rx_prepare( + NRF_TWIS_Type * const p_twis, + uint8_t * p_buf, + nrf_twis_amount_t length) +{ + nrf_twis_rx_buffer_set(p_twis, p_buf, length); + nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARERX); +} + +nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis) +{ + return (nrf_twis_amount_t)p_twis->RXD.AMOUNT; +} + +void nrf_twis_tx_buffer_set( + NRF_TWIS_Type * const p_twis, + uint8_t const * p_buf, + nrf_twis_amount_t length) +{ + p_twis->TXD.PTR = (uint32_t)p_buf; + p_twis->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twis_tx_prepare( + NRF_TWIS_Type * const p_twis, + uint8_t const * p_buf, + nrf_twis_amount_t length) +{ + nrf_twis_tx_buffer_set(p_twis, p_buf, length); + nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARETX); +} + +nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis) +{ + return (nrf_twis_amount_t)p_twis->TXD.AMOUNT; +} + +void nrf_twis_address_set( + NRF_TWIS_Type * const p_twis, + uint_fast8_t n, + nrf_twis_address_t addr) +{ + p_twis->ADDRESS[n] = addr; +} + +nrf_twis_address_t nrf_twis_address_get( + NRF_TWIS_Type const * const p_twis, + uint_fast8_t n) +{ + return (nrf_twis_address_t)p_twis->ADDRESS[n]; +} +void nrf_twis_config_address_set( + NRF_TWIS_Type * const p_twis, + nrf_twis_config_addr_mask_t addr_mask) +{ + /* This is the only configuration in TWIS - just write it without masking */ + p_twis->CONFIG = addr_mask; +} + +nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_twis) +{ + return (nrf_twis_config_addr_mask_t)(p_twis->CONFIG & TWIS_ADDRESS_ADDRESS_Msk); +} + +void nrf_twis_orc_set( + NRF_TWIS_Type * const p_twis, + uint8_t orc) +{ + p_twis->ORC = orc; +} + +uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis) +{ + return (uint8_t)p_twis->ORC; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#endif /* NRF_TWIS_H__ */ + diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uart.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uart.h new file mode 100644 index 00000000..2a83bca6 --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uart.h @@ -0,0 +1,488 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_UART_H__ +#define NRF_UART_H__ + +#include "nrf.h" +#include +#include +#include + +/** + * @defgroup nrf_uart_hal UART HAL + * @{ + * @ingroup nrf_uart + * + * @brief Hardware access layer for accessing the UART peripheral. + */ + +#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF + +/** + * @enum nrf_uart_task_t + * @brief UART tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_UART_TASK_STARTRX = offsetof(NRF_UART_Type, TASKS_STARTRX), /**< Task for starting reception. */ + NRF_UART_TASK_STOPRX = offsetof(NRF_UART_Type, TASKS_STOPRX), /**< Task for stopping reception. */ + NRF_UART_TASK_STARTTX = offsetof(NRF_UART_Type, TASKS_STARTTX), /**< Task for starting transmission. */ + NRF_UART_TASK_STOPTX = offsetof(NRF_UART_Type, TASKS_STOPTX), /**< Task for stopping transmission. */ + NRF_UART_TASK_SUSPEND = offsetof(NRF_UART_Type, TASKS_SUSPEND), /**< Task for suspending UART. */ + /*lint -restore*/ +} nrf_uart_task_t; + +/** + * @enum nrf_uart_event_t + * @brief UART events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UART_EVENT_CTS = offsetof(NRF_UART_Type, EVENTS_CTS), /**< Event from CTS line activation. */ + NRF_UART_EVENT_NCTS = offsetof(NRF_UART_Type, EVENTS_NCTS), /**< Event from CTS line deactivation. */ + NRF_UART_EVENT_RXDRDY = offsetof(NRF_UART_Type, EVENTS_RXDRDY),/**< Event from data ready in RXD. */ + NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */ + NRF_UART_EVENT_ERROR = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */ + NRF_UART_EVENT_RXTO = offsetof(NRF_UART_Type, EVENTS_RXTO) /**< Event from receiver timeout. */ + /*lint -restore*/ +} nrf_uart_event_t; + +/** + * @enum nrf_uart_int_mask_t + * @brief UART interrupts. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UART_INT_MASK_CTS = UART_INTENCLR_CTS_Msk, /**< CTS line activation interrupt. */ + NRF_UART_INT_MASK_NCTS = UART_INTENCLR_NCTS_Msk, /**< CTS line deactivation interrupt. */ + NRF_UART_INT_MASK_RXDRDY = UART_INTENCLR_RXDRDY_Msk, /**< Data ready in RXD interrupt. */ + NRF_UART_INT_MASK_TXDRDY = UART_INTENCLR_TXDRDY_Msk, /**< Data sent from TXD interrupt. */ + NRF_UART_INT_MASK_ERROR = UART_INTENCLR_ERROR_Msk, /**< Error detection interrupt. */ + NRF_UART_INT_MASK_RXTO = UART_INTENCLR_RXTO_Msk /**< Receiver timeout interrupt. */ + /*lint -restore*/ +} nrf_uart_int_mask_t; + +/** + * @enum nrf_uart_baudrate_t + * @brief Baudrates supported by UART. + */ +typedef enum +{ +#ifdef NRF52 + NRF_UART_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */ + NRF_UART_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */ + NRF_UART_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */ + NRF_UART_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */ + NRF_UART_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */ + NRF_UART_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */ + NRF_UART_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */ + NRF_UART_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */ + NRF_UART_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */ + NRF_UART_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */ + NRF_UART_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */ + NRF_UART_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */ + NRF_UART_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */ + NRF_UART_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */ + NRF_UART_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */ + NRF_UART_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */ +#else + NRF_UART_BAUDRATE_1200 = UART_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */ + NRF_UART_BAUDRATE_2400 = UART_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */ + NRF_UART_BAUDRATE_4800 = UART_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */ + NRF_UART_BAUDRATE_9600 = UART_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */ + NRF_UART_BAUDRATE_14400 = UART_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */ + NRF_UART_BAUDRATE_19200 = UART_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */ + NRF_UART_BAUDRATE_28800 = UART_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */ + NRF_UART_BAUDRATE_38400 = UART_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */ + NRF_UART_BAUDRATE_57600 = UART_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */ + NRF_UART_BAUDRATE_76800 = UART_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */ + NRF_UART_BAUDRATE_115200 = UART_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */ + NRF_UART_BAUDRATE_230400 = UART_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */ + NRF_UART_BAUDRATE_250000 = UART_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */ + NRF_UART_BAUDRATE_460800 = UART_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */ + NRF_UART_BAUDRATE_921600 = UART_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */ + NRF_UART_BAUDRATE_1000000 = UART_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */ +#endif +} nrf_uart_baudrate_t; + +/** + * @enum nrf_uart_error_mask_t + * @brief Types of UART error masks. + */ +typedef enum +{ + NRF_UART_ERROR_OVERRUN_MASK = UART_ERRORSRC_OVERRUN_Msk, /**< Overrun error. */ + NRF_UART_ERROR_PARITY_MASK = UART_ERRORSRC_PARITY_Msk, /**< Parity error. */ + NRF_UART_ERROR_FRAMING_MASK = UART_ERRORSRC_FRAMING_Msk, /**< Framing error. */ + NRF_UART_ERROR_BREAK_MASK = UART_ERRORSRC_BREAK_Msk, /**< Break error. */ +} nrf_uart_error_mask_t; + +/** + * @enum nrf_uart_parity_t + * @brief Types of UART parity modes. + */ +typedef enum +{ + NRF_UART_PARITY_EXCLUDED = UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos, /**< Parity excluded. */ + NRF_UART_PARITY_INCLUDED = UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos, /**< Parity included. */ +} nrf_uart_parity_t; + +/** + * @enum nrf_uart_hwfc_t + * @brief Types of UART flow control modes. + */ +typedef enum +{ + NRF_UART_HWFC_DISABLED = UART_CONFIG_HWFC_Disabled, /**< HW flow control disabled. */ + NRF_UART_HWFC_ENABLED = UART_CONFIG_HWFC_Enabled, /**< HW flow control enabled. */ +} nrf_uart_hwfc_t; + +/** + * @brief Function for clearing a specific UART event. + * + * @param[in] p_reg UART instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event); + +/** + * @brief Function for checking the state of a specific UART event. + * + * @param[in] p_reg UART instance. + * @param[in] event Event to check. + * + * @retval True if event is set, False otherwise. + */ +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event); + +/** + * @brief Function for returning the address of a specific UART event register. + * + * @param[in] p_reg UART instance. + * @param[in] event Desired event. + * + * @retval Address of specified event register. + */ +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, + nrf_uart_event_t event); + +/** + * @brief Function for enabling a specific interrupt. + * + * @param p_reg Instance. + * @param int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param p_reg Instance. + * @param int_mask Mask of interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for disabling specific interrupts. + * + * @param p_reg Instance. + * @param int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for getting error source mask. Function is clearing error source flags after reading. + * + * @param p_reg Instance. + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg); + +/** + * @brief Function for enabling UART. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg); + +/** + * @brief Function for disabling UART. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg); + +/** + * @brief Function for configuring TX/RX pins. + * + * @param p_reg Instance. + * @param pseltxd TXD pin number. + * @param pselrxd RXD pin number. + */ +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd); + +/** + * @brief Function for disconnecting TX/RX pins. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting TX pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting RX pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting RTS pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting CTS pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg); + + +/** + * @brief Function for configuring flow control pins. + * + * @param p_reg Instance. + * @param pselrts RTS pin number. + * @param pselcts CTS pin number. + */ +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, + uint32_t pselrts, + uint32_t pselcts); + +/** + * @brief Function for disconnecting flow control pins. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg); + +/** + * @brief Function for reading RX data. + * + * @param p_reg Instance. + * @return Received byte. + */ +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for setting Tx data. + * + * @param p_reg Instance. + * @param txd Byte. + */ +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd); + +/** + * @brief Function for starting an UART task. + * + * @param p_reg Instance. + * @param task Task. + */ +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task); + +/** + * @brief Function for returning the address of a specific task register. + * + * @param p_reg Instance. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task); + +/** + * @brief Function for configuring UART. + * + * @param p_reg Instance. + * @param hwfc Hardware flow control. Enabled if true. + * @param parity Parity. Included if true. + */ +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc); + +/** + * @brief Function for setting UART baudrate. + * + * @param p_reg Instance. + * @param baudrate Baudrate. + */ +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; + +} + +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, + nrf_uart_event_t event) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg) +{ + uint32_t errsrc_mask = p_reg->ERRORSRC; + p_reg->ERRORSRC = errsrc_mask; + return errsrc_mask; +} + +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg) +{ + p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled; +} + +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg) +{ + p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled; +} + +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) +{ + p_reg->PSELTXD = pseltxd; + p_reg->PSELRXD = pselrxd; +} + +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg) +{ + nrf_uart_txrx_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg) +{ + return p_reg->PSELTXD; +} + +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg) +{ + return p_reg->PSELRXD; +} + +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg) +{ + return p_reg->PSELRTS; +} + +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg) +{ + return p_reg->PSELCTS; +} + +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts) +{ + p_reg->PSELRTS = pselrts; + p_reg->PSELCTS = pselcts; +} + +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg) +{ + nrf_uart_hwfc_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg) +{ + return p_reg->RXD; +} + +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd) +{ + p_reg->TXD = txd; +} + +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task) +{ + return (uint32_t)p_reg + (uint32_t)task; +} + +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc) +{ + p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc; +} + +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate) +{ + p_reg->BAUDRATE = baudrate; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ +#endif //NRF_UART_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uarte.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uarte.h new file mode 100644 index 00000000..dd9cd56c --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_uarte.h @@ -0,0 +1,551 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_UARTE_H__ +#define NRF_UARTE_H__ + +#include "nrf.h" +#include +#include +#include + +#define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF + +/** + * @defgroup nrf_uarte_hal UARTE HAL + * @{ + * @ingroup nrf_uart + * + * @brief Hardware access layer for accessing the UARTE peripheral. + */ + +/** + * @enum nrf_uarte_task_t + * @brief UARTE tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UARTE_TASK_STARTRX = offsetof(NRF_UARTE_Type, TASKS_STARTRX),///< Start UART receiver. + NRF_UARTE_TASK_STOPRX = offsetof(NRF_UARTE_Type, TASKS_STOPRX), ///< Stop UART receiver. + NRF_UARTE_TASK_STARTTX = offsetof(NRF_UARTE_Type, TASKS_STARTTX),///< Start UART transmitter. + NRF_UARTE_TASK_STOPTX = offsetof(NRF_UARTE_Type, TASKS_STOPTX), ///< Stop UART transmitter. + NRF_UARTE_TASK_FLUSHRX = offsetof(NRF_UARTE_Type, TASKS_FLUSHRX) ///< Flush RX FIFO in RX buffer. + /*lint -restore*/ +} nrf_uarte_task_t; + +/** + * @enum nrf_uarte_event_t + * @brief UARTE events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UARTE_EVENT_CTS = offsetof(NRF_UARTE_Type, EVENTS_CTS), ///< CTS is activated. + NRF_UARTE_EVENT_NCTS = offsetof(NRF_UARTE_Type, EVENTS_NCTS), ///< CTS is deactivated. + NRF_UARTE_EVENT_ENDRX = offsetof(NRF_UARTE_Type, EVENTS_ENDRX), ///< Receive buffer is filled up. + NRF_UARTE_EVENT_ENDTX = offsetof(NRF_UARTE_Type, EVENTS_ENDTX), ///< Last TX byte transmitted. + NRF_UARTE_EVENT_ERROR = offsetof(NRF_UARTE_Type, EVENTS_ERROR), ///< Error detected. + NRF_UARTE_EVENT_RXTO = offsetof(NRF_UARTE_Type, EVENTS_RXTO), ///< Receiver timeout. + NRF_UARTE_EVENT_RXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_RXSTARTED),///< Receiver has started. + NRF_UARTE_EVENT_TXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_TXSTARTED),///< Transmitter has started. + NRF_UARTE_EVENT_TXSTOPPED = offsetof(NRF_UARTE_Type, EVENTS_TXSTOPPED) ///< Transmitted stopped. + /*lint -restore*/ +} nrf_uarte_event_t; + +/** + * @brief Types of UARTE shortcuts. + */ +typedef enum +{ + NRF_UARTE_SHORT_ENDRX_STARTRX = UARTE_SHORTS_ENDRX_STARTRX_Msk,///< Shortcut between ENDRX event and STARTRX task. + NRF_UARTE_SHORT_ENDRX_STOPRX = UARTE_SHORTS_ENDRX_STOPRX_Msk, ///< Shortcut between ENDRX event and STOPRX task. +} nrf_uarte_short_t; + + +/** + * @enum nrf_uarte_int_mask_t + * @brief UARTE interrupts. + */ +typedef enum +{ + NRF_UARTE_INT_CTS_MASK = UARTE_INTENSET_CTS_Msk, ///< Interrupt on CTS event. + NRF_UARTE_INT_NCTSRX_MASK = UARTE_INTENSET_NCTS_Msk, ///< Interrupt on NCTS event. + NRF_UARTE_INT_ENDRX_MASK = UARTE_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event. + NRF_UARTE_INT_ENDTX_MASK = UARTE_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event. + NRF_UARTE_INT_ERROR_MASK = UARTE_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_UARTE_INT_RXTO_MASK = UARTE_INTENSET_RXTO_Msk, ///< Interrupt on RXTO event. + NRF_UARTE_INT_RXSTARTED_MASK = UARTE_INTENSET_RXSTARTED_Msk,///< Interrupt on RXSTARTED event. + NRF_UARTE_INT_TXSTARTED_MASK = UARTE_INTENSET_TXSTARTED_Msk,///< Interrupt on TXSTARTED event. + NRF_UARTE_INT_TXSTOPPED_MASK = UARTE_INTENSET_TXSTOPPED_Msk ///< Interrupt on TXSTOPPED event. +} nrf_uarte_int_mask_t; + +/** + * @enum nrf_uarte_baudrate_t + * @brief Baudrates supported by UARTE. + */ +typedef enum +{ + NRF_UARTE_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud. + NRF_UARTE_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud. + NRF_UARTE_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, ///< 4800 baud. + NRF_UARTE_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, ///< 9600 baud. + NRF_UARTE_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, ///< 14400 baud. + NRF_UARTE_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, ///< 19200 baud. + NRF_UARTE_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, ///< 28800 baud. + NRF_UARTE_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, ///< 38400 baud. + NRF_UARTE_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, ///< 57600 baud. + NRF_UARTE_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, ///< 76800 baud. + NRF_UARTE_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, ///< 115200 baud. + NRF_UARTE_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, ///< 230400 baud. + NRF_UARTE_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, ///< 250000 baud. + NRF_UARTE_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, ///< 460800 baud. + NRF_UARTE_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, ///< 921600 baud. + NRF_UARTE_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud. +} nrf_uarte_baudrate_t; + +/** + * @enum nrf_uarte_error_mask_t + * @brief Types of UARTE error masks. + */ +typedef enum +{ + NRF_UARTE_ERROR_OVERRUN_MASK = UARTE_ERRORSRC_OVERRUN_Msk, ///< Overrun error. + NRF_UARTE_ERROR_PARITY_MASK = UARTE_ERRORSRC_PARITY_Msk, ///< Parity error. + NRF_UARTE_ERROR_FRAMING_MASK = UARTE_ERRORSRC_FRAMING_Msk, ///< Framing error. + NRF_UARTE_ERROR_BREAK_MASK = UARTE_ERRORSRC_BREAK_Msk, ///< Break error. +} nrf_uarte_error_mask_t; + +/** + * @enum nrf_uarte_parity_t + * @brief Types of UARTE parity modes. + */ +typedef enum +{ + NRF_UARTE_PARITY_EXCLUDED = UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos, ///< Parity excluded. + NRF_UARTE_PARITY_INCLUDED = UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos, ///< Parity included. +} nrf_uarte_parity_t; + +/** + * @enum nrf_uarte_hwfc_t + * @brief Types of UARTE flow control modes. + */ +typedef enum +{ + NRF_UARTE_HWFC_DISABLED = UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control disabled. + NRF_UARTE_HWFC_ENABLED = UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control enabled. +} nrf_uarte_hwfc_t; + + +/** + * @brief Function for clearing a specific UARTE event. + * + * @param[in] p_reg UARTE instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); + +/** + * @brief Function for checking the state of a specific UARTE event. + * + * @param[in] p_reg UARTE instance. + * @param[in] event Event to check. + * + * @retval True if event is set, False otherwise. + */ +__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); + +/** + * @brief Function for returning the address of a specific UARTE event register. + * + * @param[in] p_reg UARTE instance. + * @param[in] event Desired event. + * + * @retval Address of specified event register. + */ +__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, + nrf_uarte_event_t event); + +/** + * @brief Function for enabling UARTE shortcuts. + * + * @param p_reg UARTE instance. + * @param shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + +/** + * @brief Function for disabling UARTE shortcuts. + * + * @param p_reg UARTE instance. + * @param shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + +/** + * @brief Function for enabling UARTE interrupts. + * + * @param p_reg Instance. + * @param int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param p_reg Instance. + * @param int_mask Mask of interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask); + +/** + * @brief Function for disabling specific interrupts. + * + * @param p_reg Instance. + * @param int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for getting error source mask. Function is clearing error source flags after reading. + * + * @param p_reg Instance. + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for enabling UARTE. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for disabling UARTE. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for configuring TX/RX pins. + * + * @param p_reg Instance. + * @param pseltxd TXD pin number. + * @param pselrxd RXD pin number. + */ +__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd); + +/** + * @brief Function for disconnecting TX/RX pins. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting TX pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting RX pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting RTS pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting CTS pin. + * + * @param p_reg Instance. + */ +__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg); + + +/** + * @brief Function for configuring flow control pins. + * + * @param p_reg Instance. + * @param pselrts RTS pin number. + * @param pselcts CTS pin number. + */ +__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, + uint32_t pselrts, + uint32_t pselcts); + +/** + * @brief Function for disconnecting flow control pins. + * + * @param p_reg Instance. + */ +__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for starting an UARTE task. + * + * @param p_reg Instance. + * @param task Task. + */ +__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task); + +/** + * @brief Function for returning the address of a specific task register. + * + * @param p_reg Instance. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task); + +/** + * @brief Function for configuring UARTE. + * + * @param p_reg Instance. + * @param hwfc Hardware flow control. Enabled if true. + * @param parity Parity. Included if true. + */ +__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg, + nrf_uarte_parity_t parity, + nrf_uarte_hwfc_t hwfc); + + +/** + * @brief Function for setting UARTE baudrate. + * + * @param p_reg Instance. + * @param baudrate Baudrate. + */ +__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Instance. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for getting number of bytes transmitted in the last transaction. + * + * @param[in] p_reg Instance. + * + * @retval Amount of bytes transmitted. + */ +__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Instance. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for getting number of bytes received in the last transaction. + * + * @param[in] p_reg Instance. + * + * @retval Amount of bytes received. + */ +__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; + +} + +__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, + nrf_uarte_event_t event) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg) +{ + uint32_t errsrc_mask = p_reg->ERRORSRC; + p_reg->ERRORSRC = errsrc_mask; + return errsrc_mask; +} + +__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg) +{ + p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled; +} + +__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg) +{ + p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled; +} + +__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) +{ + p_reg->PSEL.TXD = pseltxd; + p_reg->PSEL.RXD = pselrxd; +} + +__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg) +{ + nrf_uarte_txrx_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.TXD; +} + +__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.RXD; +} + +__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.RTS; +} + +__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.CTS; +} + +__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, uint32_t pselrts, uint32_t pselcts) +{ + p_reg->PSEL.RTS = pselrts; + p_reg->PSEL.CTS = pselcts; +} + +__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg) +{ + nrf_uarte_hwfc_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED); +} + +__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task) +{ + return (uint32_t)p_reg + (uint32_t)task; +} + +__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg, + nrf_uarte_parity_t parity, + nrf_uarte_hwfc_t hwfc) +{ + p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc; +} + +__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate) +{ + p_reg->BAUDRATE = baudrate; +} + +__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->TXD.AMOUNT; +} + +__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->RXD.AMOUNT; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ +#endif //NRF_UARTE_H__ diff --git a/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_wdt.h b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_wdt.h new file mode 100644 index 00000000..96ac0a7e --- /dev/null +++ b/cores/nRF5/SDK/components/drivers_nrf/hal/nrf_wdt.h @@ -0,0 +1,316 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_wdt_hal WDT HAL + * @{ + * @ingroup nrf_wdt + * + * @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral. + */ + +#ifndef NRF_WDT_H__ +#define NRF_WDT_H__ + +#include +#include +#include + +#include "nrf.h" + +#define NRF_WDT_CHANNEL_NUMBER 0x8UL +#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ + +#define NRF_WDT_TASK_SET 1UL +#define NRF_WDT_EVENT_CLEAR 0UL + +/** + * @enum nrf_wdt_task_t + * @brief WDT tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */ + /*lint -restore*/ +} nrf_wdt_task_t; + +/** + * @enum nrf_wdt_event_t + * @brief WDT events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */ + /*lint -restore*/ +} nrf_wdt_event_t; + +/** + * @enum nrf_wdt_behaviour_t + * @brief WDT behavior in CPU SLEEP or HALT mode. + */ +typedef enum +{ + NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */ + NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */ + NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */ + NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */ +} nrf_wdt_behaviour_t; + +/** + * @enum nrf_wdt_rr_register_t + * @brief WDT reload request registers. + */ +typedef enum +{ + NRF_WDT_RR0 = 0, /**< Reload request register 0. */ + NRF_WDT_RR1, /**< Reload request register 1. */ + NRF_WDT_RR2, /**< Reload request register 2. */ + NRF_WDT_RR3, /**< Reload request register 3. */ + NRF_WDT_RR4, /**< Reload request register 4. */ + NRF_WDT_RR5, /**< Reload request register 5. */ + NRF_WDT_RR6, /**< Reload request register 6. */ + NRF_WDT_RR7 /**< Reload request register 7. */ +} nrf_wdt_rr_register_t; + +/** + * @enum nrf_wdt_int_mask_t + * @brief WDT interrupts. + */ +typedef enum +{ + NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */ +} nrf_wdt_int_mask_t; + +/** + * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted. + * + * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode. + */ +__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour) +{ + NRF_WDT->CONFIG = behaviour; +} + + +/** + * @brief Function for starting the watchdog. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET; +} + + +/** + * @brief Function for clearing the WDT event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; +} + + +/** + * @brief Function for retrieving the state of the WDT event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event)); +} + + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask) +{ + NRF_WDT->INTENSET = int_mask; +} + + +/** + * @brief Function for retrieving the state of given interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true Interrupt is enabled. + * @retval false Interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask) +{ + return (bool)(NRF_WDT->INTENSET & int_mask); +} + + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask) +{ + NRF_WDT->INTENCLR = int_mask; +} + + +/** + * @brief Function for returning the address of a specific WDT task register. + * + * @param[in] task Task. + */ +__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task) +{ + return ((uint32_t)NRF_WDT + task); +} + + +/** + * @brief Function for returning the address of a specific WDT event register. + * + * @param[in] event Event. + * + * @retval address of requested event register + */ +__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event) +{ + return ((uint32_t)NRF_WDT + event); +} + + +/** + * @brief Function for retrieving the watchdog status. + * + * @retval true If the watchdog is started. + * @retval false If the watchdog is not started. + */ +__STATIC_INLINE bool nrf_wdt_started(void) +{ + return (bool)(NRF_WDT->RUNSTATUS); +} + + +/** + * @brief Function for retrieving the watchdog reload request status. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If a reload request is running. + * @retval false If no reload request is running. + */ +__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL); +} + + +/** + * @brief Function for setting the watchdog reload value. + * + * @param[in] reload_value Watchdog counter initial value. + */ +__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) +{ + NRF_WDT->CRV = reload_value; +} + + +/** + * @brief Function for retrieving the watchdog reload value. + * + * @retval Reload value. + */ +__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void) +{ + return (uint32_t)NRF_WDT->CRV; +} + + +/** + * @brief Function for enabling a specific reload request register. + * + * @param[in] rr_register Reload request register to enable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN |= 0x1UL << rr_register; +} + + +/** + * @brief Function for disabling a specific reload request register. + * + * @param[in] rr_register Reload request register to disable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN &= ~(0x1UL << rr_register); +} + + +/** + * @brief Function for retrieving the status of a specific reload request register. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If the reload request register is enabled. + * @retval false If the reload request register is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(NRF_WDT->RREN & (0x1UL << rr_register)); +} + + +/** + * @brief Function for setting a specific reload request register. + * + * @param[in] rr_register Reload request register to set. + */ +__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE; +} + + +#endif + +/** @} */ diff --git a/cores/nRF5/SDK/components/libraries/trace/app_trace.c b/cores/nRF5/SDK/components/libraries/trace/app_trace.c new file mode 100644 index 00000000..b61a3541 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/trace/app_trace.c @@ -0,0 +1,60 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include +#include +#include + + +#ifdef ENABLE_DEBUG_LOG_SUPPORT +#include "app_trace.h" +#include "nrf_log.h" + +void app_trace_init(void) +{ + (void)NRF_LOG_INIT(); +} + +void app_trace_dump(uint8_t * p_buffer, uint32_t len) +{ + app_trace_log("\r\n"); + for (uint32_t index = 0; index < len; index++) + { + app_trace_log("0x%02X ", p_buffer[index]); + } + app_trace_log("\r\n"); +} + +#endif // ENABLE_DEBUG_LOG_SUPPORT + +/** + *@} + **/ + diff --git a/cores/nRF5/SDK/components/libraries/trace/app_trace.h b/cores/nRF5/SDK/components/libraries/trace/app_trace.h new file mode 100644 index 00000000..57a7dd0d --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/trace/app_trace.h @@ -0,0 +1,84 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 __DEBUG_H_ +#define __DEBUG_H_ + +#include +#include + +/** + * @defgroup app_trace Debug Logger + * @ingroup app_common + * @{ + * @brief Enables debug logs/ trace over UART. + * @details Enables debug logs/ trace over UART. Tracing is enabled only if + * ENABLE_DEBUG_LOG_SUPPORT is defined in the project. + */ +#ifdef ENABLE_DEBUG_LOG_SUPPORT +#include "nrf_log.h" +/** + * @brief Module Initialization. + * + * @details Initializes the module to use UART as trace output. + * + * @warning This function will configure UART using default board configuration. + * Do not call this function if UART is configured from a higher level in the application. + */ +void app_trace_init(void); + +/** + * @brief Log debug messages. + * + * @details This API logs messages over UART. The module must be initialized before using this API. + * + * @note Though this is currently a macro, it should be used used and treated as function. + */ +#define app_trace_log NRF_LOG_PRINTF + +/** + * @brief Dump auxiliary byte buffer to the debug trace. + * + * @details This API logs messages over UART. The module must be initialized before using this API. + * + * @param[in] p_buffer Buffer to be dumped on the debug trace. + * @param[in] len Size of the buffer. + */ +void app_trace_dump(uint8_t * p_buffer, uint32_t len); + +#else // ENABLE_DEBUG_LOG_SUPPORT + +#define app_trace_init(...) +#define app_trace_log(...) +#define app_trace_dump(...) + +#endif // ENABLE_DEBUG_LOG_SUPPORT + +/** @} */ + +#endif //__DEBUG_H_ diff --git a/cores/nRF5/SDK/components/libraries/util/app_error.c b/cores/nRF5/SDK/components/libraries/util/app_error.c new file mode 100644 index 00000000..29c49ea1 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_error.c @@ -0,0 +1,141 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler. + */ + +#include "nrf.h" +#include +#include "app_error.h" +#include "nordic_common.h" +#include "sdk_errors.h" +#include "nrf_log.h" + +#ifdef DEBUG +#include "bsp.h" +#endif + + + +/**@brief Function for error handling, which is called when an error has occurred. + * + * @warning This handler is an example only and does not fit a final product. You need to analyze + * how your product is supposed to react in case of error. + * + * @param[in] error_code Error code supplied to the handler. + * @param[in] line_num Line number where the handler is called. + * @param[in] p_file_name Pointer to the file name. + */ + +/*lint -save -e14 */ +void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) +{ + error_info_t error_info = + { + .line_num = line_num, + .p_file_name = p_file_name, + .err_code = error_code, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + +/*lint -save -e14 */ +void app_error_handler_bare(ret_code_t error_code) +{ + error_info_t error_info = + { + .line_num = 0, + .p_file_name = NULL, + .err_code = error_code, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + + +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info) +{ + /* static error variables - in order to prevent removal by optimizers */ + static volatile struct + { + uint32_t fault_id; + uint32_t pc; + uint32_t error_info; + assert_info_t * p_assert_info; + error_info_t * p_error_info; + ret_code_t err_code; + uint32_t line_num; + const uint8_t * p_file_name; + } m_error_data = {0}; + + // The following variable helps Keil keep the call stack visible, in addition, it can be set to + // 0 in the debugger to continue executing code after the error check. + volatile bool loop = true; + UNUSED_VARIABLE(loop); + + m_error_data.fault_id = id; + m_error_data.pc = pc; + m_error_data.error_info = info; + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + m_error_data.p_assert_info = (assert_info_t *)info; + m_error_data.line_num = m_error_data.p_assert_info->line_num; + m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name; + break; + + case NRF_FAULT_ID_SDK_ERROR: + m_error_data.p_error_info = (error_info_t *)info; + m_error_data.err_code = m_error_data.p_error_info->err_code; + m_error_data.line_num = m_error_data.p_error_info->line_num; + m_error_data.p_file_name = m_error_data.p_error_info->p_file_name; + break; + } + + UNUSED_VARIABLE(m_error_data); + + // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger. + __disable_irq(); + + while(loop); + + __enable_irq(); +} + +/*lint -restore */ diff --git a/cores/nRF5/SDK/components/libraries/util/app_error.h b/cores/nRF5/SDK/components/libraries/util/app_error.h new file mode 100644 index 00000000..7cf524b5 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_error.h @@ -0,0 +1,218 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler and macros for utilizing a common error handler. + */ + +#ifndef APP_ERROR_H__ +#define APP_ERROR_H__ + +#include +#include +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "nordic_common.h" +#include "nrf_log.h" +#include "app_error_weak.h" + +#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */ + +/**@defgroup APP_ERROR_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */ +#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */ +/**@} */ + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ + uint32_t err_code; /**< The error code representing the error that occurred. */ +} error_info_t; + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ +} assert_info_t; + +/**@brief Function for error handling, which is called when an error has occurred. + * + * @param[in] error_code Error code supplied to the handler. + * @param[in] line_num Line number where the handler is called. + * @param[in] p_file_name Pointer to the file name. + */ +void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name); + +/**@brief Function for error handling, which is called when an error has occurred. + * + * @param[in] error_code Error code supplied to the handler. + */ +void app_error_handler_bare(ret_code_t error_code); + +/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info); + +/**@brief Function for printing all error info (using nrf_log). + * + * @details Nrf_log library must be initialized using NRF_LOG_INIT macro before calling + * this function. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +static __INLINE void app_error_log(uint32_t id, uint32_t pc, uint32_t info) +{ + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + NRF_LOG(NRF_LOG_COLOR_RED "\n*** ASSERTION FAILED ***\n"); + if (((assert_info_t *)(info))->p_file_name) + { + NRF_LOG_PRINTF(NRF_LOG_COLOR_WHITE "Line Number: %u\n", (unsigned int) ((assert_info_t *)(info))->line_num); + NRF_LOG_PRINTF("File Name: %s\n", ((assert_info_t *)(info))->p_file_name); + } + NRF_LOG_PRINTF(NRF_LOG_COLOR_DEFAULT "\n"); + break; + + case NRF_FAULT_ID_SDK_ERROR: + NRF_LOG(NRF_LOG_COLOR_RED "\n*** APPLICATION ERROR *** \n" NRF_LOG_COLOR_WHITE); + if (((error_info_t *)(info))->p_file_name) + { + NRF_LOG_PRINTF("Line Number: %u\n", (unsigned int) ((error_info_t *)(info))->line_num); + NRF_LOG_PRINTF("File Name: %s\n", ((error_info_t *)(info))->p_file_name); + } + NRF_LOG_PRINTF("Error Code: 0x%X\n" NRF_LOG_COLOR_DEFAULT "\n", (unsigned int) ((error_info_t *)(info))->err_code); + break; + } +} + +/**@brief Function for printing all error info (using printf). + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +//lint -save -e438 +static __INLINE void app_error_print(uint32_t id, uint32_t pc, uint32_t info) +{ + unsigned int tmp = id; + printf("app_error_print():\r\n"); + printf("Fault identifier: 0x%X\r\n", tmp); + printf("Program counter: 0x%X\r\n", tmp = pc); + printf("Fault information: 0x%X\r\n", tmp = info); + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + printf("Line Number: %u\r\n", tmp = ((assert_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name); + break; + + case NRF_FAULT_ID_SDK_ERROR: + printf("Line Number: %u\r\n", tmp = ((error_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name); + printf("Error Code: 0x%X\r\n", tmp = ((error_info_t *)(info))->err_code); + break; + } +} +//lint -restore + + +/**@brief Macro for calling error handler function. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#ifdef DEBUG +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ + app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \ + } while (0) +#else +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ + app_error_handler_bare((ERR_CODE)); \ + } while (0) +#endif +/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#define APP_ERROR_CHECK(ERR_CODE) \ + do \ + { \ + const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \ + if (LOCAL_ERR_CODE != NRF_SUCCESS) \ + { \ + APP_ERROR_HANDLER(LOCAL_ERR_CODE); \ + } \ + } while (0) + +/**@brief Macro for calling error handler function if supplied boolean value is false. + * + * @param[in] BOOLEAN_VALUE Boolean value to be evaluated. + */ +#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \ + do \ + { \ + const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \ + if (!LOCAL_BOOLEAN_VALUE) \ + { \ + APP_ERROR_HANDLER(0); \ + } \ + } while (0) + +#endif // APP_ERROR_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/libraries/util/app_error_weak.c b/cores/nRF5/SDK/components/libraries/util/app_error_weak.c new file mode 100644 index 00000000..acdfb1cf --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_error_weak.c @@ -0,0 +1,70 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "app_error.h" + +#ifdef DEBUG +#include "bsp.h" +#endif + +/*lint -save -e14 */ + +/** + * Function is implemented as weak so that it can be overwritten by custom application error handler + * when needed. + */ +__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) +{ + // On assert, the system can only recover with a reset. +#ifndef DEBUG + NVIC_SystemReset(); +#else + +#ifdef BSP_DEFINES_ONLY + LEDS_ON(LEDS_MASK); +#else + UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR)); + // This call can be used for debug purposes during application development. + // @note CAUTION: Activating this code will write the stack to flash on an error. + // This function should NOT be used in a final product. + // It is intended STRICTLY for development/debugging purposes. + // The flash write will happen EVEN if the radio is active, thus interrupting + // any communication. + // Use with care. Uncomment the line below to use. + //ble_debug_assert_handler(error_code, line_num, p_file_name); +#endif // BSP_DEFINES_ONLY + + app_error_save_and_stop(id, pc, info); + +#endif // DEBUG +} + +/*lint -restore */ + + diff --git a/cores/nRF5/SDK/components/libraries/util/app_error_weak.h b/cores/nRF5/SDK/components/libraries/util/app_error_weak.h new file mode 100644 index 00000000..153153b9 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_error_weak.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 APP_ERROR_WEAK_H__ +#define APP_ERROR_WEAK_H__ + +/** @file + * + * @defgroup app_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler. + */ + +/**@brief Callback function for asserts in the SoftDevice. + * + * @details A pointer to this function will be passed to the SoftDevice. This function will be + * called by the SoftDevice if certain unrecoverable errors occur within the + * application or SoftDevice. + * + * See @ref nrf_fault_handler_t for more details. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + * + * @remarks Function is implemented as weak so that it can be overwritten by custom application + * error handler when needed. + */ +#ifdef __CC_ARM + void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info); +#else +__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info); +#endif + + +/** @} */ + +#endif // APP_ERROR_WEAK_H__ diff --git a/cores/nRF5/SDK/components/libraries/util/app_util.h b/cores/nRF5/SDK/components/libraries/util/app_util.h new file mode 100644 index 00000000..66ff57b6 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_util.h @@ -0,0 +1,510 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_util Utility Functions and Definitions + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications. + */ + +#ifndef APP_UTIL_H__ +#define APP_UTIL_H__ + +#include +#include +#include "compiler_abstraction.h" +#include "nrf.h" + +//lint -save -e27 -e10 -e19 +#if defined ( __CC_ARM ) +extern char STACK$$Base; +extern char STACK$$Length; +#define STACK_BASE &STACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length)) +#elif defined ( __ICCARM__ ) +extern char CSTACK$$Base; +extern char CSTACK$$Length; +#define STACK_BASE &CSTACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length)) +#elif defined ( __GNUC__ ) +extern uint32_t __StackTop; +extern uint32_t __StackLimit; +#define STACK_BASE &__StackLimit +#define STACK_TOP &__StackTop +#endif +//lint -restore + +enum +{ + UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */ + UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */ + UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */ +}; + + +/**@brief Implementation specific macro for delayed macro expansion used in string concatenation +* +* @param[in] lhs Left hand side in concatenation +* @param[in] rhs Right hand side in concatenation +*/ +#define STRING_CONCATENATE_IMPL(lhs, rhs) lhs ## rhs + + +/**@brief Macro used to concatenate string using delayed macro expansion +* +* @note This macro will delay concatenation until the expressions have been resolved +* +* @param[in] lhs Left hand side in concatenation +* @param[in] rhs Right hand side in concatenation +*/ +#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs) + + +// Disable lint-warnings/errors for STATIC_ASSERT +//lint --emacro(10,STATIC_ASSERT) +//lint --emacro(18,STATIC_ASSERT) +//lint --emacro(19,STATIC_ASSERT) +//lint --emacro(30,STATIC_ASSERT) +//lint --emacro(37,STATIC_ASSERT) +//lint --emacro(42,STATIC_ASSERT) +//lint --emacro(26,STATIC_ASSERT) +//lint --emacro(102,STATIC_ASSERT) +//lint --emacro(533,STATIC_ASSERT) +//lint --emacro(534,STATIC_ASSERT) +//lint --emacro(132,STATIC_ASSERT) +//lint --emacro(414,STATIC_ASSERT) +//lint --emacro(578,STATIC_ASSERT) +//lint --emacro(628,STATIC_ASSERT) +//lint --emacro(648,STATIC_ASSERT) +//lint --emacro(830,STATIC_ASSERT) + + +/**@brief Macro for doing static (i.e. compile time) assertion. +* +* @note If the EXPR isn't resolvable, then the error message won't be shown. +* +* @note The output of STATIC_ASSERT will be different across different compilers. +* +* @param[in] EXPR Constant expression to be verified. +*/ +#if defined ( __COUNTER__ ) + +#define STATIC_ASSERT(EXPR) \ + ;enum { STRING_CONCATENATE(static_assert_, __COUNTER__) = 1/(!!(EXPR)) } + +#else + +#define STATIC_ASSERT(EXPR) \ + ;enum { STRING_CONCATENATE(assert_line_, __LINE__) = 1/(!!(EXPR)) } + +#endif + + +/**@brief Implementation details for NUM_VAR_ARGS */ +#define NUM_VA_ARGS_IMPL( \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, N, ...) N + + +/**@brief Macro to get the number of arguments in a call variadic macro call + * + * param[in] ... List of arguments + * + * @retval Number of variadic arguments in the argument list + */ +#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \ + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ + 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + + +/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */ +typedef uint8_t uint16_le_t[2]; + +/**@brief Type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */ +typedef uint8_t uint32_le_t[4]; + +/**@brief Byte array type. */ +typedef struct +{ + uint16_t size; /**< Number of array entries. */ + uint8_t * p_data; /**< Pointer to array entries. */ +} uint8_array_t; + + +/**@brief Macro for performing rounded integer division (as opposed to truncating the result). + * + * @param[in] A Numerator. + * @param[in] B Denominator. + * + * @return Rounded (integer) result of dividing A by B. + */ +#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) + + +/**@brief Macro for checking if an integer is a power of two. + * + * @param[in] A Number to be tested. + * + * @return true if value is power of two. + * @return false if value not power of two. + */ +#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) + + +/**@brief Macro for converting milliseconds to ticks. + * + * @param[in] TIME Number of milliseconds to convert. + * @param[in] RESOLUTION Unit to be converted to in [us/ticks]. + */ +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) + + +/**@brief Macro for performing integer division, making sure the result is rounded up. + * + * @details One typical use for this is to compute the number of objects with size B is needed to + * hold A number of bytes. + * + * @param[in] A Numerator. + * @param[in] B Denominator. + * + * @return Integer result of dividing A by B, rounded up. + */ +#define CEIL_DIV(A, B) \ + (((A) + (B) - 1) / (B)) + + +/**@brief Macro for creating a buffer aligned to 4 bytes. + * + * @param[in] NAME Name of the buffor. + * @param[in] MIN_SIZE Size of this buffor (it will be rounded up to multiples of 4 bytes). + */ +#define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))] + + +/**@brief Macro for calculating the number of words that are needed to hold a number of bytes. + * + * @details Adds 3 and divides by 4. + * + * @param[in] n_bytes The number of bytes. + * + * @return The number of words that @p n_bytes take up (rounded up). + */ +#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2) + + +/**@brief The number of bytes in a word. + */ +#define BYTES_PER_WORD (4) + + +/**@brief Macro for increasing a number to the nearest (larger) multiple of another number. + * + * @param[in] alignment The number to align to. + * @param[in] number The number to align (increase). + * + * @return The aligned (increased) @p number. + */ +#define ALIGN_NUM(alignment, number) ((number - 1) + alignment - ((number - 1) % alignment)) + + +/**@brief Function for changing the value unit. + * + * @param[in] value Value to be rescaled. + * @param[in] old_unit_reversal Reversal of the incoming unit. + * @param[in] new_unit_reversal Reversal of the desired unit. + * + * @return Number of bytes written. + */ +static __INLINE uint64_t value_rescale(uint32_t value, uint32_t old_unit_reversal, uint16_t new_unit_reversal) +{ + return (uint64_t)ROUNDED_DIV((uint64_t)value * new_unit_reversal, old_unit_reversal); +} + +/**@brief Function for encoding a uint16 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8); + return sizeof(uint16_t); +} + +/**@brief Function for encoding a three-byte value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint24_encode(uint32_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16); + return 3; +} + +/**@brief Function for encoding a uint32 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24); + return sizeof(uint32_t); +} + +/**@brief Function for encoding a uint48 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint48_encode(uint64_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24); + p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32); + p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40); + return 6; +} + +/**@brief Function for decoding a uint16 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 )); +} + +/**@brief Function for decoding a uint16 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) | + (((uint16_t)((uint8_t *)p_encoded_data)[1])) ); +} + +/**@brief Function for decoding a three-byte value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value (uint32_t). + */ +static __INLINE uint32_t uint24_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16)); +} + +/**@brief Function for decoding a uint32 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 )); +} + +/**@brief Function for decoding a uint32 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) ); +} + +/**@brief Function for encoding a uint32 value in big-endian format. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data will be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data) +{ +#ifdef NRF51 + p_encoded_data[0] = (uint8_t) ((value & 0xFF000000) >> 24); + p_encoded_data[1] = (uint8_t) ((value & 0x00FF0000) >> 16); + p_encoded_data[2] = (uint8_t) ((value & 0x0000FF00) >> 8); + p_encoded_data[3] = (uint8_t) ((value & 0x000000FF) >> 0); +#elif NRF52 + *(uint32_t *)p_encoded_data = __REV(value); +#endif + return sizeof(uint32_t); +} + +/**@brief Function for decoding a uint48 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. (uint64_t) + */ +static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) | + (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) | + (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 )); +} + +/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts. + * + * @details The calculation is based on a linearized version of the battery's discharge + * curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and + * is considered to be the lower boundary. + * + * The discharge curve for CR2032 is non-linear. In this model it is split into + * 4 linear sections: + * - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV) + * - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV) + * - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV) + * - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV) + * + * These numbers are by no means accurate. Temperature and + * load in the actual application is not accounted for! + * + * @param[in] mvolts The voltage in mV + * + * @return Battery level in percent. +*/ +static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts) +{ + uint8_t battery_level; + + if (mvolts >= 3000) + { + battery_level = 100; + } + else if (mvolts > 2900) + { + battery_level = 100 - ((3000 - mvolts) * 58) / 100; + } + else if (mvolts > 2740) + { + battery_level = 42 - ((2900 - mvolts) * 24) / 160; + } + else if (mvolts > 2440) + { + battery_level = 18 - ((2740 - mvolts) * 12) / 300; + } + else if (mvolts > 2100) + { + battery_level = 6 - ((2440 - mvolts) * 6) / 340; + } + else + { + battery_level = 0; + } + + return battery_level; +} + +/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary. + * + * @param[in] p Pointer value to be checked. + * + * @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise. + */ +static __INLINE bool is_word_aligned(void const* p) +{ + return (((uintptr_t)p & 0x03) == 0); +} + +/** + * @brief Function for checking if provided address is located in stack space. + * + * @param[in] ptr Pointer to be checked. + * + * @return true if address is in stack space, false otherwise. + */ +static __INLINE bool is_address_from_stack(void * ptr) +{ + if (((uint32_t)ptr >= (uint32_t)STACK_BASE) && + ((uint32_t)ptr < (uint32_t)STACK_TOP) ) + { + return true; + } + else + { + return false; + } +} + +#endif // APP_UTIL_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/libraries/util/app_util_bds.h b/cores/nRF5/SDK/components/libraries/util/app_util_bds.h new file mode 100644 index 00000000..404f127e --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_util_bds.h @@ -0,0 +1,430 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_util Utility Functions and Definitions + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications. + */ + +#ifndef APP_UTIL_BDS_H__ +#define APP_UTIL_BDS_H__ + +#include +#include +#include +#include "compiler_abstraction.h" +#include "app_util.h" +#include "ble_srv_common.h" +#include "nordic_common.h" + +typedef uint8_t nibble_t; +typedef uint32_t uint24_t; +typedef uint64_t uint40_t; + +/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */ +typedef struct +{ + uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */ + uint8_t list_len; /**< Length of the byte array. */ +} regcertdatalist_t; + +/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */ + int16_t mantissa; /**< Mantissa, should be using only 12 bits */ +} sfloat_t; + +/**@brief Date and Time structure. */ +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} ble_date_time_t; + + +/**@brief Function for encoding a uint16 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8); + return sizeof(uint16_t); +} + +static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data) +{ + uint16_t tmp = *p_value; + return bds_uint16_encode(&tmp, p_encoded_data); +} + +/**@brief Function for encoding a uint24 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16); + return (3); +} + + +/**@brief Function for encoding a uint32 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24); + return sizeof(uint32_t); +} + + +/**@brief Function for encoding a uint40 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24); + p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32); + return 5; +} + +/**@brief Function for encoding a sfloat value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data) +{ + uint16_t encoded_val; + + encoded_val = ((p_value->exponent << 12) & 0xF000) | + ((p_value->mantissa << 0) & 0x0FFF); + + return(bds_uint16_encode(&encoded_val, p_encoded_data)); +} + + +/**@brief Function for encoding a uint8_array value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + */ +static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_data, p_value->size); + return p_value->size; +} + + +/**@brief Function for encoding a utf8_str value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + + */ +static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_str, p_value->length); + return p_value->length; +} + +/**@brief Function for encoding a regcertdatalist value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + + */ +static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_list, p_value->list_len); + return p_value->list_len; +} + + +/**@brief Function for decoding a date_time value. + * + * @param[in] p_date_time pointer to the date_time structure to encode. + * @param[in] p_encoded_data pointer to the encoded data + * @return length of the encoded field. + */ +static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time, + uint8_t * p_encoded_data) +{ + uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]); + + p_encoded_data[len++] = p_date_time->month; + p_encoded_data[len++] = p_date_time->day; + p_encoded_data[len++] = p_date_time->hours; + p_encoded_data[len++] = p_date_time->minutes; + p_encoded_data[len++] = p_date_time->seconds; + + return len; +} + + +/**@brief Function for decoding a uint16 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint16_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint16_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ); + return (sizeof(uint16_t)); +} + + +/**@brief Function for decoding a int16 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_int16_decode(const uint8_t len, + const uint8_t * p_encoded_data, + int16_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + uint16_t tmp = 0; + uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp); + *p_decoded_val = (int16_t)tmp; + return retval; +} + + +/**@brief Function for decoding a uint24 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint24_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint32_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16); + return (3); +} + + +/**@brief Function for decoding a uint32 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint32_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint32_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ); + return (sizeof(uint32_t)); +} + + +/**@brief Function for decoding a uint40 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint40_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint64_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )| + (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 ); + return (40); +} + + +/**@brief Function for decoding a sfloat value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + + */ +static __INLINE uint8_t bds_sfloat_decode(const uint8_t len, + const uint8_t * p_encoded_data, + sfloat_t * p_decoded_val) +{ + + p_decoded_val->exponent = 0; + bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa); + p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12); + p_decoded_val->mantissa &= 0x0FFF; + return len; +} + + +/**@brief Function for decoding a uint8_array value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint8_array_t * p_decoded_val) +{ + memcpy(p_decoded_val->p_data, p_encoded_data, len); + p_decoded_val->size = len; + return p_decoded_val->size; +} + + +/**@brief Function for decoding a utf8_str value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len, + const uint8_t * p_encoded_data, + ble_srv_utf8_str_t * p_decoded_val) +{ + p_decoded_val->p_str = (uint8_t*)p_encoded_data; + p_decoded_val->length = len; + return p_decoded_val->length; +} + + +/**@brief Function for decoding a regcertdatalist value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len, + const uint8_t * p_encoded_data, + regcertdatalist_t * p_decoded_val) +{ + memcpy(p_decoded_val->p_list, p_encoded_data, len); + p_decoded_val->list_len = len; + return p_decoded_val->list_len; +} + + +/**@brief Function for decoding a date_time value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_date_time pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len, + const uint8_t * p_encoded_data, + ble_date_time_t * p_date_time) +{ + UNUSED_VARIABLE(len); + uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year); + p_date_time->month = p_encoded_data[pos++]; + p_date_time->day = p_encoded_data[pos++]; + p_date_time->hours = p_encoded_data[pos++]; + p_date_time->minutes = p_encoded_data[pos++]; + p_date_time->seconds = p_encoded_data[pos++]; + + return pos; +} + +#endif // APP_UTIL_BDS_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/libraries/util/app_util_platform.c b/cores/nRF5/SDK/components/libraries/util/app_util_platform.c new file mode 100644 index 00000000..8c25a13e --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_util_platform.c @@ -0,0 +1,77 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "app_util_platform.h" + +static uint32_t m_in_critical_region = 0; + +void app_util_disable_irq(void) +{ + __disable_irq(); + m_in_critical_region++; +} + +void app_util_enable_irq(void) +{ + m_in_critical_region--; + if (m_in_critical_region == 0) + { + __enable_irq(); + } +} + +void app_util_critical_region_enter(uint8_t *p_nested) +{ +#ifdef NRF52 + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_enter(p_nested); +#else + app_util_disable_irq(); +#endif +} + +void app_util_critical_region_exit(uint8_t nested) +{ +#ifdef NRF52 + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_exit(nested); +#else + app_util_enable_irq(); +#endif +} + + diff --git a/cores/nRF5/SDK/components/libraries/util/app_util_platform.h b/cores/nRF5/SDK/components/libraries/util/app_util_platform.h new file mode 100644 index 00000000..5944f30a --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/app_util_platform.h @@ -0,0 +1,228 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_util_platform Utility Functions and Definitions (Platform) + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications when using SoftDevice. + */ + +#ifndef APP_UTIL_PLATFORM_H__ +#define APP_UTIL_PLATFORM_H__ + +#include +#include "compiler_abstraction.h" +#include "nrf.h" +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#include "nrf_nvic.h" +#endif +#include "nrf_assert.h" +#include "app_error.h" + +#if defined(NRF51) +#define _PRIO_SD_HIGH 0 +#define _PRIO_APP_HIGH 1 +#define _PRIO_APP_MID 1 +#define _PRIO_SD_LOW 2 +#define _PRIO_APP_LOW 3 +#define _PRIO_APP_LOWEST 3 +#define _PRIO_THREAD 4 +#elif defined(NRF52) +#define _PRIO_SD_HIGH 0 +#define _PRIO_SD_MID 1 +#define _PRIO_APP_HIGH 2 +#define _PRIO_APP_MID 3 +#define _PRIO_SD_LOW 4 +#define _PRIO_SD_LOWEST 5 +#define _PRIO_APP_LOW 6 +#define _PRIO_APP_LOWEST 7 +#define _PRIO_THREAD 15 +#else + #error "No platform defined" +#endif + +/**@brief The interrupt priorities available to the application while the SoftDevice is active. */ +typedef enum +{ +#ifdef SOFTDEVICE_PRESENT + APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH, +#else + APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH, +#endif + APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH, +#ifndef SOFTDEVICE_PRESENT + APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW, +#else + APP_IRQ_PRIORITY_MID = _PRIO_APP_MID, +#endif + APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW, + APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST, + APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */ +} app_irq_priority_t; + +/*@brief The privilege levels available to applications in Thread Mode */ +typedef enum +{ + APP_LEVEL_UNPRIVILEGED, + APP_LEVEL_PRIVILEGED +} app_level_t; + +/**@cond NO_DOXYGEN */ +#define EXTERNAL_INT_VECTOR_OFFSET 16 +/**@endcond */ + +#define PACKED(TYPE) __packed TYPE + +void app_util_critical_region_enter (uint8_t *p_nested); +void app_util_critical_region_exit (uint8_t nested); + +/**@brief Macro for entering a critical region. + * + * @note Due to implementation details, there must exist one and only one call to + * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located + * in the same scope. + */ +#ifdef SOFTDEVICE_PRESENT +#define CRITICAL_REGION_ENTER() \ + { \ + uint8_t __CR_NESTED = 0; \ + app_util_critical_region_enter(&__CR_NESTED); +#else +#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL) +#endif + +/**@brief Macro for leaving a critical region. + * + * @note Due to implementation details, there must exist one and only one call to + * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located + * in the same scope. + */ +#ifdef SOFTDEVICE_PRESENT +#define CRITICAL_REGION_EXIT() \ + app_util_critical_region_exit(__CR_NESTED); \ + } +#else +#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0) +#endif + +/* Workaround for Keil 4 */ +#ifndef IPSR_ISR_Msk +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ +#endif + + + +/**@brief Macro to enable anonymous unions from a certain point in the code. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_ENABLE _Pragma("push") \ + _Pragma("anon_unions") +#elif defined(__ICCARM__) + #define ANON_UNIONS_ENABLE _Pragma("language=extended") +#else + #define ANON_UNIONS_ENABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + +/**@brief Macro to disable anonymous unions from a certain point in the code. + * @note Call only after first calling @ref ANON_UNIONS_ENABLE. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_DISABLE _Pragma("pop") +#elif defined(__ICCARM__) + #define ANON_UNIONS_DISABLE + // for IAR leave anonymous unions enabled +#else + #define ANON_UNIONS_DISABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + + +/* Workaround for Keil 4 */ +#ifndef CONTROL_nPRIV_Msk +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ +#endif + +/**@brief Function for finding the current interrupt level. + * + * @return Current interrupt level. + * @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level. + * @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level. + * @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode. + */ +static __INLINE uint8_t current_int_priority_get(void) +{ + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; + if (isr_vector_num > 0) + { + int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET); + return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF); + } + else + { + return APP_IRQ_PRIORITY_THREAD; + } +} + +/**@brief Function for finding out the current privilege level. + * + * @return Current privilege level. + * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level. + * @retval APP_LEVEL_PRIVILEGED We are running in privileged level. + */ +static __INLINE uint8_t privilege_level_get(void) +{ +#if defined(NRF51) + /* the Cortex-M0 has no concept of privilege */ + return APP_LEVEL_PRIVILEGED; +#elif defined(NRF52) + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; + if (0 == isr_vector_num) + { + /* Thread Mode, check nPRIV */ + int32_t control = __get_CONTROL(); + return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED; + } + else + { + /* Handler Mode, always privileged */ + return APP_LEVEL_PRIVILEGED; + } +#endif +} + +#endif // APP_UTIL_PLATFORM_H__ + +/** @} */ diff --git a/cores/nRF5/SDK/components/libraries/util/common.h b/cores/nRF5/SDK/components/libraries/util/common.h new file mode 100644 index 00000000..7623e911 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/common.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 COMMON_H +#define COMMON_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +/* @file +* @brief Common header file for generic macros and definitions + * + */ + +/* + * GPIO glue macros, this can be used to define a pin number in source/header file and use that macro for pin + * configuration using this expansion. + * example: + * #define RESET_PIN 8 + * NRF_GPIO->PINCNF(RESET_PIN) = XXX ; // Expanded NRF_GPIO->PIN_CNF[8] = XXX + */ +#define PINX_GLUE(x, y, z) x##y##_##z /*!< first level glue for pin macros */ +#define PINCNF(p) PINX_GLUE(PIN,p,CNF) /*!< gpio configure pin number 'p' */ +#define PINOUT(p) PINX_GLUE(PIN,p,OUT) /*!< gpio out pin number 'p' */ + +/*lint --flb "Leave library region" */ +#endif diff --git a/cores/nRF5/SDK/components/libraries/util/nordic_common.h b/cores/nRF5/SDK/components/libraries/util/nordic_common.h new file mode 100644 index 00000000..688a1d40 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/nordic_common.h @@ -0,0 +1,126 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief Common defines and macros for firmware developed by Nordic Semiconductor. + */ + +#ifndef NORDIC_COMMON_H__ +#define NORDIC_COMMON_H__ + +/** The upper 8 bits of a 32 bit value */ +//lint -emacro(572,MSB) // Suppress warning 572 "Excessive shift value" +#define MSB_32(a) (((a) & 0xFF000000) >> 24) +/** The lower 8 bits (of a 32 bit value) */ +#define LSB_32(a) ((a) & 0x000000FF) + +/** The upper 8 bits of a 16 bit value */ +//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value" +#define MSB_16(a) (((a) & 0xFF00) >> 8) +/** The lower 8 bits (of a 16 bit value) */ +#define LSB_16(a) ((a) & 0x00FF) + +/** Leaves the minimum of the two 32-bit arguments */ +/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +/** Leaves the maximum of the two 32-bit arguments */ +/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */ +#define MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** Concatenates two parameters. Useful as a second level of indirection, + * when a parameter can be macro itself. */ +#define CONCAT_2(p1, p2) p1##p2 +/** Concatenates three parameters. Useful as a second level of indirection, + * when a parameter can be macro itself. */ +#define CONCAT_3(p1, p2, p3) p1##p2##p3 + +/**@brief Set a bit in the uint32 word. + * + * @param[in] W Word whose bit is being set. + * @param[in] B Bit number in the word to be set. + */ +#define SET_BIT(W,B) ((W) |= (uint32_t)(1U << (B))) + + +/**@brief Clears a bit in the uint32 word. + * + * @param[in] W Word whose bit is to be cleared. + * @param[in] B Bit number in the word to be cleared. + */ +#define CLR_BIT(W, B) ((W) &= (~((uint32_t)1 << (B)))) + + +/**@brief Checks if a bit is set. + * + * @param[in] W Word whose bit is to be checked. + * @param[in] B Bit number in the word to be checked. + * + * @retval 1 if bit is set. + * @retval 0 if bit is not set. + */ +#define IS_SET(W,B) (((W) >> (B)) & 1) + +#define BIT_0 0x01 /**< The value of bit 0 */ +#define BIT_1 0x02 /**< The value of bit 1 */ +#define BIT_2 0x04 /**< The value of bit 2 */ +#define BIT_3 0x08 /**< The value of bit 3 */ +#define BIT_4 0x10 /**< The value of bit 4 */ +#define BIT_5 0x20 /**< The value of bit 5 */ +#define BIT_6 0x40 /**< The value of bit 6 */ +#define BIT_7 0x80 /**< The value of bit 7 */ +#define BIT_8 0x0100 /**< The value of bit 8 */ +#define BIT_9 0x0200 /**< The value of bit 9 */ +#define BIT_10 0x0400 /**< The value of bit 10 */ +#define BIT_11 0x0800 /**< The value of bit 11 */ +#define BIT_12 0x1000 /**< The value of bit 12 */ +#define BIT_13 0x2000 /**< The value of bit 13 */ +#define BIT_14 0x4000 /**< The value of bit 14 */ +#define BIT_15 0x8000 /**< The value of bit 15 */ +#define BIT_16 0x00010000 /**< The value of bit 16 */ +#define BIT_17 0x00020000 /**< The value of bit 17 */ +#define BIT_18 0x00040000 /**< The value of bit 18 */ +#define BIT_19 0x00080000 /**< The value of bit 19 */ +#define BIT_20 0x00100000 /**< The value of bit 20 */ +#define BIT_21 0x00200000 /**< The value of bit 21 */ +#define BIT_22 0x00400000 /**< The value of bit 22 */ +#define BIT_23 0x00800000 /**< The value of bit 23 */ +#define BIT_24 0x01000000 /**< The value of bit 24 */ +#define BIT_25 0x02000000 /**< The value of bit 25 */ +#define BIT_26 0x04000000 /**< The value of bit 26 */ +#define BIT_27 0x08000000 /**< The value of bit 27 */ +#define BIT_28 0x10000000 /**< The value of bit 28 */ +#define BIT_29 0x20000000 /**< The value of bit 29 */ +#define BIT_30 0x40000000 /**< The value of bit 30 */ +#define BIT_31 0x80000000 /**< The value of bit 31 */ + +#define UNUSED_VARIABLE(X) ((void)(X)) +#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X) +#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X) + +#endif // NORDIC_COMMON_H__ diff --git a/cores/nRF5/SDK/components/libraries/util/nrf_assert.c b/cores/nRF5/SDK/components/libraries/util/nrf_assert.c new file mode 100644 index 00000000..b17965ba --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/nrf_assert.c @@ -0,0 +1,45 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_assert.h" +#include "app_error.h" +#include "nordic_common.h" + +#if defined(DEBUG_NRF) +void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name) +{ + assert_info_t assert_info = + { + .line_num = line_num, + .p_file_name = file_name, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info)); + + UNUSED_VARIABLE(assert_info); +} +#endif /* DEBUG_NRF */ diff --git a/cores/nRF5/SDK/components/libraries/util/nrf_assert.h b/cores/nRF5/SDK/components/libraries/util/nrf_assert.h new file mode 100644 index 00000000..aa8ed0dc --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/nrf_assert.h @@ -0,0 +1,80 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief Utilities for verifying program logic + */ + +#ifndef NRF_ASSERT_H_ +#define NRF_ASSERT_H_ + +#include +#include "nrf.h" +#include "app_error.h" + +#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) + +/** @brief Function for handling assertions. + * + * + * @note + * This function is called when an assertion has triggered. + * + * + * @post + * All hardware is put into an idle non-emitting state (in particular the radio is highly + * important to switch off since the radio might be in a state that makes it send + * packets continiously while a typical final infinit ASSERT loop is executing). + * + * + * @param line_num The line number where the assertion is called + * @param file_name Pointer to the file name + */ +void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name); + +/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ +/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ + +/** @brief Function for checking intended for production code. + * + * Check passes if "expr" evaluates to true. */ +#define ASSERT(expr) \ +if (expr) \ +{ \ +} \ +else \ +{ \ + assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ +} +#else +#define ASSERT(expr) //!< Assert empty when disabled +__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name); +#endif /* defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) */ + +#endif /* NRF_ASSERT_H_ */ diff --git a/cores/nRF5/SDK/components/libraries/util/nrf_log.c b/cores/nRF5/SDK/components/libraries/util/nrf_log.c new file mode 100644 index 00000000..b65b406a --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/nrf_log.c @@ -0,0 +1,453 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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.h" +#include "nrf_log.h" +#include "nrf_error.h" +#include +#include +#include + +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 + +#include +#include + +static char buf_normal_up[BUFFER_SIZE_UP]; +static char buf_down[BUFFER_SIZE_DOWN]; + +uint32_t log_rtt_init(void) +{ + static bool initialized = false; + if (initialized) + { + return NRF_SUCCESS; + } + + if (SEGGER_RTT_ConfigUpBuffer(LOG_TERMINAL_NORMAL, + "Normal", + buf_normal_up, + BUFFER_SIZE_UP, + SEGGER_RTT_MODE_NO_BLOCK_TRIM + ) + != 0) + { + return NRF_ERROR_INVALID_STATE; + } + + if (SEGGER_RTT_ConfigDownBuffer(LOG_TERMINAL_INPUT, + "Input", + buf_down, + BUFFER_SIZE_DOWN, + SEGGER_RTT_MODE_NO_BLOCK_SKIP + ) + != 0) + { + return NRF_ERROR_INVALID_STATE; + } + + initialized = true; + + return NRF_SUCCESS; +} + +// Forward declaration of SEGGER RTT vprintf function +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +void log_rtt_printf(int terminal_index, char * format_msg, ...) +{ + //lint -save -e526 -e628 -e530 + va_list p_args; + va_start(p_args, format_msg); + (void)SEGGER_RTT_vprintf(terminal_index, format_msg, &p_args); + va_end(p_args); + //lint -restore +} + +__INLINE void log_rtt_write_string(int terminal_index, int num_args, ...) +{ + const char* msg; + //lint -save -e516 -e530 + va_list p_args; + va_start(p_args, num_args); + //lint -restore + + for (int i = 0; i < num_args; i++) + { + //lint -save -e26 -e10 -e64 -e526 -e628 -e530 + msg = va_arg(p_args, const char*); + //lint -restore + (void)SEGGER_RTT_WriteString(terminal_index, msg); + } + va_end(p_args); +} + +void log_rtt_write_hex(int terminal_index, uint32_t value) +{ + char temp[11]; + temp[0] = '0'; + temp[1] = 'x'; + temp[10] = 0; // Null termination + uint8_t nibble; + uint8_t i = 8; + + while(i-- != 0) + { + nibble = (value >> (4 * i)) & 0x0F; + temp[9-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } + + (void)SEGGER_RTT_WriteString(terminal_index, temp); +} + +void log_rtt_write_hex_char(int terminal_index, uint8_t value) +{ + char temp[3]; + temp[2] = 0; // Null termination + uint8_t nibble; + uint8_t i = 2; + + while(i-- != 0) + { + nibble = (value >> (4 * i)) & 0x0F; + temp[1-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } + + (void)SEGGER_RTT_WriteString(terminal_index, temp); +} + +__INLINE int log_rtt_has_input() +{ + return SEGGER_RTT_HasKey(); +} + +uint32_t log_rtt_read_input(char * c) +{ + int r; + + r = SEGGER_RTT_Read(LOG_TERMINAL_INPUT, c, 1); + if (r == 1) + return NRF_SUCCESS; + else + return NRF_ERROR_NULL; +} + +#elif defined(NRF_LOG_USES_UART) && NRF_LOG_USES_UART == 1 + +#include "app_uart.h" +#include "app_error.h" +#include +#include +#include "nrf.h" +#include "bsp.h" + +#define MAX_TEST_DATA_BYTES (15U) /**< max number of test bytes to be used for tx and rx. */ +#define UART_TX_BUF_SIZE 512 /**< UART TX buffer size. */ +#define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */ + +static uint8_t m_uart_data; +static bool m_uart_has_input; + +void uart_error_cb(app_uart_evt_t * p_event) +{ + if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) + { + APP_ERROR_HANDLER(p_event->data.error_communication); + } + else if (p_event->evt_type == APP_UART_FIFO_ERROR) + { + APP_ERROR_HANDLER(p_event->data.error_code); + } +} + +uint32_t log_uart_init() +{ + static bool initialized = false; + if (initialized) + { + return NRF_SUCCESS; + } + + uint32_t err_code; + const app_uart_comm_params_t comm_params = + { + RX_PIN_NUMBER, + TX_PIN_NUMBER, + RTS_PIN_NUMBER, + CTS_PIN_NUMBER, + APP_UART_FLOW_CONTROL_ENABLED, + false, + UART_BAUDRATE_BAUDRATE_Baud115200 + }; + + APP_UART_FIFO_INIT(&comm_params, + UART_RX_BUF_SIZE, + UART_TX_BUF_SIZE, + uart_error_cb, + APP_IRQ_PRIORITY_LOW, + err_code); + + initialized = true; + + return err_code; +} + +//lint -save -e530 -e64 +void log_uart_printf(const char * format_msg, ...) +{ + va_list p_args; + va_start(p_args, format_msg); + (void)vprintf(format_msg, p_args); + va_end(p_args); +} + +__INLINE void log_uart_write_string_many(int num_args, ...) +{ + const char* msg; + va_list p_args; + va_start(p_args, num_args); + + for (int i = 0; i < num_args; i++) + { + msg = va_arg(p_args, const char*); + log_uart_write_string(msg); + } + va_end(p_args); +} + +__INLINE void log_uart_write_string(const char* msg) +{ + while( *msg ) + { + (void)app_uart_put(*msg++); + } +} +//lint -restore + +void log_uart_write_hex(uint32_t value) +{ + uint8_t nibble; + uint8_t i = 8; + + (void)app_uart_put('0'); + (void)app_uart_put('x'); + while( i-- != 0 ) + { + nibble = (value >> (4 * i)) & 0x0F; + (void)app_uart_put( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); + } +} + +void log_uart_write_hex_char(uint8_t c) +{ + uint8_t nibble; + uint8_t i = 2; + + while( i-- != 0 ) + { + nibble = (c >> (4 * i)) & 0x0F; + (void)app_uart_put( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); + } +} + +__INLINE int log_uart_has_input() +{ + if (m_uart_has_input) return 1; + if (app_uart_get(&m_uart_data) == NRF_SUCCESS) + { + m_uart_has_input = true; + return 1; + } + return 0; +} + +uint32_t log_uart_read_input(char * c) +{ + if (m_uart_has_input) + { + *c = (char)m_uart_data; + m_uart_has_input = false; + return NRF_SUCCESS; + } + if (app_uart_get((uint8_t *)c) == NRF_SUCCESS) + { + return NRF_SUCCESS; + } + return NRF_ERROR_NULL; +} + +#elif defined(NRF_LOG_USES_RAW_UART) && NRF_LOG_USES_RAW_UART == 1 + +#include "app_uart.h" +#include +#include +#include "bsp.h" + +uint32_t log_raw_uart_init() +{ + // Disable UART + NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled; + + // Configure RX/TX pins + nrf_gpio_cfg_output( TX_PIN_NUMBER ); + nrf_gpio_cfg_input(RX_PIN_NUMBER, NRF_GPIO_PIN_NOPULL); + + // Set a default baud rate of UART0_CONFIG_BAUDRATE + NRF_UART0->PSELTXD = TX_PIN_NUMBER; + NRF_UART0->BAUDRATE = UART0_CONFIG_BAUDRATE; + + NRF_UART0->PSELRTS = 0xFFFFFFFF; + NRF_UART0->PSELCTS = 0xFFFFFFFF; + + // Disable parity and interrupt + NRF_UART0->CONFIG = (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos ); + NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos ); + + // Re-enable the UART + NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled; + NRF_UART0->INTENSET = 0; + NRF_UART0->TASKS_STARTTX = 1; + NRF_UART0->TASKS_STARTRX = 1; + + return NRF_SUCCESS; +} + +void log_raw_uart_printf(const char * format_msg, ...) +{ + static char buffer[256]; + + va_list p_args; + va_start(p_args, format_msg); + sprintf(buffer, format_msg, p_args); + va_end(p_args); + + log_raw_uart_write_string(buffer); +} + +__INLINE void log_raw_uart_write_char(const char c) +{ + NRF_UART0->TXD = c; + while( NRF_UART0->EVENTS_TXDRDY != 1 ); + NRF_UART0->EVENTS_TXDRDY = 0; +} + +__INLINE void log_raw_uart_write_string_many(int num_args, ...) +{ + + const char* msg; + va_list p_args; + va_start(p_args, num_args); + + for (int i = 0; i < num_args; i++) + { + msg = va_arg(p_args, const char*); + log_raw_uart_write_string(msg); + } + va_end(p_args); +} + +__INLINE void log_raw_uart_write_string(const char* msg) +{ + while( *msg ) + { + NRF_UART0->TXD = *msg++; + while( NRF_UART0->EVENTS_TXDRDY != 1 ); + NRF_UART0->EVENTS_TXDRDY = 0; + } +} + +void log_raw_uart_write_hex(uint32_t value) +{ + uint8_t nibble; + uint8_t i = 8; + + log_raw_uart_write_string( "0x" ); + while( i-- != 0 ) + { + nibble = (value >> (4 * i)) & 0x0F; + log_raw_uart_write_char( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); + } +} + +void log_raw_uart_write_hex_char(uint8_t c) +{ + uint8_t nibble; + uint8_t i = 2; + + while( i-- != 0 ) + { + nibble = (c >> (4 * i)) & 0x0F; + log_raw_uart_write_hex( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); + } +} + +__INLINE int log_raw_uart_has_input() +{ + return 0; +} + +uint32_t log_raw_uart_read_input(char * c) +{ + return NRF_ERROR_NULL; +} + +#endif // NRF_LOG_USES_RAW_UART == 1 + + +const char* log_hex_char(const char c) +{ + static volatile char hex_string[3]; + hex_string[2] = 0; // Null termination + uint8_t nibble; + uint8_t i = 2; + while(i-- != 0) + { + nibble = (c >> (4 * i)) & 0x0F; + hex_string[1-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } + return (const char*) hex_string; +} + +const char* log_hex(uint32_t value) +{ + static volatile char hex_string[11]; + hex_string[0] = '0'; + hex_string[1] = 'x'; + hex_string[10] = 0; + uint8_t nibble; + uint8_t i = 8; + + while(i-- != 0) + { + nibble = (value >> (4 * i)) & 0x0F; + hex_string[9-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } + + return (const char*)hex_string; +} + diff --git a/cores/nRF5/SDK/components/libraries/util/nrf_log.h b/cores/nRF5/SDK/components/libraries/util/nrf_log.h new file mode 100644 index 00000000..82358ecf --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/nrf_log.h @@ -0,0 +1,728 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_H_ +#define NRF_LOG_H_ + +#ifndef DOXYGEN + +#include +#include +#include + +#ifndef NRF_LOG_USES_RTT +#define NRF_LOG_USES_RTT 0 +#endif + +#ifndef NRF_LOG_USES_UART +#define NRF_LOG_USES_UART 0 +#endif + +#ifndef NRF_LOG_USES_RAW_UART +#define NRF_LOG_USES_RAW_UART 0 +#endif + +#ifndef NRF_LOG_USES_COLORS + #define NRF_LOG_USES_COLORS 1 +#endif + +#if NRF_LOG_USES_COLORS == 1 + #define NRF_LOG_COLOR_DEFAULT "\x1B[0m" + #define NRF_LOG_COLOR_BLACK "\x1B[1;30m" + #define NRF_LOG_COLOR_RED "\x1B[1;31m" + #define NRF_LOG_COLOR_GREEN "\x1B[1;32m" + #define NRF_LOG_COLOR_YELLOW "\x1B[1;33m" + #define NRF_LOG_COLOR_BLUE "\x1B[1;34m" + #define NRF_LOG_COLOR_MAGENTA "\x1B[1;35m" + #define NRF_LOG_COLOR_CYAN "\x1B[1;36m" + #define NRF_LOG_COLOR_WHITE "\x1B[1;37m" +#else + #define NRF_LOG_COLOR_DEFAULT + #define NRF_LOG_COLOR_BLACK + #define NRF_LOG_COLOR_RED + #define NRF_LOG_COLOR_GREEN + #define NRF_LOG_COLOR_YELLOW + #define NRF_LOG_COLOR_BLUE + #define NRF_LOG_COLOR_MAGENTA + #define NRF_LOG_COLOR_CYAN + #define NRF_LOG_COLOR_WHITE +#endif + +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 + +#define LOG_TERMINAL_NORMAL (0) +#define LOG_TERMINAL_ERROR (1) +#define LOG_TERMINAL_INPUT (0) + +/**@brief Function for initializing the SEGGER RTT logger. + * + * @details See segger.com + * for information about SEGGER Real Time Transfer (RTT). + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use the macro @ref NRF_LOG_INIT instead. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR Otherwise. + */ +uint32_t log_rtt_init(void); + +/**@brief Function for writing a printf string using RTT. + * + * @details The printf implementation in SEGGER's RTT is more efficient than + * the standard implementation. However, printf requires more processor time + * than other logging functions. Therefore, applications that require logging + * but need it to interfere as little as possible with the execution, should + * avoid using printf. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_PRINTF + * - @ref NRF_LOG_PRINTF_DEBUG + * - @ref NRF_LOG_PRINTF_ERROR + * + * @param terminal_index Segger RTT terminal index to use as output. + * @param format_msg Printf format string. + */ +void log_rtt_printf(int terminal_index, char * format_msg, ...); + +/**@brief Function for writing a string using RTT. + * + * @details The string to write must be null-terminated, but the null termination will not be stored + * in the ring buffer. + * The impact of running this function should be very low compared to writing to UART. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG + * - @ref NRF_LOG_DEBUG + * - @ref NRF_LOG_ERROR + * + * @param terminal_index Segger RTT terminal index to use as output. + * @param num_args Number of arguments. + */ +void log_rtt_write_string(int terminal_index, int num_args, ...); + +/**@brief Function for writing an integer as HEX using RTT. + * + * The output data is formatted as, for example, 0x89ABCDEF. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX + * - @ref NRF_LOG_HEX_DEBUG + * - @ref NRF_LOG_HEX_ERROR + * + * @param terminal_index Segger RTT terminal index to use as output. + * @param value Integer value to be printed as HEX. + */ +void log_rtt_write_hex(int terminal_index, uint32_t value); + +/**@brief Function for writing a single character as HEX using RTT. + * + * The output string is formatted as, for example, AA. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX_CHAR + * - @ref NRF_LOG_HEX_CHAR_DEBUG + * - @ref NRF_LOG_HEX_CHAR_ERROR + * + * @param terminal_index Segger RTT terminal index to use as output. + * @param value Character to print as HEX. + */ +void log_rtt_write_hex_char(int terminal_index, uint8_t value); + +/**@brief Function for checking if data is available in the input buffer. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use @ref NRF_LOG_HAS_INPUT instead. + * + * @retval 1 If characters are available to read. + * @retval 0 If no characters are available. + */ +int log_rtt_has_input(void); + +/**@brief Function for reading one character from the input buffer. + * + * @param[out] p_char Pointer where to store the character. + * + * This function is available only when NRF_LOG_USES_RTT is defined as 1. + * + * @note Do not call this function directly. Use @ref NRF_LOG_READ_INPUT instead. + * + * @retval NRF_SUCCESS If the character was read out. + * @retval NRF_ERROR_INVALID_DATA If no character could be read. + */ +uint32_t log_rtt_read_input(char* p_char); + +#define NRF_LOG_INIT() log_rtt_init() /*!< Initialize the module. */ + +#define NRF_LOG_PRINTF(...) log_rtt_printf(LOG_TERMINAL_NORMAL, ##__VA_ARGS__) /*!< Print a log message using printf. */ +#define NRF_LOG_PRINTF_DEBUG(...) log_rtt_printf(LOG_TERMINAL_NORMAL, ##__VA_ARGS__) /*!< If DEBUG is set, print a log message using printf. */ +#define NRF_LOG_PRINTF_ERROR(...) log_rtt_printf(LOG_TERMINAL_ERROR, ##__VA_ARGS__) /*!< Print a log message using printf to the error stream. */ + +#define NRF_LOG(...) log_rtt_write_string(LOG_TERMINAL_NORMAL, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message. The input string must be null-terminated. */ +#define NRF_LOG_DEBUG(...) log_rtt_write_string(LOG_TERMINAL_NORMAL, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< If DEBUG is set, print a log message. The input string must be null-terminated. */ +#define NRF_LOG_ERROR(...) log_rtt_write_string(LOG_TERMINAL_ERROR, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message to the error stream. The input string must be null-terminated. */ + +#define NRF_LOG_HEX(val) log_rtt_write_hex(LOG_TERMINAL_NORMAL, val) /*!< Log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_DEBUG(val) log_rtt_write_hex(LOG_TERMINAL_NORMAL, val) /*!< If DEBUG is set, log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_ERROR(val) log_rtt_write_hex(LOG_TERMINAL_ERROR, val) /*!< Log an integer as HEX value to the error stream (example output: 0x89ABCDEF). */ + +#define NRF_LOG_HEX_CHAR(val) log_rtt_write_hex_char(LOG_TERMINAL_NORMAL, val) /*!< Log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_DEBUG(val) log_rtt_write_hex_char(LOG_TERMINAL_NORMAL, val) /*!< If DEBUG is set, log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_ERROR(val) log_rtt_write_hex_char(LOG_TERMINAL_ERROR, val) /*!< Log a character as HEX value to the error stream (example output: AA). */ + +#define NRF_LOG_HAS_INPUT() log_rtt_has_input() /*!< Check if the input buffer has unconsumed characters. */ +#define NRF_LOG_READ_INPUT(p_char) log_rtt_read_input(p_char) /*!< Consume a character from the input buffer. */ + +#if !defined(DEBUG) && !defined(DOXYGEN) + +#undef NRF_LOG_DEBUG +#define NRF_LOG_DEBUG(...) + +#undef NRF_LOG_STR_DEBUG +#define NRF_LOG_STR_DEBUG(...) + +#undef NRF_LOG_HEX_DEBUG +#define NRF_LOG_HEX_DEBUG(...) + +#undef NRF_LOG_HEX_CHAR_DEBUG +#define NRF_LOG_HEX_CHAR_DEBUG(...) + +#endif // !defined(DEBUG) && !defined(DOXYGEN) + +#elif defined(NRF_LOG_USES_UART) && NRF_LOG_USES_UART == 1 + +/**@brief Function for initializing the UART logger. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note Do not call this function directly. Use the macro @ref NRF_LOG_INIT instead. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR Otherwise. + */ +uint32_t log_uart_init(void); + +/**@brief Function for logging a printf string to UART. + * + * @details Printf requires more processor time + * than other logging functions. Therefore, applications that require logging + * but need it to interfere as little as possible with the execution, should + * avoid using printf. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_PRINTF + * - @ref NRF_LOG_PRINTF_DEBUG + * - @ref NRF_LOG_PRINTF_ERROR + * + * @param format_msg Printf format string. + */ +void log_uart_printf(const char * format_msg, ...); + +/**@brief Function for logging a single character to UART. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @param c Character. + */ +void log_uart_write_char(const char c); + +/**@brief Function for logging null-terminated strings to UART. + * + * @details This function is more efficient than using printf. + * The null termination will not be logged. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG + * - @ref NRF_LOG_DEBUG + * - @ref NRF_LOG_ERROR + * + * @param num_args Number of arguments. + */ +void log_uart_write_string_many(int num_args, ...); + + +/**@brief Function for logging a null-terminated string to UART. + * + * @details This function is more efficient than using printf. + * The null termination will not be logged. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG + * - @ref NRF_LOG_DEBUG + * - @ref NRF_LOG_ERROR + * + * @param msg Null-terminated string. + */ +void log_uart_write_string(const char* msg); + + +/**@brief Function for logging an integer value as HEX to UART. + * + * @details The output data is formatted as, for example, 0x89ABCDEF. + * This function is more efficient than printf. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX + * - @ref NRF_LOG_HEX_DEBUG + * - @ref NRF_LOG_HEX_ERROR + * + * @param value Integer value to be printed as HEX. + */ +void log_uart_write_hex(uint32_t value); + +/**@brief Function for logging a single character as HEX to UART. + * + * @details The output string is formatted as, for example, AA. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX_CHAR + * - @ref NRF_LOG_HEX_CHAR_DEBUG + * - @ref NRF_LOG_HEX_CHAR_ERROR + * + * @param c Character. + */ +void log_uart_write_hex_char(uint8_t c); + +/**@brief Function for checking if data is available in the input buffer. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note Do not call this function directly. Use @ref NRF_LOG_HAS_INPUT instead. + * + * @retval 1 If characters are available to read. + * @retval 0 If no characters are available. + */ +int log_uart_has_input(void); + +/**@brief Function for reading one character from the input buffer. + * + * @param[out] p_char Pointer where to store the character. + * + * This function is available only when NRF_LOG_USES_UART is defined as 1. + * + * @note Do not call this function directly. Use NRF_LOG_READ_INPUT instead. + * + * @retval NRF_SUCCESS If the character was read out. + * @retval NRF_ERROR_INVALID_DATA If no character could be read. + */ +uint32_t log_uart_read_input(char* p_char); + + +#define NRF_LOG_INIT() log_uart_init() /*!< Initialize the module. */ + +#define NRF_LOG_PRINTF(...) log_uart_printf(__VA_ARGS__) /*!< Print a log message using printf. */ +#define NRF_LOG_PRINTF_DEBUG(...) log_uart_printf(__VA_ARGS__) /*!< If DEBUG is set, print a log message using printf. */ +#define NRF_LOG_PRINTF_ERROR(...) log_uart_printf(__VA_ARGS__) /*!< Print a log message using printf to the error stream. */ + +#define NRF_LOG(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message. The input string must be null-terminated. */ +#define NRF_LOG_DEBUG(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< If DEBUG is set, print a log message. The input string must be null-terminated. */ +#define NRF_LOG_ERROR(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message to the error stream. The input string must be null-terminated. */ + +#define NRF_LOG_HEX(val) log_uart_write_hex(val) /*!< Log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_DEBUG(val) log_uart_write_hex(val) /*!< If DEBUG is set, log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_ERROR(val) log_uart_write_hex(val) /*!< Log an integer as HEX value to the error stream (example output: 0x89ABCDEF). */ + +#define NRF_LOG_HEX_CHAR(val) log_uart_write_hex_char(val) /*!< Log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_DEBUG(val) log_uart_write_hex_char(val) /*!< If DEBUG is set, log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_ERROR(val) log_uart_write_hex_char(val) /*!< Log a character as HEX value to the error stream (example output: AA). */ + +#define NRF_LOG_HAS_INPUT() log_uart_has_input() /*!< Check if the input buffer has unconsumed characters. */ +#define NRF_LOG_READ_INPUT(p_char) log_uart_read_input(p_char) /*!< Consume a character from the input buffer. */ + +#if !defined(DEBUG) && !defined(DOXYGEN) + +#undef NRF_LOG_DEBUG +#define NRF_LOG_DEBUG(...) + +#undef NRF_LOG_PRINTF_DEBUG +#define NRF_LOG_PRINTF_DEBUG(...) + +#undef NRF_LOG_STR_DEBUG +#define NRF_LOG_STR_DEBUG(...) + +#undef NRF_LOG_HEX_DEBUG +#define NRF_LOG_HEX_DEBUG(...) + +#undef NRF_LOG_HEX_CHAR_DEBUG +#define NRF_LOG_HEX_CHAR_DEBUG(...) + +#endif // !defined(DEBUG) && !defined(DOXYGEN) + +#elif defined(NRF_LOG_USES_RAW_UART) && NRF_LOG_USES_RAW_UART == 1 + +/**@brief Function for initializing the raw UART logger. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note Do not call this function directly. Use the macro @ref NRF_LOG_INIT instead. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR Otherwise. + */ +uint32_t log_raw_uart_init(void); + +/**@brief Function for logging a printf string to raw UART. + * + * @details Printf requires more processor time + * than other logging functions. Therefore, applications that require logging + * but need it to interfere as little as possible with the execution, should + * avoid using printf. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_PRINTF + * - @ref NRF_LOG_PRINTF_DEBUG + * - @ref NRF_LOG_PRINTF_ERROR + * + * @param format_msg Printf format string. + */ +void log_raw_uart_printf(const char * format_msg, ...); + +/**@brief Function for logging a single character to raw UART. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @param c Character. + */ +void log_raw_uart_write_char(const char c); + +/**@brief Function for logging null-terminated strings to raw UART. + * + * @details This function is more efficient than using printf. + * The null termination will not be logged. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG + * - @ref NRF_LOG_DEBUG + * - @ref NRF_LOG_ERROR + * + * @param num_args Number of arguments. + */ +void log_raw_uart_write_string_many(int num_args, ...); + + +/**@brief Function for logging a null-terminated string to raw UART. + * + * @details This function is more efficient than using printf. + * The null termination will not be logged. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG + * - @ref NRF_LOG_DEBUG + * - @ref NRF_LOG_ERROR + * + * @param str Null-terminated string. + */ +void log_raw_uart_write_string(const char * str); + +/**@brief Function for logging an integer value as HEX to raw UART. + * + * @details The output data is formatted as, for example, 0x89ABCDEF. + * This function is more efficient than printf. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX + * - @ref NRF_LOG_HEX_DEBUG + * - @ref NRF_LOG_HEX_ERROR + * + * @param value Integer value to be printed as HEX. + */ +void log_raw_uart_write_hex(uint32_t value); + +/**@brief Function for logging a single character as HEX to raw UART. + * + * @details The output string is formatted as, for example, AA. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note This function is non-blocking. If too much data is sent to the UART, + * some characters might be skipped. + * + * @note Do not call this function directly. Use one of the following macros instead: + * - @ref NRF_LOG_HEX_CHAR + * - @ref NRF_LOG_HEX_CHAR_DEBUG + * - @ref NRF_LOG_HEX_CHAR_ERROR + * + * @param c Character. + */ +void log_raw_uart_write_hex_char(uint8_t c); + +/**@brief Function for checking if data is available in the input buffer. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note Do not call this function directly. Use @ref NRF_LOG_HAS_INPUT instead. + * + * @retval 1 If characters are available to read. + * @retval 0 If no characters are available. + */ +int log_raw_uart_has_input(void); + +/**@brief Function for reading one character from the input buffer. + * + * @param[out] p_char Pointer where to store the character. + * + * This function is available only when NRF_LOG_USES_RAW_UART is defined as 1. + * + * @note Do not call this function directly. Use NRF_LOG_READ_INPUT instead. + * + * @retval NRF_SUCCESS If the character was read out. + * @retval NRF_ERROR_INVALID_DATA If no character could be read. + */ + +uint32_t log_raw_uart_read_input(char* p_char); + +#define NRF_LOG_INIT() log_raw_uart_init() /*!< nitialize the module. */ + +#define NRF_LOG_PRINTF(...) log_raw_uart_printf(__VA_ARGS__) /*!< Print a log message using printf. */ +#define NRF_LOG_PRINTF_DEBUG(...) log_raw_uart_printf(__VA_ARGS__) /*!< If DEBUG is set, print a log message using printf. */ +#define NRF_LOG_PRINTF_ERROR(...) log_raw_uart_printf(__VA_ARGS__) /*!< Print a log message using printf to the error stream. */ + +#define NRF_LOG(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message. The input string must be null-terminated. */ +#define NRF_LOG_DEBUG(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< If DEBUG is set, print a log message. The input string must be null-terminated. */ +#define NRF_LOG_ERROR(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< Print a log message to the error stream. The input string must be null-terminated. */ + +#define NRF_LOG_HEX(val) log_raw_uart_write_hex(val) /*!< Log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_DEBUG(val) log_raw_uart_write_hex(val) /*!< If DEBUG is set, log an integer as HEX value (example output: 0x89ABCDEF). */ +#define NRF_LOG_HEX_ERROR(val) log_raw_uart_write_hex(val) /*!< Log an integer as HEX value to the error stream (example output: 0x89ABCDEF). */ + +#define NRF_LOG_HEX_CHAR(val) log_raw_uart_write_hex_char(val) /*!< Log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_DEBUG(val) log_raw_uart_write_hex_char(val) /*!< If DEBUG is set, log a character as HEX value (example output: AA). */ +#define NRF_LOG_HEX_CHAR_ERROR(val) log_raw_uart_write_hex_char(val) /*!< Log a character as HEX value to the error stream (example output: AA). */ + +#define NRF_LOG_HAS_INPUT() log_raw_uart_has_input() /*!< Check if the input buffer has unconsumed characters. */ +#define NRF_LOG_READ_INPUT(p_char) log_raw_uart_read_input(p_char) /*!< Consume a character from the input buffer. */ + +#if !defined(DEBUG) && !defined(DOXYGEN) + +#undef NRF_LOG_DEBUG +#define NRF_LOG_DEBUG(...) + +#undef NRF_LOG_PRINTF_DEBUG +#define NRF_LOG_PRINTF_DEBUG(...) + +#undef NRF_LOG_STR_DEBUG +#define NRF_LOG_STR_DEBUG(...) + +#undef NRF_LOG_HEX_DEBUG +#define NRF_LOG_HEX_DEBUG(...) + +#undef NRF_LOG_HEX_CHAR_DEBUG +#define NRF_LOG_HEX_CHAR_DEBUG(...) + +#endif // !defined(DEBUG) && !defined(DOXYGEN) + +#else + +#include "nrf_error.h" +#include "nordic_common.h" + +// Empty definitions + +#define NRF_LOG_INIT() NRF_SUCCESS +#define NRF_LOG(...) +#define NRF_LOG_DEBUG(...) +#define NRF_LOG_ERROR(...) + +#define NRF_LOG_PRINTF(...) +#define NRF_LOG_PRINTF_DEBUG(...) +#define NRF_LOG_PRINTF_ERROR(...) + +#define NRF_LOG_HEX(val) +#define NRF_LOG_HEX_DEBUG(val) +#define NRF_LOG_HEX_ERROR(val) + +#define NRF_LOG_HEX_CHAR(val) +#define NRF_LOG_HEX_CHAR_DEBUG(val) +#define NRF_LOG_HEX_CHAR_ERROR(val) + +#define NRF_LOG_HAS_INPUT() 0 +#define NRF_LOG_READ_INPUT(ignore) NRF_SUCCESS + +#endif + +/**@brief Function for writing HEX values. + * + * @note This function not thread-safe. It is written for convenience. + * If you log from different application contexts, you might get different results. + * + * @retval NULL By default. + */ +const char* log_hex(uint32_t value); + +/**@brief Function for writing HEX characters. + * + * @note This function not thread-safe. It is written for convenience. + * If you log from different application contexts, you might get different results. + * + * @retval NULL By default. + */ +const char* log_hex_char(const char value); + + + + +#else // DOXYGEN + +/** @defgroup nrf_log UART/RTT logging + * @{ + * @ingroup app_common + * + * @brief Library to output logging information over SEGGER's Real Time Transfer + * (RTT), UART, or raw UART. + * + * This library provides macros that call the respective functions depending on + * which protocol is used. Define LOG_USES_RTT=1 to enable logging over RTT, + * NRF_LOG_USES_UART=1 to enable logging over UART, or NRF_LOG_USES_RAW_UART=1 + * to enable logging over raw UART. One of these defines must be set for any of + * the macros to have effect. If you choose to not output information, all + * logging macros can be left in the code without any cost; they will just be + * ignored. + */ + + + +/**@brief Macro for initializing the logger. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR Otherwise. + */ +uint32_t NRF_LOG_INIT(void); + +/**@brief Macro for logging null-terminated strings. + * + * @details This function is more efficient than using printf. + * The null termination will not be logged. + * + * @param msg Null-terminated string. + */ +void NRF_LOG(const char* msg); + +/**@brief Macro for logging a printf string. + * + * @details Printf requires more processor time + * than other logging functions. Therefore, applications that require logging + * but need it to interfere as little as possible with the execution, should + * avoid using printf. + * + * @note When NRF_LOG_USES_UART is set to 1, this macro is non-blocking. + * If too much data is sent, some characters might be skipped. + * + * @param format_msg Printf format string. + * @param ... Additional arguments replacing format specifiers in format_msg. + */ +void NRF_LOG_PRINTF(const char * format_msg, ...); + +/**@brief Macro for logging an integer value as HEX. + * + * @details The output data is formatted as, for example, 0x89ABCDEF. + * This function is more efficient than printf. + * + * @note When NRF_LOG_USES_UART is set to 1, this macro is non-blocking. + * If too much data is sent, some characters might be skipped. + * + * @param value Integer value to be printed as HEX. + */ +void NRF_LOG_HEX(uint32_t value); + +/**@brief Macro for logging a single character as HEX. + * + * @details The output string is formatted as, for example, AA. + * + * @note When NRF_LOG_USES_UART is set to 1, this macro is non-blocking. + * If too much data is sent, some characters might be skipped. + * + * @param c Character. + */ +void NRF_LOG_HEX_CHAR(uint8_t c); + +/**@brief Macro for checking if data is available in the input buffer. + * + * @note When NRF_LOG_USES_UART is set to 1, this macro is non-blocking. + * If too much data is sent, some characters might be skipped. + * + * @retval 1 If characters are available to read. + * @retval 0 If no characters are available. + */ +int NRF_LOG_HAS_INPUT(void); + +/**@brief Macro for reading one character from the input buffer. + * + * @param[out] p_char Pointer where to store the character. + * + * @retval NRF_SUCCESS If the character was read out. + * @retval NRF_ERROR_INVALID_DATA If no character could be read. + */ +uint32_t NRF_LOG_READ_INPUT(char* p_char); + +/** @} */ +#endif // DOXYGEN +#endif // NRF_LOG_H_ diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_common.h b/cores/nRF5/SDK/components/libraries/util/sdk_common.h new file mode 100644 index 00000000..ad8ed737 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_common.h @@ -0,0 +1,191 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + */ + +/** @cond */ +/**@file + * + * @ingroup experimental_api + * @defgroup sdk_common SDK Common Header + * @breif All common headers needed for SDK examples will be included here so that application + * developer does not have to include headers on him/herself. + * @{ + */ + +#ifndef SDK_COMMON_H__ +#define SDK_COMMON_H__ + +#include +#include +#include +#include "nordic_common.h" +#include "compiler_abstraction.h" +#include "sdk_os.h" +#include "sdk_errors.h" +#include "app_util.h" + +/**@brief Macro for verifying that the module is initialized. It will cause the function to return + * if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifndef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL(param) \ +do \ +{ \ + if (param == NULL) \ + { \ + return NRF_ERROR_NULL; \ + } \ +} while(0) +#else +#define VERIFY_PARAM_NOT_NULL() +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the function to return + * if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifndef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL_VOID(param) \ +do \ +{ \ + if (param == NULL) \ + { \ + return; \ + } \ +} while(0) +#else +#define VERIFY_PARAM_NOT_NULL_VOID() +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. Will return the err code + * if not. + * + * @param[in] err_code The error code to check. + */ +#ifndef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS(err_code) \ +do \ +{ \ + if (err_code != NRF_SUCCESS) \ + { \ + return err_code; \ + } \ +} while(0) +#else +#define VERIFY_SUCCESS() +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. Will return if not. + * + * @param[in] err_code The error code to check. + */ +#ifndef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS_VOID(err_code) \ +do \ +{ \ + if (err_code != NRF_SUCCESS) \ + { \ + return; \ + } \ +} while(0) +#else +#define VERIFY_SUCCESS_VOID() +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying statement to be true. Will return err_code if not. +* +* @param[in] statement Statement to test. +* @param[in] err_code Error value to return if test was invalid. +* +* @retval err_code if test fails. +*/ +#define VERIFY_TRUE(statement, err_code) \ +do \ +{ \ + if (!(statement)) \ + { \ + return err_code; \ + } \ +} while(0) + + +/**@brief Macro for verifying statement to be true. Will return if not. +* +* @param[in] statement Statement to test. +*/ +#define VERIFY_TRUE_VOID(statement) \ +do \ +{ \ + if (!(statement)) \ + { \ + return; \ + } \ +} while(0) + + +/**@brief Macro for verifying statement to be false. Will return err_code if not. +* +* @param[in] statement Statement to test. +* @param[in] err_code Error value to return if test was invalid. +* +* @retval err_code if test fails. +*/ +#define VERIFY_FALSE(statement, err_code) \ +do \ +{ \ + if ((statement)) \ + { \ + return err_code; \ + } \ +} while(0) + + +/**@brief Macro for verifying statement to be false. Will return if not. +* +* @param[in] statement Statement to test. +*/ +#define VERIFY_FALSE_VOID(statement) \ +do \ +{ \ + if ((statement)) \ + { \ + return; \ + } \ +} while(0) + +/** @} */ +/** @endcond */ +#endif // SDK_COMMON_H__ + diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_errors.h b/cores/nRF5/SDK/components/libraries/util/sdk_errors.h new file mode 100644 index 00000000..2a742774 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_errors.h @@ -0,0 +1,132 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 sdk_error SDK Error codes + * @{ + * @ingroup app_common + * @{ + * @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for + * identifying the module where the error occurred while the least least significant LSB + * are used to provide the cause or nature of error. Each module is assigned a 16-bit + * unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit + * LSB range is with module id as the MSB in the 32-bit error code is reserved for the + * module. As an example, if 0x8800 identifies a certain SDK module, all values from + * 0x88000000 - 0x8800FFFF are reserved for this module. + * It should be noted that common error reasons have been assigned values to make it + * possible to decode error reason easily. As an example, lets module uninitialized has + * been assigned an error code 0x000A0. Then, if application encounters an error code + * 0xZZZZ00A0, it knows that it accessing a certain module without initializing it. + * Apart from this, each module is allowed to define error codes that are not covered by + * the common ones, however, these values are defined in a range that does not conflict + * with common error values. For module, specific error however, it is possible that the + * same error value is used by two different modules to indicated errors of very different + * nature. If error is already defined by the NRF common error codes, these are reused. + * A range is reserved for application as well, it can use this range for defining + * application specific errors. + * + * @note Success code, NRF_SUCCESS, does not include any module identifier. + + */ + +#ifndef SDK_ERRORS_H__ +#define SDK_ERRORS_H__ + +#include +#include "nrf_error.h" + +/** + * @defgroup sdk_err_base Base defined for SDK Modules + * @{ + */ +#define SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */ +#define SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */ +/* @} */ + +/** + * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred. + * @{ + */ +#define DEVICE_MANAGER_ERR_BASE (0x8000) +#define MEMORY_MANAGER_ERR_BASE (0x8100) +/* @} */ + + +/** + * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors. + * @{ + */ +#define IOT_ERR_BASE_START (0xA000) +#define IOT_ERR_BASE_STOP (0xAFFF) +/* @} */ + + +/** + * @defgroup sdk_common_errors Codes reserved as identification for common errors. + * @{ + */ +#define MODULE_NOT_INITIALZED (SDK_COMMON_ERROR_BASE + 0x0000) +#define MUTEX_INIT_FAILED (SDK_COMMON_ERROR_BASE + 0x0001) +#define MUTEX_LOCK_FAILED (SDK_COMMON_ERROR_BASE + 0x0002) +#define MUTEX_UNLOCK_FAILED (SDK_COMMON_ERROR_BASE + 0x0003) +#define MUTEX_COND_INIT_FAILED (SDK_COMMON_ERROR_BASE + 0x0004) +#define MODULE_ALREADY_INITIALIZED (SDK_COMMON_ERROR_BASE + 0x0005) +#define API_NOT_IMPLEMENTED (SDK_COMMON_ERROR_BASE + 0x0010) +#define FEATURE_NOT_ENABLED (SDK_COMMON_ERROR_BASE + 0x0011) +/* @} */ + + +/** + * @defgroup dm_specific_errors Error / status codes specific to device manager. + * @{ + */ +#define DM_NO_APP_CONTEXT (DEVICE_MANAGER_ERR_BASE + 0x0040) +#define DM_SERVICE_CONTEXT_NOT_APPLIED (DEVICE_MANAGER_ERR_BASE + 0x0041) +#define DM_CONTEXT_INFO_LOST (DEVICE_MANAGER_ERR_BASE + 0x0042) +#define DM_DEVICE_CONTEXT_FULL (DEVICE_MANAGER_ERR_BASE + 0x0043) +/* @} */ + +/** + * @brief API Result. + * + * @details Indicates success or failure of an API procedure. In case of failure, a comprehensive + * error code indicating cause or reason for failure is provided. + * + * Though called an API result, it could used in Asynchronous notifications callback along + * with asynchronous callback as event result. This mechanism is employed when an event + * marks the end of procedure initiated using API. API result, in this case, will only be + * an indicative of whether the procedure has been requested successfully. + */ +typedef uint32_t ret_code_t; +/** @} */ +/** @} */ + +#endif // SDK_ERRORS_H__ + diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_macros.h b/cores/nRF5/SDK/components/libraries/util/sdk_macros.h new file mode 100644 index 00000000..36de050d --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_macros.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + */ + +/** @cond */ +/**@file + * + * @ingroup sdk_util + * @defgroup sdk_common_macros SDK Common Header + * @breif Macros for parameter checking and similar tasks + * @{ + */ + +#ifndef SDK_MACROS_H__ +#define SDK_MACROS_H__ + +/**@brief Macro for verifying that the module is initialized. It will cause the function to return + * @ref NRF_ERROR_INVALID_STATE if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED() +#else +#ifdef MODULE_INITIALIZED +#define VERIFY_MODULE_INITIALIZED() \ +do \ +{ \ + if (!MODULE_INITIALIZED) \ + { \ + return NRF_ERROR_INVALID_STATE; \ + } \ +} while(0) +#else +#define VERIFY_MODULE_INITIALIZED() +#endif /* MODULE_INITIALIZED */ +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the function to return + * if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED_VOID() +#else +#ifdef MODULE_INITIALIZED +#define VERIFY_MODULE_INITIALIZED_VOID() \ +do \ +{ \ + if (!MODULE_INITIALIZED) \ + { \ + return; \ + } \ +} while(0) +#else +#define VERIFY_MODULE_INITIALIZED_VOID() +#endif /* MODULE_INITIALIZED */ +#endif /* DISABLE_PARAM_CHECK */ + + + + +/** @} */ +/** @endcond */ +#endif // SDK_MACROS_H__ + diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.c b/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.c new file mode 100644 index 00000000..8d3171e3 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.c @@ -0,0 +1,178 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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_mapped_flags.h" +#include +#include +#include +#include "compiler_abstraction.h" + + +/**@brief Function for setting the state of a flag to true. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to modify. + * @param[in] index The index of the flag to modify. + */ +static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index) +{ + *p_flags |= (1U << index); +} + + +/**@brief Function for setting the state of a flag to false. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to modify. + * @param[in] index The index of the flag to modify. + */ +static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index) +{ + *p_flags &= ~(1U << index); +} + + +/**@brief Function for getting the state of a flag. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to read. + * @param[in] index The index of the flag to get. + */ +static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index) +{ + return ((flags & (1 << index)) != 0); +} + + + +uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags) +{ + for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + return i; + } + } + return SDK_MAPPED_FLAGS_INVALID_INDEX; +} + + +void sdk_mapped_flags_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint16_t key, + bool value) +{ + sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value); +} + + +void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint32_t n_flag_collections, + uint16_t key, + bool value) +{ + if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0)) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (p_keys[i] == key) + { + for (uint32_t j = 0; j < n_flag_collections; j++) + { + if (value) + { + sdk_mapped_flags_set_by_index(&p_flags[j], i); + } + else + { + sdk_mapped_flags_clear_by_index(&p_flags[j], i); + } + } + return; + } + } + } +} + + +bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key) +{ + if (p_keys != NULL) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (p_keys[i] == key) + { + return sdk_mapped_flags_get_by_index(flags, i); + } + } + } + return false; +} + + +sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys, + sdk_mapped_flags_t flags) +{ + sdk_mapped_flags_key_list_t key_list; + key_list.len = 0; + + if (p_keys != NULL) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + key_list.flag_keys[key_list.len++] = p_keys[i]; + } + } + } + + return key_list; +} + + +uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags) +{ + uint32_t n_flags_set = 0; + + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + n_flags_set += 1; + } + } + return n_flags_set; +} diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.h b/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.h new file mode 100644 index 00000000..92d1e0b2 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_mapped_flags.h @@ -0,0 +1,170 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 SDK_MAPPED_FLAGS_H__ +#define SDK_MAPPED_FLAGS_H__ + +#include +#include +#include "app_util.h" +#include "compiler_abstraction.h" + +/** + * @file + * @defgroup sdk_mapped_flags Mapped flags + * @ingroup app_common + * @{ + * @brief Module for writing and reading flags that are associated + * with keys. + * + * @details The flags are represented as bits in a bitmap called a flag collection. The keys + * are uint16_t. Each flag collection contains all flags of the same type, one flag for + * each key. + * + * The mapped flags module does not keep the flag states, nor the list of keys. These are + * provided in the API calls. A key's index in the key list determines which bit in the + * flag collection is associated with it. This module does not ever edit the key list, and + * does not edit flags except in function calls that take the flag collection as a pointer. + * + */ + +#define SDK_MAPPED_FLAGS_N_KEYS 8 /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */ +#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8 /**< The number of flags that fit in one byte. */ +#define SDK_MAPPED_FLAGS_INVALID_INDEX 0xFFFF /**< A flag index guaranteed to be invalid. */ + +typedef uint8_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */ + + +// Test whether the flag collection type is large enough to hold all the flags. If this fails, +// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t. +STATIC_ASSERT(( + sizeof(sdk_mapped_flags_t)*SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS); + + +/**@brief Type used to present a subset of the registered keys. + */ +typedef struct +{ + uint32_t len; /**< The length of the list. */ + uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS]; /**< The list of keys. */ +} sdk_mapped_flags_key_list_t; + + +/**@brief Function for getting the first index at which the flag is true in the provided + * collection. + * + * @param[in] flags The flag collection to search for a flag set to true. + * + * @return The first index that has its flag set to true. If none were found, the + * function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX. + */ +uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags); + + +/**@brief Function for updating the state of a flag. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[out] p_flags The flag collection to modify. + * @param[in] key The key to modify the flag of. + * @param[in] value The state to set the flag to. + */ +void sdk_mapped_flags_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint16_t key, + bool value); + + +/**@brief Function for updating the state of the same flag in multiple flag collections. + * + * @details The key and value are the same for all flag collections in the p_flags array. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[out] p_flags The flag collections to modify. + * @param[out] n_flag_collections The number of flag collections in p_flags. + * @param[in] key The key to modify the flag of. + * @param[in] value The state to set the flag to. + */ +void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint32_t n_flag_collections, + uint16_t key, + bool value); + + +/**@brief Function for getting the state of a specific flag. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[in] flags The flag collection to read from. + * @param[in] key The key to get the flag for. + * + * @return The state of the flag. + */ +bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key); + + +/**@brief Function for getting a list of all keys that have a specific flag set to true. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[in] flags The flag collection to search. + * + * @return The list of keys. + */ +sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys, + sdk_mapped_flags_t flags); + + +/**@brief Function for getting the number of keys that have a specific flag set to true. + * + * @param[in] flags The flag collection to search. + * + * @return The number of keys. + */ +uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags); + + +/**@brief Function for querying whether any flags in the collection are set. + * + * @param[in] flags The flag collection to query. + * + * @retval true If one or more flags are set to true. + * @retval false Otherwise. + */ +static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags) +{ + return (flags != 0); +} + + +/** @} */ + +#endif /* SDK_MAPPED_FLAGS_H__ */ diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_os.h b/cores/nRF5/SDK/components/libraries/util/sdk_os.h new file mode 100644 index 00000000..e3e96f95 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_os.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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. + */ + + /** @cond */ +/**@file + * + * @defgroup sdk_os SDK OS Abstraction + * @ingroup experimental_api + * @details In order to made SDK modules independent of use of an embedded OS, and permit + * application with varied task architecture, SDK abstracts the OS specific + * elements here in order to make all other modules agnostic to the OS or task + * architecture. + * @{ + */ + +#ifndef SDK_OS_H__ +#define SDK_OS_H__ + +#define SDK_MUTEX_DEFINE(X) +#define SDK_MUTEX_INIT(X) +#define SDK_MUTEX_LOCK(X) +#define SDK_MUTEX_UNLOCK(X) + +/** + * @defgroup os_data_type Data types. + */ + +/** @} */ +/** @endcond */ +#endif // SDK_OS_H__ + diff --git a/cores/nRF5/SDK/components/libraries/util/sdk_resources.h b/cores/nRF5/SDK/components/libraries/util/sdk_resources.h new file mode 100644 index 00000000..a441a6e1 --- /dev/null +++ b/cores/nRF5/SDK/components/libraries/util/sdk_resources.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 + * @brief Definition file for resource usage by SoftDevice, ESB and Gazell. + */ + +#ifndef APP_RESOURCES_H__ +#define APP_RESOURCES_H__ + +#ifdef SOFTDEVICE_PRESENT + #include "nrf_sd_def.h" +#else + #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */ + #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ + #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */ + #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */ + #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */ +#endif + +#ifdef GAZELL_PRESENT + #include "nrf_gzll_resources.h" +#else + #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */ +#endif + +#ifdef ESB_PRESENT + #include "nrf_esb_resources.h" +#else + #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */ + #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */ +#endif + +#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED) +#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED) +#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED) +#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED) + +#endif // APP_RESOURCES_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.c b/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.c new file mode 100644 index 00000000..e480a762 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.c @@ -0,0 +1,127 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "nfc_ndef_msg.h" +#include "nrf.h" + +/** + * @brief Resolve the value of record location flags of the NFC NDEF record within a NFC NDEF message. + */ +__STATIC_INLINE nfc_ndef_record_location_t record_location_get(uint32_t index, + uint32_t record_count) +{ + nfc_ndef_record_location_t record_location; + + if (index == 0) + { + if (record_count == 1) + { + record_location = NDEF_LONE_RECORD; + } + else + { + record_location = NDEF_FIRST_RECORD; + } + } + else if (record_count == index + 1) + { + record_location = NDEF_LAST_RECORD; + } + else + { + record_location = NDEF_MIDDLE_RECORD; + } + + return record_location; +} + + +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len) +{ + nfc_ndef_record_location_t record_location; + uint32_t temp_len; + uint32_t i; + uint32_t err_code; + + uint32_t sum_of_len = 0; + + nfc_ndef_record_desc_t * * pp_record_rec_desc = p_ndef_msg_desc->pp_record; + + for (i = 0; i < p_ndef_msg_desc->record_count; i++) + { + record_location = record_location_get(i, p_ndef_msg_desc->record_count); + + temp_len = *p_msg_len - sum_of_len; + + err_code = nfc_ndef_record_encode(*pp_record_rec_desc, + record_location, + p_msg_buffer, + &temp_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + sum_of_len += temp_len; + p_msg_buffer += temp_len; + + /* next record */ + pp_record_rec_desc++; + } + + *p_msg_len = sum_of_len; + + return NRF_SUCCESS; +} + + +void nfc_ndef_msg_clear(nfc_ndef_msg_desc_t * p_msg) +{ + p_msg->record_count = 0; +} + + +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record) +{ + if (p_msg->record_count >= p_msg->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_msg->pp_record[p_msg->record_count] = p_record; + p_msg->record_count++; + + return NRF_SUCCESS; +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.h b/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.h new file mode 100644 index 00000000..b3031090 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/generic/message/nfc_ndef_msg.h @@ -0,0 +1,165 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_MSG_H__ +#define NFC_NDEF_MSG_H__ + +#include "nfc_ndef_record.h" +/**@file + * + * @defgroup nfc_ndef_msg Custom NDEF messages + * @{ + * @ingroup nfc_modules + * + * @brief Generation of NFC NDEF messages for the NFC Type 2 Tag. + * + */ + + /** + * @brief NDEF message descriptor. + */ + typedef struct { + nfc_ndef_record_desc_t ** pp_record; ///< Pointer to an array of pointers to NDEF record descriptors. + uint32_t max_record_count; ///< Number of elements in the allocated pp_record array, which defines the maximum number of records within the NDEF message. + uint32_t record_count; ///< Number of records in the NDEF message. + } nfc_ndef_msg_desc_t; + + /** + * @brief Function for encoding an NDEF message. + * + * This function encodes an NDEF message according to the provided message descriptor. + * + * @param[in] p_ndef_msg_desc Pointer to the message descriptor. + * @param[out] p_msg_buffer Pointer to the message destination. + * @param[in,out] p_msg_len Size of the available memory for the message as input. Size of the generated + * message as output. + * + * @return Return value from @ref nfc_ndef_record_encode. + */ +ret_code_t nfc_ndef_msg_encode( nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len); + +/** + * @brief Function for clearing an NDEF message. + * + * This function clears an NDEF message descriptor, thus empties the NDEF message. + * + * @param[in,out] p_msg Pointer to the message descriptor. + */ +void nfc_ndef_msg_clear( nfc_ndef_msg_desc_t * p_msg); + +/** + * @brief Function for adding a record to an NDEF message. + * + * @param[in] p_record Pointer to the record descriptor. + * @param[in,out] p_msg Pointer to the message descriptor. + * + * @retval NRF_SUCCESS If the record was added successfully. + * @retval NRF_ERROR_NO_MEM If the message already contains the maximum number of records and the operation is not allowed. + */ +ret_code_t nfc_ndef_msg_record_add( nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record); + + +/**@brief Macro for creating and initializing an NFC NDEF message descriptor. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_msg_desc_t + * and a static array of pointers to record descriptors (@ref nfc_ndef_record_desc_t) used + * by the message. + * + * Use the macro @ref NFC_NDEF_MSG to access the NDEF message descriptor instance. + * + * @param[in] NAME Name of the related instance. + * @param[in] MAX_RECORD_CNT Maximal count of records in the message. + */ +#define NFC_NDEF_MSG_DEF(NAME, MAX_RECORD_CNT) \ + static nfc_ndef_record_desc_t * NAME##_nfc_ndef_p_record_desc_array[MAX_RECORD_CNT]; \ + static nfc_ndef_msg_desc_t NAME##_nfc_ndef_msg_desc = \ + { \ + .pp_record = NAME##_nfc_ndef_p_record_desc_array, \ + .max_record_count = MAX_RECORD_CNT, \ + .record_count = 0, \ + } + +/** @brief Macro for accessing the NFC NDEF message descriptor instance + * that you created with @ref NFC_NDEF_MSG_DEF. + */ +#define NFC_NDEF_MSG(NAME) (NAME##_nfc_ndef_msg_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor with an encapsulated NDEF message. + + * This macro creates and initializes a static instance of type + * @ref nfc_ndef_record_desc_t that contains an encapsulated NDEF message as + * payload. @ref nfc_ndef_msg_encode is used as payload constructor to encode + * the message. The encoded message is then used as payload for the record. + * + * Use the macro @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_NESTED_MESSAGE Pointer to the message descriptor to encapsulate + * as the record's payload. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF( NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_NESTED_MESSAGE ) \ + static nfc_ndef_record_desc_t NAME##_ndef_record_nested_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)(nfc_ndef_msg_encode), \ + .p_payload_descriptor = (void*) (P_NESTED_MESSAGE) \ + } + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD(NAME) (NAME##_ndef_record_nested_desc) + +/** + * @} + */ + #endif + diff --git a/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.c b/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.c new file mode 100644 index 00000000..ad9e31e3 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.c @@ -0,0 +1,157 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nfc_ndef_record.h" +#include "app_util.h" +#include "nrf.h" + + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in long NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SIZE 2 + \ + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE + +__STATIC_INLINE uint32_t record_header_size_calc(nfc_ndef_record_desc_t const * p_ndef_record_desc) +{ + uint32_t len = NDEF_RECORD_BASE_LONG_SIZE; + + len += p_ndef_record_desc->id_length + p_ndef_record_desc->type_length; + + if (p_ndef_record_desc->id_length > 0) + { + len++; + } + + return len; +} + + +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len) +{ + uint8_t * p_flags; // use as pointer to TNF+flags field + uint8_t * p_payload_len; // use as pointer to payload length field + uint32_t record_payload_len; + + // count record length without payload + uint32_t record_header_len = record_header_size_calc(p_ndef_record_desc); + uint32_t err_code = NRF_SUCCESS; + + /* verify location range */ + if ((record_location & (~NDEF_RECORD_LOCATION_MASK)) != 0x00) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* verify if there is enough available memory */ + if (record_header_len > *p_record_len) + { + return NRF_ERROR_NO_MEM; + } + + p_flags = p_record_buffer; + p_record_buffer++; + + // set location bits and clear other bits in 1st byte. + *p_flags = record_location; + + *p_flags |= p_ndef_record_desc->tnf; + + /* TYPE LENGTH */ + *(p_record_buffer++) = p_ndef_record_desc->type_length; + + // use always long record and remember payload len field memory offset. + p_payload_len = p_record_buffer; + p_record_buffer += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + + /* ID LENGTH - option */ + if (p_ndef_record_desc->id_length > 0) + { + *(p_record_buffer++) = p_ndef_record_desc->id_length; + + /* IL flag */ + *p_flags |= NDEF_RECORD_IL_MASK; + } + + /* TYPE */ + memcpy(p_record_buffer, p_ndef_record_desc->p_type, p_ndef_record_desc->type_length); + p_record_buffer += p_ndef_record_desc->type_length; + + /* ID */ + if (p_ndef_record_desc->id_length > 0) + { + memcpy(p_record_buffer, p_ndef_record_desc->p_id, p_ndef_record_desc->id_length); + p_record_buffer += p_ndef_record_desc->id_length; + } + + // count how much memory is left in record buffer for payload field. + record_payload_len = (*p_record_len - record_header_len); + + /* PAYLOAD */ + err_code = p_ndef_record_desc->payload_constructor(p_ndef_record_desc->p_payload_descriptor, + p_record_buffer, + &record_payload_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + /* PAYLOAD LENGTH */ + (void) uint32_big_encode(record_payload_len, p_payload_len); + + *p_record_len = record_header_len + record_payload_len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len) +{ + + if ( *p_len < p_payload_descriptor->payload_length) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_buffer, + p_payload_descriptor->p_payload, + p_payload_descriptor->payload_length); + + + *p_len = p_payload_descriptor->payload_length; + + return NRF_SUCCESS; +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.h b/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.h new file mode 100644 index 00000000..3134bd1d --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/generic/record/nfc_ndef_record.h @@ -0,0 +1,283 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_RECORD_H__ +#define NFC_NDEF_RECORD_H__ + +#include +#include +#include "compiler_abstraction.h" +#include "sdk_errors.h" +#include "nrf.h" + +/**@file + * + * @defgroup nfc_ndef_record Custom NDEF records + * @{ + * @ingroup nfc_ndef_msg + * + * @brief Generation of NFC NDEF records for NFC messages. + * + */ + + +#define NDEF_RECORD_IL_MASK 0x08 ///< Mask of the ID field presence bit in the flags byte of an NDEF record. +#define NDEF_RECORD_TNF_MASK 0x07 ///< Mask of the TNF value field in the first byte of an NDEF record. +#define NDEF_RECORD_SR_MASK 0x10 ///< Mask of the SR flag. If set, this flag indicates that the PAYLOAD_LENGTH field has a size of 1 byte. Otherwise, PAYLOAD_LENGTH has 4 bytes. +#define NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE 4 ///< Size of the Payload Length field in a long NDEF record. +#define NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE 1 ///< Size of the Payload Length field in a short NDEF record. +#define NDEF_RECORD_ID_LEN_SIZE 1 ///< Size of the ID Length field in an NDEF record. + + +/** + * @brief Payload constructor type. + + * A payload constructor is a function for constructing the payload of an NDEF + * record. + * + * @param[in] p_payload_descriptor Pointer to the input data for the constructor. + * @param[out] p_buffer Pointer to the payload destination. + * + * @param[in,out] p_len Size of the available memory to write as input. Size of the generated + * record payload as output. The implementation must check if the payload + * will fit in the provided buffer. This must be checked by the caller function. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +typedef ret_code_t (* p_payload_constructor_t)(void * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + + +/** + * @brief Type Name Format (TNF) Field Values. + * + * Values to specify the TNF of a record. + */ +typedef enum +{ + TNF_EMPTY = 0x00, ///< The value indicates that there is no type or payload associated with this record. + TNF_WELL_KNOWN = 0x01, ///< NFC Forum well-known type [NFC RTD]. + TNF_MEDIA_TYPE = 0x02, ///< Media-type as defined in RFC 2046 [RFC 2046]. + TNF_ABSOLUTE_URI = 0x03, ///< Absolute URI as defined in RFC 3986 [RFC 3986]. + TNF_EXTERNAL_TYPE = 0x04, ///< NFC Forum external type [NFC RTD]. + TNF_UNKNOWN_TYPE = 0x05, ///< The value indicates that there is no type associated with this record. + TNF_UNCHANGED = 0x06, ///< The value is used for the record chunks used in chunked payload. + TNF_RESERVED = 0x07, ///< The value is reserved for future use. +} nfc_ndef_record_tnf_t; + + +/** + * @brief NDEF record descriptor. + */ +typedef struct +{ + nfc_ndef_record_tnf_t tnf; ///< Value of the Type Name Format (TNF) field. + + uint8_t id_length; ///< Length of the ID field. If 0, a record format without ID field is assumed. + uint8_t const * p_id; ///< Pointer to the ID field data. Not relevant if id_length is 0. + + uint8_t type_length; ///< Length of the type field. + uint8_t const * p_type; ///< Pointer to the type field data. Not relevant if type_length is 0. + + p_payload_constructor_t payload_constructor; ///< Pointer to the payload constructor function. + void * p_payload_descriptor; ///< Pointer to the data for the payload constructor function. + +} nfc_ndef_record_desc_t; + +/** + * @brief Record position within the NDEF message. + * + * Values to specify the location of a record within the NDEF message. + */ +typedef enum +{ + NDEF_FIRST_RECORD = 0x80, ///< First record. + NDEF_MIDDLE_RECORD = 0x00, ///< Middle record. + NDEF_LAST_RECORD = 0x40, ///< Last record. + NDEF_LONE_RECORD = 0xC0 ///< Only one record in the message. +} nfc_ndef_record_location_t; + +#define NDEF_RECORD_LOCATION_MASK (NDEF_LONE_RECORD) ///< Mask of the Record Location bits in the NDEF record's flags byte. + +/** + * @brief Binary data descriptor containing the payload for the record. + */ +typedef struct +{ + uint8_t const * p_payload; ///< Pointer to the buffer with the data. + uint32_t payload_length; ///< Length of data in bytes. +} nfc_ndef_bin_payload_desc_t; + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a generic record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t. + * + * Use the macro @ref NFC_NDEF_GENERIC_RECORD_DESC to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD_CONSTRUCTOR Pointer to the payload constructor function. + * The constructor must be of type @ref p_payload_constructor_t. + * @param[in] P_PAYLOAD_DESCRIPTOR Pointer to the data for the payload constructor. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD_CONSTRUCTOR, \ + P_PAYLOAD_DESCRIPTOR) \ + static nfc_ndef_record_desc_t NAME##_ndef_generic_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)P_PAYLOAD_CONSTRUCTOR, \ + .p_payload_descriptor = (void *) P_PAYLOAD_DESCRIPTOR \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_GENERIC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC(NAME) (NAME##_ndef_generic_record_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a record with + * binary payload. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and a binary data descriptor containing the payload data. + * + * Use the macro @ref NFC_NDEF_RECORD_BIN_DATA to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD Pointer to the payload data that will be copied to the payload field. + * @param[in] PAYLOAD_LEN Length of the payload. + */ +#define NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \ + TNF, \ + P_ID, ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD, \ + PAYLOAD_LEN) \ + static nfc_ndef_bin_payload_desc_t NAME##_nfc_ndef_bin_payload_desc = \ + { \ + .p_payload = P_PAYLOAD, \ + .payload_length = PAYLOAD_LEN \ + }; \ + \ + static nfc_ndef_record_desc_t NAME##_nfc_ndef_bin_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy, \ + .p_payload_descriptor = (void *) &NAME##_nfc_ndef_bin_payload_desc \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_RECORD_BIN_DATA(NAME) (NAME##_nfc_ndef_bin_record_desc) + +/** @brief Macro for accessing the binary data descriptor that contains + * the payload of the record that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_BIN_PAYLOAD_DESC(NAME) (NAME##_nfc_ndef_bin_payload_desc) + +/** + * @brief Function for encoding an NDEF record. + * + * This function encodes an NDEF record according to the provided record descriptor. + * + * @param[in] p_ndef_record_desc Pointer to the record descriptor. + * @param[in] record_location Location of the record within the NDEF message. + * @param[out] p_record_buffer Pointer to the record destination. + * @param[in,out] p_record_len Size of the available memory for the record as input. Size of the generated + * record as output. + * + * @retval NRF_SUCCESS If the record was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted record size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If the location of the record is erroneous. + * @retval Other Other codes might be returned depending on the NDEF record payload constructor implementation. + */ +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len); + +/** + * @brief Function for constructing the payload for an NFC NDEF record from binary data. + * + * This function copies data from a binary buffer to the payload field of the NFC NDEF record. + * + * @param[in] p_payload_descriptor Pointer to the descriptor of the binary data location and size. + * + * @param[out] p_buffer Pointer to the payload destination. + * @param[in,out] p_len Size of the available memory for the payload as input. Size of the copied payload + * as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + +/** + * @} + */ + +#endif // NFC_NDEF_RECORD_H__ + diff --git a/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.c b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.c new file mode 100644 index 00000000..5fb15fd4 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.c @@ -0,0 +1,135 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include +#include "nfc_launchapp_rec.h" +#include "nfc_launchapp_msg.h" +#include "nrf_error.h" + +/** @brief Function for generating a description of an NFC NDEF launch application message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and the NFC NDEF record descriptions that are referenced by this message description. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp Record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] pp_launchapp_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + */ +__STATIC_INLINE ret_code_t nfc_launchapp_msg_declare(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + nfc_ndef_msg_desc_t ** pp_launchapp_msg_desc) +{ + + uint32_t err_code; + + nfc_ndef_record_desc_t * p_win_rec, * p_android_rec; + + /* Create NFC NDEF message description, capacity - 2 records */ + NFC_NDEF_MSG_DEF(nfc_launchapp_msg, 2); + + /* The message description is static, therefore you must */ + /* clear the message (needed for supporting multiple calls). */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_launchapp_msg)); + + if (p_win_app_id != NULL) + { + /* Create NFC NDEF Windows Phone LaunchApp Record description */ + p_win_rec = nfc_windows_launchapp_rec_declare(p_win_app_id, + win_app_id_length); + + /* Add Windows LaunchApp record as first record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_win_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (p_android_package_name != NULL) + { + /* Create NFC NDEF Android Application Record description */ + p_android_rec = nfc_android_application_rec_declare(p_android_package_name, + android_package_name_length); + + /* Add Android App Record as second record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_android_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (NFC_NDEF_MSG(nfc_launchapp_msg).record_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_launchapp_msg_desc = &NFC_NDEF_MSG(nfc_launchapp_msg); + + return NRF_SUCCESS; +} + + +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_launchapp_msg_desc; + ret_code_t err_code; + + err_code = nfc_launchapp_msg_declare(p_android_package_name, + android_package_name_length, + p_win_app_id, + win_app_id_length, + &p_launchapp_msg_desc); + + if (err_code != NRF_SUCCESS) + return err_code; + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_launchapp_msg_desc, + p_buf, + p_len); + + return err_code; +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.h b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.h new file mode 100644 index 00000000..303e7148 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_msg.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_LAUNCHAPP_MSG_H__ +#define NFC_LAUNCHAPP_MSG_H__ + +/** @file + * + * @defgroup nfc_launch_app_msg Launch app messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages that can be used to launch apps. + * + */ + +#include +#include "nfc_ndef_msg.h" + + +/** @brief Function for encoding an NFC NDEF launch app message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode + */ +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + #endif // NFC_LAUNCHAPP_MSG_H__ + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.c b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.c new file mode 100644 index 00000000..9e9915fa --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.c @@ -0,0 +1,151 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nrf_error.h" +#include "app_util.h" +#include "nfc_ndef_record.h" + +/** + * @brief Type of description of payload of Windows LaunchApp record. + */ +typedef struct +{ + const uint8_t * platform; + uint8_t platform_length; + const uint8_t * app_id; + uint8_t app_id_length; +} win_launchapp_payload_desc_t; + +/** @brief Description of payload of Windows LaunchApp record. */ +static win_launchapp_payload_desc_t win_launchapp_dsc; + +static const uint8_t launchapp_type_str[] = {'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', 'c', 'o', 'm', + ':', 'p', 'k', 'g'}; + +static const uint8_t win_launchapp_type_str[] = {'w', 'i', 'n', 'd', 'o', 'w', 's', '.', 'c', 'o', + 'm', '/', 'L', 'a', 'u', 'n', 'c', 'h', 'A', 'p', + 'p'}; + +static const uint8_t win_phone_str[] = {'W', 'i', 'n', 'd', 'o', 'w', 's', 'P', 'h', 'o', 'n', 'e'}; + +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length) +{ + NFC_NDEF_RECORD_BIN_DATA_DEF(android_app_rec, + TNF_EXTERNAL_TYPE, // tnf <- external + NULL, // no id + 0, // no id + launchapp_type_str, + sizeof(launchapp_type_str), + NULL, + 0); + + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).p_payload = p_package_name; + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).payload_length = package_name_length; + + return &NFC_NDEF_RECORD_BIN_DATA(android_app_rec); +} + +#define WIN_LUNCHAPP_EMPTY_PARAMETER 0x20 ///< The empty parameter value for the Wndows LaunchApp Record. + +/** + * @brief Function for constructing the payload for a Windows LaunchApp Record. + * + * This function encodes the payload according to the LaunchApp record definition. It implements an API + * compatible with p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, the function will calculate + * the expected size of the write based on the description. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS Always success. + */ +static ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + + win_launchapp_payload_desc_t * launch_desc = (win_launchapp_payload_desc_t *) p_input; + + uint32_t temp_len = (uint32_t)launch_desc->platform_length + launch_desc->app_id_length + 7; + + if (temp_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_len = temp_len; + + *p_buff++ = 0x00; // platform count: 1 + *p_buff++ = 0x01; // -||- + + *p_buff++ = launch_desc->platform_length; + memcpy(p_buff, launch_desc->platform, launch_desc->platform_length); // platform + p_buff += launch_desc->platform_length; + + + *p_buff++ = launch_desc->app_id_length; + memcpy(p_buff, launch_desc->app_id, launch_desc->app_id_length); + p_buff += launch_desc->app_id_length; + + *p_buff++ = 0x00; // parameters length 1B + *p_buff++ = 0x01; // -||- + *p_buff++ = WIN_LUNCHAPP_EMPTY_PARAMETER; // empty parameter + + return NRF_SUCCESS; +} + + +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length) +{ + + NFC_NDEF_GENERIC_RECORD_DESC_DEF(win_launchapp, + TNF_ABSOLUTE_URI, + NULL, + 0, + win_launchapp_type_str, + sizeof(win_launchapp_type_str), + nfc_win_launchapp_payload_constructor, + &win_launchapp_dsc); + + win_launchapp_dsc.platform = win_phone_str; + win_launchapp_dsc.platform_length = sizeof(win_phone_str); + + win_launchapp_dsc.app_id = p_win_app_id; + win_launchapp_dsc.app_id_length = win_app_id_length; + + return &NFC_NDEF_GENERIC_RECORD_DESC(win_launchapp); +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.h b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.h new file mode 100644 index 00000000..bc10152f --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/launchapp/nfc_launchapp_rec.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_LAUNCHAPP_REC_H__ +#define NFC_LAUNCHAPP_REC_H__ + +/**@file + * + * @defgroup nfc_launch_app_rec Launch app records + * @{ + * @ingroup nfc_launch_app_msg + * + * @brief Generation of NFC NDEF record descriptions that launch apps. + * + */ + +#include +#include "nfc_ndef_record.h" + +/** @brief Function for generating a description of an NFC NDEF Android Application Record (AAR). + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of an Android Application Record (AAR). + * + * @note The record payload data (@p p_package_name) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_package_name Pointer to the Android package name string. + * @param[in] package_name_length Length of the Android package name. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length); + +/** @brief Function for generating a description of an NFC NDEF Windows LaunchApp record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a Windows LaunchApp record. + * + * @note The record payload data (@p p_win_app_id) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * @param[in] win_app_id_length Length of the Windows application ID. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length); +/** @} */ +#endif // NFC_LAUNCHAPP_REC diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c new file mode 100644 index 00000000..aa538e0d --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c @@ -0,0 +1,76 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "nfc_ndef_msg_parser.h" +#include "nfc_ndef_parser_logger.h" +#include "nrf_delay.h" + +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + ret_code_t ret_code; + nfc_ndef_parser_memo_desc_t parser_memory_helper; + + ret_code = ndef_parser_memo_resolve(p_result_buf, + p_result_buf_len, + &parser_memory_helper); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + ret_code = internal_ndef_msg_parser(&parser_memory_helper, + p_nfc_data, + p_nfc_data_len); + + return ret_code; +} + + +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc) +{ + uint32_t i; + + nrf_delay_ms(100); + NDEF_PARSER_TRACE("NDEF message contains %d record(s)", p_msg_desc->record_count); + if (p_msg_desc->record_count > 1) + { + NDEF_PARSER_TRACE("s"); + } + NDEF_PARSER_TRACE("\r\n\r\n"); + + for (i = 0; i < p_msg_desc->record_count; i++) + { + ndef_record_printout(i, p_msg_desc->pp_record[i]); + } +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h new file mode 100644 index 00000000..a5c3f82e --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_MSG_PARSER_H__ +#define NFC_NDEF_MSG_PARSER_H__ + +/**@file + * + * @defgroup nfc_ndef_parser NDEF message parser + * @{ + * @ingroup nfc_modules + * + * @brief Parser for NFC NDEF messages and records. + * + * @defgroup nfc_ndef_msg_parser Parser for NDEF messages + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg_parser_local.h" + +/** + * @brief Macro for calculating the memory size required for holding the + * description of a message that consists of a certain number of NDEF records. + * + * @param[in] max_count_of_records Maximum number of records to hold. + */ +#define NFC_NDEF_PARSER_REQIRED_MEMO_SIZE_CALC(max_count_of_records) \ + ((uint32_t)(max_count_of_records) <= 1) ? \ + (sizeof(parsed_ndef_msg_1_t) * (uint32_t)(max_count_of_records)) : \ + (sizeof(parsed_ndef_msg_1_t) + ((NFC_PARSER_M_DELTA) *((uint32_t)(max_count_of_records) - 1))) + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This function parses NDEF messages using NDEF binary record descriptors. + * + * @param[out] p_result_buf Pointer to the buffer that will be used to hold + * the NDEF message descriptor. After parsing is completed successfully, the first address + * in the buffer is filled by the NDEF message descriptor + * (@ref nfc_ndef_msg_desc_t), which provides a full description of + * the parsed NDEF message. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message or + * the buffer is too small to hold the actual result of the parsing. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of the provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + */ +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of an NDEF message. + * + * @param[in] p_msg_desc Pointer to the descriptor of the message that should be printed. + */ +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc); + +/** + * @} + * @} + */ + +#endif // NFC_NDEF_MSG_PARSER_H__ + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c new file mode 100644 index 00000000..e02ccf00 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c @@ -0,0 +1,151 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "nfc_ndef_msg_parser_local.h" + + +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + nfc_ndef_record_location_t record_location; + + ret_code_t ret_code; + + uint32_t nfc_data_left = *p_nfc_data_len; + uint32_t temp_nfc_data_len = 0; + + // want to modify -> use local copy + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_parser_memo_desc->p_bin_pay_desc; + nfc_ndef_record_desc_t * p_rec_desc = p_parser_memo_desc->p_rec_desc; + + + while (nfc_data_left > 0) + { + temp_nfc_data_len = nfc_data_left; + + ret_code = ndef_record_parser(p_bin_pay_desc, + p_rec_desc, + &record_location, + p_nfc_data, + &temp_nfc_data_len); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + // verify the records location flags + if (p_parser_memo_desc->p_msg_desc->record_count == 0) + { + if ((record_location != NDEF_FIRST_RECORD) && (record_location != NDEF_LONE_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + if ((record_location != NDEF_MIDDLE_RECORD) && (record_location != NDEF_LAST_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + + ret_code = nfc_ndef_msg_record_add(p_parser_memo_desc->p_msg_desc, p_rec_desc); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + nfc_data_left -= temp_nfc_data_len; + + if ((record_location == NDEF_LAST_RECORD) || (record_location == NDEF_LONE_RECORD)) + { + *p_nfc_data_len = *p_nfc_data_len - nfc_data_left; + return NRF_SUCCESS; + } + else + { + if (p_parser_memo_desc->p_msg_desc->record_count == + p_parser_memo_desc->p_msg_desc->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_nfc_data += temp_nfc_data_len; + p_bin_pay_desc++; + p_rec_desc++; + } + } + + return NRF_ERROR_INVALID_DATA; + +} + + +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc) +{ + + uint32_t max_rec_num; + uint32_t memory_last; + uint8_t * p_end; + nfc_ndef_record_desc_t * * pp_record_desc_array; + + if (*p_result_buf_len < sizeof(parsed_ndef_msg_1_t)) + { + return NRF_ERROR_NO_MEM; + } + + memory_last = (*p_result_buf_len) - sizeof(parsed_ndef_msg_1_t); + max_rec_num = (memory_last / (NFC_PARSER_M_DELTA)) + 1; + + p_parser_memo_desc->p_msg_desc = (nfc_ndef_msg_desc_t *) p_result_buf; + pp_record_desc_array = + (nfc_ndef_record_desc_t * *) &p_parser_memo_desc->p_msg_desc[1]; + p_parser_memo_desc->p_bin_pay_desc = + (nfc_ndef_bin_payload_desc_t *) &pp_record_desc_array[max_rec_num]; + p_parser_memo_desc->p_rec_desc = + (nfc_ndef_record_desc_t *) &p_parser_memo_desc->p_bin_pay_desc[max_rec_num]; + + // initialize message description + p_parser_memo_desc->p_msg_desc->pp_record = pp_record_desc_array; + p_parser_memo_desc->p_msg_desc->max_record_count = max_rec_num; + p_parser_memo_desc->p_msg_desc->record_count = 0; + + p_end = (uint8_t *) &p_parser_memo_desc->p_rec_desc[max_rec_num]; + + *p_result_buf_len = p_end - p_result_buf; + + return NRF_SUCCESS; +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h new file mode 100644 index 00000000..ee9e856a --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h @@ -0,0 +1,148 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_MSG_PARSER_LOCAL_H__ +#define NFC_NDEF_MSG_PARSER_LOCAL_H__ + +/**@file + * + * @defgroup nfc_ndef_msg_parser_local NDEF message parser (internal) + * @{ + * @ingroup nfc_ndef_msg_parser + * + * @brief Internal part of the parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg.h" +#include "nfc_ndef_record_parser.h" + +/** + * @brief Type for holding descriptors that are used by the NDEF parser. + */ +typedef struct +{ + nfc_ndef_msg_desc_t * p_msg_desc; ///< Pointer to the message descriptor. + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc; ///< Pointer to the array of binary payload descriptors. + nfc_ndef_record_desc_t * p_rec_desc; ///< Pointer to the array of record descriptors. +} nfc_ndef_parser_memo_desc_t; + +/** + * @brief Memory allocated for a one-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[1]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[1]; + nfc_ndef_record_desc_t rec_desc[1]; +} parsed_ndef_msg_1_t; + +/** + * @brief Memory allocated for a two-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[2]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[2]; + nfc_ndef_record_desc_t rec_desc[2]; +} parsed_ndef_msg_2_t; + +/** + * @brief Amount of memory that is required per record in addition to the memory allocated for the message descriptor. + */ +#define NFC_PARSER_M_DELTA (sizeof(parsed_ndef_msg_2_t) - sizeof(parsed_ndef_msg_1_t)) + + +/** + * @brief Function for resolving data instances in the provided buffer according + * to requirements of the function @ref internal_ndef_msg_parser. + * + * This internal function distributes the provided memory between certain data instances that are required + * by @ref internal_ndef_msg_parser. + * + * This function should not be used directly. + * + * @param[in] p_result_buf Pointer to the buffer that will be used to allocate + * data instances. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[out] p_parser_memo_desc Pointer to the structure for holding descriptors of the allocated data + * instances. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message. + */ +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc); + + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This internal function parses NDEF messages into certain data instances. + * + * This function should not be used directly. + * + * @param[in,out] p_parser_memo_desc Pointer to the structure that holds descriptors of the allocated data + * instances for the parser. This structure contains the following fields: @n + * .p_msg_desc Pointer to the message descriptor that will + * be filled with parsed data. @n + * .p_bin_pay_desc Pointer to the array of binary payload + * descriptors that will be filled with parsed + * data. @n + * .p_rec_desc Pointer to the array of record descriptors + * that will be filled with parsed data. @n + * The arrays specified by @p .p_bin_pay_desc and @p .p_rec_desc must not + * contain more elements than the message descriptor + * specified by \p .p_msg_desc can hold. + * + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. + * As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + * @retval NRF_ERROR_NO_MEM If the provided memory resources are too small to hold the parsing result. + */ +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @} + */ + +#endif // NFC_NDEF_MSG_PARSER_LOCAL_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_parser_logger.h b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_parser_logger.h new file mode 100644 index 00000000..0b286c8f --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_parser_logger.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_PARSER_LOGGER_H__ +#define NFC_NDEF_PARSER_LOGGER_H__ + +#ifdef NDEF_PARSER_LOG_ENABLE + #ifdef ENABLE_DEBUG_LOG_SUPPORT + + #include "app_trace.h" + + #define NDEF_PARSER_TRACE app_trace_log + + #elif defined(NRF_LOG_USES_RTT) + + #include "nrf_log.h" + + + #define NDEF_PARSER_TRACE(...) NRF_LOG_PRINTF(##__VA_ARGS__) + #endif +#endif + +#ifndef NDEF_PARSER_TRACE + #define NDEF_PARSER_TRACE(...) +#endif + +#endif // NFC_NDEF_PARSER_LOGGER_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c new file mode 100644 index 00000000..1cb904ee --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c @@ -0,0 +1,266 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include +#include "nfc_ndef_record_parser.h" +#include "nfc_ndef_parser_logger.h" +#include "app_util.h" +#include "nordic_common.h" +#include "nrf_delay.h" + + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in short NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SHORT 2 + NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE + + +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len) +{ + uint32_t expected_rec_size = NDEF_RECORD_BASE_LONG_SHORT; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->tnf = (nfc_ndef_record_tnf_t) ((*p_nfc_data) & NDEF_RECORD_TNF_MASK); + + /* An NDEF parser that receives an NDEF record with an unknown or unsupported TNF field value + SHOULD treat it as Unknown. See NFCForum-TS-NDEF_1.0 */ + if (p_rec_desc->tnf == TNF_RESERVED) + { + p_rec_desc->tnf = TNF_UNKNOWN_TYPE; + } + + *p_record_location = (nfc_ndef_record_location_t) ((*p_nfc_data) & NDEF_RECORD_LOCATION_MASK); + + uint8_t flags = *(p_nfc_data++); + + p_rec_desc->type_length = *(p_nfc_data++); + + uint32_t payload_lenght; + + if (flags & NDEF_RECORD_SR_MASK) + { + payload_lenght = *(p_nfc_data++); + } + else + { + expected_rec_size += + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE - NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + payload_lenght = uint32_big_decode(p_nfc_data); + p_nfc_data += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + } + + if (flags & NDEF_RECORD_IL_MASK) + { + expected_rec_size += NDEF_RECORD_ID_LEN_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->id_length = *(p_nfc_data++); + } + else + { + p_rec_desc->id_length = 0; + p_rec_desc->p_id = NULL; + } + + expected_rec_size += p_rec_desc->type_length + p_rec_desc->id_length + payload_lenght; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_rec_desc->type_length > 0) + { + p_rec_desc->p_type = p_nfc_data; + + p_nfc_data += p_rec_desc->type_length; + } + else + { + p_rec_desc->p_type = NULL; + } + + if (p_rec_desc->id_length > 0) + { + p_rec_desc->p_id = p_nfc_data; + + p_nfc_data += p_rec_desc->id_length; + } + + if (payload_lenght == 0) + { + p_bin_pay_desc->p_payload = NULL; + } + else + { + p_bin_pay_desc->p_payload = p_nfc_data; + } + + p_bin_pay_desc->payload_length = payload_lenght; + + p_rec_desc->p_payload_descriptor = p_bin_pay_desc; + p_rec_desc->payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy; + + *p_nfc_data_len = expected_rec_size; + + return NRF_SUCCESS; +} + + +char const * const tnf_strings[] = +{ + "Empty\r\n", + "NFC Forum well-known type\r\n", + "Media-type (RFC 2046)\r\n", + "Absolute URI (RFC 3986)\r\n", + "NFC Forum external type (NFC RTD)\r\n", + "Unknown\r\n", + "Unchanged\r\n", + "Reserved\r\n" +}; + + +#define MAX_NDEF_PASER_HEX_STRING_LEN 8 + +static void ndef_hexdata_printout(uint32_t num, uint8_t const * p_data, uint16_t indent) +{ + uint32_t i; + uint32_t j; + uint8_t tempbuf[MAX_NDEF_PASER_HEX_STRING_LEN + 1] = {[MAX_NDEF_PASER_HEX_STRING_LEN] = 0}; + + if (num > 0) + { + for (j = 0; j < indent; j++) + { + NDEF_PARSER_TRACE(" "); + } + + for (i = 0; i < num; i++) + { + if (i && ((i % MAX_NDEF_PASER_HEX_STRING_LEN) == 0)) + { + NDEF_PARSER_TRACE(" %s\r\n", tempbuf); + + for (j = 0; j < indent; j++) + { + NDEF_PARSER_TRACE(" "); + } + + nrf_delay_ms(10); + } + NDEF_PARSER_TRACE("%02X ", *p_data); + + + if (*p_data > ' ' && *p_data <= '~') + { + tempbuf[i % MAX_NDEF_PASER_HEX_STRING_LEN] = *p_data; + } + else + { + tempbuf[i % MAX_NDEF_PASER_HEX_STRING_LEN] = '.'; + } + + p_data++; + } + + i = i % MAX_NDEF_PASER_HEX_STRING_LEN; + if (i == 0) + i = MAX_NDEF_PASER_HEX_STRING_LEN; + + if (i > 0) + { + for (j = i; j < MAX_NDEF_PASER_HEX_STRING_LEN; j++) + { + NDEF_PARSER_TRACE(" "); + } + + tempbuf[i] = 0; + NDEF_PARSER_TRACE(" %s", tempbuf); + } + } + + NDEF_PARSER_TRACE("\r\n"); + + UNUSED_VARIABLE(tempbuf); +} + + +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc) +{ + NDEF_PARSER_TRACE("NDEF record %d content:\r\n", num); + NDEF_PARSER_TRACE("TNF: "); + NDEF_PARSER_TRACE((char *)tnf_strings[(uint32_t) p_rec_desc->tnf]); + + if (p_rec_desc->p_id != NULL) + { + NDEF_PARSER_TRACE("ID:\r\n"); + ndef_hexdata_printout(p_rec_desc->id_length, p_rec_desc->p_id, 2); + } + + if (p_rec_desc->p_type != NULL) + { + NDEF_PARSER_TRACE("type:\r\n"); + ndef_hexdata_printout(p_rec_desc->type_length, p_rec_desc->p_type, 2); + } + + if (p_rec_desc->payload_constructor == (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_rec_desc->p_payload_descriptor; + + if (p_bin_pay_desc->p_payload != NULL) + { + NDEF_PARSER_TRACE("Payload data (%d bytes):\r\n", p_bin_pay_desc->payload_length); + ndef_hexdata_printout(p_bin_pay_desc->payload_length, p_bin_pay_desc->p_payload, 2); + } + else + { + NDEF_PARSER_TRACE("No payload\r\n"); + } + } + NDEF_PARSER_TRACE("\r\n"); +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h new file mode 100644 index 00000000..751dc5b6 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_NDEF_RECORD_PARSER_H__ +#define NFC_NDEF_RECORD_PARSER_H__ + +#include +#include "sdk_errors.h" +#include "nfc_ndef_record.h" + +/**@file + * + * @defgroup nfc_ndef_record_parser Parser for NDEF records + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF records. + * + */ + + +/** + * @brief Function for parsing NDEF records. + * + * This parsing implementation uses the binary payload descriptor (@ref nfc_ndef_bin_payload_desc_t) to describe the payload for the record. + * + * @param[out] p_bin_pay_desc Pointer to the binary payload descriptor that will be filled and referenced by the record descriptor. + * @param[out] p_rec_desc Pointer to the record descriptor that will be filled with parsed data. + * @param[out] p_record_location Pointer to the record location. + * @param[in] p_nfc_data Pointer to the raw data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed record. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected record length is bigger than the provided input data amount. + */ +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of the NDEF record. + * + * @param[in] num Sequence number of the record within the NDEF message. + * @param[in] p_rec_desc Pointer to the descriptor of the record that should be printed. + * + */ +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc); + +/** + * @} + */ + +#endif // NFC_NDEF_RECORD_PARSER_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.c b/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.c new file mode 100644 index 00000000..c5d8b4b5 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nfc_text_rec.h" +#include "nrf_error.h" + +#define TEXT_REC_STATUS_SIZE 1 ///< Size of the status. +#define TEXT_REC_STATUS_UTF_POS 7 ///< Position of a character encoding type. +#define TEXT_REC_RESERVED_POS 6 ///< Reserved position. + +const uint8_t nfc_text_rec_type_field[] = {'T'}; + + +/** + * @brief Function for calculating payload size. + */ +__STATIC_INLINE uint32_t nfc_text_rec_payload_size_get(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc) +{ + return (TEXT_REC_STATUS_SIZE + + p_nfc_rec_text_payload_desc->lang_code_len + + p_nfc_rec_text_payload_desc->data_len); +} + +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + if ((p_nfc_rec_text_payload_desc->lang_code_len == 0) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_RESERVED_POS)) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_STATUS_UTF_POS)) + || (p_nfc_rec_text_payload_desc->p_lang_code == NULL) + || (p_nfc_rec_text_payload_desc->data_len == 0) + || (p_nfc_rec_text_payload_desc->p_data == NULL) + || (p_buff == NULL) + || (p_len == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t payload_size = nfc_text_rec_payload_size_get(p_nfc_rec_text_payload_desc); + + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff = (p_nfc_rec_text_payload_desc->lang_code_len + + (p_nfc_rec_text_payload_desc->utf << TEXT_REC_STATUS_UTF_POS)); + p_buff += TEXT_REC_STATUS_SIZE; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_lang_code, + p_nfc_rec_text_payload_desc->lang_code_len); + p_buff += p_nfc_rec_text_payload_desc->lang_code_len; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_data, + p_nfc_rec_text_payload_desc->data_len); + *p_len = payload_size; + + return NRF_SUCCESS; +} + + diff --git a/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.h b/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.h new file mode 100644 index 00000000..766ac307 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/text/nfc_text_rec.h @@ -0,0 +1,141 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_TEXT_REC_H__ +#define NFC_TEXT_REC_H__ + +/**@file + * + * @defgroup nfc_text_rec Text records + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF Text record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +typedef enum{ + UTF_8 = 0, + UTF_16 = 1, + } UTF; + +/** + * @brief Text record payload descriptor. + */ +typedef struct +{ + // enum{ + // UTF_8 = 0, + // UTF_16 = 1, + // } utf; ///< Type of the Unicode Transformation Format. + + UTF utf; + + uint8_t const * p_lang_code; ///< Pointer to the IANA language code. + uint8_t lang_code_len; ///< Length of the IANA language code. + + uint8_t const * p_data; ///< Pointer to the user text. + uint32_t data_len; ///< Length of the user text. +} nfc_text_rec_payload_desc_t; + +/** + * @brief Constructor for an NFC NDEF Text record payload. + * + * @param[in] p_nfc_rec_text_payload_desc Pointer to the Text record description. + * @param[out] p_buff Pointer to the payload destination. + * + * @param[in,out] p_len Size of the available memory to write as input. + * Size of the generated record payload as output. + */ +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_text_rec_type_field[]; + +/** + * @brief Size of the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +#define NFC_TEXT_REC_TYPE_LENGTH 1 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for an Text record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_text_rec_payload_desc_t, which together constitute + * an instance of an Text record. + * + * Use the macro @ref NFC_NDEF_TEXT_RECORD_DESC to access the NDEF Text record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] UTF Unicode Transformation Format. + * @param[in] P_LANG_CODE Pointer to the IANA language code. + * @param[in] LANG_CODE_LEN Length of the IANA language code. + * @param[in] P_DATA Pointer to the user text. + * @param[in] DATA_LEN Length of the user text. + */ +#define NFC_NDEF_TEXT_RECORD_DESC_DEF(NAME, \ + UTF, \ + P_LANG_CODE, \ + LANG_CODE_LEN, \ + P_DATA, \ + DATA_LEN) \ + static nfc_text_rec_payload_desc_t NAME##_nfc_text_rec_payload_desc; \ + NAME##_nfc_text_rec_payload_desc = (nfc_text_rec_payload_desc_t) \ + { \ + .utf = UTF, \ + .p_lang_code = P_LANG_CODE, \ + .lang_code_len = LANG_CODE_LEN, \ + .p_data = P_DATA, \ + .data_len = DATA_LEN, \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_text_rec_type_field, \ + NFC_TEXT_REC_TYPE_LENGTH, \ + nfc_text_rec_payload_constructor, \ + &(NAME##_nfc_text_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Text record descriptor + * instance that was created with @ref NFC_NDEF_TEXT_RECORD_DESC_DEF. + */ +#define NFC_NDEF_TEXT_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ +#endif // NFC_TEXT_REC_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.c b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.c new file mode 100644 index 00000000..8d3bb62a --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.c @@ -0,0 +1,114 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nfc_uri_msg.h" + +/** @brief Function for generating a description of an NFC NDEF URI message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and NFC NDEF records descriptions. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * This string should not contain the protocol field if the protocol + * was specified in @p uri_id_code + * @param[in] uri_data_len Length of the URI string. + * @param[out] pp_uri_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + */ +static ret_code_t nfc_uri_msg_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + nfc_ndef_msg_desc_t ** pp_uri_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_uri_rec; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_uri_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_uri_msg)); + + if(p_uri_data != NULL) + { + /* Create NFC NDEF URI Record description */ + p_uri_rec = nfc_uri_rec_declare(uri_id_code, + p_uri_data, + uri_data_len); + + /* Add URI record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_uri_msg), p_uri_rec); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_uri_msg_desc = &NFC_NDEF_MSG(nfc_uri_msg); + + return NRF_SUCCESS; +} + +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + nfc_ndef_msg_desc_t * p_uri_msg_desc; + + /* Create NFC NDEF message description with URI record */ + err_code = nfc_uri_msg_declare( uri_id_code, + p_uri_data, + uri_data_len, + &p_uri_msg_desc); + + if(err_code != NRF_SUCCESS) + { + return err_code; + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_uri_msg_desc, + p_buf, + p_len); + + return err_code; +} diff --git a/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.h b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.h new file mode 100644 index 00000000..2f566861 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_msg.h @@ -0,0 +1,76 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_URI_MSG_H__ +#define NFC_URI_MSG_H__ + +/**@file + * + * @defgroup nfc_uri_msg URI messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages with a URI record. + * + */ + +#include "nfc_ndef_msg.h" +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +/** @brief Function for encoding an NFC NDEF URI message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode. + */ +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ +#endif // NFC_URI_MSG_H__ diff --git a/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.c b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.c new file mode 100644 index 00000000..9d171137 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +/** + * @brief Type of description of the payload of a URI record. + */ +typedef struct +{ + nfc_uri_id_t uri_id_code; ///< URI identifier code. + uint8_t const * p_uri_data; ///< Pointer to a URI string. + uint8_t uri_data_len; ///< Length of the URI string. +} uri_payload_desc_t; + +/** + * @brief Function for constructing the payload for a URI record. + * + * This function encodes the payload according to the URI record definition. It implements an API + * compatible with @ref p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space. + */ +static ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + /* Verify if there is enough available memory */ + if(p_input->uri_data_len >= *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Copy descriptor content into the buffer */ + *p_len = p_input->uri_data_len + 1; + *(p_buff++) = p_input->uri_id_code; + memcpy(p_buff, p_input->p_uri_data, p_input->uri_data_len ); + + return NRF_SUCCESS; +} + +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len) +{ + static uri_payload_desc_t uri_payload_desc; + static const uint8_t static_uri_type = 'U'; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( uri_rec, + TNF_WELL_KNOWN, // tnf <- well-known + NULL, + 0, // no id + &static_uri_type, + 1, // type size 1B + nfc_uri_payload_constructor, + &uri_payload_desc); + + uri_payload_desc.uri_id_code = uri_id_code; + uri_payload_desc.p_uri_data = p_uri_data; + uri_payload_desc.uri_data_len = uri_data_len; + + return &NFC_NDEF_GENERIC_RECORD_DESC( uri_rec); +} + diff --git a/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.h b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.h new file mode 100644 index 00000000..3f801c9a --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/ndef/uri/nfc_uri_rec.h @@ -0,0 +1,113 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_URI_REC_H__ +#define NFC_URI_REC_H__ + +/**@file + * + * @defgroup nfc_uri_rec URI records + * @{ + * @ingroup nfc_uri_msg + * + * @brief Generation of NFC NDEF URI record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +/** + * @enum nfc_uri_id_t + * @brief URI identifier codes according to "URI Record Type Definition" + * (denotation "NFCForum-TS-RTD_URI_1.0" published on 2006-07-24) chapter 3.2.2. + */ +typedef enum +{ + NFC_URI_NONE = 0x00, /**< No prepending is done. */ + NFC_URI_HTTP_WWW = 0x01, /**< "http://www./" */ + NFC_URI_HTTPS_WWW = 0x02, /**< "https://www./" */ + NFC_URI_HTTP = 0x03, /**< "http:" */ + NFC_URI_HTTPS = 0x04, /**< "https:" */ + NFC_URI_TEL = 0x05, /**< "tel:" */ + NFC_URI_MAILTO = 0x06, /**< "mailto:" */ + NFC_URI_FTP_ANONYMOUS = 0x07, /**< "ftp://anonymous:anonymous@" */ + NFC_URI_FTP_FTP = 0x08, /**< "ftp://ftp." */ + NFC_URI_FTPS = 0x09, /**< "ftps://" */ + NFC_URI_SFTP = 0x0A, /**< "sftp://" */ + NFC_URI_SMB = 0x0B, /**< "smb://" */ + NFC_URI_NFS = 0x0C, /**< "nfs://" */ + NFC_URI_FTP = 0x0D, /**< "ftp://" */ + NFC_URI_DAV = 0x0E, /**< "dav://" */ + NFC_URI_NEWS = 0x0F, /**< "news:" */ + NFC_URI_TELNET = 0x10, /**< "telnet://" */ + NFC_URI_IMAP = 0x11, /**< "imap:" */ + NFC_URI_RTSP = 0x12, /**< "rtsp://" */ + NFC_URI_URN = 0x13, /**< "urn:" */ + NFC_URI_POP = 0x14, /**< "pop:" */ + NFC_URI_SIP = 0x15, /**< "sip:" */ + NFC_URI_SIPS = 0x16, /**< "sips:" */ + NFC_URI_TFTP = 0x17, /**< "tftp:" */ + NFC_URI_BTSPP = 0x18, /**< "btspp://" */ + NFC_URI_BTL2CAP = 0x19, /**< "btl2cap://" */ + NFC_URI_BTGOEP = 0x1A, /**< "btgoep://" */ + NFC_URI_TCPOBEX = 0x1B, /**< "tcpobex://" */ + NFC_URI_IRDAOBEX = 0x1C, /**< "irdaobex://" */ + NFC_URI_FILE = 0x1D, /**< "file://" */ + NFC_URI_URN_EPC_ID = 0x1E, /**< "urn:epc:id:" */ + NFC_URI_URN_EPC_TAG = 0x1F, /**< "urn:epc:tag:" */ + NFC_URI_URN_EPC_PAT = 0x20, /**< "urn:epc:pat:" */ + NFC_URI_URN_EPC_RAW = 0x21, /**< "urn:epc:raw:" */ + NFC_URI_URN_EPC = 0x22, /**< "urn:epc:" */ + NFC_URI_URN_NFC = 0x23, /**< "urn:nfc:" */ + NFC_URI_RFU = 0xFF /**< No prepending is done. Reserved for future use. */ +} nfc_uri_id_t; + +/** @brief Function for generating a description of a URI record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a URI record. + * + * @note The record payload data (@p uri_id_code, @p p_uri_data, and @p + * uri_data_len) should be declared as static. If it is declared as + * automatic, the NDEF message encoding (see @ref nfc_uri_msg_encode) + * must be done in the same variable scope. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len); +/** @} */ +#endif // NFC_URI_REC_H__ diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c new file mode 100644 index 00000000..b0a11527 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c @@ -0,0 +1,876 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 "hal_nfc_t2t.h" +#include +#include +#include "nfc_t2t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "hal_nfc_t2t_logger.h" +#include "nrf_drv_clock.h" + + +// Pin for debug signals +#define HCLOCK_ON_PIN 11 +#define HCLOCK_OFF_PIN 12 +#define NFC_EVENT_PIN 24 +#define DETECT_EVENT_PIN 25 +#define TIMER4_EVENT_PIN 28 + +#ifdef HAL_NFC_DEBUG_PIN_ENABLE + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + HAL_NFC_DEBUG_PIN_CONFIG(HCLOCK_OFF_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HCLOCK_ON_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(NFC_EVENT_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(NFC_EVENT_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(DETECT_EVENT_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(DETECT_EVENT_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(TIMER4_EVENT_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN) + + +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_DEBUG_PIN_ENABLE + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit) + * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit) + * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode + */ + +#define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */ +#define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */ +#define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */ +#define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */ +#define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */ +#define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */ +#define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ + +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ + +#define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */ +#define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ + +#define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk ///< Mask for checking FIELDPRESENT register for state: FIELD ON. +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk ///< Mask for checking FIELDPRESENT register for state: FIELD OFF. + +typedef enum +{ + NFC_FIELD_STATE_NONE, ///< Initial value indicating no NFCT Field events. + NFC_FIELD_STATE_OFF, ///< NFCT FIELDLOST Event has been set. + NFC_FIELD_STATE_ON, ///< NFCT FIELDDETECTED Event has been set. + NFC_FIELD_STATE_UNKNOWN ///< Both NFCT Field Events have been set - ambiguous state. +}nfct_field_sense_state_t; + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND +/* Begin: Bugfix for FTPAN-57 (IC-9563) */ +#define NRF_NFCT_SHUNTREGTHRESHOLDS (*(uint32_t volatile *)(0x40005610)) +#define NRF_NFCT_MODSTEPFIXED (*(uint32_t volatile *)(0x40005614)) +#define NRF_NFCT_MODSTEPMULTIPLIER (*(uint32_t volatile *)(0x40005618)) +#define NRF_NFCT_INITIALLOADCTRLVAL (*(uint32_t volatile *)(0x40005688)) +/* End: Bugfix for FTPAN-57 (IC-9563) */ + +/* Begin: Bugfix for FTPAN-24 */ +#define NRF_NFCT_AUTOCOLRESSTATUS (*(uint32_t volatile *)(0x40005408)) +/* End: Bugfix for FTPAN-24 */ + +/* Begin: Bugfix for FTPAN-27 */ +#define NRF_NFCT_TASKS_DISABLERXDATA (*(uint32_t volatile *)(0x40005020)) +/* End: Bugfix for FTPAN-27 */ + +/* Begin: Bugfix for FTPAN-17 */ +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) \ + |(NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#define NFC_HAL_FIELDPRESENT_NO_FIELD (NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) +/* End: Bugfix for FTPAN-17*/ + +static void hal_nfc_field_check(void); +#endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); + +/* Static data */ +static hal_nfc_callback m_nfc_lib_callback = (hal_nfc_callback) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) \ + |(NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) +#endif + + +#if defined(HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND) || defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) +static void field_timer_with_callback_config() +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; + NRF_TIMER4->CC[0] = 100 << TIMER_CC_CC_Pos; + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(TIMER4_IRQn); +} + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(TIMER4_EVENT_PIN); + hal_nfc_field_check(); + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN); +} +#endif + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND +/* Begin: Bugfix for FTPAN-45 (IC-6915) */ +volatile uint8_t m_nfc_active = 0; +/* End: Bugfix for FTPAN-45 (IC-6915) */ + +/* Begin: Bugfix for FTPAN-17 (IC-9563) */ +/* The following three function definitions are a workaround for IC-9563: NFC in nRF52 IC rev. Engineering A does not + * give the field lost signal when field is turned off. */ + +static bool field_on = false; +volatile bool hal_nfc_fielddetected = false; +volatile bool hal_nfc_fieldlost = false; + +static void hal_nfc_field_check(void) +{ + static uint32_t field_state_cnt = 0; + volatile uint32_t dummy; + uint32_t nfc_fieldpresen_masked; + + /* Begin: Bugfix for FTPAN-24 */ + NRF_NFCT_AUTOCOLRESSTATUS = 0; /* dummy write - no effect. */ + NRF_NFCT_AUTOCOLRESSTATUS = 0; /* dummy write - no effect. */ + // Don't worry about interrupted case - NRF_NFCT->FIELDPRESENT is read each 100 us, so the workaround should succeed most of the times. + /* End: Bugfix for FTPAN-24 */ + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (field_on) + { + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + field_state_cnt = 0; + hal_nfc_fieldlost = true; + dummy = hal_nfc_fieldlost; + field_on = false; + NVIC_SetPendingIRQ(NFCT_IRQn); + UNUSED_VARIABLE(dummy); + } + + return; + } + } + else + { + nfc_fieldpresen_masked &= NFCT_FIELDPRESENT_FIELDPRESENT_Msk; + if (nfc_fieldpresen_masked != NFC_HAL_FIELDPRESENT_NO_FIELD) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + field_state_cnt = 0; + hal_nfc_fielddetected = true; + dummy = hal_nfc_fielddetected; + field_on = true; + NVIC_SetPendingIRQ(NFCT_IRQn); + UNUSED_VARIABLE(dummy); + } + + return; + } + } + + field_state_cnt = 0; +} +/* End: Bugfix for FTPAN-17, FTPAN-27 */ +#endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#else +static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#endif +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + +/* Begin: Bugfix for FTPAN-17 */ +/* fixed by avoiding usage of FIELDLOST and FIELDETECTED events */ +#ifndef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + #ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); + #else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); + #endif +#endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND +/* End: Bugfix for FTPAN-17 */ + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-45 (IC-6915) */ + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMESTART_Enabled << NFCT_INTENSET_RXFRAMESTART_Pos) | + (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos); + /* End: Bugfix for FTPAN-45 (IC-6915) */ +#endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + + /* According to ISO/IEC 14443-3 */ + nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); //SN0 + nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); //SN1 + nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); //SN2 + nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]); //BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2 + nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); //SN3 + nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); //SN4 + nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); //SN5 + nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); //SN6 + nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]); //BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6 + nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); //For internal use + + + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + + NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT); + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ +} + + +hal_nfc_retval hal_nfc_setup(hal_nfc_callback callback, void *cbContext) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + m_nfc_lib_callback = callback; + m_nfc_lib_context = cbContext; + + hal_nfc_common_hw_setup(nfc_internal); + + (void) nfcSetInternal((char *) nfc_internal, sizeof(nfc_internal)); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-57 (IC-9563) */ + /* Values taken from IC-9563 */ + NRF_NFCT_SHUNTREGTHRESHOLDS = 0x00000005; + NRF_NFCT_MODSTEPFIXED = 0x0000003F; + NRF_NFCT_MODSTEPMULTIPLIER = 0x00000001; + NRF_NFCT_INITIALLOADCTRLVAL = 0x00000001; + /* End: Bugfix for FTPAN-57 (IC-9563) */ + + /* Begin: Bugfix for FTPAN-17 (IC-9563) */ + /* Activating workaround. */ + field_timer_with_callback_config(); + NRF_TIMER4->TASKS_START = 1; + /* End: Bugfix for FTPAN-17 (IC-9563) */ +#endif // HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + field_timer_with_callback_config(); +#endif + + LOG_HAL_NFC("[NFC_HAL]: initialize\r\n"); + + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == MODULE_ALREADY_INITIALIZED)) + { + return HAL_NFC_RETVAL_OK; + } + else + { + return HAL_NFC_RETVAL_ERROR; + } +} + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch(event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG! + NRF_NFCT->TASKS_ACTIVATE = 1; + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch(field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HCLOCK_OFF_PIN); //DEBUG! + + NRF_NFCT->TASKS_SENSE = 1; + + + nrf_drv_clock_hfclk_release(); + + //NRF_NFCT->TASKS_SENSE = 1; + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif + +/* This function is used by nfc_lib for unit testing only */ +hal_nfc_retval hal_nfc_set_parameter(hal_nfc_param_id id, void *data, size_t dataLength) +{ + (void)id; + (void)data; + (void)dataLength; + + return HAL_NFC_RETVAL_OK; +} + +/* This function is used by nfc_lib for unit testing only */ +hal_nfc_retval hal_nfc_get_parameter(hal_nfc_param_id id, void *data, size_t *maxDataLength) +{ + (void)id; + (void)data; + (void)maxDataLength; + + return HAL_NFC_RETVAL_OK; +} + + +hal_nfc_retval hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_NFCT->TASKS_SENSE = 1; + + LOG_HAL_NFC("[NFC_HAL]: start\r\n"); + + return HAL_NFC_RETVAL_OK; +} + +hal_nfc_retval hal_nfc_send(const char *data, size_t dataLength) +{ + if (dataLength == 0) + { + return HAL_NFC_RETVAL_INVALID_SIZE; + } + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->PACKETPTR = (uint32_t) data; + NRF_NFCT->TXD.AMOUNT = (dataLength << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->TASKS_STARTTX = 1; + + LOG_HAL_NFC("[NFC_HAL]: send\r\n"); + + return HAL_NFC_RETVAL_OK; +} + +hal_nfc_retval hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + LOG_HAL_NFC("[NFC_HAL]: stop\r\n"); + + return HAL_NFC_RETVAL_OK; +} + +hal_nfc_retval hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback) NULL; + + return HAL_NFC_RETVAL_OK; +} + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(NFC_EVENT_PIN); //DEBUG! + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-27 */ + if (hal_nfc_fielddetected) + { + hal_nfc_fielddetected = false; + NRF_NFCT_TASKS_DISABLERXDATA = 1; + /* End: Bugfix for FTPAN-27 */ +#else + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); +#endif + HAL_NFC_DEBUG_PIN_SET(DETECT_EVENT_PIN); //DEBUG! + current_field = NFC_FIELD_STATE_ON; + + LOG_HAL_NFC("[NFC_HAL]: fielddetected\r\n"); + HAL_NFC_DEBUG_PIN_CLEAR(DETECT_EVENT_PIN); //DEBUG! + } + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-27 */ + if (hal_nfc_fieldlost) + { + hal_nfc_fieldlost = false; + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_NFCT->TASKS_SENSE = 1; + + LOG_HAL_NFC("[NFC_HAL]: fieldlost\r\n"); + } + /* End: Bugfix for FTPAN-27 */ +#elif !defined( HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND ) + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + LOG_HAL_NFC("[NFC_HAL]: fieldlost\r\n"); + } +#endif + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + /* Look for Tag 2 Type READ Command */ + if (m_nfc_rx_buffer[0] == T2T_READ_CMD) + { + if(m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + /*(void*)*/(char *) m_nfc_rx_buffer, + rx_data_size); + } + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if(m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + } + /* Not a READ Command, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-45 (IC-6915) */ + m_nfc_active = 0; + /* End: Bugfix for FTPAN-45 (IC-69150) */ +#endif + LOG_HAL_NFC("[NFC_HAL]: rx_fend\r\n"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-45 (IC-6915) */ + m_nfc_active = 0; + /* End: Bugfix for FTPAN-45 (IC-6915) */ +#endif + LOG_HAL_NFC("[NFC_HAL]: tx_fend\r\n"); + } + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + /* Begin: Bugfix for FTPAN-45 (IC-6915) */ + if (NRF_NFCT->EVENTS_RXFRAMESTART) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMESTART); + + if (m_nfc_active == 0) + { + m_nfc_active = 1; + } + LOG_HAL_NFC("[NFC_HAL]: rx_fstart\r\n"); + } + if (NRF_NFCT->EVENTS_TXFRAMESTART) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + + if (m_nfc_active == 0) + { + m_nfc_active = 1; + } + LOG_HAL_NFC("[NFC_HAL]: tx_fstart\r\n"); + } + /* End: Bugfix for FTPAN-45 (IC-6915) */ +#endif + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + LOG_HAL_NFC("[NFC_HAL]: selected\r\n"); + } + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + LOG_HAL_NFC("[NFC_HAL]: rxerror (0x%x)\r\n", (unsigned int) rx_status); + (void) rx_status; + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + LOG_HAL_NFC("[NFC_HAL]: error (SLP_REQ)\r\n"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + if (err_status) + { + LOG_HAL_NFC("[NFC_HAL]: error (0x%x)\r\n", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + HAL_NFC_DEBUG_PIN_CLEAR(NFC_EVENT_PIN); //DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HCLOCK_OFF_PIN); //DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + /* Begin: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */ + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* END: Bugfix for FTPAN-XX (IC-XXXX) NFCT won't release HFCLK */ + + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_OFF_PIN); //DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HCLOCK_ON_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HCLOCK_ON_PIN); //DEBUG! + } + m_field_on = true; +} + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + hal_nfc_common_hw_setup(nfc_internal); + + LOG_HAL_NFC("[NFC_HAL]: reinitialize\r\n"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h new file mode 100644 index 00000000..1f04a648 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h @@ -0,0 +1,173 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_hal NFC Type 2 Tag HAL + * @{ + * @ingroup nfc_library + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 2 Tag library. + * + */ + +#include +#include /* Accessing the size_t type */ + +/** @brief Return values generated by HAL_NFC functions. */ +typedef enum { + HAL_NFC_RETVAL_OK, + HAL_NFC_RETVAL_ERROR, + HAL_NFC_RETVAL_INVALID_SIZE, + HAL_NFC_RETVAL_TIMEOUT +} hal_nfc_retval; + +/** @brief Events passed to upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, + HAL_NFC_EVENT_FIELD_OFF, + HAL_NFC_EVENT_DATA_RECEIVED, + HAL_NFC_EVENT_DATA_TRANSMITTED +} hal_nfc_event; + +/** @brief Parameter IDs for set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id; + + +/** \brief Callback from HAL_NFC layer into upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * data points to the transmitted packet. The memory belongs to the application. + * + * If event == \: + * data definition is event-specific (to be defined). + * + * \param context Context for callback execution. + * \param event The event that occurred. + * \param data Received/transmitted data or NULL. + * \param dataLength Size of the received/transmitted packet. + */ +typedef void (*hal_nfc_callback)(void *context, hal_nfc_event event, const char *data, size_t dataLength); + +/** \brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * \param callback Pointer to the callback function. + * \param cbContext Context of callback. + * + * \retval OK If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +hal_nfc_retval hal_nfc_setup(hal_nfc_callback callback, void *cbContext); + +/** \brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * \param id ID of the parameter to set. + * \param data Pointer to a buffer containing the data to set. + * \param dataLength Size of the buffer containing the data to set. + * + * \retval OK If the parameter was set successfully. If one of the arguments + * was invalid (for example, a wrong data length), an error code + * is returned. + */ +hal_nfc_retval hal_nfc_set_parameter(hal_nfc_param_id id, void *data, size_t dataLength); + + +/** \brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, maxDataLength will contain the required buffer size. + * + * \param id ID of the parameter to query. + * \param data Pointer to a buffer receiving the queried data. + * \param maxDataLength Size of the buffer, receives needed size if buffer is too small. + * + * \retval OK If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +hal_nfc_retval hal_nfc_get_parameter(hal_nfc_param_id id, void *data, size_t *maxDataLength); + +/** \brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * \retval OK If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +hal_nfc_retval hal_nfc_start(void); + + +/** \brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * \param data The data packet to send. + * \param dataLength Size of the packet in bytes. + * + * \retval OK If the packet was sent. Otherwise, an error code is returned. + */ +hal_nfc_retval hal_nfc_send(const char *data, size_t dataLength); + +/** \brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * \retval OK If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +hal_nfc_retval hal_nfc_stop(void); + +/** \brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * \retval OK This function always succeeds. + */ +hal_nfc_retval hal_nfc_done(void); + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t_logger.h b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t_logger.h new file mode 100644 index 00000000..4207de5d --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t_logger.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 HAL_NFC_LOGGER_H__ +#define HAL_NFC_LOGGER_H__ + +#include "nrf_log.h" + +#define LOG_HAL_NFC(...) NRF_LOG_PRINTF(__VA_ARGS__) + +#endif // HAL_NFC_LOGGER_H__ diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/licence_agreement.txt b/cores/nRF5/SDK/components/nfc/t2t_lib/licence_agreement.txt new file mode 100644 index 00000000..e1d177ee --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/licence_agreement.txt @@ -0,0 +1,36 @@ +Copyright (c) 2010 - 2017, 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. \ No newline at end of file diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_fixes.h b/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_fixes.h new file mode 100644 index 00000000..d637c462 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_fixes.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include + +/** @file + * @defgroup nfc_fixes NFC fixes + * @{ + * @ingroup nfc_library + * @brief @tagAPI52 Fixes for HW anomaly. + * + * If you are using PCA10036 (part of nRF52 Preview Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND to apply + * workarounds for the following anomalies: + * - 17. NFCT: The EVENTS_FIELDLOST is not generated + * - 24. NFCT: The FIELDPRESENT register read is not reliable + * - 27. NFCT: Triggering NFCT ACTIVATE task also activates the Rx easyDMA + * - 45. NFCT: EasyDMA does not function properly while System ON CPU IDLE state + * - 57. NFCT: NFC Modulation amplitude + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost + * - NFCT does not release HFCLK when switching from ACTVATED to SENSE mode. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10036 // assume nRF52832 chip in IC rev. Engineering A + #define HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10040) // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#endif + +/* Begin: Bugfix for FTPAN-45 */ +#ifdef HAL_NFC_ENGINEERING_A_FTPAN_WORKAROUND + extern volatile uint8_t m_nfc_active; + #define NFC_NEED_MCU_RUN_STATE() (m_nfc_active != 0) +#else + #define NFC_NEED_MCU_RUN_STATE() (0) +#endif +/* End: Bugfix for FTPAN-45 */ + +/** @} */ +#endif /* NFC_FIXES_H__ */ + diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib.h b/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib.h new file mode 100644 index 00000000..d2988e9b --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2010 - 2017, 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 + * + * @addtogroup nfc_api + * + * @defgroup nfc_library NFC Type 2 Tag + * @ingroup nfc_api + * @brief @tagAPI52 Implementation of NFC Type 2 Tag. + * + * @defgroup nfc_lib NFC Type 2 Tag library + * @{ + * @ingroup nfc_library + * @brief @tagAPI52 Type 2 Tag library. + */ + +#ifndef NFC_LIB_H +#define NFC_LIB_H + +#include + +#define NFC_SIZEOF_INTERNAL_BYTES 10 +#define NFC_MAX_PAYLOAD_SIZE 988 +#define NFC_MAX_PAYLOAD_SIZE_RAW 1008 /* No NDEF-TLV and no implicit lock bytes at the end */ + +/** @brief Return values generated by NFC_LIB functions. */ +typedef enum +{ + NFC_RETVAL_OK, + NFC_RETVAL_ERROR, + NFC_RETVAL_INVALID_STATE, + NFC_RETVAL_INVALID_SIZE, + NFC_RETVAL_INVALID_ARGUMENT +} NfcRetval; + +/** @brief Events passed to the callback function. */ +typedef enum +{ + NFC_EVENT_NONE, + NFC_EVENT_FIELD_ON, + NFC_EVENT_FIELD_OFF, + NFC_EVENT_DATA_READ, + NFC_EVENT_STOPPED +} NfcEvent; + +typedef enum +{ + NFC_PARAM_TESTING /* Used for unit tests */ +} NfcParamId; + +/** \brief Callback to pass events from NFCLib to application. + * + * \param context Application context for callback execution. + * \param event The event that occurred. + * \param data Data to send to the application (event specific). + * \param dataLength Length of the data. + */ +typedef void (*NfcCallbackFunction) (void *context, NfcEvent event, const char *data, size_t dataLength); + +/** \brief Function for registering the application callback for event signaling. + * + * The callback will be called by NFCLib to notify the application of relevant + * events. It will be called from the HAL_NFC callback context. + * + * \param callback Function pointer to the callback. + * \param cbContext Pointer to a memory area used by the callback for execution (optional). + * + * \retval OK If the application callback was registered successfully. If one + * of the arguments was invalid, an error code is returned. + */ +NfcRetval nfcSetup (NfcCallbackFunction callback, void *cbContext); + +/** \brief Function for setting an NFC parameter. + * + * \note Not implemented. For future use. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * \param id ID of the parameter to set. + * \param data Pointer to a buffer containing the data to set. + * \param dataLength Size of the buffer containing the data to set. + * + * \retval OK If the parameter was set successfully. If one of the arguments + * was invalid (for example, a wrong data length), an error code + * is returned. + */ +NfcRetval nfcSetParameter (NfcParamId id, void *data, size_t dataLength); + +/** \brief Function for querying an NFC parameter value. + * + * \note Not implemented. For future use. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, maxDataLength will contain the required buffer size. If the + * buffer is big enough, maxDataLength will contain the actual size of the + * data. + * + * \param id ID of the parameter to query. + * \param data Pointer to a buffer receiving the queried data. + * \param maxDataLength Size of the buffer, receives actual size of queried data. + * + * \retval OK If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +NfcRetval nfcGetParameter (NfcParamId id, void *data, size_t *maxDataLength); + +/** \brief Function for registering the payload to send on reception of a READ request. + * + * The payload is considered to only contain the NDEF message to deliver to a + * reader. The required NDEF TLV will be created implicitly by NFCLib. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If the pointer is not NULL, but the length is zero, the paypload is + * considered to be an empty NDEF message. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * \param payload Pointer to the memory area containing the payload to send. + * \param payloadLength Size of the payload in bytes. + * + * \retval OK If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +NfcRetval nfcSetPayload (const char *payload, size_t payloadLength); + +/** \brief Function for registering the raw payload to send on reception of a READ request. + * + * The payload will be delivered directly as-is to the reader, without + * implicitly adding an NDEF TLV container. This can be used if the + * application wants to define the TLVs itself, for example, to provide a different + * memory layout. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload, without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * \param payload Pointer to the memory area containing the payload to send. + * \param payloadLength Size of the payload in bytes. + * + * \retval OK If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +NfcRetval nfcSetPayloadRaw (const char *payload, size_t payloadLength); + +/** \brief Function for registering the sequence of internal bytes. + * + * This refers to the first 10 bytes of the tag memory. The library will set + * a sensible default for these bytes. The application can use this function + * to override the default. + * + * Passing a NULL pointer reverts back to the default sequence. + * The data will be copied by NFCLib, so the memory does not have to remain valid + * after the function returns. + * + * \note When modifying the internal bytes, remember that they must be consistent + * with the NFC hardware register settings (see @ref nfc_t2t_format_internal). + * + * \param data Pointer to the memory area containing the data. + * \param dataLength Size of the data in bytes. + * + * \retval OK If the operation was successful. If the data was not NULL and the + * data length was not 10, an error code is returned. + */ +NfcRetval nfcSetInternal (const char *data, size_t dataLength); + +/** \brief Function for activating the NFC frontend. + * + * You must call this function so that events are posted to the application + * callback. + * + * \retval OK If the NFC frontend was activated successfully. If the lower layer + * could not be started, an error code is returned. + */ +NfcRetval nfcStartEmulation (void); + +/** \brief Function for deactivating the NFC frontend. + * + * After calling this function, no more events will be posted to the + * application callback. + * + * \retval OK If the NFC frontend was deactivated successfully. If the lower layer + * could not be stopped, an error code is returned. + */ +NfcRetval nfcStopEmulation (void); + +/** \brief Function for releasing the reference to the application callback. + * + * After calling this function, the passed callback pointer is no longer + * considered valid. + * + * \retval OK This function always succeeds. + */ +NfcRetval nfcDone (void); + +#endif /* NFC_LIB_H */ + +/** @} */ diff --git a/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a b/cores/nRF5/SDK/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a new file mode 100644 index 0000000000000000000000000000000000000000..a5d8ad1a6954e27587fae629fbbd5a9c75e2d1fe GIT binary patch literal 5566 zcma)AeQX@X6`$GN`|vrj_s%Z0oe%bWj$`NWpgy4F%5(tkk?)^K$>Sxorrj>zXBY;j zpzD-8p{Y4JliM+Qa6--{Q&YMnl`b=gsVM~=`zDfOp_DP*>&-F}4)^r*2ts$XC#J8< zsOP~QLlUJFCaDW0ZN$1;6V&N#;{=vC_U8IE@ zBcn`U`ne%4ND3d!ID&=z6UBt^L@^oW{7?1y(-%QMAdpQL@^zAuIFVreCkJR?ws;_n zEP-h*_)pald_!e}ujjddk_e6q%B4!1v+XM&IB{nHP9fop#_|5%aEd?h)u^c{zz`TKoM=|2{J zF!NNB-*&8zy!*YGbBW2OHj($QT>WTeWa%9H*Gn(c-z~GXblK&&cQ>v9zp!2$DbSi9 z!dNxe99Q`zmxEJM8C2Oeeu2Bh*3gYV1(fR= z{U5*N)cQHeBVf5j>$iJ7X(xqW&bXHu>Mg9$4wY@U_2XUFoL9U{4#KJaB?pCmd`x0s zy!3ipqodG|)%tm%U#%JtY3t*Fab6>~Ua&@dSnD+lv%%f!mcr5okpvDy9AFEZyNEs- zh%9#Qb}q+UF^Ty3W?Ywl6zd-y-ZA{zy^VjqROPG<(d8BzlZMYlCG>6)ho!$P^UkM} z8+M)Q^DXR6^2vPSQq#+qNY&hqwzG3mOllN&Y1rqX|FAeBM%8~OPxaL-+_mP}zP7WS z(vJbt1mmp}ZxoReae^8+aH_9*;hr_~fawOrCTT_6r$cKti(WM*MWF|xt9GtmchVnl-{}GeB%&iB86;a^NdhD!wKmDHu%0uf>-mbv|6IA z+;R)?4#r14&A%9JO~17f$MCkU1ZtZf*x;9{cg_|=ux6W~gwwOd$mnb_x@Wf7DIku7 z8_rT-C1=fXv2L7m&o}*^72Mir7S0VgKlthrYd+CCcjdkZ=>iK87M{C#IB3MpK-`5t zVAR(j>Y_@6cji5Tu3eqGS?xR>pAM!;+g_CoeAIrV*cC2}M&!Spt`_?iJf0)PExkvI zJ;F*$eKRLCh%;`lICA-cLnD`G;)jb#@+KiE#4o|6bnK}{kc0ME$0ZvHo;bMXuE*>Blu~XutcNcxl zjPR#LCg?u9I`Fjmmn?*k0kknCLR%Lz+MkSoISAJZ+u-Gki zNpIQa*D&X4rz-Ao?XEhQofk5*7Vgp2u&>p5ex8%+(hOwe_Bp@g(as|g_%jUPxj|hQ zB;J;9?)g<34`w)pOmUxKgC9ViybpX=RVH{P&j#w!YhiN9)lbDx*&#HwR(;Q zYcv)nP&J5aTP>3C@#(rW=DGWfEASrdex$&Df(BHpJXdBr5CE<=#Y9cG_Pi2JLZXXtQOpYnz$R*WtkUHi6njAi7hctXf1hmu+NsteI*BpMCh zLvF*{MONgoB%vW_I{H(YoHE@p+(n$LUBgw3$LZth>F4O@*#_E3o9G(4mab=-DG6oo zpUlaSi`iU8uM=hq2y!GeF6U$t8p~!$2m%YCF_e%ecJGh(%M%l0a{L=MhyIFz=ZuBb zP1ZxE%v1KnDf8GKJJ+$}v!~KkdH|I>%AZ0NKKrAn%%we#aONSH13Zynv=pueER~#7 zCgpe{3GXMx=;p?n%H44BGsKQspe9|r~HCMfz7PgBXmb%fjr&Gk?a zg9XPMgkt9lLjcoYGsWcF0R}tY1>kD~8}i{An0$9b+s=0q_|}5W6q65QvGc8}*W*Dx zjLYOZ1Z_LtE7#%6RPfc?`0&YZ@;zF?_a^XhIDjE$d=Gw~a zeD$zdcq5r&#&-@3cD}o9@%g}K@)e zCxK4{zbR&XwE(j7&D!F-0l;Q_e!yY=z_w~~9{47VHdZEIhcT{sbPyN*1YBPQZk0>l ze-mo*ebvC391VcG*91WgZmq`&s$MAO98iA=a9JcV#B5@1&H-I9 zNG2YFx)Iu&pLrD4p~*8wctMCJTWjnCSD*kqfqkSXPO%p6Nt;;HcC zO=1ZPH$i#-RoZwTmLPajSi-_=%kecD9?zaGxEhwQuyf^jUc>J!L2zd+VTrE-@6+&I zB?z8mOISFG<^1&;UMxZIq*}tl&XnVC(D1z_h_!QQV&TN&ep=E%1Vh0+q1ugLd0Em} zfp65li-_pZ@QoH2S}bX*z&8HD?czO*0NEX*hUGFIjrHkfwzjMThDLL z7PxEC4meB< +#include +#include "app_trace.h" +#include "nrf_delay.h" +#include "app_util.h" +#include "nfc_t2t_parser.h" + +#ifdef T2T_PARSER_ENABLE + +#define T2T_PARSER_TRACE app_trace_log + +#else + +#define T2T_PARSER_TRACE(...) + +#endif + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for inserting the TLV block into a @ref type_2_tag_t structure. + * + * The content of a TLV block structure pointed by the p_tlv_block is copied into a TLV block + * array within the structure pointed by the p_type_2_tag. + * + * @param[in,out] p_type_2_tag Pointer to the structure that contains the TLV blocks array. + * @param[in] p_tlv_block Pointer to the TLV block to insert. + * + * @retval NRF_SUCCESS If the block was inserted successfully. + * @retval NRF_ERROR_NO_MEM If there is already maximum number of blocks stored in the array. + * + */ +static ret_code_t type_2_tag_tlv_block_insert(type_2_tag_t * p_type_2_tag, + tlv_block_t * p_tlv_block) +{ + if (p_type_2_tag->tlv_count == p_type_2_tag->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_type_2_tag->p_tlv_block_array[p_type_2_tag->tlv_count] = *p_tlv_block; + p_type_2_tag->tlv_count++; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking if the TLV block length is correct. + * + * Some TLV block has predefined length: + * TLV_NULL and TLV_TERMINATOR always have a length of 1 byte. + * TLV_LOCK_CONTROL and TLV_MEMORY_CONTROL always have a length of 3 bytes. + * + * @param[in] p_block_to_check Pointer to the structure that contains the TLV block length. + * + * @retval TRUE If the length is correct. + * @retval FALSE Otherwise. + * + */ +static bool tlv_block_is_data_length_correct(tlv_block_t * p_block_to_check) +{ + switch(p_block_to_check->tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + if (p_block_to_check->length != TLV_NULL_TERMINATOR_LEN) + { + return false; + } + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + if (p_block_to_check->length != TLV_LOCK_MEMORY_CTRL_LEN) + { + return false; + } + break; + + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Any length will do. + break; + } + + return true; +} + +/** + * @brief Function for checking if the end of the tag data area was reached. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset Current byte offset. + * + * @retval TRUE If the offset indicates the end of the data area. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_end_reached(type_2_tag_t * p_type_2_tag, uint16_t offset) +{ + return offset == (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET); +} + + +/** + * @brief Function for checking if version of Type 2 Tag specification read from a tag is supported. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the tag version. + * + * @retval TRUE If the version is supported and tag data can be parsed. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_version_supported(type_2_tag_t * p_type_2_tag) +{ + // Simple check atm, as only 1 major version has been issued so far, so no backward compatibility + // is needed, tags with newer version implemented shall be rejected according to the doc. + return p_type_2_tag->cc.major_version == T2T_SUPPORTED_MAJOR_VERSION; +} + + +/** + * @brief Function for checking if the field fits into the data area specified in + * the Capability Container. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset As Offset of the field to check. + * @param[in] field_length Length of the field to check. + * + * @retval TRUE If the field fits into the data area. + * @retval FALSE If the field exceeds the data area. + * + */ +static bool type_2_tag_is_field_within_data_range(type_2_tag_t * p_type_2_tag, + uint16_t offset, + uint16_t field_length) +{ + // Invalid argument, return false. + if (field_length == 0) + { + return false; + } + return ( (offset + field_length - 1) < + (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET) ) + && ( offset >= T2T_FIRST_DATA_BLOCK_OFFSET ); +} + + +/** + * @brief Function for reading the tag field of a TLV block from the p_raw_data buffer. + * + * This function reads the tag field containing a TLV block type and inserts its value into + * a structure pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_t_offset As input: offset of the tag field to read. As output: offset of + * the first byte after the tag field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the tag type will be + * inserted. + * + * @retval NRF_SUCCESS If the tag field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the tag field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_type_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_t_offset, + tlv_block_t * p_tlv_buf) +{ + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_t_offset, TLV_T_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->tag = p_raw_data[*p_t_offset]; + *p_t_offset += TLV_T_LENGTH; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading the length field of a TLV block from the p_raw_data buffer. + * + * This function reads the length field of a TLV block and inserts its value into a structure + * pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_l_offset As input: offset of the length field to read. As output: offset of + * the first byte after the length field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the length will be + * inserted. + * + * @retval NRF_SUCCESS If the length field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the length field at specified offset exceeds the data + * area specified in the Capability Container or has + * incorrect format. + * + */ +static ret_code_t type_2_tag_length_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_l_offset, + tlv_block_t * p_tlv_buf) +{ + uint16_t length; + + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_SHORT_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = p_raw_data[*p_l_offset]; + + if (length == TLV_L_FORMAT_FLAG) + { + // Check another two bytes. + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_LONG_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = uint16_big_decode(&p_raw_data[*p_l_offset + 1]); + + // Long length value cannot be lower than 0xFF. + if (length < 0xFF) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->length = length; + *p_l_offset += TLV_L_LONG_LENGTH; + + } + else + { + p_tlv_buf->length = length; + *p_l_offset += TLV_L_SHORT_LENGTH; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a pointer to the value field of a TLV block from the p_raw_data buffer. + * + * This function reads a pointer to the value field of a TLV block and inserts it into + * a structure pointed by the p_tlv_buf pointer. If there is no value field present in the + * TLV block, NULL is inserted. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_v_offset As input: offset of the value field to read. As output: offset of + * the first byte after the value field. + * @param[in,out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the value field + * pointer will be inserted. + * + * @retval NRF_SUCCESS If the value field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the value field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_value_ptr_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_v_offset, + tlv_block_t * p_tlv_buf) +{ + if (p_tlv_buf->length == 0) + { + // Clear the value pointer, don't touch the offset. + p_tlv_buf->p_value = NULL; + } + else + { + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_v_offset, p_tlv_buf->length)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->p_value = p_raw_data + *p_v_offset; + *p_v_offset += p_tlv_buf->length; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a single TLV block from the p_raw_data buffer. + * + * This function reads a single TLV block from the p_raw_data buffer and stores its contents in a + * structure pointed by the p_tlv_buf. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to read. As output: offset of the + * next TLV block, 0 if it was the last block. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure that will be filled with + * the data read. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_block_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_offset, + tlv_block_t * p_tlv_buf) +{ + ret_code_t err_code; + memset(p_tlv_buf, 0, sizeof(tlv_block_t)); + + // TLV Tag field. + err_code = type_2_tag_type_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Further processing depends on tag field value. + switch(p_tlv_buf->tag) + { + case TLV_NULL: + // Simply ignore NULL blocks, leave the incremented offset. + break; + + case TLV_TERMINATOR: + // Write 0 to the offset variable, indicating that last TLV block was found. + *p_offset = 0; + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown blocks should also be extracted. + err_code = type_2_tag_length_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_tlv_buf->length > 0) + { + err_code = type_2_tag_value_ptr_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + break; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking the checksum bytes of the UID stored in internal area. + * + * This function calculates the block check character (BCC) bytes based on the parsed serial number + * and compares them with bytes read from the Type 2 Tag. + * + * @param[in] p_sn Pointer to the @ref type_2_tag_serial_number_t structure to check. + * + * @retval TRUE If the calculated BCC matched the BCC from the tag. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_bcc_correct(type_2_tag_serial_number_t * p_sn) +{ + uint8_t bcc1 = (uint8_t)T2T_UID_BCC_CASCADE_BYTE ^ + (uint8_t)p_sn->manufacturer_id ^ + (uint8_t)((p_sn->serial_number_part_1 >> 8) & 0xFF) ^ + (uint8_t)(p_sn->serial_number_part_1 & 0xFF); + + uint8_t bcc2 = (uint8_t)((p_sn->serial_number_part_2 >> 24) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 16) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 8) & 0xFF) ^ + (uint8_t)( p_sn->serial_number_part_2 & 0xFF); + + return (bcc1 == p_sn->check_byte_0) && (bcc2 == p_sn->check_byte_1); +} + + +/** + * @brief Function for parsing an internal area of a Type 2 Tag. + * + * This function reads data from an internal area in the raw data buffer and fills the + * @ref type_2_tag_serial_number_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the internal area succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_internal_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + p_type_2_tag->sn.manufacturer_id = p_raw_data[0]; + p_type_2_tag->sn.serial_number_part_1 = uint16_big_decode(&p_raw_data[1]); + p_type_2_tag->sn.check_byte_0 = p_raw_data[3]; + p_type_2_tag->sn.serial_number_part_2 = uint32_big_decode(&p_raw_data[4]); + p_type_2_tag->sn.check_byte_1 = p_raw_data[8]; + p_type_2_tag->sn.internal = p_raw_data[9]; + + p_type_2_tag->lock_bytes = uint16_big_decode(&p_raw_data[10]); + + if (!type_2_tag_is_bcc_correct(&p_type_2_tag->sn)) + { + T2T_PARSER_TRACE("Warning! BCC of the serial number is not correct!\r\n"); + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a Capabiliy Container area of a Type 2 Tag. + * + * This function reads data from a Capability Container area in the raw data buffer and fills the + * @ref type_2_tag_capability_container_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the Capability Container succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_cc_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + uint8_t * p_cc_block = p_raw_data + T2T_CC_BLOCK_OFFSET; + + if (p_cc_block[0] != T2T_NFC_FORUM_DEFINED_DATA) + { + return NRF_ERROR_INVALID_DATA; + } + + p_type_2_tag->cc.major_version = MSN_GET(p_cc_block[1]); + p_type_2_tag->cc.minor_version = LSN_GET(p_cc_block[1]); + p_type_2_tag->cc.data_area_size = p_cc_block[2] * 8; + p_type_2_tag->cc.read_access = MSN_GET(p_cc_block[3]); + p_type_2_tag->cc.write_access = LSN_GET(p_cc_block[3]); + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a single TLV block. + * + * This function reads a single TLV block from the raw data buffer, from the position indicated by + * the p_tlv_offset, and adds it to the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to parse. As output: offset of the + * next TLV block, 0 if it was the last block. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_parse(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_tlv_offset) +{ + ret_code_t err_code; + tlv_block_t new_block; + + // Get tag field. + err_code = type_2_tag_tlv_block_extract(p_type_2_tag, p_raw_data, p_tlv_offset, &new_block); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!tlv_block_is_data_length_correct(&new_block)) + { + return NRF_ERROR_INVALID_DATA; + } + + // Further action depends on tag type. + switch (new_block.tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + // Ignore them. + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown tag types are also added. + err_code = type_2_tag_tlv_block_insert(p_type_2_tag, &new_block); + if (err_code != NRF_SUCCESS) + { + T2T_PARSER_TRACE("Warning! Not enough memory to insert all of the blocks!\r\n"); + return err_code; + } + break; + } + + return NRF_SUCCESS; +} + + +void type_2_tag_clear(type_2_tag_t * p_type_2_tag) +{ + p_type_2_tag->tlv_count = 0; + memset(&p_type_2_tag->cc, 0, sizeof(p_type_2_tag->cc)); + memset(&p_type_2_tag->sn, 0, sizeof(p_type_2_tag->sn)); +} + + +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + ret_code_t err_code; + + type_2_tag_clear(p_type_2_tag); + + err_code = type_2_tag_internal_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = type_2_tag_cc_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!type_2_tag_is_version_supported(p_type_2_tag)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint16_t offset = T2T_FIRST_DATA_BLOCK_OFFSET; + + while(offset > 0) + { + // Check if end of tag is reached (no terminator block was present). + if (type_2_tag_is_end_reached(p_type_2_tag, offset)) + { + T2T_PARSER_TRACE("Warning! No terminator block was found in the tag!\r\n"); + break; + } + + err_code = type_2_tag_tlv_parse(p_type_2_tag, p_raw_data, &offset); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +void type_2_tag_printout(type_2_tag_t * p_type_2_tag) +{ + uint32_t i, j; + T2T_PARSER_TRACE("Type 2 Tag contents:\r\n"); + T2T_PARSER_TRACE("\r\n Number of TLV blocks: %d\r\n", p_type_2_tag->tlv_count); + + T2T_PARSER_TRACE("\r\n Internal data:\r\n"); + T2T_PARSER_TRACE(" Manufacturer ID: 0x%02x\r\n", p_type_2_tag->sn.manufacturer_id); + T2T_PARSER_TRACE(" Serial number part 1: 0x%04x\r\n", p_type_2_tag->sn.serial_number_part_1); + T2T_PARSER_TRACE(" Check byte 0: 0x%02x\r\n", p_type_2_tag->sn.check_byte_0); + T2T_PARSER_TRACE(" Serial number part 2: 0x%08lx\r\n", p_type_2_tag->sn.serial_number_part_2); + T2T_PARSER_TRACE(" Check byte 1: 0x%02x\r\n", p_type_2_tag->sn.check_byte_1); + T2T_PARSER_TRACE(" Internal byte: 0x%02x\r\n", p_type_2_tag->sn.internal); + T2T_PARSER_TRACE(" Lock bytes: 0x%04x\r\n", p_type_2_tag->lock_bytes); + + T2T_PARSER_TRACE("\r\n Capability Container data:\r\n"); + T2T_PARSER_TRACE(" Major version number: %d\r\n", p_type_2_tag->cc.major_version); + T2T_PARSER_TRACE(" Minor version number: %d\r\n", p_type_2_tag->cc.minor_version); + T2T_PARSER_TRACE(" Data area size: %d\r\n", p_type_2_tag->cc.data_area_size); + T2T_PARSER_TRACE(" Read access: 0x%02X\r\n", p_type_2_tag->cc.read_access); + T2T_PARSER_TRACE(" Write access: 0x%02X\r\n", p_type_2_tag->cc.write_access); + + nrf_delay_ms(100); + + for(i = 0; i < p_type_2_tag->tlv_count; i++) + { + T2T_PARSER_TRACE("\r\n TLV block 0x%02X: ", p_type_2_tag->p_tlv_block_array[i].tag); + switch(p_type_2_tag->p_tlv_block_array[i].tag) + { + case TLV_LOCK_CONTROL: + T2T_PARSER_TRACE("Lock Control\r\n"); + break; + case TLV_MEMORY_CONTROL: + T2T_PARSER_TRACE("Memory Control\r\n"); + break; + case TLV_NDEF_MESSAGE: + T2T_PARSER_TRACE("NDEF Message\r\n"); + break; + case TLV_PROPRIETARY: + T2T_PARSER_TRACE("Proprietary\r\n"); + break; + case TLV_NULL: + T2T_PARSER_TRACE("Null\r\n"); + break; + case TLV_TERMINATOR: + T2T_PARSER_TRACE("Terminator\r\n"); + break; + default: + T2T_PARSER_TRACE("Unknown\r\n"); + break; + } + + T2T_PARSER_TRACE(" Length: %d\r\n", p_type_2_tag->p_tlv_block_array[i].length); + + if (p_type_2_tag->p_tlv_block_array[i].length > 0) + { + T2T_PARSER_TRACE(" Data: "); + + for (j = 0; j < p_type_2_tag->p_tlv_block_array[i].length; j++) + { + T2T_PARSER_TRACE("%02X ", p_type_2_tag->p_tlv_block_array[i].p_value[j]); + if ( ((j + 1) % 16 == 0) && (j != p_type_2_tag->p_tlv_block_array[i].length - 1) ) + { + T2T_PARSER_TRACE("\r\n "); + nrf_delay_ms(10); + } + } + + T2T_PARSER_TRACE("\r\n"); + } + } +} diff --git a/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_t2t_parser.h b/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_t2t_parser.h new file mode 100644 index 00000000..7ca74503 --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_t2t_parser.h @@ -0,0 +1,176 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_TYPE_2_TAG_PARSER_H__ +#define NFC_TYPE_2_TAG_PARSER_H__ + +#include +#include "nfc_tlv_block.h" +#include "sdk_errors.h" + +/** + * @defgroup nfc_type_2_tag Type 2 Tag + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag. + * + */ + +/** + * @brief Descriptor for the internal bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t manufacturer_id; ///< Manufacturer ID (the most significant byte of the UID/serial number). + uint16_t serial_number_part_1; ///< Bytes 5-4 of the tag UID. + uint8_t check_byte_0; ///< First block check character byte (XOR of the cascade tag byte, manufacturer ID byte, and the serial_number_part_1 bytes). + uint32_t serial_number_part_2; ///< Bytes 3-0 of the tag UID. + uint8_t check_byte_1; ///< Second block check character byte (XOR of the serial_number_part_2 bytes). + uint8_t internal; ///< Tag internal bytes. +} type_2_tag_serial_number_t; + +/** + * @brief Descriptor for the Capability Container (CC) bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t major_version; ///< Major version of the supported Type 2 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 2 Tag specification. + uint16_t data_area_size; ///< Size of the data area in bytes. + uint8_t read_access; ///< Read access for the data area. + uint8_t write_access; ///< Write access for the data area. +} type_2_tag_capability_container_t; + +/** + * @brief Type 2 Tag descriptor. + */ +typedef struct +{ + type_2_tag_serial_number_t sn; ///< Values within the serial number area of the tag. + uint16_t lock_bytes; ///< Value of the lock bytes. + type_2_tag_capability_container_t cc; ///< Values within the Capability Container area of the tag. + + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks that can be stored. + tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 2 Tag. + +} type_2_tag_t; + +/** + * @brief Macro for creating and initializing a Type 2 Tag descriptor. + * + * This macro creates and initializes a static instance of a @ref type_2_tag_t structure and + * an array of @ref tlv_block_t descriptors. + * + * Use the macro @ref NFC_TYPE_2_TAG_DESC to access the Type 2 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref tlv_block_t descriptors that can be stored in the array. + * + */ +#define NFC_TYPE_2_TAG_DESC_DEF(NAME, MAX_BLOCKS) \ + static tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static type_2_tag_t NAME##_type_2_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref type_2_tag_t instance that was created + * with @ref NFC_TYPE_2_TAG_DESC_DEF. + */ +#define NFC_TYPE_2_TAG_DESC(NAME) (NAME##_type_2_tag) + + +#define T2T_NFC_FORUM_DEFINED_DATA 0xE1 ///< Value indicating that the Type 2 Tag contains NFC Forum defined data. +#define T2T_UID_BCC_CASCADE_BYTE 0x88 ///< Value used for calculating the first BCC byte of a Type 2 Tag serial number. + +#define T2T_SUPPORTED_MAJOR_VERSION 1 ///< Supported major version of the Type 2 Tag specification. +#define T2T_SUPPORTED_MINOR_VERSION 2 ///< Supported minor version of the Type 2 Tag specification. + +#define T2T_BLOCK_SIZE 4 ///< Type 2 Tag block size in bytes. + +#define T2T_CC_BLOCK_OFFSET 12 ///< Offset of the Capability Container area in the Type 2 Tag. +#define T2T_FIRST_DATA_BLOCK_OFFSET 16 ///< Offset of the data area in the Type 2 Tag. + +/** + * @} + */ + + +/** + * @defgroup nfc_type_2_tag_parser NFC Type 2 Tag parser + * @{ + * @ingroup nfc_library + * + * @brief Parser for Type 2 Tag data. + * + */ + +/** + * @brief Function for clearing the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that should be cleared. + * + */ +void type_2_tag_clear(type_2_tag_t * p_type_2_tag); + +/** + * @brief Function for parsing raw data read from a Type 2 Tag. + * + * This function parses the header and the following TLV blocks of a Type 2 Tag. The data is read + * from a buffer and stored in a @ref type_2_tag_t structure. + * + * @param[out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag (should + * point at the first byte of the first block of the tag). + * + * @retval NRF_SUCCESS If the data was parsed successfully. + * @retval NRF_ERROR_NO_MEM If there is not enough memory to store all of the TLV blocks. + * @retval Other If an error occurred during the parsing operation. + * + */ +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data); + +/** + * @brief Function for printing parsed contents of the Type 2 Tag. + * + * @param[in] p_type_2_tag Pointer to the structure that should be printed. + * + */ +void type_2_tag_printout(type_2_tag_t * p_type_2_tag); + +/** + * @} + */ + +#endif /* NFC_TYPE_2_TAG_PARSER_H__ */ diff --git a/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_tlv_block.h b/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_tlv_block.h new file mode 100644 index 00000000..3bf05f3a --- /dev/null +++ b/cores/nRF5/SDK/components/nfc/t2t_parser/nfc_tlv_block.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2010 - 2017, 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 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. + * + * 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 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 NFC_TLV_BLOCK_H__ +#define NFC_TLV_BLOCK_H__ + +#include + +/**@file + * + * @defgroup nfc_type_2_tag_tlv_block Type 2 Tag TLV blocks + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag TLV block. + * + */ + +/** + * @brief Tag field values. + * + * Possible values for the tag field in a TLV block. + */ +typedef enum +{ + TLV_NULL = 0x00, ///< Might be used for padding of memory areas. + TLV_LOCK_CONTROL = 0x01, ///< Defines details of the lock bits. + TLV_MEMORY_CONTROL = 0x02, ///< Identifies reserved memory areas. + TLV_NDEF_MESSAGE = 0x03, ///< Contains an NDEF message. + TLV_PROPRIETARY = 0xFD, ///< Tag proprietary information. + TLV_TERMINATOR = 0xFE ///< Last TLV block in the data area. +} tlv_block_types_t; + +/** + * @brief TLV block descriptor. + */ +typedef struct +{ + uint8_t tag; ///< Type of the TLV block. + uint16_t length; ///< Length of the value field. + uint8_t * p_value; ///< Pointer to the value field (NULL if no value field is present in the block). +} tlv_block_t; + +#define TLV_T_LENGTH 1 ///< Length of a tag field. + +#define TLV_L_SHORT_LENGTH 1 ///< Length of a short length field. +#define TLV_L_LONG_LENGTH 3 ///< Length of an extended length field. +#define TLV_L_FORMAT_FLAG 0xFF ///< Value indicating the use of an extended length field. + +#define TLV_NULL_TERMINATOR_LEN 0 ///< Predefined length of the NULL and TERMINATOR TLV blocks. +#define TLV_LOCK_MEMORY_CTRL_LEN 3 ///< Predefined length of the LOCK CONTROL and MEMORY CONTROL blocks. + +/** + * @} + */ + +#endif /* NFC_TLV_BLOCK_H__ */ diff --git a/cores/nRF5/SDK/components/softdevice/s132/hex/sfe_nrf52832_dfu.hex b/cores/nRF5/SDK/components/softdevice/s132/hex/sfe_nrf52832_dfu.hex new file mode 100644 index 00000000..96d3bd0d --- /dev/null +++ b/cores/nRF5/SDK/components/softdevice/s132/hex/sfe_nrf52832_dfu.hex @@ -0,0 +1,964 @@ +:0200000270008C +:10A00000807F002025DA07004DDA07004FDA0700CD +:10A0100051DA070053DA070055DA070000000000A4 +:10A0200000000000000000000000000057DA0700F8 +:10A0300059DA0700000000005BDA07005DDA07006C +:10A040005FDA07005FDA0700B9CC07005FDA0700C4 +:10A050005FDA07005FDA07005FDA07005FDA070000 +:10A060005FDA0700D5D907005FDA07005FDA07007B +:10A070005FDA07005FDA07005FDA07005FDA0700E0 +:10A080005FDA0700B5A807005FDA07005FDA0700AC +:10A0900075A907005FDA0700F5D607005FDA070049 +:10A0A0005FDA07005FDA07005FDA07005FDA0700B0 +:10A0B0005FDA07005FDA0700000000000000000020 +:10A0C0005FDA07005FDA07005FDA07005FDA070090 +:10A0D0005FDA07005FDA07005FDA070000000000C0 +:10A0E0000000000000000000000000000000000070 +:10A0F0000000000000000000000000000000000060 +:10A10000000000000000000000000000000000004F +:10A11000000000000000000000000000000000003F +:10A12000000000000000000000000000000000002F +:10A13000000000000000000000000000000000001F +:10A14000000000000000000000000000000000000F +:10A1500000000000000000000000000000000000FF +:10A1600000000000000000000000000000000000EF +:10A1700000000000000000000000000000000000DF +:10A1800000000000000000000000000000000000CF +:10A1900000000000000000000000000000000000BF +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C000000000000000000000000000000000008F +:10A1D000000000000000000000000000000000007F +:10A1E000000000000000000000000000000000006F +:10A1F000000000000000000000000000000000005F +:10A20000000000000000000000000000000000004E +:10A21000000000000000000000000000000000003E +:10A22000000000000000000000000000000000002E +:10A23000000000000000000000000000000000001E +:10A24000000000000000000000000000000000000E +:10A2500000000000000000000000000000000000FE +:10A2600000000000000000000000000000000000EE +:10A2700000000000000000000000000000000000DE +:10A2800000000000000000000000000000000000CE +:10A2900000000000000000000000000000000000BE +:10A2A00000000000000000000000000000000000AE +:10A2B000000000000000000000000000000000009E +:10A2C000000000000000000000000000000000008E +:10A2D000000000000000000000000000000000007E +:10A2E000000000000000000000000000000000006E +:10A2F000000000000000000000000000000000005E +:10A30000000000000000000000000000000000004D +:10A31000000000000000000000000000000000003D +:10A32000000000000000000000000000000000002D +:10A33000000000000000000000000000000000001D +:10A34000000000000000000000000000000000000D +:10A3500000000000000000000000000000000000FD +:10A3600000000000000000000000000000000000ED +:10A3700000000000000000000000000000000000DD +:10A3800000000000000000000000000000000000CD +:10A3900000000000000000000000000000000000BD +:10A3A00000000000000000000000000000000000AD +:10A3B000000000000000000000000000000000009D +:10A3C000000000000000000000000000000000008D +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A4000010B5054C237833B9044B13B10448AFF3AE +:10A4100000800123237010BD782C00200000000074 +:10A4200038DB0700084B10B51BB108490848AFF3EB +:10A4300000800848036803B910BD074B002BFBD010 +:10A44000BDE81040184700BF000000007C2C002031 +:10A4500038DB0700742C002000000000154B002B97 +:10A4600008BF134B9D46A3F5803A00218B460F464B +:10A470001348144A121A00F065F80F4B002B00D055 +:10A4800098470E4B002B00D0984700200021040075 +:10A490000D000D48002802D00C48AFF3008000F0FA +:10A4A0002BF82000290002F0B7FE00F011F800BFE1 +:10A4B00000000800807F0020000000000000000075 +:10A4C000782C002040380020000000000000000030 +:10A4D00008B5074B044613B10021AFF30080054BCC +:10A4E0001868836A03B19847204600F033F800BF2C +:10A4F0000000000094DA070070B50E4B0E4CE41A11 +:10A50000A41000251E46A54204D056F825309847D1 +:10A510000135F8E703F0B0FA084C094BE41AA4102F +:10A5200000251E46A54204D056F82530984701352F +:10A53000F8E770BD6C2C00206C2C0020702C0020E3 +:10A540006C2C002002440346934202D003F8011B06 +:10A55000FAE77047FEE700BF1FB50021039001AA8C +:10A5600044F20100ADF80410029100F003F805B0C8 +:10A570005DF804FBBFF34F8F0549064BCA6802F430 +:10A58000E0621343CB60BFF34F8F00BFFDE700BF16 +:10A5900000ED00E00400FA0510B512F0030411D13B +:10A5A000094B1A604B1CDB009BB21A44074B1A6024 +:10A5B000074B1C70074B1C70074B1880074B19800A +:10A5C000204610BD072010BD942C0020982C0020A0 +:10A5D0009F2C00209E2C00209C2C0020A02C0020D2 +:10A5E0002DE9F3472B4D2B888B4206460C46174628 +:10A5F0004AD302A84FF0000800F8018D00F0D4FC07 +:10A60000254B264A18781178CBB2254909888B4208 +:10A6100038BF0133C0B238BF5FFA83F840450AD073 +:10A6200092F800801378DBB2994286BF0133DBB227 +:10A630000023137001E04FF6FF789DF8070000F04B +:10A64000D9FC4FF6FF73984520D0DFF85CA0DAF80C +:10A6500000304FEAC80903EB090243F8387086B1AD +:10A660007CB1104B28881B68224608FB003031461D +:10A6700003F0F6F9DAF8003099440020A9F8044014 +:10A6800005E00020908002E0092000E0042002B0F4 +:10A69000BDE8F0879C2C00209E2C00209F2C0020E1 +:10A6A000A02C0020982C0020942C0020F8B5124CEF +:10A6B000124E2546227833789A421CD010492278CF +:10A6C000237809880F48DBB2994286BF0133DBB299 +:10A6D00000232B700C4B07881B680C48D2B211B2B8 +:10A6E00003EBC10E006853F83130BEF8041002FBD2 +:10A6F00007009847DEE7F8BD9E2C00209F2C002025 +:10A70000A02C00209C2C0020942C0020982C0020B1 +:10A71000494B4FF40032C3F8802003F1C04303F5E6 +:10A720003C534FF48032C3F848230121C3F8082377 +:10A730002F2259601046013800BF00BF00BF00BF84 +:10A7400000BF00BF00BF00BF00BF00BF00BF00BF11 +:10A7500000BF00BF00BF00BF00BF00BF00BF00BF01 +:10A7600000BF00BF00BF00BF00BF00BF00BF00BFF1 +:10A7700000BF00BF00BF00BF00BF00BF00BF00BFE1 +:10A7800000BF00BF00BF00BF00BF00BF00BF00BFD1 +:10A7900000BF00BF00BF00BF00BF00BF00BF00BFC1 +:10A7A00000BF00BF00BF00BF00BF00BFC3D19960A2 +:10A7B000224900230B601046013800BF00BF00BFD4 +:10A7C00000BF00BF00BF00BF00BF00BF00BF00BF91 +:10A7D00000BF00BF00BF00BF00BF00BF00BF00BF81 +:10A7E00000BF00BF00BF00BF00BF00BF00BF00BF71 +:10A7F00000BF00BF00BF00BF00BF00BF00BF00BF61 +:10A8000000BF00BF00BF00BF00BF00BF00BF00BF50 +:10A8100000BF00BF00BF00BF00BF00BF00BF00BF40 +:10A8200000BF00BF00BF00BF00BF00BF00BFC3D15B +:10A83000034A1370704700BF00E100E0A42C002021 +:10A84000C42C0020437882780133DBB29A4208BFDF +:10A85000002302789A421FBF0B70437803EB430238 +:10A86000436814BF03EBC20000207047EFF3058379 +:10A87000C3F30803BBB1103B5AB2002AABBF02F1CD +:10A88000604303F00F0303F56143094AACBF93F83B +:10A890000033D35C5B09DBB2022B06D0062B0CBF66 +:10A8A000012002207047022070470020704700BF3F +:10A8B00014ED00E02DE9F0412649274B0022C1F8B4 +:10A8C0004021C1F84421C1F84821C1F84C21C1F808 +:10A8D0000021C1F804211B68002B38D01F48D1F893 +:10A8E00004150468DFF888800C1B24F07F441546AB +:10A8F00017461A68A24215D8A41A15441A7CDE69B4 +:10A900006AB1D8F800201F7432B19969586990472C +:10A9100028B1FFF721FE02E05A69986990470EB10D +:10A920003346E6E70E4B0F4A197813788B4205D170 +:10A930000133DBB2022B08BF0023137012780A4BDD +:10A9400043F82250094B4FF48012C3F80021BDE8B0 +:10A95000F08100BF00100140A82C0020A42C002092 +:10A96000B82C0020B92C0020BC2C002000E100E015 +:10A97000AC2C00202DE9F04F9049914A91480B688A +:10A98000007887B003931378984211D00133DBB27B +:10A99000022B08BF0023137012788B4B53F8225000 +:10A9A000039B2B4423F07F430B604FF0010E01E02B +:10A9B0000025AE46854BD1F800901B680293844B6E +:10A9C00002991C78834B1B680193834B00201B78F2 +:10A9D0000493264605900746013EF6B2FF2E33D07B +:10A9E00033B2019A02EBC30C12F833200B469CF8E9 +:10A9F000018090451946EFD002EB4208DCF80410C4 +:10AA00009CF802B001EBC80A013211F83810D2B23A +:10AA1000934508BF0022022902D00329E7D10BE0A9 +:10AA2000DAF804A0194698460029E0D08A4500F0DB +:10AA3000A3818846C969F7E7002BD8D04FF0000101 +:10AA400019740127DB69F7E7604B07B11960059AB4 +:10AA500012B15A4AC2F8009018B15F4A9DF810101E +:10AA600011701A68BEF1000F07D10299B2EB010C08 +:10AA700018BF4FF0010C704623E0002108460F4636 +:10AA80008C46D2B11668AE4204D901B11A60751B6A +:10AA9000156014E0AD1B3744D668C2F800C0D2F888 +:10AAA0001C803EB10399D061394421F07F4151604F +:10AAB0009660104642467146E3E701B11A604FF0D6 +:10AAC000010CD3F800903D4BD3F800A0424B4FF05F +:10AAD000000E1B7802934946F046013CE4B2FF2C7D +:10AAE0007ED0019B0A4603EBC40610B10346C06941 +:10AAF00024E0337875789D421146EED003EB43078E +:10AB000096F802B075680133DBB29B45337008BF1D +:10AB1000307015F83730012B05EBC70148D14B6871 +:10AB20001D7C002D44D18F685F60CF689F600F69E6 +:10AB3000DF6049699961029901B15D605968274FE9 +:10AB4000CAEB010525F07F45BD429F6802D83D4410 +:10AB50001D6009E0C1EB0A0121F07F41B9423ABF13 +:10AB6000791A1960C3F800804FF00101C3F804801E +:10AB7000C3F808801974C3F81C80DAB11D68116825 +:10AB80008D4203D84D1B1560DA6113E093461146E0 +:10AB90000F68AF4205D2ED1BCF698B462FB1394606 +:10ABA000F6E77F1B0F600F4659461D60DF61CB61E2 +:10ABB000134601E04FF0010E1A4696E7A42C002040 +:10ABC000B82C0020B92C0020BC2C0020A82C002080 +:10ABD000B02C0020B42C0020BA2C0020FEFF7F00F7 +:10ABE000744BBEF1000F00D019601B68994503D16A +:10ABF000BCF1000F00F0BA80002B00F0B5801F6898 +:10AC00006D496E4BD1F804451B686D4DE21A2878EA +:10AC100022F07F42033200284BD14FF48030C1F83C +:10AC20004403C1F8040367484FF40036C0F880615C +:10AC3000066001260E602F20013800BF00BF00BF54 +:10AC400000BF00BF00BF00BF00BF00BF00BF00BF0C +:10AC500000BF00BF00BF00BF00BF00BF00BF00BFFC +:10AC600000BF00BF00BF00BF00BF00BF00BF00BFEC +:10AC700000BF00BF00BF00BF00BF00BF00BF00BFDC +:10AC800000BF00BF00BF00BF00BF00BF00BF00BFCC +:10AC900000BF00BF00BF00BF00BF00BF00BF00BFBC +:10ACA00000BF00BF00BF00BF00BF00BF00BFC3D1D7 +:10ACB0002E7097422CBFDA199A1822F07F43C1F800 +:10ACC0004035D1F804253C48121B22F07F421B1B63 +:10ACD000033223F07F439A4248D9D0F80435C0F8B4 +:10ACE00040352F20013800BF00BF00BF00BF00BFAC +:10ACF00000BF00BF00BF00BF00BF00BF00BF00BF5C +:10AD000000BF00BF00BF00BF00BF00BF00BF00BF4B +:10AD100000BF00BF00BF00BF00BF00BF00BF00BF3B +:10AD200000BF00BF00BF00BF00BF00BF00BF00BF2B +:10AD300000BF00BF00BF00BF00BF00BF00BF00BF1B +:10AD400000BF00BF00BF00BF00BF00BF00BF00BF0B +:10AD500000BF00BF00BF00BF00BFC3D1194B4FF4FD +:10AD60000032C3F8002101E0FFF7D2FC164B0022AD +:10AD70001A7007B0BDE8F08F41450AD1DB690BB10D +:10AD8000012706E00C48012787609946384604975A +:10AD90000597D1F81CB0D1F800A0C8F81CB0BBF1E1 +:10ADA000000F3FF424AEDBF800105144CBF8001044 +:10ADB0001DE600BFA82C002000100140A42C00209C +:10ADC000C42C002000E100E0BA2C00202DE9F8435B +:10ADD00012F0030507468846144699463BD11F4E9C +:10ADE0000AB9326037E0FFF793FC1D4A1D4BC2F8E9 +:10ADF000009003221A70346004F1180208EB480630 +:10AE0000F600114662602570657084F8028008348F +:10AE10008C424FF000033244F4D1134A1360134ABA +:10AE20001370134A1370134A4FF48011C020C2F8F4 +:10AE3000801182F81403116001F18041A1F56F21A6 +:10AE4000C1F8087582F811030B4AD1F80415116096 +:10AE50001846BDE8F8830720BDE8F883B42C00202D +:10AE6000AC2C0020B02C0020A82C0020B82C0020F6 +:10AE7000B92C002000E100E0A42C0020074B1B6847 +:10AE80004BB132B128B10368187C20B959745A61AA +:10AE90007047072070470820704700BFB42C00207F +:10AEA0002DE9F3411B4B1C6805460E4617466CB353 +:10AEB00060B3042928D9436943B3437C012B0CBFF9 +:10AEC00088464FF00008FFF7D1FC04EBC0040DF1F9 +:10AED00007012046FFF7B6FCA0B1012303700E4B1B +:10AEE0004560D3F8043583609DF80730C660C0F82C +:10AEF000108047616370094B4FF48012C3F8002142 +:10AF0000002004E0042002E0072000E0082002B056 +:10AF1000BDE8F081B42C00200010014000E100E009 +:10AF200073B5124B1D680646EDB1E0B14369D3B16C +:10AF300000240474FFF79AFC05EBC0050DF107012E +:10AF40002846FFF77FFC60B1022303709DF80730AD +:10AF500046606B70064B4FF48012C3F80021204608 +:10AF600002E0042000E0082002B070BDB42C0020F4 +:10AF700000E100E0082910B5044602D00020FFF7E8 +:10AF8000EBFA23686068BDE81040184707B5054A2A +:10AF90008DE8030008216846FFF722FB03B05DF847 +:10AFA00004FB00BF75AF070070B5EFF3108572B6F4 +:10AFB0000D4A9468012394B993600C4B0C49D3F863 +:10AFC0008060314011600A49C3F88010D3F88410C2 +:10AFD00051604FF0FF32C3F88420047000E003702A +:10AFE00005B962B670BD00BF3438002000E100E052 +:10AFF000FC06FFBC10B5084B9A685AB150B9EFF384 +:10B00000108272B605491C680C605C684C609860E0 +:10B0100002B962B610BD00BF3438002000E100E084 +:10B0200048DF704711DF704713DF7047064B187811 +:10B03000012803D1012904BF0221197012B1104661 +:10B04000FFF78ABA704700BFE42C002010B5064C09 +:10B05000FFF7E6FF08B1FFF77FFAFFF727FB23783A +:10B06000023B022BF4D810BDE42C002008B51C21B3 +:10B07000084802F01FF808B1FFF76EFA00231C22FF +:10B080000549044802F006F818B1BDE80840FFF78A +:10B0900063BA08BDE82C0020C82C002007B503685F +:10B0A000013301D1002014E001A800F03DF9019B1B +:10B0B0001A78012AF6D1588830B1996843F208030A +:10B0C0000022186800F054F9019B5B881B1A584253 +:10B0D000584103B05DF804FB84B02DE9F34108AC9E +:10B0E00084E80F009DF82040BDF82280099F0A9E49 +:10B0F0000B9D01A800F018F944B9354B0122FF213E +:10B10000A3F802809D601A7019713EE0012C13D1E2 +:10B110002F4BBA192A449A60A5221A70FF221A717D +:10B120000C9AA3F80280DF601E615D619A61294B71 +:10B130001C70FFF79BFF45E0032C0DD1019A244BB7 +:10B1400011781970518892689A60AA2259801A71F0 +:10B15000DF601E615D6117E0022C19D1019A1C4B62 +:10B160001178A52905D100225A809A60FF221A7011 +:10B1700004E019705188926859809A60FF221A7110 +:10B180000022DA601A615A610122124B1A70D0E76C +:10B19000052C06D100F0B6FD08B1FFF7DDF903225A +:10B1A0000EE0042C09D10A4B00229A605A80FF223B +:10B1B0001A70019A12791A71BBE7062C02D1042287 +:10B1C000044B1A7002B0BDE8F04104B0704700BFF4 +:10B1D000C82C0020E42C00201FB500230293039309 +:10B1E000074B019301F01CFF30B906494FF4FE23D1 +:10B1F00001A84B6001F03AFF05B05DF804FB00BF09 +:10B200002DB00700E82C002010B500F01FFA28B977 +:10B2100000F054FD0446FFF719FF204610BD000062 +:10B2200010B5FFF7FFFE08B1FFF796F90D4A106859 +:10B230000023012404FA03F1014203F1010318BFC2 +:10B24000C2F88010202BF5D143F208031868FFF7ED +:10B25000EBFE1C4608B1FFF77FF92068BDE81040FF +:10B2600000F068B800E100E007B501A800F05CF864 +:10B27000019B1A78A52A05D01879A0F1AA03584293 +:10B28000584100E0012003B05DF804FB10B500F068 +:10B29000F7FB40B1642001F02EFA00F065FB38B1F5 +:10B2A000FFF75AF904E000F0C5FB0028F2D110BD09 +:10B2B00000F0E6FB08B1FFF74FF900F098FB0446F9 +:10B2C00008B1FFF749F9204610BD10B588B003ACAE +:10B2D000142200212046FFF735F902238DF80C30A7 +:10B2E0000023009394E80F00FFF7F6FEFFF7AEFE91 +:10B2F000002008B010BD13B5044601A800F014F8F2 +:10B30000019B1A7822705A8862809A68A2601A7922 +:10B310002271DA68E2601A6922615A6962619B6986 +:10B32000A36102B010BD0000014B0360704700BF75 +:10B3300000F00700F0B50346186880F308885868E5 +:10B34000FF2464B2EFF30585002D01D1A646004726 +:10B350002546064621273FBAF0B4002400250026E2 +:10B360000027F0B4F92040B2004700BFF0BD00BF95 +:10B370000AB1138801E04FF6FF730144884210D0F0 +:10B3800010F8012B5BBA9BB25340C3F30312534036 +:10B3900083EA03331AB2530103F4FF5353409BB2C1 +:10B3A000ECE71846704718DF704770470129F8B579 +:10B3B0000D4614461F4602D003290CD01AE0114B4B +:10B3C0001B78052B16D1104B1B689BB13A462146C2 +:10B3D000042098470EE00B4E3378022B0AD10B4B1A +:10B3E0005B689847084B35701E681EB13A46214687 +:10B3F0002846B04724B12046BDE8F840FFF7ACB876 +:10B40000F8BD00BFF82C0020F02C0020402D0020BB +:10B4100000B5084B89B001221A7005238DF80C3055 +:10B42000079B009303AB0FCBFFF756FE09B05DF807 +:10B4300004FB00BF042D002000B589B003238DF864 +:10B440000C300A4B1B88ADF80E30094B5A68049239 +:10B450009A68DB680693079B0093059203AB0FCBBA +:10B46000FFF73AFE002009B05DF804FBF62C00203F +:10B47000302D002000B589B001238DF80C300B4B26 +:10B480001B88ADF80E3043F208031A68084B596860 +:10B4900004919968DB6806930591009203AB0FCB8A +:10B4A000FFF71AFE002009B05DF804FBF62C00201F +:10B4B000302D002010B588B003AC142200212046A6 +:10B4C000FFF740F804238DF80C300023009394E834 +:10B4D0000F00FFF701FE08B010BD000008B50C4BCF +:10B4E0000C4818600C4B02221A7043F208031968CA +:10B4F000494221F4FF5121F01F0101F5F4214908CF +:10B5000001F0D8FD18B1BDE80840FFF725B808BD27 +:10B51000CC2D0020082D0020F82C002008B5084B69 +:10B5200008481860084B02221A70084B196801F08D +:10B53000C1FD18B1BDE80840FFF70EB808BD00BF57 +:10B54000CC2D0020FC2C0020F82C0020D42D002035 +:10B5500030B5154C1548E16889B001F0ABFD08B174 +:10B56000FEF7FAFF1249E26849681048002301F02B +:10B5700091FD0546A0B903AC014614222046FEF712 +:10B58000E1FF0C4B8DF80C501B88ADF80E30064BCC +:10B59000DB680693079B009394E80F00FFF79CFD80 +:10B5A000284609B030BD00BF302D0020FC2C002003 +:10B5B000082D0020F62C002010B50C4B1B7883B909 +:10B5C0000B48FFF7ADFC08B1FEF7C6FF00224FF4B1 +:10B5D00070110748FFF764FC044620B1FEF7BCFF7A +:10B5E00001E0082010BD204610BD00BF042D002042 +:10B5F000102D00207FB505460C46960803216846AD +:10B600008DE8220002940396FFF7CDFED8B1B4F581 +:10B61000805F11D8012368468DE8280002940396C4 +:10B62000FFF7C1FE78B9032368468DE8280002942D +:10B630000396FFF7B8FE06E01A46E11AE81AFFF78C +:10B64000D9FF0028E6D004B070BD00007FB51F4BC5 +:10B6500001931F4B1F4E204D00241C701F4B029462 +:10B66000314601A81C80039401F000FD034608B197 +:10B670002C7029E043F20802194C1168716096E8B9 +:10B68000030084E80300116816484A4222F4FF527E +:10B6900022F01F0202F5F42201EB52026260194609 +:10B6A000114AFFF7EBFB08B1FEF756FF00224FF4FB +:10B6B00070110E48FFF7F4FB08B1FEF74DFF0C4B7D +:10B6C0000020186001232B7004B070BDADB30700DB +:10B6D000F42C0020FC2C0020F82C0020F62C00205C +:10B6E000082D002098DA070011B40700102D002063 +:10B6F000D02D0020014B1860704700BFF02C0020B7 +:10B7000038B54368294C0FCB84E80F0021784B07EC +:10B7100001D58D0742D16268244B90073ED19868CD +:10B7200085073BD1DB689C0738D10244204D1A4481 +:10B73000B0F5A04F2A6033D843F2080311F0010F8F +:10B740001B680AD0C3F5F4239A4229D8194B1A4A28 +:10B750001A601A4A5A601A4A12E05B4223F4FF53F5 +:10B7600023F01F0303F5F423B2EB530F18D8114B4A +:10B77000144A1A60144A5A608A074CBF134A144A82 +:10B780009A60144B1B78012B0CD1FFF715FF044670 +:10B7900050B9084B28681B68984705E0062038BD5B +:10B7A0000C2038BD082038BD204638BD302D002083 +:10B7B000D42D0020402D00201DB50700B5B4070092 +:10B7C00075B40700DDB40700ABB3070039B4070058 +:10B7D00051B50700F82C0020F8B5064640B3836841 +:10B7E0009B0727D1154B1B78052B25D1144C42689C +:10B7F000144F236895003A682B44934204D94FF0C4 +:10B80000FF3323600C20F8BDFFF7D6FEA8B90E4821 +:10B810002368B16800682A4601F03CFC68B92068DA +:10B820002A1838682260824214BF09200020F8BD1F +:10B830000E20F8BD1020F8BD0820F8BDF82C00201F +:10B84000D02D0020D42D0020CC2D002070B50B4B26 +:10B850001C687CB90A4E3378042B0BD1094D0A4879 +:10B86000297800F039F910B90523337003E02C7002 +:10B87000044600E00824204670BD00BFD02D002003 +:10B88000F82C0020F42C00204C2D0020F8B5144B8F +:10B890001A78032A074602D0042A02D018E00422AC +:10B8A0001A70104B1D689DB9FFF786FE90B90E4EB9 +:10B8B0007C683378A4001A19802A0DD80B48B9681F +:10B8C0002246184402F0CCF833781C44347004E06B +:10B8D000082502E0054600E009252846F8BD00BF1E +:10B8E000F82C0020D02D0020F42C00204C2D00201E +:10B8F00038B50D4C2378052B14D10C4B0C4D1A6820 +:10B900002B689A420ED106232370FFF755FE50B9DB +:10B91000084B29681B68586800F020F918B90723FC +:10B92000237038BD082038BDF82C0020D02D002011 +:10B93000D42D0020CC2D002010B5084B1B78072BF0 +:10B940000AD10748FFF7ECFA08B1FEF705FE054BF0 +:10B95000BDE810409B681847082010BDF82C002057 +:10B96000102D0020402D002010B58CB005A8FFF749 +:10B97000C2FC089A002A37D00B9C02F58053A342E0 +:10B9800026D943F20801A4F5805309688A424FEA98 +:10B99000530307D85800121A00F580512044FFF7CE +:10B9A00029FE20E003F5805001210290039001A8B8 +:10B9B00001910491FFF7F7FCA8B94FF48050029071 +:10B9C000039001A801910491FFF7EDFC58B9E1E75C +:10B9D0000123019392084FF4805301A8029403932A +:10B9E0000492FFF7E0FC024610460CB010BD00B513 +:10B9F0008DB005A8FFF77FFC0998C0B1089A62B91D +:10BA000043F208031A68534223F4FF5323F01F0341 +:10BA100003F5F42302EB530301E00B9B134480086E +:10BA20000022039001A801920293FFF7BCFC0DB025 +:10BA30005DF804FB00B58DB005A8FFF75CFC099824 +:10BA4000D8B1089A62B943F208031A68534223F442 +:10BA5000FF5323F01F0303F5F42302EB530301E02C +:10BA60000B9B134403228008019204904FF4F422AC +:10BA700001A802920393FFF796FC0DB05DF804FB5A +:10BA800030B58DB005A8FFF736FC089808B30B9CBD +:10BA900000F58053A3420FD943F208031B68984274 +:10BAA00016D8A4F580535B085D00421B05F5805154 +:10BAB0006019FFF79FFD0CE00323800801930490B9 +:10BAC0004FF4805301A802930394FFF76CFC00E04D +:10BAD0000E200DB030BD00000B2970B5044633D9DF +:10BAE000038900EB43030A33C21A0A44D2B2012A83 +:10BAF0002AD901448B4227D81946164801F0B0FFD5 +:10BB0000154B1A884FF6FF718A4202D02188914264 +:10BB10001CD15B884FF6FF72934202D062889A4232 +:10BB200014D134F8081F00234FF6FE7043F20C05C1 +:10BB30008B420BD234F8022F824209D02E88B242B7 +:10BB400003F10103F4D103E0092070BD0B2070BDA7 +:10BB5000002070BDD82D00208010001008B50022F4 +:10BB6000FFF706FC044A5178137843EA0123984210 +:10BB700014BF0B20002008BDD82D0020F7B50023EE +:10BB80000DF1020101A8ADF80230019300F002FDB1 +:10BB900020BB019A16785EB3184B93F83010032936 +:10BBA00028D00C2707FB00F5144C595999B994F883 +:10BBB000303066510133DBB284F83030BDF80230EA +:10BBC00060199B08013B0432436082600C4A0846BE +:10BBD000FEF706FD02E001300428E3D1019B5BB1D2 +:10BBE00050B1184600F0F2FC30B1FEF7B5FC03E0AE +:10BBF0000720F3E70420F1E703B0F0BDE42D0020B7 +:10BC000049BC070011B10846FEF7A6BC704700000A +:10BC100010B50C230B4A4343D418D15881B192F884 +:10BC20003010A0680139C9B282F830100021D1501B +:10BC3000A1606160043800F0C9FC08B1FEF78CFC1B +:10BC4000002010BDE42D002070B51B4E96F830305A +:10BC500083B3194C0025236833B3013B042B1DD853 +:10BC6000DFE803F00D1C070316002046FFF7B4FDC4 +:10BC700014E0A36863602046FFF742FD04E020461D +:10BC8000FFF704FEFFF7E2FD40B1FEF765FC05E0BB +:10BC9000FFF72EFEBDE87040FFF74EBEE8B2FFF79B +:10BCA000B7FF08B1FEF758FC0135042D04F10C0470 +:10BCB000D1D1CBE770BD00BFE42D00200E4A08B5FE +:10BCC000002382F830301946D150D0180C33302B75 +:10BCD00081604160F8D10948FFF70CFD00F0F4FBEA +:10BCE00008B1FEF739FC064800F0DAFB08B1FEF7B0 +:10BCF00033FC002008BD00BFE42D002005BC070078 +:10BD00007DBB070008B50020FFF782FF0120FFF789 +:10BD10007FFF0220FFF77CFF0320FFF779FFBDE8DC +:10BD2000084000F017BC0000064B074A00201870BE +:10BD3000064B1A6002225A609860D86018615861F8 +:10BD400098617047EC320020182E0020D03200207D +:10BD50000020704730B5F1B1124B5C6800220A60D8 +:10BD6000DCB1B0F5167F1AD8D8681D680130013CE7 +:10BD7000D86018695C604FF4177404FB00540C60C1 +:10BD80009C69012181400130214300F001001861CC +:10BD90009961104630BD0E2030BD042030BD0C200E +:10BDA00030BD00BFD0320020F0B51B4B9A6882B383 +:10BDB0005D691E68AC1A04F0010421464FF4177740 +:10BDC00007FB016E70450FD19D69012088406840D6 +:10BDD000986100205E68D3F818E04FF0010C002550 +:10BDE000164481EA0C0109E081F001018D42E7D19E +:10BDF0001020EFE74AB1013A0C4601250CFA04F491 +:10BE000014EA0E0FA6EB0207F4D01DB19A605F6032 +:10BE1000F0BD0420F0BD00BFD032002006490B6900 +:10BE2000013B03F001020B684FF4177101FB023371 +:10BE3000C3F8580200207047D032002030B5C0B19E +:10BE4000B9B10E4BDA68B2B1013ADA609A681D688E +:10BE500001329A605A694FF4177404FB025401329C +:10BE6000046002F00102D4F858025A610860002010 +:10BE700030BD0E2030BD042030BD00BFD0320020C8 +:10BE800030B50B49086885B078B10A4B1C6864B1BD +:10BE9000094A0390002315688DF804300B60136085 +:10BEA000029504AB13E90700A04705B030BD00BF01 +:10BEB00004330020FC3200200C330020DC2810B5B5 +:10BEC00006D0DD280CD0C02813D1FFF7D9FF17E02A +:10BED0000D4A0E4B19681368581C1060C02206E00A +:10BEE000094A0A4B19681368581C1060DB22CA54AF +:10BEF00006E0064B044A196813685C1CC8541460B9 +:10BF0000034B044A1A6010BD043300200C33002098 +:10BF1000602C002049BF0700C02802BF014B024A25 +:10BF20001A607047602C002049BF070008B5DB206D +:10BF300000F0CAFB10B9024B024A1A6008BD00BFEC +:10BF4000642C0020E1C00700C02810B405D0DB2815 +:10BF500007D1094B094A1A600AE05DF8044BFFF764 +:10BF60008FBF074B074A196813685C1CC8541460DC +:10BF70005DF8044B704700BF602C0020BDBE070079 +:10BF80000C3300200433002010B5064A064C12681A +:10BF90002368D05C00F098FB10B92368013323605C +:10BFA00010BD00BF08330020F032002008B5C020CB +:10BFB00000F08AFB28B9034B1B6813B9024B034AF4 +:10BFC0001A6008BDF0320020642C002089BF0700F1 +:10BFD0007FB51C4C1C4E1D4D226833689A4216D208 +:10BFE0001B4B22681B689A5CC02A03D022689B5CAA +:10BFF000DB2B05D1174B2A689A4204BF164B2B60E6 +:10C000002B68984704281AD01128E5D117E00F4B68 +:10C01000124A1A60FFF7CAFF88B9114B01221A7041 +:10C02000104B1B685BB18DF80420094A126802921C +:10C03000044A1268039204AA12E90700984704B060 +:10C0400070BD00BFF0320020F4320020642C0020CC +:10C050000833002089BF07002DBF0700ADBF0700D0 +:10C0600000330020FC3200201FB50378032B044668 +:10C0700005D1154B1B78022B01D1FFF7A9FF2378BF +:10C08000042B1ED1114B1A682AB1114B1968114BA0 +:10C090001B6899420ED3104B1B6893B102920C4A55 +:10C0A0000221126803928DF8041004AA12E9070015 +:10C0B000984706E0094B20791B6804B0BDE81040A2 +:10C0C000184704B010BD00BF003300200C3300201F +:10C0D00004330020F8320020FC320020602C0020C5 +:10C0E00010B50C4A0C4C12682368D35CC02B03D0EB +:10C0F000DB2B0CD1DD2000E0DC2000F0E5FA38B9C4 +:10C100002368064A01332360054B1A6010BD0420E2 +:10C1100010BD00BF08330020F032002089BF0700A7 +:10C12000642C0020014B186000207047FC32002076 +:10C130007FB50B4D2E787EB90A4B93E8070001AC12 +:10C1400084E807000623084A3146204600F072FAC8 +:10C1500018B901232B7000E0002004B070BD00BFAF +:10C16000003300209CDA070069C00700024B002260 +:10C170001A7000F0BBBA00BF0033002010B5C0B188 +:10C180000D4B1A78012A04D0022A0CBF0420082083 +:10C1900010BD0A4A00241460094A1160094A10605F +:10C1A00002221A70084B094A1A60FFF711FF204655 +:10C1B00010BD102010BD00BF00330020F032002061 +:10C1C000F432002008330020642C0020ADBF0700AB +:10C1D000054B064A1860064B1960064B0020186094 +:10C1E000054B1A60704700BF0C33002019BF0700D1 +:10C1F000F832002004330020602C0020064B074852 +:10C200001B68DB00DBB20022037004215B4242703A +:10C210008270C370FFF7B2BF2C330020253300209B +:10C2200070B52D4C2D4E024625462378012B14D097 +:10C2300002D3022B20D070BD002A4BD12848FEF734 +:10C240006FFE08B1FEF788F9264B1B68002B41D022 +:10C25000254ABDE8704010781847012A3AD1316864 +:10C26000224B06311868FFF789FF08B1FEF774F911 +:10C2700002232B700022D8E7022A16D0032A01D00D +:10C2800042BB06E01A4A1368013303F00703136048 +:10C290001DE0184B12481A6044F6DF71FEF700FEED +:10C2A000C0B1BDE87040FEF757B9124A1368052BBC +:10C2B0000AD001331360094B19680C4B063118681A +:10C2C000BDE87040FFF75ABF074B01221A700023E8 +:10C2D0002370CFE770BD00BF1C3300203033002037 +:10C2E000343300202033002010330020603300203E +:10C2F0005433002018330020F0B585B004AB03E9B7 +:10C3000007009DF8040003285FD8DFE800F008026A +:10C310005A5D012005B0BDE8F040FFF781BF039EE4 +:10C32000564D032E39D9029C637813F00F021DD0AD +:10C330000E2A32D1042E7ED0227850067BD51106EB +:10C3400079D51344A278E17813440B4413F0FF022B +:10C3500071D1B71E39462046FFF70AF8E3195A781B +:10C36000E35D43EA0223984265D133E02178A27865 +:10C370000B441344E278134413F0FF030DD1404AF9 +:10C3800012680132C1F3C20102F00702914204D1E6 +:10C390003C4A03201370FFF743FF2C68374E1CB153 +:10C3A0004FF41671204649E031464FF41670FFF7FE +:10C3B000D1FC002858D004285AD02046FEF7CCF8EB +:10C3C00056E00521304839E0032005B0BDE8F040D3 +:10C3D000FEF7C2B82D4922780B6802F00702D8B2E6 +:10C3E00082421BD1013303F007030B60FFF706FF06 +:10C3F000274B012230461A70FFF710FD08B1FEF7F7 +:10C40000ABF81E4C4FF416702146FFF7A3FCC8B1E1 +:10C41000042826D00020FEF79FF822E04FF4167182 +:10C420002868FFF7D5FE08B1FEF796F805B0BDE81D +:10C43000F040FFF7E3BE28684FF41671FFF7C8FE1F +:10C44000C8B1C2E720684FF41671FFF7C1FE08B10A +:10C45000FEF782F80F4B1B686BB14FF00000984756 +:10C4600009E009480521F0E730684FF41671E5E767 +:10C4700005480521E2E705B0F0BD00BF5C330020B0 +:10C480005433002010330020113300202C330020BF +:10C4900024330020583300200220FFF7C1BE0000E3 +:10C4A000074B10B5044618600648FFF73BFE08B17D +:10C4B000FEF752F8002C0CBF0E20002010BD00BF6C +:10C4C00058330020F9C20700174A1848002310B556 +:10C4D0001360174A1360174A1360174A1370174AFC +:10C4E0001370174B174A01211960174B1960174B2E +:10C4F0001970FEF7C3FC08B1032010BDFFF714FC50 +:10C5000088B9FFF715FE70B9114C4FF4167021462B +:10C51000FFF720FC0028EFD120684FF41671BDE82A +:10C520001040FFF755BE10BD60330020A8DA0700A9 +:10C530003033002018330020243300201C33002027 +:10C540002C33002099C407005433002010330020FE +:10C550005C3300200C4A08B5002313600B4A1360BB +:10C56000FFF7F6FB08B1FDF7F7FFFFF7FFFD08B196 +:10C57000FDF7F2FF0648FEF7D3FC042802D10020A5 +:10C58000FDF7EAFF002008BD2033002058330020CB +:10C590003433002037B50D46044690B189B10A4BBB +:10C5A00019780022019251B101A91A70FFF746FCD7 +:10C5B000019B063B2B8023680433236002E00420A8 +:10C5C00000E00E2003B030BD243300200438FFF714 +:10C5D000EBBB000013B50478012C0DD104238DF8BA +:10C5E0000030436810481B788DF80430214600F075 +:10C5F0009FFA0E4B1C7009E0022C0BD1C3680A484D +:10C600008DF800400121019300F092FA084B684632 +:10C610001B6806E034B902A8032300F8083D044B68 +:10C620001B68984702B010BD6C3300206D330020AA +:10C6300068330020F0B51F4D064617469E460FCDC5 +:10C6400089B06C460FC495E80F0084E80F00B3680A +:10C65000069333798DF81CE01A1C18BF01228DF85F +:10C6600014207279002A14BF0E2200228DF81520A2 +:10C67000F2780292B2780392327801927278009244 +:10C680000D4A17600D4A0021022B11700ED00C4983 +:10C69000684600F0F7F850B99DF81D300BB900F06E +:10C6A000F7FA0121074800F043FA00E0062009B03C +:10C6B000F0BD00BFACDA0700683300206D33002006 +:10C6C000D5C507006C33002008B5074B0121187051 +:10C6D000184600F0BFF9112804D0002814BF032029 +:10C6E000002008BD042008BD6433002008B500F018 +:10C6F0005DF9002008BD82B00190019B002B41D064 +:10C70000019B013B019340F2E730013800BF00BFBD +:10C7100000BF00BF00BF00BF00BF00BF00BF00BF21 +:10C7200000BF00BF00BF00BF00BF00BF00BF00BF11 +:10C7300000BF00BF00BF00BF00BF00BF00BF00BF01 +:10C7400000BF00BF00BF00BF00BF00BF00BF00BFF1 +:10C7500000BF00BF00BF00BF00BF00BF00BF00BFE1 +:10C7600000BF00BF00BF00BF00BF00BF00BF00BFD1 +:10C7700000BF00BF00BF00BF00BF00BF00BF00BFC1 +:10C78000C3D1BAE702B0704700284FEA4111BFBFDA +:10C7900000F00F020E4BC9B29954A8BF00F16043DC +:10C7A00000F01F024FEA5010A8BF03F561434FEAA3 +:10C7B0008000A8BFC9B200F16040A8BF83F8001391 +:10C7C00000F5614001239340C0F880310360704759 +:10C7D00014ED00E0074B00221A60074A938A916823 +:10C7E0009BB2C95C938A01339BB29382034BC3F81B +:10C7F0001C1570471C2100407033002000200040B1 +:10C800001FB501238DF80030054B8DF8080001910C +:10C81000684693E80600904705B05DF804FB00BF4A +:10C82000703300201FB5084B8DF8080099680191FE +:10C8300000228DF800209A75684693E8060090471C +:10C8400005B05DF804FB00BF703300200A4B0B49B4 +:10C85000D87D0B4A18B90860D2F818357047002007 +:10C860000860597ED2F81805DA6850545A7E0132B1 +:10C87000D2B25A76704700BF7033002008210040C2 +:10C88000002000402DE9F041404C94F81BC0884640 +:10C89000BCF1000F77D13E4B002808BF184601239A +:10C8A0000268457F257793404FF0A0420327C2F8E6 +:10C8B0000835036803F5E07342F82370436803F515 +:10C8C000E07342F823C0334B8669C3F8246590F8BF +:10C8D00015E0067D4EEA0606C3F86C6590E8420056 +:10C8E000C3F80C15C3F81465067D3DB1012E1BD1AC +:10C8F000816801F5E07E42F82EC006E0012E13D1DA +:10C90000816801F5E07E42F82E50C1688E40C2F881 +:10C910000865C66806F5E07642F82670C668826843 +:10C92000C3F80865C3F810250369C4F804802360C0 +:10C93000B8F1000F16D0017F174A55B117480023F0 +:10C940000360036143611360124B154AC3F804236B +:10C9500005E0144B1D601560134AC3F8E82102205E +:10C96000FFF712FF227F0B4B0AB1082200E00422DE +:10C97000C3F8002500200123E0752076A075E3763A +:10C98000A076BDE8F0810820BDE8F081703300207A +:10C99000CCDA070000200040442100401021004074 +:10C9A000100302001C2100408000020070B5244AE0 +:10C9B000244B117F19B10020C3F8000501E0C3F832 +:10C9C0000015536853B11F4B09B11F4800E01F48C1 +:10C9D000C3F808031E4B0420C3F88000194BD3F89A +:10C9E0000C55D3F81445D3F80815D3F810054FF0BB +:10C9F000FF36C3F80C6504F5E074C3F8146505F55B +:10CA0000E075C3F80865C3F810654FF0A04302262F +:10CA100043F8256043F82460441C1CBF00F5E07017 +:10CA200043F820604B1C1FBF4FF0A04301F5E0719D +:10CA3000022043F821000023D376536070BD00BF6D +:10CA40007033002000200040100302008402020026 +:10CA500000E100E0F8B52F4C237F23B1020C120453 +:10CA6000B2F1005F52D1A67D2A4D002E50D1A9759A +:10CA7000A860AE822849D3B1284B294A1E601660AF +:10CA8000284EAF7DC6F844050120C6F848750860F9 +:10CA9000696819B10020F8BD002933D11868116800 +:10CAA0000028F9D0002914BF0F2000202BE01E48D9 +:10CAB000036001230B60FFF78DFE6B68002BE9D14B +:10CAC000A27DA38A9BB293420ED2036823B9A38AA4 +:10CAD0009BB2B3F5807FF8D1A38A9BB2B3F5807F78 +:10CAE000EFD0FFF777FEEBE70A4B9B8A9BB2B3F5DB +:10CAF000807F07D00368002BFCD00C4B01221A600A +:10CB0000002000E00F200023A375F8BD1020F8BD21 +:10CB10001120F8BD70330020082000402021004083 +:10CB200058210040002000401C2100400C20004003 +:10CB30002DE9F0414F4D2B7F23B1020C1204B2F1CD +:10CB4000005F1CD16E6846B14B4A13B14FF40474B8 +:10CB500001E04FF40174C2F80843EC7D454A84B10A +:10CB6000147E002C4FD046B1434A13B14FF40473E6 +:10CB700001E04FF40173C2F80433112477E010246C +:10CB800075E0D175D06054761476002B40D1AA7E22 +:10CB90003AB933B9394A136042F81C3C364B01228A +:10CBA0001A606A6842BB364B344FDFF8E0801A6087 +:10CBB0001E463B68D8F8002034681AB95CB9002BCF +:10CBC000F7D008E03BB934B9FFF740FE6B7EEA7D51 +:10CBD0009A42EED823460022EA750BB1032446E0C0 +:10CBE0000CB10F2443E0234B9A7E01230AB1224A61 +:10CBF00000E0244A13603AE04FF401721E4B002417 +:10CC0000C3F8042333E01061117613BB0123BEE7A0 +:10CC10001D4B1C605C63C3F82404C3F82814A3F5FF +:10CC2000887301221A606B6883B9174A1449134844 +:10CC300016680C68036816B90CB9002BF8D00022EE +:10CC4000EA75002BCAD1002CCBD110E04FF404724E +:10CC5000D4E70D4B1C605C63C3F82404C3F82814AC +:10CC6000D3F8F02042F02002C3F8F020DBE72046A2 +:10CC7000BDE8F081703300200020004024210040F6 +:10CC800044210040042000401021004008210040C1 +:10CC9000074B1A7F52B99A7E42B906490A6041F899 +:10CCA0001C2CA1F5927101220A609A76704700BF90 +:10CCB0007033002024210040F0B56B4C6B4D217F78 +:10CCC00085B0002958D06A490A68BAB10023022207 +:10CCD0000B608DF80020674AD2F88014C2F88014E7 +:10CCE0000391D2F83C258DF80820E268E37523769D +:10CCF000019294E80A00684698471CE05E4B196868 +:10CD0000C9B15C4E1A60D6F83C35E07DDBB2984282 +:10CD100011D1237E5BB1D6F80072E16827F02007BD +:10CD2000C6F80072E3752369E360227601E0E168EA +:10CD3000E375FFF765FD2B686BB14C4B00221A6061 +:10CD4000E17D494B39B1DA754A4AD968D2F83C05D8 +:10CD5000C0B2FFF755FD494B1A68002A00F08280E7 +:10CD600000221A60A37D002B7CD0424BD3F84C05E7 +:10CD7000C0B2FFF757FD75E03E4BD3F8042312F421 +:10CD8000007F184622D03A4A1668FEB111604FF46F +:10CD90000172C3F80823A37E13B9394B01221A602C +:10CDA000344A02238DF80030D2F88034C2F880343F +:10CDB0000393E37D8DF80830E36801930023E37566 +:10CDC0002376684694E80A00984728E0D0F80433B0 +:10CDD0005B0724D52B4B1B680BB3FFF737FD627E37 +:10CDE000E17D214B91421AD11A7E42B1DA751A695E +:10CDF000D968DA600022587E1A765A760DE09B7E5A +:10CE000013B91F4B01221A601A4B4FF40172C3F879 +:10CE10000823607EE1680023E375FFF7F1FC1A4AFE +:10CE2000136863B1A38AA07D9BB2984202D9FFF731 +:10CE3000D1FC04E00023136008B1FFF7F3FC2B687A +:10CE400083B10A4B00221A60A37E13B1094B012261 +:10CE50001A60E27D044B2AB10022587ED968DA7547 +:10CE6000FFF7CEFC05B0F0BD703300204421004038 +:10CE700024210040002000401021004020210040DB +:10CE800004200040082100401C21004029DF704799 +:10CE900028DF704737B50B460C465A6814F80C1B50 +:10CEA000DD680092044A5B6952F82550024620462C +:10CEB000A84703B030BD00BF8434002038B5174CFC +:10CEC0002378182202FB03431A795869012A0DD0EE +:10CED000032A21D14FF080531B699BB2B0FBF3F0C2 +:10CEE0000F4B1B681844FFF7D3FF11E00C4A9969F8 +:10CEF00015689A68DB682D03521BB2F5805F1844F1 +:10CF00002944284434BF92084FF48062FFF7BEFFE3 +:10CF100018B90123A37038BD0F2038BD903300200D +:10CF20009434002070B5134D6E780A2E1FD02C78E3 +:10CF30003444E4B2092C84BF0A3CE4B2182606FB50 +:10CF40000454A261207103C9A360049BE360AB7821 +:10CF500004F1100282E803000BB1002003E0FFF7A8 +:10CF6000ADFF1128F9D06B7801336B7070BD0420D0 +:10CF700070BD00BF9033002038B5274B9A781D460E +:10CF8000002A47D0002402289C7002D0032831D008 +:10CF900038BD1B782149182000FB03500A688068BF +:10CFA0000132B0EB023F0A6019D86A780C60013A8E +:10CFB0006A705A1CD2B2182404FB0354092A88BF91 +:10CFC000A3F10902211D00202A70FFF763FF00234F +:10CFD00003222371A36022616361A361E3606B7824 +:10CFE0000D4CBBB1A378ABB9FFF768FF90B1112826 +:10CFF00007D138BD1A78182101FB023104310D2008 +:10D0000004E02378182101FB03410431BDE83840D6 +:10D01000FFF740BF38BD00BF90330020943400209C +:10D020000E4B002210B51A600D4B03241A705A7073 +:10D030009A7003F1F0011A719A601C615A619A6149 +:10D04000DA6018338B424FF00000F4D1054B1860C2 +:10D05000054B18605860986010BD00BF94340020E4 +:10D06000903300209034002084340020074A136855 +:10D07000032B1FBF0B60591C1160054A1DBF0168BF +:10D0800042F8231000200420704700BF9034002095 +:10D090008434002013B5CC180C43A40707D10093A7 +:10D0A00013460A4601460120FFF73CFF00E010202E +:10D0B00002B010BD07B500220B46009201460320C6 +:10D0C000FFF730FF03B05DF804FB13DF704718DF94 +:10D0D0007047000010B58AB004461022002101A854 +:10D0E000FDF730FA022301931A4B186800902CB117 +:10D0F00001A8FFF7ECFF08B1FDF72EFA4FF4F4207A +:10D10000FFF7E3FF08B1FDF727FA134B1349482255 +:10D11000684600F0ABFA08B1FDF71EFA012105AA36 +:10D12000084600F0F9FA08B1FDF716FA9DF820302C +:10D1300005A843F001038DF8203000F005FB08B18D +:10D14000FDF70AFA064800F0CBFA08B1FDF704FA39 +:10D150000AB010BDECDA070079D70700F0350020DF +:10D1600065D10700FFF708BF08B5054A142108205C +:10D17000FDF712FA18B1BDE80840FDF7EDB908BD9A +:10D1800098340020F0B51E4C1E4B217861BB1E4D1B +:10D190001E4E2A68186856F822600130B0421860A6 +:10D1A0002DDB19604FF0A043194FD3F8040557F851 +:10D1B0002270C64306F08006C3F8086500F08000C0 +:10D1C000144EC3F80C0530680130B842306016DBED +:10D1D0000132062A31602A6011DD8022C3F80C2555 +:10D1E000012323702960F0BD1A6842F20F710132E9 +:10D1F0008A4201DC1A60F0BD00221A602270F0BD84 +:10D20000EC350020E8350020043800200CDB070056 +:10D21000F0DA07003836002070B54FF080434FF049 +:10D22000A041D3F81C45B12C04BF0022C3F81C2533 +:10D23000414A4FF00303C1F81C37C2F80037C2F867 +:10D240000437C2F80837C2F80C37C2F810374FF469 +:10D25000CC53C1F80835394B1B680CBF012600269A +:10D26000B3F5F42F02D00020FDF776F94FF080538C +:10D270001B69B3F5805F02D00020FDF76DF9304BDC +:10D28000304A05210020FDF7A1FD08B1FDF764F942 +:10D290004FF0A0452C4BC5F81837FDF79DFF8023B4 +:10D2A000C5F80C3500F088FA00234FF47A7227494C +:10D2B000012000F0A3FAFDF7D7FF90B1FDF7E6FFDC +:10D2C00008B1FDF749F9B4F1B10018BF0120FFF72B +:10D2D00001FFFFF749FFFDF7F8FF50B1FDF73CF9FB +:10D2E00007E0B4F1B10018BF0120FFF7F3FEFFF72C +:10D2F0003BFF4FF0A043D3F810355B0600D52EB1AD +:10D30000FDF782FF48B1FDF727F906E043F2080375 +:10D310001868FDF7C3FE0028F2D043F20804206825 +:10D32000FDF7BCFE28B1FDF79FFF10B92068FDF79F +:10D3300077FF002070BD00BF2000005014100010C7 +:10D340008DAF07003C3600200C00030085D107009C +:10D350000C4B1B78062B10D10B4B1B681A070CD1FA +:10D360000A4B186800F0F003302B08D000F0E00002 +:10D37000A0F14003584258417047002070470120F7 +:10D38000704700BFE00F00F0E40F00F0E80F00F07E +:10D39000094B1B78062B0CD1084B1B681A0708D1C8 +:10D3A000074B186800F0F000A0F1300358425841D4 +:10D3B00070470020704700BFE00F00F0E40F00F05E +:10D3C000E80F00F008B5FFF7E3FF10B1684B694ABA +:10D3D0001A60FFF7BDFF28B1674B684A1B68C3F3AB +:10D3E00042331360FFF7D4FF20B1654AD36823F0BE +:10D3F0008073D360FFF7ACFF40B14FF08043002251 +:10D40000C3F80C21C3F81021C3F83825FFF7C0FF7B +:10D4100010B15C4B03221A60FFF7BAFF40B15A4BC0 +:10D4200005221A6001229A6700229A603F225A6000 +:10D43000564B1B78062B09D1554B1B681B0705D192 +:10D44000544B1B6803F0F003502B48D0524AD2F8DB +:10D45000883043F47003C2F88830BFF34F8FBFF3B6 +:10D460006F8F4FF01023D3F80022002A03DBD3F88C +:10D470000432002B2FDA494B0122C3F80425D3F8DC +:10D480000024002AFBD04FF010221521C2F8001210 +:10D49000D3F80024002AFBD04FF0102315223F4977 +:10D4A000C3F80422D1F800243C4B002AFAD0002211 +:10D4B000C3F80425D3F80024002AFBD0BFF34F8F14 +:10D4C0003549374BCA6802F4E0621343CB60BFF3BF +:10D4D0004F8F00BFFDE7334B334A1A6008BD4FF052 +:10D4E0008052324BD2F80414C3F82015D2F8081435 +:10D4F000C3F82415D2F80C14C3F82815D2F8101468 +:10D50000C3F82C15D2F81414C3F83015D2F8181437 +:10D51000C3F83415D2F81C14C3F84015D2F82014FF +:10D52000C3F84415D2F82414C3F84815D2F82814C7 +:10D53000C3F84C15D2F82C14C3F85015D2F8301497 +:10D54000C3F85415D2F83414C3F86015D2F838145F +:10D55000C3F86415D2F83C14C3F86815D2F8401427 +:10D56000C3F86C15D2F84424C3F870256EE700BFE9 +:10D5700074C007400DF0ADBA440200103C050040F5 +:10D58000F0ED00E0A005004010560040E00F00F074 +:10D59000E40F00F0E80F00F000ED00E000E00140D3 +:10D5A0000400FA05682C00200090D00300C0004061 +:10D5B00052DF704710DF704760DF704761DF7047F0 +:10D5C00008B5FCF7D7FF08BD2DE9F743224B1B78C0 +:10D5D000002B3ED0214E224F35683C68DFF8848016 +:10D5E000DFF88490B5FA85F5B4FA84F46D0964091E +:10D5F0006DBB01A8FFF7DCFF052807D010B1FCF7D1 +:10D60000ABFF04E033680198984700E00125DCB9DE +:10D61000B8F80030ADF80430D9F8003001A9184648 +:10D62000FFF7CCFF0528044608D018B1FCF794FF9B +:10D63000002404E03A681846904700E00124002DD9 +:10D64000D7D0002CD4D004E0002DD2D001E0002CA3 +:10D65000DED003B0BDE8F083083800201038002089 +:10D66000143800200A3800200C38002010B5C1B151 +:10D670008C0716D1134C216013490A80134A1449B0 +:10D680001360FFF797FFA8B9124B134901221A70D4 +:10D6900091F81633C3F34113934204D842F20203C4 +:10D6A0000DE007230BE00D4A93682BB1136843F498 +:10D6B00080031360034602E04FF480020A601846BC +:10D6C00010BD00BF0C3800200A3800201838002098 +:10D6D000C1D507000838002000E100E03438002000 +:10D6E00018B1034B1860002070470E20704700BF30 +:10D6F0001038002008B5074B1B682BB1984738B18C +:10D70000BDE80840FCF728BFBDE80840FFF75CBF54 +:10D7100008BD00BF1838002070B5144605460E46F7 +:10D72000142200212046FCF70DFF227B26720021E7 +:10D73000012361F30002238021612273657205B128 +:10D74000A372002070BD000007B5054B019302A92C +:10D75000019B41F8083DFFF72FFF03B05DF804FB84 +:10D76000002C002008B511B10020FCF7F5FEBDE843 +:10D770000840FFF729BF00000021024A0846FCF7D5 +:10D780002FBF00BF65D70700B0F5A07F0AD1064BB9 +:10D790001B7813B9054B02221A70054B054A1B680A +:10D7A00010681847704700BF1C3800201D38002043 +:10D7B000243800202038002008B5054A05480021FB +:10D7C00000F068F810B9044B01221A7008BD00BFC0 +:10D7D00089D7070028DB07001D38002010B5054C4D +:10D7E0002378032B04D1044800F0C2F802232370ED +:10D7F000002010BD1D38002028DB07002DE9F7436D +:10D800000546904699460F4691B3012803D088BB40 +:10D810004FF4807600E00646194C237863B3032B5F +:10D8200004D1FFF7DBFF08B1FCF796FE2378022B4B +:10D8300002D1144800F0A0F8134B12481D70134B8E +:10D840001F60134BC3F800900123009342463346F8 +:10D85000002100F0A6F823780A48022B02D100F03C +:10D8600083F801E000F072F803232370002004E045 +:10D870000E2002E0072000E0082003B0BDE8F0839E +:10D880001D38002028DB07001C3800202438002029 +:10D8900020380020F8B52B4E05790C2303FB0563D7 +:10D8A00007461B7A0C46002B47D1002A47D011B9F6 +:10D8B000254C04EBC5040C236B43F118F2500022F5 +:10D8C00063684B60964679793868D3B2994202F121 +:10D8D000010205D99B0003F5A07340F803E0F2E7CD +:10D8E000E17840F30730FEF74FFF39686278D1F8EE +:10D8F000043502F0030223F003031343C1F8043597 +:10D900003968A278D1F8083502F0030223F0030346 +:10D910001343C1F8083539682278D1F8103502F080 +:10D920000F0223F00F031343C1F810350C2303FB40 +:10D93000056501232B720020F8BD0820F8BD0720E3 +:10D94000F8BD00BF2838002030DB07000368012243 +:10D950001A600279034B0C2101FB023302221A7276 +:10D96000704700BF28380020036801221A60704702 +:10D97000036801225A60704703680122DA60704729 +:10D9800030B54FF480348C40056813B1C5F80443BA +:10D9900001E0C5F80843036801F5A87143F82120A8 +:10D9A00030BDF0B507689DF814E0D7F8005240F29A +:10D9B00001148C4025EA0404C7F800420568D5F834 +:10D9C00000422343C5F800327346BDE8F040FFF73C +:10D9D000D7BF00002DE9F0410E4CDFF844800E4E19 +:10D9E0000E4F0025236804F5E04080B25BB1D8F803 +:10D9F00004234FF48033AB40134204D00023236050 +:10DA00003368716898470434BC4205F10105E9D1D7 +:10DA1000BDE8F0814091004028380020509100403E +:10DA2000009000400649074A074B9B1A03DD043B60 +:10DA3000C858D050FBDCFFF7C5FCFCF70FFD000019 +:10DA400044DB0700002C0020782C0020FEE7FEE7D6 +:10DA5000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE79E +:10DA600010B5431E0A44914204D011F8014B03F84B +:10DA7000014FF8E710BD0000F8B500BFF8BC08BCC6 +:10DA80009E467047F8B500BFF8BC08BC9E4670477C +:10DA900043000000002C0020102D00201A1B191834 +:10DAA0000000000000509D003433002006000000FC +:10DAB0000800000007000000050000000000000052 +:10DAC000000000000000D601060000000600000073 +:10DAD0000800000007000000050000000000000032 +:10DAE000000000000000D601060000000100000751 +:10DAF000010000000200000003000000040000001C +:10DB000005000000080000000A00000010270000C7 +:10DB100088130000A60E0000C4090000530700008F +:10DB2000E2040000E8030000009000400004000050 +:0CDB3000000000060000000000000000E3 +:08DB3C0020C9FF7F0100000079 +:10DB440000000000000000000000000000000000D1 +:10DB540000000000000000000000000000000000C1 +:10DB640090DA070000000000000000000000000040 +:10DB740000000000000000000000000000000000A1 +:10DB84000000000000000000000000000000000091 +:10DB94000000000000000000000000000000000081 +:10DBA40019BF070089BF07000090D00325A4070010 +:08DBB40001A4070000000000BD +:020000020000FC +:020000041000EA +:0410140000A0070031 +:0410180000E00700ED +:040000037000DA258A +:00000001FF diff --git a/dist/package_nRF5_b_boards_index.json b/dist/package_nRF5_b_boards_index.json new file mode 100644 index 00000000..aab696f7 --- /dev/null +++ b/dist/package_nRF5_b_boards_index.json @@ -0,0 +1,829 @@ +{ + "packages": [ + { + "name": "sandeepmistry", + "maintainer": "Sandeep Mistry", + "websiteURL": "https://github.com/sandeepmistry/arduino-nRF5", + "email": "sandeep.mistry@gmail.com", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "platforms": [ + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.1.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.1.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.1.0.tar.gz", + "checksum": "MD5:1825f6420104225f5fee11b467923b7d", + "size": "591297", + "boards": [ + { + "name": "nRF52 DK" + }, + { + "name": "Bluz DK" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.2.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.2.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.2.0.tar.gz", + "checksum": "MD5:1ed95ee9030e4ca1371665258a3cdee4", + "size": "562847", + "boards": [ + { + "name": "nRF52 DK" + }, + { + "name": "Bluz DK" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "BBC micro:bit" + }, + { + "name": "OSHChip" + }, + { + "name": "Generic nRF51822" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.3.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.3.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.3.0.tar.gz", + "checksum": "MD5:3308f42e982e96a7f4329524ef46f5f8", + "size": "569306", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "Bluz DK" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.4.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.4.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.4.0.tar.gz", + "checksum": "MD5:E82DA39642AB48492A9FEDE8159871F5", + "size": "573440", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "Bluz DK" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.5.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.5.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.5.0.tar.gz", + "checksum": "MD5:BC732D8377244913AA7556083965FAA0", + "size": "575959", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "Bluz DK" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Electronut labs hackaBLE" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Sino:bit" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.5.1", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.5.1.tar.gz", + "archiveFileName": "arduino-nRF52-0.5.1.tar.gz", + "checksum": "MD5:02F963846158BBB4B3B69C78801D5FCB", + "size": "576878", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "Bluz DK" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Electronut labs hackaBLE" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Sino:bit" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.6.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.6.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.6.0.tar.gz", + "checksum": "MD5:edee8046e7f58bb06c466bb1c67ac02f", + "size": "577994", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "Bluz DK" + }, + { + "name": "Calliope mini" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Electronut labs hackaBLE" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Sino:bit" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.7.0", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/sandeepmistry/arduino-nRF5/archive/0.7.0.tar.gz", + "archiveFileName": "arduino-nRF52-0.7.0.tar.gz", + "checksum": "MD5:7316605161783e2b944e08fc44c7b6f8", + "size": "1487463", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "BBC micro:bit v2" + }, + { + "name": "Bluz DK" + }, + { + "name": "Calliope mini" + }, + { + "name": "decaWave DWM1001 Module Development Board" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Electronut labs hackaBLE" + }, + { + "name": "Electronut labs hackaBLE v2" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "Generic nRF52833" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Seeed Arch Link" + }, + { + "name": "Sino:bit" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + } + ] + }, + { + "name": "Nordic Semiconductor nRF5 Boards", + "architecture": "nRF5", + "version": "0.7.62", + "category": "Contributed", + "help": { + "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" + }, + "url": "https://github.com/biii-in/arduino-nRF5/raw/master/dist/arduino-nRF52-0.7.62.zip", + "archiveFileName": "arduino-nRF52-0.7.62.zip", + "checksum": "SHA-256:6572371C8139AC69BD85DFBC83A97428C7538B22634C4DF274B21917A59E391A", + "size": "2257666", + "boards": [ + { + "name": "BBC micro:bit" + }, + { + "name": "BBC micro:bit v2" + }, + { + "name": "Bluz DK" + }, + { + "name": "Calliope mini" + }, + { + "name": "decaWave DWM1001 Module Development Board" + }, + { + "name": "Electronut labs bluey" + }, + { + "name": "Electronut labs hackaBLE" + }, + { + "name": "Electronut labs hackaBLE v2" + }, + { + "name": "Generic nRF51822" + }, + { + "name": "Generic nRF52823" + }, + { + "name": "Generic nRF52833" + }, + { + "name": "OSHChip" + }, + { + "name": "ng-beacon" + }, + { + "name": "nRF51 Dongle" + }, + { + "name": "nRF51822 Development Kit" + }, + { + "name": "nRF52 DK" + }, + { + "name": "Nordic Beacon Kit" + }, + { + "name": "RedBear BLE Nano 2" + }, + { + "name": "RedBear Blend 2" + }, + { + "name": "RedBearLab BLE Nano" + }, + { + "name": "RedBearLab nRF51822" + }, + { + "name": "Seeed Arch Link" + }, + { + "name": "Sino:bit" + }, + { + "name": "Taida Century nRF52 mini board" + }, + { + "name": "TinyBLE" + }, + { + "name": "Waveshare BLE400" + } + ], + "toolsDependencies": [ + { + "packager": "sandeepmistry", + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4" + }, + { + "packager": "sandeepmistry", + "name": "openocd", + "version": "0.10.0-dev.nrf5" + }, + { + "packager": "sandeepmistry", + "name": "nrfutil", + "version": "0.5.2-SFE" + } + ] + } + ], + "tools": [ + { + "name": "gcc-arm-none-eabi", + "version": "5_2-2015q4", + "systems": [ + { + "host": "i386-apple-darwin11", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/gcc-arm-none-eabi-5_2-2015q4-20151219-mac.tar.bz2", + "archiveFileName": "gcc-arm-none-eabi-5_2-2015q4-20151219-mac.tar.bz2", + "size": "96372129", + "checksum": "MD5:603bcce8e59683ac27054b3197a53254" + }, + { + "host": "i686-linux-gnu", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2", + "archiveFileName": "gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2", + "size": "92811866", + "checksum": "MD5:f88caac80b4444a17344f57ccb760b90" + }, + { + "host": "x86_64-pc-linux-gnu", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2", + "archiveFileName": "gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2", + "size": "92811866", + "checksum": "MD5:f88caac80b4444a17344f57ccb760b90" + }, + { + "host": "i686-mingw32", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/gcc-arm-none-eabi-5_2-2015q4-20151219-win32.tar.bz2", + "archiveFileName": "gcc-arm-none-eabi-5_2-2015q4-20151219-win32.tar.bz2", + "size": "102981732", + "checksum": "MD5:32d950225b6c7c886f6225c1fc578934" + } + ] + }, + { + "name": "openocd", + "version": "0.10.0-dev.nrf5", + "systems": [ + { + "host": "i386-apple-darwin11", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/openocd-osx-0.10.0-dev-nrf5.tar.gz", + "archiveFileName": "openocd-osx-0.10.0-dev-nrf5.tar.gz", + "size": "1345243", + "checksum": "MD5:3ffaa4e7cd4b96770eec65002c5959e3" + }, + { + "host": "i686-linux-gnu", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/openocd-linux32-0.10.0-dev-nrf5.tar.gz", + "archiveFileName": "openocd-linux32-0.10.0-dev-nrf5.tar.gz", + "size": "3585042", + "checksum": "MD5:02b3f4a3004cae86631bf13837c84504" + }, + { + "host": "x86_64-pc-linux-gnu", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/openocd-linux32-0.10.0-dev-nrf5.tar.gz", + "archiveFileName": "openocd-linux32-0.10.0-dev-nrf5.tar.gz", + "size": "3585042", + "checksum": "MD5:02b3f4a3004cae86631bf13837c84504" + }, + { + "host": "i686-mingw32", + "url": "https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/openocd-win32-0.10.0-dev-nrf5.tar.gz", + "archiveFileName": "openocd-win32-0.10.0-dev-nrf5.tar.gz", + "size": "5498373", + "checksum": "MD5:3acd3b08afda2bb09e75a0de5ac7c3cd" + } + ] + }, + { + "name": "nrfutil", + "version": "0.5.2-SFE", + "systems": [ + { + "host": "i386-apple-darwin11", + "url": "https://cdn.sparkfun.com/assets/learn_tutorials/5/4/9/nrfutil-src-0.5.2-SFE-mac.tar.bz2", + "archiveFileName": "nrfutil-src-0.5.2-SFE-mac.tar.bz2", + "size": "11327272", + "checksum": "SHA-256:4c695c1acc82f1b1adedc1de05d09694c576ad3dba7da713b848cd1c93426773" + }, + { + "host": "i686-linux-gnu", + "url": "https://cdn.sparkfun.com/assets/learn_tutorials/5/4/9/nrfutil-src-0.5.2-SFE-linux64.tar.bz2", + "archiveFileName": "nrfutil-src-0.5.2-SFE-linux64.tar.bz2", + "size": "11555072", + "checksum": "SHA-256:96d8a733a0136e6cd372c64c70b1f663dc29566562de6bf0467896fbf5d2b0a3" + }, + { + "host": "x86_64-pc-linux-gnu", + "url": "https://cdn.sparkfun.com/assets/learn_tutorials/5/4/9/nrfutil-src-0.5.2-SFE-linux64.tar.bz2", + "archiveFileName": "nrfutil-src-0.5.2-SFE-linux64.tar.bz2", + "size": "11555072", + "checksum": "SHA-256:96d8a733a0136e6cd372c64c70b1f663dc29566562de6bf0467896fbf5d2b0a3" + }, + { + "host": "i686-mingw32", + "url": "https://cdn.sparkfun.com/assets/learn_tutorials/5/4/9/nrfutil-src-0.5.2-SFE-windows.tar.bz2", + "archiveFileName": "nrfutil-src-0.5.2-SFE-windows.tar.bz2", + "size": "11746447", + "checksum": "SHA-256:84d78202970a33e40711bf40a97fcfee02bc7462419d6c9026529afd0c9b2f4a" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/libraries/BADC/BADC.cpp b/libraries/BADC/BADC.cpp new file mode 100644 index 00000000..c9578dcc --- /dev/null +++ b/libraries/BADC/BADC.cpp @@ -0,0 +1,124 @@ +/// +/// @file BADC.cpp +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-04 +/// +/// @copyright Copyright (c) 2021 +/// +/// + +#include "BADC.h" + +#if 1 //defined(NRF52_SERIES) +#ifdef __cplusplus +extern "C" +{ +#endif + void SAADC_IRQHandler() + { + if (NRF_SAADC->EVENTS_STARTED) + { + NRF_SAADC->EVENTS_STARTED = 0; + NRF_SAADC->TASKS_SAMPLE = 0x01UL; + } + if (NRF_SAADC->EVENTS_END) + { + NRF_SAADC->EVENTS_END = 0; + NRF_SAADC->TASKS_STOP = 0x01UL; + } + if (NRF_SAADC->EVENTS_STOPPED) + { + NRF_SAADC->EVENTS_STOPPED = 0; + BADC._callback(BADC._results, BADC._ch_count); + BADC.convDone = true; + } + } +#ifdef __cplusplus +} +#endif + +void BADCClass::sartScanMode(uint8_t *ch_ids, uint8_t ch_count, BADC_Callback callback) +{ + this->_callback = callback; + this->_ch_count = ch_count; + // configure each channel + for (int i = 0; i < 8; i++) + { + if (i < ch_count) + { + NRF_SAADC->CH[i].PSELN = ch_ids[i]; + NRF_SAADC->CH[i].PSELP = ch_ids[i]; + NRF_SAADC->CH[i].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) | // disable +res bypass + ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) | // disable -res bypass + ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) | // set gain to 1/6 => 3.3/6 => 0.55 + ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) | // internal ref 0.6 + ((SAADC_CH_CONFIG_TACQ_40us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) | // taq 40us + ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); // single ended + } + else + { + NRF_SAADC->CH[i].PSELN = 0; + NRF_SAADC->CH[i].PSELP = 0; + } + } + // + NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_12bit; + NRF_SAADC->SAMPLERATE = ((SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos) | + (SAADC_SAMPLERATE_CC_Msk << SAADC_SAMPLERATE_CC_Pos)); + // + NRF_SAADC->INTEN = ((SAADC_INTEN_STARTED_Enabled << SAADC_INTEN_STARTED_Pos) | + (SAADC_INTEN_STOPPED_Enabled << SAADC_INTEN_STOPPED_Pos) | + (SAADC_INTEN_END_Enabled << SAADC_INTEN_END_Pos)); + NRF_SAADC->INTENSET = ((SAADC_INTENSET_STARTED_Enabled << SAADC_INTENSET_STARTED_Pos) | + (SAADC_INTENSET_STOPPED_Enabled << SAADC_INTENSET_STOPPED_Pos) | + (SAADC_INTENSET_END_Enabled << SAADC_INTENSET_END_Pos)); + // + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); + // + NVIC_ClearPendingIRQ(SAADC_IRQn); + NVIC_SetPriority(SAADC_IRQn, 3); + NVIC_EnableIRQ(SAADC_IRQn); + // + // while (!NRF_SAADC->EVENTS_STARTED) + // ; + // NRF_SAADC->EVENTS_STARTED = 0x00UL; + // NRF_SAADC->TASKS_SAMPLE = 0x01UL; +} + +void BADCClass::startSampling() +{ + BADC.convDone = false; + NRF_SAADC->RESULT.PTR = (uint32_t)_results; // + NRF_SAADC->RESULT.MAXCNT = _ch_count; // + NRF_SAADC->TASKS_START = 0x01UL; +} + +float BADCClass::getVoltsFromAdcVal(int16_t val) +{ + long volts = 0; + if (val > 0) + { + volts = val; + volts *= 3600; + volts >>= 12; + } + return (float)(volts / 1000.0); +} + +float BADCClass::readTemperature() +{ + NRF_TEMP->TASKS_START = 0x01UL; // start temp calculation + while (!NRF_TEMP->EVENTS_DATARDY) // wait for data + { + } + NRF_TEMP->EVENTS_DATARDY = 0x00UL; // clear event for future + NRF_TEMP->TASKS_STOP = 0x01UL; // stop calculations + + return ((float)NRF_TEMP->TEMP) / 4.0; +} + +BADCClass BADC; + +#endif diff --git a/libraries/BADC/BADC.h b/libraries/BADC/BADC.h new file mode 100644 index 00000000..1e9dd070 --- /dev/null +++ b/libraries/BADC/BADC.h @@ -0,0 +1,59 @@ +/// +/// @file BADC.h +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-04 +/// +/// @copyright Copyright (c) 2021 +/// +/// + +#ifndef BADC_h +#define BADC_h + +#include "Arduino.h" + +#define BADC_ADC_PIN_2 (1UL) /*!< AIN0 */ +#define BADC_ADC_PIN_3 (2UL) /*!< AIN1 */ +#define BADC_ADC_PIN_4 (3UL) /*!< AIN2 */ +#define BADC_ADC_PIN_5 (4UL) /*!< AIN3 */ +#define BADC_ADC_PIN_28 (5UL) /*!< AIN4 */ +#define BADC_ADC_PIN_29 (6UL) /*!< AIN5 */ +#define BADC_ADC_PIN_30 (7UL) /*!< AIN6 */ +#define BADC_ADC_PIN_31 (8UL) /*!< AIN7 */ +#define BADC_ADC_PIN_VDD (9UL) /*!< VDD */ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "nrf_nvic.h" +#ifdef __cplusplus +} +#endif + +typedef void (*BADC_Callback)(int16_t *result, uint8_t result_cnt); + +class BADCClass +{ +public: + BADC_Callback _callback; + uint8_t _ch_count; + int16_t _results[8]; + bool convDone; + + void sartScanMode(uint8_t *ch_ids, uint8_t ch_count, BADC_Callback callback); + + void startSampling(); + + float getVoltsFromAdcVal(int16_t val); + + float readTemperature(); + +private: +}; + +extern BADCClass BADC; + +#endif //NFC_h \ No newline at end of file diff --git a/libraries/BADC/examples/AdcScan/AdcScan.ino b/libraries/BADC/examples/AdcScan/AdcScan.ino new file mode 100644 index 00000000..826a8752 --- /dev/null +++ b/libraries/BADC/examples/AdcScan/AdcScan.ino @@ -0,0 +1,45 @@ +/// +/// @file AdcScan.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-05 +/// +/// @copyright Copyright (c) 2021 +/// +/// + +#include + +uint8_t adc_ch_seq[] = {BADC_ADC_PIN_3, BADC_ADC_PIN_4}; +int16_t adc_results[sizeof(adc_ch_seq)]; +uint8_t adc_result_cnt = 0; + +void adc_seq_Callback(int16_t *results, uint8_t result_cnt) +{ + memcpy(adc_results, results, result_cnt * sizeof(results[0])); + adc_result_cnt = result_cnt; +} + +void setup() +{ + Serial.begin(115200); + Serial.println("BADC Scan Start"); + BADC.sartScanMode(adc_ch_seq, sizeof(adc_ch_seq), adc_seq_Callback); +} + +void loop() +{ + BADC.startSampling(); + delay(500); + if (BADC.convDone) + { + Serial.print("ADC Val\t"); + for (int i = 0; i < adc_result_cnt; i++) + { + Serial.print(BADC.getVoltsFromAdcVal(adc_results[i])); + Serial.print(",\t"); + } + Serial.println(); + } +} \ No newline at end of file diff --git a/libraries/BADC/examples/tempMonitor/tempMonitor.ino b/libraries/BADC/examples/tempMonitor/tempMonitor.ino new file mode 100644 index 00000000..3f25d714 --- /dev/null +++ b/libraries/BADC/examples/tempMonitor/tempMonitor.ino @@ -0,0 +1,24 @@ +/// +/// @file tempMnitor.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-05 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +void setup() +{ + Serial.begin(115200); + Serial.println("Temp Start"); +} + +void loop() +{ + delay(1000); + Serial.print("Temp = "); + Serial.println(BADC.readTemperature()); +} \ No newline at end of file diff --git a/libraries/BADC/examples/vddMonitor/vddMonitor.ino b/libraries/BADC/examples/vddMonitor/vddMonitor.ino new file mode 100644 index 00000000..ee410180 --- /dev/null +++ b/libraries/BADC/examples/vddMonitor/vddMonitor.ino @@ -0,0 +1,37 @@ +/// +/// @file vddMonitor.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-05 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +uint8_t adc_ch_seq[] = {BADC_ADC_PIN_VDD}; +float vdd; + +void adc_seq_Callback(int16_t *results, uint8_t result_cnt) +{ + vdd = BADC.getVoltsFromAdcVal(results[0]); +} + +void setup() +{ + Serial.begin(115200); + Serial.println("BADC Scan Start"); + BADC.sartScanMode(adc_ch_seq, sizeof(adc_ch_seq), adc_seq_Callback); +} + +void loop() +{ + BADC.startSampling(); + delay(500); + if (BADC.convDone) + { + Serial.print("VDD = "); + Serial.println(vdd); + } +} \ No newline at end of file diff --git a/libraries/BADC/keywords.txt b/libraries/BADC/keywords.txt new file mode 100644 index 00000000..500f6a48 --- /dev/null +++ b/libraries/BADC/keywords.txt @@ -0,0 +1,29 @@ +####################################### +# Syntax Coloring Map BADC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +BADC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +sartScanMode KEYWORD2 +startSampling KEYWORD2 +getVoltsFromAdcVal KEYWORD2 +readTemperature KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +BADC_ADC_PIN_2 LITERAL1 +BADC_ADC_PIN_3 LITERAL1 +BADC_ADC_PIN_4 LITERAL1 +BADC_ADC_PIN_5 LITERAL1 +BADC_ADC_PIN_28 LITERAL1 +BADC_ADC_PIN_29 LITERAL1 +BADC_ADC_PIN_30 LITERAL1 +BADC_ADC_PIN_31 LITERAL1 +BADC_ADC_PIN_VDD LITERAL1 \ No newline at end of file diff --git a/libraries/BADC/library.properties b/libraries/BADC/library.properties new file mode 100644 index 00000000..bf8edfbf --- /dev/null +++ b/libraries/BADC/library.properties @@ -0,0 +1,9 @@ +name=BADC +version=1.0 +author=biii.in +maintainer=biii.in +sentence=Basic ADC library +paragraph= +category=ADC +url= +architectures=nRF5 \ No newline at end of file diff --git a/libraries/BLPCOMP/BLPCOMP.cpp b/libraries/BLPCOMP/BLPCOMP.cpp new file mode 100644 index 00000000..beebe7ab --- /dev/null +++ b/libraries/BLPCOMP/BLPCOMP.cpp @@ -0,0 +1,56 @@ +/// +/// @file BLPCOMP.cpp +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include "BLPCOMP.h" + +BLPCOMPClass BLPCOMP; + +#ifdef __cplusplus +extern "C" +{ +#endif + void LPCOMP_IRQHandler() + { + if (NRF_LPCOMP->EVENTS_UP) + { + NRF_LPCOMP->EVENTS_UP = 0; + BLPCOMP._crossCallback(1); + } + if (NRF_LPCOMP->EVENTS_DOWN) + { + NRF_LPCOMP->EVENTS_DOWN = 0; + BLPCOMP._crossCallback(0); + } + } +#ifdef __cplusplus +} +#endif + +bool BLPCOMPClass::startComparing(blpcomp_psel_pin_ids psel, blpcomp_nsel_ref_ids nsel, f_CrossCallback crossCallback) +{ + _crossCallback = crossCallback; + // + NRF_LPCOMP->PSEL = psel << LPCOMP_PSEL_PSEL_Pos; + NRF_LPCOMP->REFSEL = (nsel & 0x0F) << LPCOMP_REFSEL_REFSEL_Pos; + NRF_LPCOMP->EXTREFSEL = ((nsel >> 4) & 0x01) << LPCOMP_EXTREFSEL_EXTREFSEL_Pos; + NRF_LPCOMP->HYST = LPCOMP_HYST_HYST_Hyst50mV << LPCOMP_HYST_HYST_Pos; + NRF_LPCOMP->ANADETECT = LPCOMP_ANADETECT_ANADETECT_Cross << LPCOMP_ANADETECT_ANADETECT_Pos; + // + NRF_LPCOMP->INTENSET = ((LPCOMP_INTENSET_UP_Enabled << LPCOMP_INTENSET_UP_Pos) | + (LPCOMP_INTENSET_DOWN_Enabled << LPCOMP_INTENSET_DOWN_Pos)); + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->SHORTS = LPCOMP_SHORTS_READY_SAMPLE_Enabled << LPCOMP_SHORTS_READY_SAMPLE_Pos; + // + NVIC_ClearPendingIRQ(LPCOMP_IRQn); + NVIC_SetPriority(LPCOMP_IRQn, 3); + NVIC_EnableIRQ(LPCOMP_IRQn); + // + NRF_LPCOMP->TASKS_START = 1; +} \ No newline at end of file diff --git a/libraries/BLPCOMP/BLPCOMP.h b/libraries/BLPCOMP/BLPCOMP.h new file mode 100644 index 00000000..e7dbc38c --- /dev/null +++ b/libraries/BLPCOMP/BLPCOMP.h @@ -0,0 +1,72 @@ +/// +/// @file BLPCOMP.h +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#ifndef BLPCOMP_h +#define BLPCOMP_h + +#include "Arduino.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "nrf_nvic.h" +#ifdef __cplusplus +} +#endif + +typedef enum +{ + LPCOMP_PSEL_AIN0 = 0x00, /*!< AIN0 selected as analog input */ + LPCOMP_PSEL_AIN1 = 0x01, /*!< AIN1 selected as analog input */ + LPCOMP_PSEL_AIN2 = 0x02, /*!< AIN2 selected as analog input */ + LPCOMP_PSEL_AIN3 = 0x03, /*!< AIN3 selected as analog input */ + LPCOMP_PSEL_AIN4 = 0x04, /*!< AIN4 selected as analog input */ + LPCOMP_PSEL_AIN5 = 0x05, /*!< AIN5 selected as analog input */ + LPCOMP_PSEL_AIN6 = 0x06, /*!< AIN6 selected as analog input */ + LPCOMP_PSEL_AIN7 = 0x07 /*!< AIN7 selected as analog input */ +} blpcomp_psel_pin_ids; + +typedef enum +{ + LPCOMP_NSEL_REF_1_8Vdd = 0x00, /*!< VDD * 1/8 selected as reference */ + LPCOMP_NSEL_REF_2_8Vdd = 0x01, /*!< VDD * 2/8 selected as reference */ + LPCOMP_NSEL_REF_3_8Vdd = 0x02, /*!< VDD * 3/8 selected as reference */ + LPCOMP_NSEL_REF_4_8Vdd = 0x03, /*!< VDD * 4/8 selected as reference */ + LPCOMP_NSEL_REF_5_8Vdd = 0x04, /*!< VDD * 5/8 selected as reference */ + LPCOMP_NSEL_REF_6_8Vdd = 0x05, /*!< VDD * 6/8 selected as reference */ + LPCOMP_NSEL_REF_7_8Vdd = 0x06, /*!< VDD * 7/8 selected as reference */ + LPCOMP_NSEL_REF_1_16Vdd = 0x08, /*!< VDD * 1/16 selected as reference */ + LPCOMP_NSEL_REF_3_16Vdd = 0x09, /*!< VDD * 3/16 selected as reference */ + LPCOMP_NSEL_REF_5_16Vdd = 0x0A, /*!< VDD * 5/16 selected as reference */ + LPCOMP_NSEL_REF_7_16Vdd = 0x0B, /*!< VDD * 7/16 selected as reference */ + LPCOMP_NSEL_REF_9_16Vdd = 0x0C, /*!< VDD * 9/16 selected as reference */ + LPCOMP_NSEL_REF_11_16Vdd = 0x0D, /*!< VDD * 11/16 selected as reference */ + LPCOMP_NSEL_REF_13_16Vdd = 0x0E, /*!< VDD * 13/16 selected as reference */ + LPCOMP_NSEL_REF_15_16Vdd = 0x0F, /*!< VDD * 15/16 selected as reference */ + LPCOMP_NSEL_REF_AIN0 = 0x07, /*!< External analog reference selected */ + LPCOMP_NSEL_REF_AIN1 = 0x17 /*!< External analog reference selected */ +} blpcomp_nsel_ref_ids; + +typedef void (*f_CrossCallback)(uint8_t); + +class BLPCOMPClass +{ +public: + f_CrossCallback _crossCallback; + bool startComparing(blpcomp_psel_pin_ids psel, blpcomp_nsel_ref_ids nsel, f_CrossCallback crossCallback); + +private: +}; + +extern BLPCOMPClass BLPCOMP; + +#endif \ No newline at end of file diff --git a/libraries/BLPCOMP/examples/lpcomp_test/lpcomp_test.ino b/libraries/BLPCOMP/examples/lpcomp_test/lpcomp_test.ino new file mode 100644 index 00000000..9de9d112 --- /dev/null +++ b/libraries/BLPCOMP/examples/lpcomp_test/lpcomp_test.ino @@ -0,0 +1,33 @@ +/// +/// @file rtc_tick.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +uint8_t _state = 0; +void crossHandle(uint8_t state) +{ + _state = state; +} + +void setup() +{ + Serial.begin(115200); + Serial.println("LPCOMP START"); + delay(1000); + BLPCOMP.startComparing(LPCOMP_PSEL_AIN0, LPCOMP_NSEL_REF_4_8Vdd, crossHandle); +} + +void loop() +{ + Serial.print(_state ? "High ->" : "Low ->"); + Serial.println("detected"); + __WFE(); + __WFI(); +} \ No newline at end of file diff --git a/libraries/BLPCOMP/keywords.txt b/libraries/BLPCOMP/keywords.txt new file mode 100644 index 00000000..60fc0421 --- /dev/null +++ b/libraries/BLPCOMP/keywords.txt @@ -0,0 +1,42 @@ +####################################### +# Syntax Coloring Map BADC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +BLPCOMP KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +startComparing KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +LPCOMP_PSEL_AIN0 LITERAL1 +LPCOMP_PSEL_AIN1 LITERAL1 +LPCOMP_PSEL_AIN2 LITERAL1 +LPCOMP_PSEL_AIN3 LITERAL1 +LPCOMP_PSEL_AIN4 LITERAL1 +LPCOMP_PSEL_AIN5 LITERAL1 +LPCOMP_PSEL_AIN6 LITERAL1 +LPCOMP_PSEL_AIN7 LITERAL1 +LPCOMP_NSEL_REF_1_8Vdd LITERAL1 +LPCOMP_NSEL_REF_2_8Vdd LITERAL1 +LPCOMP_NSEL_REF_3_8Vdd LITERAL1 +LPCOMP_NSEL_REF_4_8Vdd LITERAL1 +LPCOMP_NSEL_REF_5_8Vdd LITERAL1 +LPCOMP_NSEL_REF_6_8Vdd LITERAL1 +LPCOMP_NSEL_REF_7_8Vdd LITERAL1 +LPCOMP_NSEL_REF_1_16Vdd LITERAL1 +LPCOMP_NSEL_REF_3_16Vdd LITERAL1 +LPCOMP_NSEL_REF_5_16Vdd LITERAL1 +LPCOMP_NSEL_REF_7_16Vdd LITERAL1 +LPCOMP_NSEL_REF_9_16Vdd LITERAL1 +LPCOMP_NSEL_REF_11_16Vdd LITERAL1 +LPCOMP_NSEL_REF_13_16Vdd LITERAL1 +LPCOMP_NSEL_REF_15_16Vdd LITERAL1 +LPCOMP_NSEL_REF_AIN0 LITERAL1 +LPCOMP_NSEL_REF_AIN1 LITERAL1 \ No newline at end of file diff --git a/libraries/BLPCOMP/library.properties b/libraries/BLPCOMP/library.properties new file mode 100644 index 00000000..656f4f98 --- /dev/null +++ b/libraries/BLPCOMP/library.properties @@ -0,0 +1,9 @@ +name=BLPCOMP +version=1.0 +author=biii.in +maintainer=biii.in +sentence=Basic LPCOMP library +paragraph= +category=COMP +url= +architectures=nRF5 \ No newline at end of file diff --git a/libraries/BRTC/BRTC.cpp b/libraries/BRTC/BRTC.cpp new file mode 100644 index 00000000..5f39653f --- /dev/null +++ b/libraries/BRTC/BRTC.cpp @@ -0,0 +1,220 @@ +/// +/// @file BRTC.cpp +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include "BRTC.h" + +BRTCClass BRTC; + +#define RTC_MAX_TICK_COUNT ((1ul << 24ul) - 128ul) +#define RTC_MIN_TICK_COUNT (8ul) + +#ifdef __cplusplus +extern "C" +{ +#endif + void RTC2_IRQHandler() + { + if (NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC]) + { + NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC] = 0; + NRF_RTC2->CC[RTC_TIMER_CHANNEL_PERIODIC] += BRTC.rtc_stm.ch[RTC_TIMER_CHANNEL_PERIODIC].ms_tick; + if (BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC]) + { + BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC](); + } + } + else + { + for (int chid = RTC_TIMER_CHANNEL_ONE_SHOT_1; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) + { + if (NRF_RTC2->EVENTS_COMPARE[chid]) + { + NRF_RTC2->EVENTS_COMPARE[chid] = 0; + if (BRTC.rtc_stm._tickCallback[chid]) + { + BRTC.rtc_stm._tickCallback[chid](); + } + NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); + } + } + } + } +#ifdef __cplusplus +} +#endif + +uint64_t BRTCClass::getTickCount(uint32_t msPeriod) +{ + uint64_t ticks = msPeriod; + ticks *= 32768; + ticks /= 1000; + return ticks; +} + +bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool debug) +{ + bool error = false; + this->rtc_stm.ch[ch_id].ms_delay = msPeriod; + uint32_t min_ms = 0xFFFFFFFFul; + uint32_t max_ms = 0; + // update min and max delay + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) + { + if (this->rtc_stm.ch[chid].ms_delay > 0) + { + if (this->rtc_stm.ch[chid].ms_delay < min_ms) + { + min_ms = this->rtc_stm.ch[chid].ms_delay; + } + if (this->rtc_stm.ch[chid].ms_delay > max_ms) + { + max_ms = this->rtc_stm.ch[chid].ms_delay; + } + } + } + error = (min_ms > max_ms); + if (!error) + { + // setup nrf rtc to tick at ms provided + uint64_t tick_in_prescaller = 0; + uint64_t ticks = getTickCount(max_ms); + uint32_t prescaller = 0; + do + { + prescaller++; + tick_in_prescaller = ticks / prescaller; + } while (tick_in_prescaller > RTC_MAX_TICK_COUNT); + // + if (debug) + { + Serial.print("PSR "); + Serial.println(prescaller); + } + error = (prescaller & 0xF000); + if (!error) + { + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) + { + if (this->rtc_stm.ch[chid].ms_delay > 0) + { + this->rtc_stm.ch[chid].ms_tick = getTickCount(this->rtc_stm.ch[chid].ms_delay); + // + if (debug) + { + Serial.print(chid); + Serial.print(": MS>"); + Serial.print(this->rtc_stm.ch[chid].ms_delay); + Serial.print(" TK>"); + Serial.println(this->rtc_stm.ch[chid].ms_tick, HEX); + } + // + if (this->rtc_stm.ch[chid].ms_tick < RTC_MIN_TICK_COUNT) + { + this->rtc_stm.ch[chid].ms_delay = 0; + error = true; + } + } + } + // everything is okay till now update all channels + if (!error) + { + NRF_RTC2->PRESCALER = prescaller - 1; + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) + { + if (this->rtc_stm.ch[chid].ms_delay > 0) + { + NRF_RTC2->CC[chid] = NRF_RTC2->COUNTER + this->rtc_stm.ch[chid].ms_tick; + NRF_RTC2->INTENSET = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); + } + else + { + NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); + } + } + } + else + { + if (debug) + { + Serial.println("RTC: RNG Over"); + } + } + } + else + { + if (debug) + { + Serial.println("RTC: PSR Over"); + } + } + } + else + { + if (debug) + { + Serial.print("RTC: mM ERR: "); + Serial.print(min_ms); + Serial.print(" "); + Serial.print(max_ms); + Serial.println(); + } + } + return !error; +} + +bool BRTCClass::setPeriodicTimer(uint32_t msPeriod, f_TickCallback periodicCallback, bool debug) +{ + NRF_RTC2->TASKS_STOP = 1; + if (updateTickCounts(RTC_TIMER_CHANNEL_PERIODIC, msPeriod, debug)) + { + this->rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC] = periodicCallback; + // + NVIC_ClearPendingIRQ(RTC2_IRQn); + NVIC_SetPriority(RTC2_IRQn, 3); + NVIC_EnableIRQ(RTC2_IRQn); + NRF_RTC2->TASKS_START = 1; + return true; + } + NRF_RTC2->TASKS_START = 1; + return false; +} + +bool BRTCClass::setOneshotTimer(rtc_timer_ch_ids ch_id, uint32_t msDelay, f_TickCallback oneshotCallback, bool debug) +{ + if ((ch_id > RTC_TIMER_CHANNEL_PERIODIC) && + (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) + { + NRF_RTC2->TASKS_STOP = 1; + if (updateTickCounts(ch_id, msDelay, debug)) + { + this->rtc_stm._tickCallback[ch_id] = oneshotCallback; + // + NVIC_ClearPendingIRQ(RTC2_IRQn); + NVIC_SetPriority(RTC2_IRQn, 3); + NVIC_EnableIRQ(RTC2_IRQn); + NRF_RTC2->TASKS_START = 1; + return true; + } + NRF_RTC2->TASKS_START = 1; + } + return false; +} + +bool BRTCClass::cancelOneshotTimer(rtc_timer_ch_ids ch_id) +{ + if ((ch_id > RTC_TIMER_CHANNEL_PERIODIC) && + (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) + { + NRF_RTC2->TASKS_STOP = 1; + NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + ch_id))); + NRF_RTC2->TASKS_START = 1; + } + return false; +} \ No newline at end of file diff --git a/libraries/BRTC/BRTC.h b/libraries/BRTC/BRTC.h new file mode 100644 index 00000000..8124a059 --- /dev/null +++ b/libraries/BRTC/BRTC.h @@ -0,0 +1,93 @@ +/// +/// @file BRTC.h +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#ifndef BRTC_h +#define BRTC_h + +#include "Arduino.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "nrf_nvic.h" +#ifdef __cplusplus +} +#endif + +typedef enum +{ + RTC_TIMER_CHANNEL_PERIODIC = 0, + RTC_TIMER_CHANNEL_ONE_SHOT_1, + RTC_TIMER_CHANNEL_ONE_SHOT_2, + RTC_TIMER_CHANNEL_ONE_SHOT_3, + RTC_TIMER_CHANNEL_ONE_SHOT_MAX, +} rtc_timer_ch_ids; + +typedef void (*f_TickCallback)(void); + +class BRTCClass +{ +public: + struct + { + struct + { + uint32_t ms_delay; + uint32_t ms_tick; + } ch[RTC_TIMER_CHANNEL_ONE_SHOT_MAX]; + f_TickCallback _tickCallback[RTC_TIMER_CHANNEL_ONE_SHOT_MAX]; + } rtc_stm; + + /// + /// @brief Set the Periodic Tick object + /// + /// @param msPeriod + /// @param tickCallback + /// @return true + /// @return false + /// + bool setPeriodicTimer(uint32_t msPeriod, f_TickCallback periodicCallback, bool debug = false); + + /// + /// @brief Set the Oneshot Timer tick handler + /// + /// @param ch_id channel id to be used to set this timer interrupt + /// @param msDelay ms delay from current time after which tickCallback should get called + /// @param tickCallback function to be called after expiry of + /// @return true + /// @return false + /// + bool setOneshotTimer(rtc_timer_ch_ids ch_id, uint32_t msDelay, f_TickCallback oneshotCallback, bool debug = false); + + /// + /// @brief + /// + /// @param ch_id + /// @return true + /// @return false + /// + bool cancelOneshotTimer(rtc_timer_ch_ids ch_id); + +private: + /// + /// @brief + /// + /// @return true + /// @return false + /// + uint64_t getTickCount(uint32_t ms); + bool updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t ms, bool debug = false); +}; + +extern BRTCClass BRTC; + +#endif \ No newline at end of file diff --git a/libraries/BRTC/examples/rtc_tick/rtc_tick.ino b/libraries/BRTC/examples/rtc_tick/rtc_tick.ino new file mode 100644 index 00000000..bf8b8c07 --- /dev/null +++ b/libraries/BRTC/examples/rtc_tick/rtc_tick.ino @@ -0,0 +1,55 @@ +/// +/// @file rtc_tick.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +bool tick = false; +uint8_t tickCount = 0; +bool timer1expired = false; + +void tickHandle() +{ + tick = true; + tickCount++; +} + +void timer1Expired() +{ + timer1expired = true; +} + +void setup() +{ + Serial.begin(115200); + Serial.println("RTC START"); + delay(1000); + BRTC.setPeriodicTimer(10000, tickHandle); +} + +void loop() +{ + if (tick) + { + tick = false; + Serial.println("tick"); + if (tickCount >= 2) + { + tickCount = 0; + BRTC.setOneshotTimer(RTC_TIMER_CHANNEL_ONE_SHOT_1, 2000, timer1Expired); + } + } + if (timer1expired) + { + timer1expired = false; + Serial.println("timer1expired"); + } + __WFE(); + __WFI(); +} \ No newline at end of file diff --git a/libraries/BRTC/keywords.txt b/libraries/BRTC/keywords.txt new file mode 100644 index 00000000..834768b8 --- /dev/null +++ b/libraries/BRTC/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map BADC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +BRTC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +setPeriodicTimer KEYWORD2 +setOneshotTimer KEYWORD2 +cancelOneshotTimer KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +RTC_TIMER_CHANNEL_PERIODIC LITERAL1 +RTC_TIMER_CHANNEL_ONE_SHOT_1 LITERAL1 +RTC_TIMER_CHANNEL_ONE_SHOT_2 LITERAL1 +RTC_TIMER_CHANNEL_ONE_SHOT_3 LITERAL1 +RTC_TIMER_CHANNEL_ONE_SHOT_MAX LITERAL1 \ No newline at end of file diff --git a/libraries/BRTC/library.properties b/libraries/BRTC/library.properties new file mode 100644 index 00000000..4c51dd2c --- /dev/null +++ b/libraries/BRTC/library.properties @@ -0,0 +1,9 @@ +name=BRTC +version=1.0 +author=biii.in +maintainer=biii.in +sentence=Basic RTC library +paragraph= +category=RTC +url= +architectures=nRF5 \ No newline at end of file diff --git a/libraries/NFC/NFC.cpp b/libraries/NFC/NFC.cpp new file mode 100644 index 00000000..2b844b07 --- /dev/null +++ b/libraries/NFC/NFC.cpp @@ -0,0 +1,138 @@ +/* + NFC class for nRF52. + Written by Chiara Ruggeri (chiara@arduino.org) + + Copyright (c) 2016 Arduino. All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Enjoy! +*/ + +#include "NFC.h" + +void nfc_callback(void *context, NfcEvent event, const char *data, size_t dataLength) +{ + NFC.onService(); +} + +uint8_t ndef_msg_buf[256]; + +void NFCClass::setTXTmessage(const char TXTMessage[], const char language[]) +{ + + nfcSetup(nfc_callback, NULL); + uint32_t len = sizeof(ndef_msg_buf); + uint8_t sizeM = strlen(TXTMessage); + uint8_t sizeL = strlen(language); + + NFC_NDEF_MSG_DEF(welcome_msg, 1); + NFC_NDEF_TEXT_RECORD_DESC_DEF(en_text_rec, + UTF_8, + (uint8_t *)language, + sizeL, + (uint8_t *)TXTMessage, + sizeM); + nfc_ndef_msg_record_add(&NFC_NDEF_MSG(welcome_msg), + &NFC_NDEF_TEXT_RECORD_DESC(en_text_rec)); + + nfc_ndef_msg_encode(&NFC_NDEF_MSG(welcome_msg), + ndef_msg_buf, + &len); + + nfcSetPayload((char *)ndef_msg_buf, len); +} + +void NFCClass::setURImessage(const char URL[], nfc_uri_id_t type) +{ + uint8_t size = strlen(URL); + memset(ndef_msg_buf, 0, 256); + uint32_t len = sizeof(ndef_msg_buf); + nfcSetup(nfc_callback, NULL); + nfc_uri_msg_encode(type, + (uint8_t *)URL, + size, + ndef_msg_buf, + &len); + nfcSetPayload((char *)ndef_msg_buf, len); +} + +void NFCClass::setAPPmessage(const char android_app[], const char windows_app[]) +{ + uint8_t sizeA = strlen(android_app); + uint8_t sizeW = strlen(windows_app); + uint32_t len = sizeof(ndef_msg_buf); + nfcSetup(nfc_callback, NULL); + nfc_launchapp_msg_encode((uint8_t *)android_app, + sizeA, + (uint8_t *)windows_app, + sizeW, + ndef_msg_buf, + &len); + nfcSetPayload((char *)ndef_msg_buf, len); +} + +// void NFCClass::setOobPairingKey() +// { +// uint8_t key[16]; +// uint8_t random_values_length, rand_values, generated; +// static ble_advdata_tk_value_t oob_auth_key; +// uint32_t len = sizeof(ndef_msg_buf); +// //try to generate the key randomly +// sd_rand_application_pool_capacity_get(&random_values_length); +// //we need only 16 bytes +// if (random_values_length > 16) +// random_values_length = 16; +// //wait until values are generated +// do +// sd_rand_application_bytes_available_get(&generated); +// while (generated < random_values_length); +// //get the random data +// sd_rand_application_vector_get(key, random_values_length); +// //if random values are less than 16 add static data to fill the buffer +// if (random_values_length < 16) +// for (int i = random_values_length; i < 16; i++) +// key[i] = i; +// memcpy(oob_auth_key.tk, key, 16); +// nfcSetup(nfc_callback, NULL); +// nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_FULL, +// &oob_auth_key, +// ndef_msg_buf, +// &len); +// nfcSetPayload((char *)ndef_msg_buf, len); +// } + +void NFCClass::start() +{ + nfcStartEmulation(); +} + +void NFCClass::stop() +{ + nfcStopEmulation(); +} + +void NFCClass::registerCallback(void (*function)(void)) +{ + Callback = function; +} + +void NFCClass::onService() +{ + if (Callback) + Callback(); +} + +NFCClass NFC; diff --git a/libraries/NFC/NFC.h b/libraries/NFC/NFC.h new file mode 100644 index 00000000..8df6472d --- /dev/null +++ b/libraries/NFC/NFC.h @@ -0,0 +1,128 @@ +/* + NFC class for nRF52. + Written by Chiara Ruggeri (chiara@arduino.org) + + Copyright (c) 2016 Arduino. All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Enjoy! +*/ + +#ifndef NFC_h +#define NFC_h + +#include "Arduino.h" + +class NFCClass +{ + +public: + /** + * @brief + * Name: + * setTXTmessage + * Description: + * Specify a text message that will pop up on a device when it is + * near to the board. + * Arguments: + * -TXTMessage: array of char containing the message + * -language: array of char containing the message's language code + */ + void setTXTmessage(const char TXTMessage[], const char language[]); + + /** + * @brief + * Name: + * setURImessage + * Description: + * Specify an URI message that will pop up on a device when it is + * near to the board. + * Arguments: + * -URL: address to the resource to reach + * -type: type of the URI message (see documentation for details) + */ + void setURImessage(const char URL[], nfc_uri_id_t type); + + /** + * @brief + * Name: + * setAPPmessage + * Description: + * Specify an application that will try to be open on a device when + * it is near to the board. + * Arguments: + * -android_app: package of the Android application + * -windows_app: ID of the Windows application + */ + void setAPPmessage(const char android_app[], const char windows_app[]); + + /** + * @brief + * Name: + * setOobPairingKey + * Description: + * Set a message for pairing the board with another BLE device. + * This function is part of OOB bond procedure and should be + * used with BLE library. + */ + // void setOobPairingKey(void); + + /** + * @brief + * Name: + * start + * Description: + * Start the NFC module. + */ + void start(void); + + /** + * @brief + * Name: + * stop + * Description: + * Stop the NFC module. + */ + void stop(void); + + /** + * @brief + * Name: + * registerCallback + * Description: + * Attach a function passed by the user to the "field detected" event. + * Argument: + * -function: function to be called when event happens + */ + void registerCallback(void (*function)(void)); + + /** + * @brief + * Name: + * onService + * Description: + * Service function called by ISR. + */ + void onService(void); + +private: + // Callback user function + void (*Callback)(void); +}; + +extern NFCClass NFC; + +#endif //NFC_h \ No newline at end of file diff --git a/libraries/NFC/examples/SendText/SendText.ino b/libraries/NFC/examples/SendText/SendText.ino new file mode 100644 index 00000000..47749197 --- /dev/null +++ b/libraries/NFC/examples/SendText/SendText.ino @@ -0,0 +1,30 @@ +/* + SendText.ino + + Written by Chiara Ruggeri (chiara@arduino.org) + + This example for the Arduino Primo board shows how to use + NFC library. + It sets a text message specifying the language code, then + starts the module, so that when a device with NFC is near + to the board the message "Hello World!" will be sent. + + This example code is in the public domain. + +*/ + +#include + + +void setup() { + // set the NFC message as first parameter and the language code as second + NFC.setTXTmessage("Hello World!", "en"); + // start the NFC module + NFC.start(); +} + + +void loop() { +} + + diff --git a/libraries/NFC/examples/SendURL/SendURL.ino b/libraries/NFC/examples/SendURL/SendURL.ino new file mode 100644 index 00000000..9fd20c85 --- /dev/null +++ b/libraries/NFC/examples/SendURL/SendURL.ino @@ -0,0 +1,62 @@ +/* + SendURL.ino + + Written by Chiara Ruggeri (chiara@arduino.org) + + This example for the Arduino Primo board shows how to use + NFC library. + It sets an URI message and then starts the module, so that + when a device with NFC is near to the board the message + http://www.arduino.org will be sent. + A list of all possible URI message can be found here: + + NFC_URI_HTTP_WWW "http://www./" + NFC_URI_HTTPS_WWW "https://www./" + NFC_URI_HTTP "http:" + NFC_URI_HTTPS "https:" + NFC_URI_TEL "tel:" + NFC_URI_MAILTO "mailto:" + NFC_URI_FTP_ANONYMOUS "ftp://anonymous:anonymous@" + NFC_URI_FTP_FTP "ftp://ftp." + NFC_URI_FTPS "ftps://" + NFC_URI_SFTP, "sftp://" + NFC_URI_SMB "smb://" + NFC_URI_NFS "nfs://" + NFC_URI_FTP "ftp://" + NFC_URI_DAV "dav://" + NFC_URI_NEWS "news:" + NFC_URI_TELNET "telnet://" + NFC_URI_IMAP "imap:" + NFC_URI_RTSP "rtsp://" + NFC_URI_URN "urn:" + NFC_URI_POP "pop:" + NFC_URI_SIP "sip:" + NFC_URI_SIPS "sips:" + NFC_URI_TFTP "tftp:" + NFC_URI_BTSPP "btspp://" + NFC_URI_BTL2CAP "btl2cap://" + NFC_URI_BTGOEP "btgoep://" + NFC_URI_TCPOBEX "tcpobex://" + NFC_URI_IRDAOBEX "irdaobex://" + NFC_URI_FILE "file://" + NFC_URI_URN_EPC_ID "urn:epc:id:" + NFC_URI_URN_EPC_TAG "urn:epc:tag:" + NFC_URI_URN_EPC_PAT "urn:epc:pat:" + NFC_URI_URN_EPC_RAW "urn:epc:raw:" + NFC_URI_URN_EPC "urn:epc:" + NFC_URI_URN_NFC "urn:nfc:" + + This example code is in the public domain. + +*/ + +#include + +void setup() { + NFC.setURImessage("arduino.org", NFC_URI_HTTP_WWW); + NFC.start(); +} + + +void loop() { +} \ No newline at end of file diff --git a/libraries/NFC/examples/StartApp/StartApp.ino b/libraries/NFC/examples/StartApp/StartApp.ino new file mode 100644 index 00000000..732760e4 --- /dev/null +++ b/libraries/NFC/examples/StartApp/StartApp.ino @@ -0,0 +1,46 @@ +/* + SendText.ino + + Written by Chiara Ruggeri (chiara@arduino.org) + + This example for the Arduino Primo board shows how to use + NFC library. + It sets a app message specifying the package name (for Android) + and the ID application (for Windows phone), then starts the + module, so that when a device with NFC is near to the board + it will try to open the application (if present) or will + look for the app in the store. Finally it register a callback + function that will be called any time an NFC field is detected + (it means that a device is near). + + This example code is in the public domain. + +*/ + +#include + +//specify the package name for windows and android phone and insert the EOL character at the end '\0' +static const char android_package_name[] = {'n', 'o', '.', 'n', 'o', 'r', 'd', 'i', 'c', 's', + 'e', 'm', 'i', '.', 'a', 'n', 'd', 'r', 'o', 'i', + 'd', '.', 'n', 'r', 'f', 't', 'o', 'o', 'l', 'b', + 'o', 'x', '\0'}; + +static const char windows_application_id[] = {'{', 'e', '1', '2', 'd', '2', 'd', 'a', '7', '-', + '4', '8', '8', '5', '-', '4', '0', '0', 'f', '-', + 'b', 'c', 'd', '4', '-', '6', 'c', 'b', 'd', '5', + 'b', '8', 'c', 'f', '6', '2', 'c', '}', '\0'}; + +void setup() { + Serial.begin(9600); + NFC.setAPPmessage(android_package_name, windows_application_id); + NFC.start(); + NFC.registerCallback(myFunction); +} + + +void loop() { +} + +void myFunction(){ + Serial.println("An user viewed the application"); +} \ No newline at end of file diff --git a/libraries/NFC/keywords.txt b/libraries/NFC/keywords.txt new file mode 100644 index 00000000..c90fe1d6 --- /dev/null +++ b/libraries/NFC/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map NFC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +NFC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +start KEYWORD2 +stop KEYWORD2 +setTXTmessage KEYWORD2 +setURImessage KEYWORD2 +setAPPmessage KEYWORD2 +setOobPairingKey KEYWORD2 +registerCallback KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/NFC/library.properties b/libraries/NFC/library.properties new file mode 100644 index 00000000..a5acfa77 --- /dev/null +++ b/libraries/NFC/library.properties @@ -0,0 +1,9 @@ +name=NFC +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Allows Arduino Primo boards to use the NFC tag onboard +paragraph= +category=Communication +url=http://www.arduino.org/learning/reference/NFC +architectures=nRF5 \ No newline at end of file diff --git a/variants/I.ONIX_TypeC/pins_arduino.h b/variants/I.ONIX_TypeC/pins_arduino.h new file mode 100644 index 00000000..3ef4d4a9 --- /dev/null +++ b/variants/I.ONIX_TypeC/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/I.ONIX_TypeC/variant.cpp b/variants/I.ONIX_TypeC/variant.cpp new file mode 100644 index 00000000..02d405b6 --- /dev/null +++ b/variants/I.ONIX_TypeC/variant.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +const uint32_t g_ADigitalPinMap[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 +}; diff --git a/variants/I.ONIX_TypeC/variant.h b/variants/I.ONIX_TypeC/variant.h new file mode 100644 index 00000000..0465065a --- /dev/null +++ b/variants/I.ONIX_TypeC/variant.h @@ -0,0 +1,87 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_NRF52_DK_ +#define _VARIANT_NRF52_DK_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (32u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) + +// LEDs +#define PIN_LED_EN (10u) +#define PIN_LED_RED (9u) +#define PIN_LED_GREEN (3u) +#define PIN_LED_BLUE (4u) +#define LED_BUILTIN PIN_LED_RED + +/* + * Analog pins + */ +#define PIN_A1 (3) +#define PIN_A2 (4) +#define PIN_A4 (28) +#define PIN_A5 (29) +#define PIN_A6 (30) + +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +#define ADC_RESOLUTION 10 + +#define PIN_LPCOMP PIN_A5 +/* + * Serial interfaces + */ +// Serial +#define PIN_SERIAL_RX (28) +#define PIN_SERIAL_TX (27) + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_CTRL (11u) +#define PIN_WIRE_SDA (12u) +#define PIN_WIRE_SCL (17u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif diff --git a/variants/SparkFun_nRF52832_Breakout/pins_arduino.h b/variants/SparkFun_nRF52832_Breakout/pins_arduino.h new file mode 100644 index 00000000..3ef4d4a9 --- /dev/null +++ b/variants/SparkFun_nRF52832_Breakout/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/SparkFun_nRF52832_Breakout/variant.cpp b/variants/SparkFun_nRF52832_Breakout/variant.cpp new file mode 100644 index 00000000..02d405b6 --- /dev/null +++ b/variants/SparkFun_nRF52832_Breakout/variant.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +const uint32_t g_ADigitalPinMap[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 +}; diff --git a/variants/SparkFun_nRF52832_Breakout/variant.h b/variants/SparkFun_nRF52832_Breakout/variant.h new file mode 100644 index 00000000..1e810948 --- /dev/null +++ b/variants/SparkFun_nRF52832_Breakout/variant.h @@ -0,0 +1,116 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_NRF52_DK_ +#define _VARIANT_NRF52_DK_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (32u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) + +// LEDs +#define PIN_LED1 (7) +#define PIN_LED2 (8) +#define PIN_LED3 (9) +#define PIN_LED4 (10) +#define LED_BUILTIN PIN_LED1 + +// Buttons +#define PIN_BUTTON1 (6) +#define PIN_BUTTON2 (5) +#define PIN_BUTTON3 (4) +#define PIN_BUTTON4 (3) + +/* + * Analog pins + */ +#define PIN_A0 (2) +#define PIN_A1 (3) +#define PIN_A2 (4) +#define PIN_A3 (5) +#define PIN_A4 (28) +#define PIN_A5 (29) +#define PIN_A6 (30) +#define PIN_A7 (31) + + static const uint8_t A0 = PIN_A0; + static const uint8_t A1 = PIN_A1; + static const uint8_t A2 = PIN_A2; + static const uint8_t A3 = PIN_A3; + static const uint8_t A4 = PIN_A4; + static const uint8_t A5 = PIN_A5; + static const uint8_t A6 = PIN_A6; + static const uint8_t A7 = PIN_A7; +#define ADC_RESOLUTION 10 + +// Other pins +#define PIN_AREF (24) + static const uint8_t AREF = PIN_AREF; + +/* + * Serial interfaces + */ +// Serial +#define PIN_SERIAL_RX (26) +#define PIN_SERIAL_TX (27) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (12) +#define PIN_SPI_MOSI (11) +#define PIN_SPI_SCK (13) + + static const uint8_t SS = 10; + static const uint8_t MOSI = PIN_SPI_MOSI; + static const uint8_t MISO = PIN_SPI_MISO; + static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (20u) +#define PIN_WIRE_SCL (21u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif From 154afbd5e990aba229379cc2eb8d433b04321c6a Mon Sep 17 00:00:00 2001 From: "biii.in" Date: Tue, 15 Jun 2021 19:56:55 +0530 Subject: [PATCH 2/7] 0.7.63-rc1 dist file --- dist/package_nRF5_b_boards_index.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/package_nRF5_b_boards_index.json b/dist/package_nRF5_b_boards_index.json index aab696f7..286c957e 100644 --- a/dist/package_nRF5_b_boards_index.json +++ b/dist/package_nRF5_b_boards_index.json @@ -612,15 +612,15 @@ { "name": "Nordic Semiconductor nRF5 Boards", "architecture": "nRF5", - "version": "0.7.62", + "version": "0.7.63", "category": "Contributed", "help": { "online": "https://github.com/sandeepmistry/arduino-nRF5/issues" }, - "url": "https://github.com/biii-in/arduino-nRF5/raw/master/dist/arduino-nRF52-0.7.62.zip", - "archiveFileName": "arduino-nRF52-0.7.62.zip", - "checksum": "SHA-256:6572371C8139AC69BD85DFBC83A97428C7538B22634C4DF274B21917A59E391A", - "size": "2257666", + "url": "https://github.com/biii-in/arduino-nRF5/releases/download/0.7.63_rc1/arduino-nRF5-0.7.63-rc1.zip", + "archiveFileName": "arduino-nRF5-0.7.63-rc1.zip", + "checksum": "SHA-256:BA0C3C00F3EB7540AFCDD7DF3FE9BB4B0AF3FBB7D6074F7B8752D208D8F63265", + "size": "2269762", "boards": [ { "name": "BBC micro:bit" @@ -826,4 +826,4 @@ ] } ] -} \ No newline at end of file +} From f530a83484c855c95ca46b46a067712fb2f6aae2 Mon Sep 17 00:00:00 2001 From: "biii.in" Date: Tue, 15 Jun 2021 20:01:53 +0530 Subject: [PATCH 3/7] sha fix --- dist/package_nRF5_b_boards_index.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/package_nRF5_b_boards_index.json b/dist/package_nRF5_b_boards_index.json index 286c957e..5b5c289b 100644 --- a/dist/package_nRF5_b_boards_index.json +++ b/dist/package_nRF5_b_boards_index.json @@ -619,8 +619,8 @@ }, "url": "https://github.com/biii-in/arduino-nRF5/releases/download/0.7.63_rc1/arduino-nRF5-0.7.63-rc1.zip", "archiveFileName": "arduino-nRF5-0.7.63-rc1.zip", - "checksum": "SHA-256:BA0C3C00F3EB7540AFCDD7DF3FE9BB4B0AF3FBB7D6074F7B8752D208D8F63265", - "size": "2269762", + "checksum": "SHA-256:3F0C855EFA84BFB5A95E15BBE1AA0D09822CD7BB73F520B66DEE5322A5208A9E", + "size": "2285233", "boards": [ { "name": "BBC micro:bit" From d49210f6473da30155e881bd6572f43b4d05df04 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Mon, 5 Sep 2022 11:57:24 +0530 Subject: [PATCH 4/7] added new board version --- boards.txt | 102 ++++++++++++++++++++ cores/nRF5/wiring_constants.h | 27 +++--- cores/nRF5/wiring_digital.c | 9 ++ libraries/BRTC/BRTC.cpp | 129 +++++++++----------------- variants/I.ONIX_TypeC2/pins_arduino.h | 17 ++++ variants/I.ONIX_TypeC2/variant.cpp | 55 +++++++++++ variants/I.ONIX_TypeC2/variant.h | 74 +++++++++++++++ 7 files changed, 317 insertions(+), 96 deletions(-) create mode 100644 variants/I.ONIX_TypeC2/pins_arduino.h create mode 100644 variants/I.ONIX_TypeC2/variant.cpp create mode 100644 variants/I.ONIX_TypeC2/variant.h diff --git a/boards.txt b/boards.txt index dbd04419..b100e996 100644 --- a/boards.txt +++ b/boards.txt @@ -1122,3 +1122,105 @@ SeeedArchLink.menu.softdevice.s130.upload.maximum_size=151552 SeeedArchLink.menu.softdevice.s130.build.extra_flags=-DNRF51 -DS130 -DNRF51_S130 SeeedArchLink.menu.softdevice.s130.build.ldscript=armgcc_s130_nrf51822_xxaa.ld +SparkFunNRF52.name=SparkFun nRF52832 Breakout + +SparkFunNRF52.upload.tool=nrfutil +SparkFunNRF52.upload.protocol= +SparkFunNRF52.upload.interface= +SparkFunNRF52.upload.target=nrf52 +SparkFunNRF52.upload.speed=38400 +SparkFunNRF52.upload.maximum_size=524288 +SparkFunNRF52.upload.use_1200bps_touch=false +SparkFunNRF52.upload.wait_for_upload_port=false +SparkFunNRF52.upload.native_usb=false + +SparkFunNRF52.bootloader.tool=sandeepmistry:openocd + +SparkFunNRF52.build.mcu=cortex-m4 +SparkFunNRF52.build.f_cpu=16000000 +SparkFunNRF52.build.board=NRF52_DK +SparkFunNRF52.build.core=nRF5 +SparkFunNRF52.build.variant=SparkFun_nRF52832_Breakout +SparkFunNRF52.build.variant_system_lib= +SparkFunNRF52.build.extra_flags=-DNRF52 +SparkFunNRF52.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +SparkFunNRF52.build.ldscript=nrf52_xxaa.ld + +SparkFunNRF52.menu.softdevice.s132=S132 +SparkFunNRF52.menu.softdevice.s132.softdevice=s132 +SparkFunNRF52.menu.softdevice.s132.softdeviceversion=2.0.1 +SparkFunNRF52.menu.softdevice.s132.upload.maximum_size=409600 +SparkFunNRF52.menu.softdevice.s132.build.extra_flags=-DNRF52 -DS132 -DNRF51_S132 +SparkFunNRF52.menu.softdevice.s132.build.ldscript=armgcc_s132_nrf52832_xxaa.ld + +SparkFunNRF52.menu.lfclk.lfxo=Crystal Oscillator +SparkFunNRF52.menu.lfclk.lfxo.build.lfclk_flags=-DUSE_LFXO +SparkFunNRF52.menu.lfclk.lfrc=RC Oscillator +SparkFunNRF52.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC +SparkFunNRF52.menu.lfclk.lfsynt=Synthesized +SparkFunNRF52.menu.lfclk.lfsynt.build.lfclk_flags=-DUSE_LFSYNT + + +IonixTypeC.name=I.ONIX TypeC + +IonixTypeC.upload.tool=sandeepmistry:openocd +IonixTypeC.upload.target=nrf52 +IonixTypeC.upload.maximum_size=524288 + +IonixTypeC.bootloader.tool=sandeepmistry:openocd + +IonixTypeC.build.mcu=cortex-m4 +IonixTypeC.build.f_cpu=64000000 +IonixTypeC.build.board=NRF52_DK +IonixTypeC.build.core=nRF5 +IonixTypeC.build.variant=I.ONIX_TypeC +IonixTypeC.build.variant_system_lib= +IonixTypeC.build.extra_flags=-DNRF52 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +IonixTypeC.build.ldscript=nrf52_xxaa.ld + +IonixTypeC.menu.softdevice.s132=S132 +IonixTypeC.menu.softdevice.s132.softdevice=s132 +IonixTypeC.menu.softdevice.s132.softdeviceversion=2.0.1 +IonixTypeC.menu.softdevice.s132.upload.maximum_size=409600 +IonixTypeC.menu.softdevice.s132.build.extra_flags=-DNRF52 -DS132 -DNRF51_S132 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC.menu.softdevice.s132.build.ldscript=armgcc_s132_nrf52832_xxaa.ld + +IonixTypeC.menu.lfclk.lfxo=Crystal Oscillator +IonixTypeC.menu.lfclk.lfxo.build.lfclk_flags=-DUSE_LFXO +IonixTypeC.menu.lfclk.lfrc=RC Oscillator +IonixTypeC.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC +IonixTypeC.menu.lfclk.lfsynt=Synthesized +IonixTypeC.menu.lfclk.lfsynt.build.lfclk_flags=-DUSE_LFSYNT + +IonixTypeC2.name=I.ONIX TypeC2 + +IonixTypeC2.upload.tool=sandeepmistry:openocd +IonixTypeC2.upload.target=nrf52 +IonixTypeC2.upload.maximum_size=524288 + +IonixTypeC2.bootloader.tool=sandeepmistry:openocd + +IonixTypeC2.build.mcu=cortex-m4 +IonixTypeC2.build.f_cpu=64000000 +IonixTypeC2.build.board=NRF52_DK +IonixTypeC2.build.core=nRF5 +IonixTypeC2.build.variant=I.ONIX_TypeC +IonixTypeC2.build.variant_system_lib= +IonixTypeC2.build.extra_flags=-DNRF52 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC2.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +IonixTypeC2.build.ldscript=nrf52_xxaa.ld + +IonixTypeC2.menu.softdevice.s132=S132 +IonixTypeC2.menu.softdevice.s132.softdevice=s132 +IonixTypeC2.menu.softdevice.s132.softdeviceversion=2.0.1 +IonixTypeC2.menu.softdevice.s132.upload.maximum_size=409600 +IonixTypeC2.menu.softdevice.s132.build.extra_flags=-DNRF52 -DS132 -DNRF51_S132 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC2.menu.softdevice.s132.build.ldscript=armgcc_s132_nrf52832_xxaa.ld + +IonixTypeC2.menu.lfclk.lfxo=Crystal Oscillator +IonixTypeC2.menu.lfclk.lfxo.build.lfclk_flags=-DUSE_LFXO +IonixTypeC2.menu.lfclk.lfrc=RC Oscillator +IonixTypeC2.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC +IonixTypeC2.menu.lfclk.lfsynt=Synthesized +IonixTypeC2.menu.lfclk.lfsynt.build.lfclk_flags=-DUSE_LFSYNT diff --git a/cores/nRF5/wiring_constants.h b/cores/nRF5/wiring_constants.h index e8573aed..2df31617 100644 --- a/cores/nRF5/wiring_constants.h +++ b/cores/nRF5/wiring_constants.h @@ -20,30 +20,31 @@ #define _WIRING_CONSTANTS_ #ifdef __cplusplus -extern "C"{ +extern "C" { #endif // __cplusplus -#define LOW (0x0) -#define HIGH (0x1) +#define LOW (0x0) +#define HIGH (0x1) -#define INPUT (0x0) -#define OUTPUT (0x1) -#define INPUT_PULLUP (0x2) -#define INPUT_PULLDOWN (0x3) +#define INPUT (0x0) +#define OUTPUT (0x1) +#define INPUT_PULLUP (0x2) +#define INPUT_PULLDOWN (0x3) +#define OUTPUT_HIGH_DRIVE (0x4) -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 #define DEG_TO_RAD 0.017453292519943295769236907684886 #define RAD_TO_DEG 57.295779513082320876798154814105 -#define EULER 2.718281828459045235360287471352 +#define EULER 2.718281828459045235360287471352 #define SERIAL 0x0 #define DISPLAY 0x1 enum BitOrder { - LSBFIRST = 0, - MSBFIRST = 1 + LSBFIRST = 0, + MSBFIRST = 1 }; // moved to WInterrupts.h diff --git a/cores/nRF5/wiring_digital.c b/cores/nRF5/wiring_digital.c index 2cf92565..f4bcd2d9 100644 --- a/cores/nRF5/wiring_digital.c +++ b/cores/nRF5/wiring_digital.c @@ -73,6 +73,15 @@ void pinMode( uint32_t ulPin, uint32_t ulMode ) | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); break ; + case OUTPUT_HIGH_DRIVE: + // Set pin to output mode + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break ; + default: // do nothing break ; diff --git a/libraries/BRTC/BRTC.cpp b/libraries/BRTC/BRTC.cpp index 5f39653f..b90f4acf 100644 --- a/libraries/BRTC/BRTC.cpp +++ b/libraries/BRTC/BRTC.cpp @@ -16,45 +16,38 @@ BRTCClass BRTC; #define RTC_MIN_TICK_COUNT (8ul) #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif - void RTC2_IRQHandler() - { - if (NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC]) - { - NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC] = 0; - NRF_RTC2->CC[RTC_TIMER_CHANNEL_PERIODIC] += BRTC.rtc_stm.ch[RTC_TIMER_CHANNEL_PERIODIC].ms_tick; - if (BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC]) - { - BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC](); - } +void RTC2_IRQHandler() +{ + if (NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC]) { + NRF_RTC2->EVENTS_COMPARE[RTC_TIMER_CHANNEL_PERIODIC] = 0; + NRF_RTC2->CC[RTC_TIMER_CHANNEL_PERIODIC] += BRTC.rtc_stm.ch[RTC_TIMER_CHANNEL_PERIODIC].ms_tick; + if (BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC]) { + BRTC.rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC](); } - else - { - for (int chid = RTC_TIMER_CHANNEL_ONE_SHOT_1; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) - { - if (NRF_RTC2->EVENTS_COMPARE[chid]) - { - NRF_RTC2->EVENTS_COMPARE[chid] = 0; - if (BRTC.rtc_stm._tickCallback[chid]) - { - BRTC.rtc_stm._tickCallback[chid](); - } - NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); + } else { + for (int chid = RTC_TIMER_CHANNEL_ONE_SHOT_1; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) { + if (NRF_RTC2->EVENTS_COMPARE[chid]) { + NRF_RTC2->EVENTS_COMPARE[chid] = 0; + if (BRTC.rtc_stm._tickCallback[chid]) { + BRTC.rtc_stm._tickCallback[chid](); } + NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); } } } +} #ifdef __cplusplus } #endif -uint64_t BRTCClass::getTickCount(uint32_t msPeriod) +uint64_t BRTCClass::getTickCount(uint32_t msPeriod, uint16_t prescaller) { uint64_t ticks = msPeriod; ticks *= 32768; ticks /= 1000; + ticks /= prescaller; return ticks; } @@ -65,49 +58,38 @@ bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool uint32_t min_ms = 0xFFFFFFFFul; uint32_t max_ms = 0; // update min and max delay - for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) - { - if (this->rtc_stm.ch[chid].ms_delay > 0) - { - if (this->rtc_stm.ch[chid].ms_delay < min_ms) - { + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) { + if (this->rtc_stm.ch[chid].ms_delay > 0) { + if (this->rtc_stm.ch[chid].ms_delay < min_ms) { min_ms = this->rtc_stm.ch[chid].ms_delay; } - if (this->rtc_stm.ch[chid].ms_delay > max_ms) - { + if (this->rtc_stm.ch[chid].ms_delay > max_ms) { max_ms = this->rtc_stm.ch[chid].ms_delay; } } } error = (min_ms > max_ms); - if (!error) - { + if (!error) { // setup nrf rtc to tick at ms provided uint64_t tick_in_prescaller = 0; - uint64_t ticks = getTickCount(max_ms); uint32_t prescaller = 0; - do - { + uint64_t ticks = getTickCount(max_ms, prescaller); + do { prescaller++; tick_in_prescaller = ticks / prescaller; } while (tick_in_prescaller > RTC_MAX_TICK_COUNT); // - if (debug) - { + if (debug) { Serial.print("PSR "); Serial.println(prescaller); } error = (prescaller & 0xF000); - if (!error) - { - for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) - { - if (this->rtc_stm.ch[chid].ms_delay > 0) - { - this->rtc_stm.ch[chid].ms_tick = getTickCount(this->rtc_stm.ch[chid].ms_delay); + if (!error) { + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) { + if (this->rtc_stm.ch[chid].ms_delay > 0) { + this->rtc_stm.ch[chid].ms_tick = getTickCount(this->rtc_stm.ch[chid].ms_delay, prescaller); // - if (debug) - { + if (debug) { Serial.print(chid); Serial.print(": MS>"); Serial.print(this->rtc_stm.ch[chid].ms_delay); @@ -115,50 +97,35 @@ bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool Serial.println(this->rtc_stm.ch[chid].ms_tick, HEX); } // - if (this->rtc_stm.ch[chid].ms_tick < RTC_MIN_TICK_COUNT) - { + if (this->rtc_stm.ch[chid].ms_tick < RTC_MIN_TICK_COUNT) { this->rtc_stm.ch[chid].ms_delay = 0; error = true; } } } // everything is okay till now update all channels - if (!error) - { + if (!error) { NRF_RTC2->PRESCALER = prescaller - 1; - for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) - { - if (this->rtc_stm.ch[chid].ms_delay > 0) - { + for (int chid = 0; chid < RTC_TIMER_CHANNEL_ONE_SHOT_MAX; chid++) { + if (this->rtc_stm.ch[chid].ms_delay > 0) { NRF_RTC2->CC[chid] = NRF_RTC2->COUNTER + this->rtc_stm.ch[chid].ms_tick; NRF_RTC2->INTENSET = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); - } - else - { + } else { NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); } } - } - else - { - if (debug) - { + } else { + if (debug) { Serial.println("RTC: RNG Over"); } } - } - else - { - if (debug) - { + } else { + if (debug) { Serial.println("RTC: PSR Over"); } } - } - else - { - if (debug) - { + } else { + if (debug) { Serial.print("RTC: mM ERR: "); Serial.print(min_ms); Serial.print(" "); @@ -172,8 +139,7 @@ bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool bool BRTCClass::setPeriodicTimer(uint32_t msPeriod, f_TickCallback periodicCallback, bool debug) { NRF_RTC2->TASKS_STOP = 1; - if (updateTickCounts(RTC_TIMER_CHANNEL_PERIODIC, msPeriod, debug)) - { + if (updateTickCounts(RTC_TIMER_CHANNEL_PERIODIC, msPeriod, debug)) { this->rtc_stm._tickCallback[RTC_TIMER_CHANNEL_PERIODIC] = periodicCallback; // NVIC_ClearPendingIRQ(RTC2_IRQn); @@ -189,11 +155,9 @@ bool BRTCClass::setPeriodicTimer(uint32_t msPeriod, f_TickCallback periodicCallb bool BRTCClass::setOneshotTimer(rtc_timer_ch_ids ch_id, uint32_t msDelay, f_TickCallback oneshotCallback, bool debug) { if ((ch_id > RTC_TIMER_CHANNEL_PERIODIC) && - (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) - { + (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) { NRF_RTC2->TASKS_STOP = 1; - if (updateTickCounts(ch_id, msDelay, debug)) - { + if (updateTickCounts(ch_id, msDelay, debug)) { this->rtc_stm._tickCallback[ch_id] = oneshotCallback; // NVIC_ClearPendingIRQ(RTC2_IRQn); @@ -210,8 +174,7 @@ bool BRTCClass::setOneshotTimer(rtc_timer_ch_ids ch_id, uint32_t msDelay, f_Tick bool BRTCClass::cancelOneshotTimer(rtc_timer_ch_ids ch_id) { if ((ch_id > RTC_TIMER_CHANNEL_PERIODIC) && - (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) - { + (ch_id < RTC_TIMER_CHANNEL_ONE_SHOT_MAX)) { NRF_RTC2->TASKS_STOP = 1; NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + ch_id))); NRF_RTC2->TASKS_START = 1; diff --git a/variants/I.ONIX_TypeC2/pins_arduino.h b/variants/I.ONIX_TypeC2/pins_arduino.h new file mode 100644 index 00000000..3ef4d4a9 --- /dev/null +++ b/variants/I.ONIX_TypeC2/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/I.ONIX_TypeC2/variant.cpp b/variants/I.ONIX_TypeC2/variant.cpp new file mode 100644 index 00000000..02d405b6 --- /dev/null +++ b/variants/I.ONIX_TypeC2/variant.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +const uint32_t g_ADigitalPinMap[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 +}; diff --git a/variants/I.ONIX_TypeC2/variant.h b/variants/I.ONIX_TypeC2/variant.h new file mode 100644 index 00000000..d208ab20 --- /dev/null +++ b/variants/I.ONIX_TypeC2/variant.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_NRF52_DK_ +#define _VARIANT_NRF52_DK_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (32u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) + +// Serial +#define PIN_SERIAL_RX (24) +#define PIN_SERIAL_TX (22) +// Wire +#define WIRE_INTERFACES_COUNT 1 +#define PIN_WIRE_SDA (5u) +#define PIN_WIRE_SCL (6u) +// SPI +#define SPI_INTERFACES_COUNT 1 +#define PIN_SPI_MISO (12) +#define PIN_SPI_MOSI (14) +#define PIN_SPI_SCK (15) + +// USER NAMES +#define LPCOMP_PIN (26u) +#define USR_BTN_PIN (25u) +#define BLUE_LED_PIN (23u) +#define MPR_VDD_CTRL_PIN (4u) +#define MPR_WIRE_SDA_PIN PIN_WIRE_SDA +#define MPR_WIRE_SCL_PIN PIN_WIRE_SCL +#define E_INK_BUSY_PIN (19u) +#define E_INK_RST_PIN (18u) +#define E_INK_DC_PIN (17u) +#define E_INK_CS_PIN (16u) +#define E_INK_SCL_PIN PIN_SPI_SCK +#define E_INK_SDA_PIN PIN_SPI_MOSI +#define E_INK_VDD_CTRL_PIN (13u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif From 08e9d69e72bc55808a5863755e925260cb8b5239 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Sun, 11 Sep 2022 18:20:09 +0530 Subject: [PATCH 5/7] bpwm --- boards.txt | 2 +- cores/nRF5/wiring_digital.c | 200 +++++++++--------- dist/package_nRF5_b_boards_index.json | 4 +- libraries/BPWM/BPWM.cpp | 84 ++++++++ libraries/BPWM/BPWM.h | 65 ++++++ .../BPWM/examples/pwm_buzzer/pwm_buzzer.ino | 28 +++ libraries/BPWM/keywords.txt | 27 +++ libraries/BPWM/library.properties | 9 + libraries/BRTC/BRTC.cpp | 12 +- libraries/BRTC/BRTC.h | 2 +- libraries/BRTC/examples/rtc_tick/rtc_tick.ino | 16 +- variants/Generic/variant.h | 76 +++---- variants/I.ONIX_TypeC/variant.h | 18 +- 13 files changed, 391 insertions(+), 152 deletions(-) create mode 100644 libraries/BPWM/BPWM.cpp create mode 100644 libraries/BPWM/BPWM.h create mode 100644 libraries/BPWM/examples/pwm_buzzer/pwm_buzzer.ino create mode 100644 libraries/BPWM/keywords.txt create mode 100644 libraries/BPWM/library.properties diff --git a/boards.txt b/boards.txt index b100e996..6ada89ca 100644 --- a/boards.txt +++ b/boards.txt @@ -1205,7 +1205,7 @@ IonixTypeC2.build.mcu=cortex-m4 IonixTypeC2.build.f_cpu=64000000 IonixTypeC2.build.board=NRF52_DK IonixTypeC2.build.core=nRF5 -IonixTypeC2.build.variant=I.ONIX_TypeC +IonixTypeC2.build.variant=I.ONIX_TypeC2 IonixTypeC2.build.variant_system_lib= IonixTypeC2.build.extra_flags=-DNRF52 -DCONFIG_NFCT_PINS_AS_GPIOS IonixTypeC2.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 diff --git a/cores/nRF5/wiring_digital.c b/cores/nRF5/wiring_digital.c index f4bcd2d9..977de957 100644 --- a/cores/nRF5/wiring_digital.c +++ b/cores/nRF5/wiring_digital.c @@ -22,106 +22,110 @@ #include "Arduino.h" #ifdef __cplusplus -extern "C" { -#endif - -void pinMode( uint32_t ulPin, uint32_t ulMode ) -{ - if (ulPin >= PINS_COUNT) { - return; - } - - NRF_GPIO_Type* port = digitalPinToPort(ulPin); - uint32_t pin = digitalPinToPin(ulPin); - - // Set pin mode according to chapter '22.6.3 I/O Pin Configuration' - switch ( ulMode ) - { - case INPUT: - // Set pin to input mode - port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - break ; - - case INPUT_PULLUP: - // Set pin to input mode with pull-up resistor enabled - port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - break ; - - case INPUT_PULLDOWN: - // Set pin to input mode with pull-down resistor enabled - port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - break ; - - case OUTPUT: - // Set pin to output mode - port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - break ; - - case OUTPUT_HIGH_DRIVE: - // Set pin to output mode - port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - break ; - - default: - // do nothing - break ; - } -} - -void digitalWrite( uint32_t ulPin, uint32_t ulVal ) +extern "C" { - if (ulPin >= PINS_COUNT) { - return; - } - - NRF_GPIO_Type* port = digitalPinToPort(ulPin); - uint32_t mask = digitalPinToBitMask(ulPin); - - switch ( ulVal ) - { - case LOW: - port->OUTCLR = mask; - break ; - - default: - port->OUTSET = mask; - break ; - } - - return ; -} - -int digitalRead( uint32_t ulPin ) -{ - if (ulPin >= PINS_COUNT) { - return 0; - } - - NRF_GPIO_Type* port = digitalPinToPort(ulPin); - uint32_t pin = digitalPinToPin(ulPin); +#endif - return ((port->IN >> pin) & 1UL) ? HIGH : LOW ; -} + void pinMode(uint32_t ulPin, uint32_t ulMode) + { + if (ulPin >= PINS_COUNT) + { + return; + } + + NRF_GPIO_Type *port = digitalPinToPort(ulPin); + uint32_t pin = digitalPinToPin(ulPin); + + // Set pin mode according to chapter '22.6.3 I/O Pin Configuration' + switch (ulMode) + { + case INPUT: + // Set pin to input mode + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break; + + case INPUT_PULLUP: + // Set pin to input mode with pull-up resistor enabled + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break; + + case INPUT_PULLDOWN: + // Set pin to input mode with pull-down resistor enabled + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break; + + case OUTPUT: + // Set pin to output mode + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break; + + case OUTPUT_HIGH_DRIVE: + // Set pin to output mode + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + break; + + default: + // do nothing + break; + } + } + + void digitalWrite(uint32_t ulPin, uint32_t ulVal) + { + if (ulPin >= PINS_COUNT) + { + return; + } + + NRF_GPIO_Type *port = digitalPinToPort(ulPin); + uint32_t mask = digitalPinToBitMask(ulPin); + + switch (ulVal) + { + case LOW: + port->OUTCLR = mask; + break; + + default: + port->OUTSET = mask; + break; + } + + return; + } + + int digitalRead(uint32_t ulPin) + { + if (ulPin >= PINS_COUNT) + { + return 0; + } + + NRF_GPIO_Type *port = digitalPinToPort(ulPin); + uint32_t pin = digitalPinToPin(ulPin); + + return ((port->IN >> pin) & 1UL) ? HIGH : LOW; + } #ifdef __cplusplus } diff --git a/dist/package_nRF5_b_boards_index.json b/dist/package_nRF5_b_boards_index.json index 5b5c289b..286c957e 100644 --- a/dist/package_nRF5_b_boards_index.json +++ b/dist/package_nRF5_b_boards_index.json @@ -619,8 +619,8 @@ }, "url": "https://github.com/biii-in/arduino-nRF5/releases/download/0.7.63_rc1/arduino-nRF5-0.7.63-rc1.zip", "archiveFileName": "arduino-nRF5-0.7.63-rc1.zip", - "checksum": "SHA-256:3F0C855EFA84BFB5A95E15BBE1AA0D09822CD7BB73F520B66DEE5322A5208A9E", - "size": "2285233", + "checksum": "SHA-256:BA0C3C00F3EB7540AFCDD7DF3FE9BB4B0AF3FBB7D6074F7B8752D208D8F63265", + "size": "2269762", "boards": [ { "name": "BBC micro:bit" diff --git a/libraries/BPWM/BPWM.cpp b/libraries/BPWM/BPWM.cpp new file mode 100644 index 00000000..7306d082 --- /dev/null +++ b/libraries/BPWM/BPWM.cpp @@ -0,0 +1,84 @@ +/// +/// @file BPWM.cpp +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include "BPWM.h" + +BPWMClass BPWM; + +int BPWMClass::begin() +{ + for (int i = 0; i < eBPWM_MAX; i++) { + this->_stm[i].hw->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_16; // 1 us + this->_stm[i].hw->MODE = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos); + this->_stm[i].hw->DECODER = (PWM_DECODER_LOAD_Individual << PWM_DECODER_LOAD_Pos) | (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos); + this->_stm[i].hw->LOOP = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos); + this->_stm[i].hw->SEQ[0].CNT = (eBPWM_CH_MAX << PWM_SEQ_CNT_CNT_Pos); + this->_stm[i].hw->SEQ[0].ENDDELAY = 0; + this->_stm[i].hw->SEQ[0].PTR = (uint32_t) & this->_stm[i].ch_us_pulse[0]; + this->_stm[i].hw->SEQ[0].REFRESH = 0; + this->_stm[i].hw->SHORTS = 0; + } +} + +int BPWMClass::setConfig(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id, uint8_t pwm_pin, uint16_t period_us, bool inverted) +{ + if ((hw_id >= eBPWM_MAX) || (ch_id >= eBPWM_CH_MAX)) { + return -1; + } + if (this->_stm[hw_id].ch_cfg[ch_id].is_active) { + return -2; + } + this->_stm[hw_id].hw->COUNTERTOP = period_us; + this->_stm[hw_id].hw->PSEL.OUT[ch_id] = pwm_pin; + this->_stm[hw_id].ch_cfg[ch_id].is_inverted = inverted; + return 0; +} + +int BPWMClass::start(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id, uint16_t pulse_us) +{ + if ((hw_id >= eBPWM_MAX) || (ch_id >= eBPWM_CH_MAX)) { + return -1; + } + if (this->_stm[hw_id].ch_cfg[ch_id].is_inverted) { + this->_stm[hw_id].ch_us_pulse[ch_id] = pulse_us | (1 << 15); + } else { + this->_stm[hw_id].ch_us_pulse[ch_id] = pulse_us; + } + // if any one is running then we need not to restart it + for (int i = 0; i < eBPWM_CH_MAX; i++) { + if (this->_stm[hw_id].ch_cfg[i].is_active) { + this->_stm[hw_id].ch_cfg[ch_id].is_active = true; + return 0; + } + } + // start hw + this->_stm[hw_id].hw->ENABLE = 1; + this->_stm[hw_id].hw->TASKS_SEQSTART[0] = 1; + this->_stm[hw_id].ch_cfg[ch_id].is_active = true; + return 0; +} + +int BPWMClass::stop(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id) +{ + if ((hw_id >= eBPWM_MAX) || (ch_id >= eBPWM_CH_MAX)) { + return -1; + } + this->_stm[hw_id].ch_us_pulse[ch_id] = 0; + this->_stm[hw_id].ch_cfg[ch_id].is_active = false; + // if any one is running then we need not to restart it + for (int i = 0; i < eBPWM_CH_MAX; i++) { + if (this->_stm[hw_id].ch_cfg[i].is_active) { + return 0; + } + } + this->_stm[hw_id].hw->TASKS_STOP = 1; + this->_stm[hw_id].hw->ENABLE = 0; + return 0; +} diff --git a/libraries/BPWM/BPWM.h b/libraries/BPWM/BPWM.h new file mode 100644 index 00000000..c7ce39c3 --- /dev/null +++ b/libraries/BPWM/BPWM.h @@ -0,0 +1,65 @@ +/// +/// @file BPWM.h +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#ifndef BPWM_h +#define BPWM_h + +#include "Arduino.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +enum bpwm_hw_id { + eBPWM_0, + eBPWM_1, + eBPWM_2, + eBPWM_MAX, +}; + +enum bpwm_ch_id { + eBPWM_CH_0, + eBPWM_CH_1, + eBPWM_CH_2, + eBPWM_CH_3, + eBPWM_CH_MAX, +}; + +class BPWMClass { +public: + int begin(); + int setConfig(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id, uint8_t pwm_pin, uint16_t period_us, bool inverted); + int start(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id, uint16_t pulse_us); + int stop(enum bpwm_hw_id hw_id, enum bpwm_ch_id ch_id); + +private: + struct { + NRF_PWM_Type *hw; + struct { + bool is_active; + bool is_inverted; + } ch_cfg[eBPWM_CH_MAX]; + uint16_t ch_us_pulse[eBPWM_CH_MAX]; + uint16_t us_period; + } _stm[eBPWM_MAX] = { + {.hw = NRF_PWM0}, + {.hw = NRF_PWM1}, + {.hw = NRF_PWM2}, + }; +}; + +extern BPWMClass BPWM; + +#endif \ No newline at end of file diff --git a/libraries/BPWM/examples/pwm_buzzer/pwm_buzzer.ino b/libraries/BPWM/examples/pwm_buzzer/pwm_buzzer.ino new file mode 100644 index 00000000..cb35176f --- /dev/null +++ b/libraries/BPWM/examples/pwm_buzzer/pwm_buzzer.ino @@ -0,0 +1,28 @@ +/// +/// @file rtc_tick.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +void setup() +{ + Serial.begin(115200); + delay(1000); + Serial.println("PWM START"); + BPWM.begin(); + BPWM.setConfig(eBPWM_0, eBPWM_CH_0, 11, 1000ul, false); +} + +void loop() +{ + BPWM.start(eBPWM_0, eBPWM_CH_0, 500ul); + delay(1000); + BPWM.stop(eBPWM_0, eBPWM_CH_0); + delay(1000); +} \ No newline at end of file diff --git a/libraries/BPWM/keywords.txt b/libraries/BPWM/keywords.txt new file mode 100644 index 00000000..2eea68aa --- /dev/null +++ b/libraries/BPWM/keywords.txt @@ -0,0 +1,27 @@ +####################################### +# Syntax Coloring Map BPWM +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +BPWM KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +setConfig KEYWORD2 +start KEYWORD2 +stop KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +eBPWM_0 LITERAL1 +eBPWM_1 LITERAL1 +eBPWM_2 LITERAL1 +eBPWM_CH_0 LITERAL1 +eBPWM_CH_1 LITERAL1 +eBPWM_CH_2 LITERAL1 +eBPWM_CH_3 LITERAL1 diff --git a/libraries/BPWM/library.properties b/libraries/BPWM/library.properties new file mode 100644 index 00000000..ce8c7369 --- /dev/null +++ b/libraries/BPWM/library.properties @@ -0,0 +1,9 @@ +name=BPWM +version=1.0 +author=biii.in +maintainer=biii.in +sentence=Basic PWM library +paragraph= +category=PWM +url= +architectures=nRF5 \ No newline at end of file diff --git a/libraries/BRTC/BRTC.cpp b/libraries/BRTC/BRTC.cpp index b90f4acf..9e1cdafa 100644 --- a/libraries/BRTC/BRTC.cpp +++ b/libraries/BRTC/BRTC.cpp @@ -42,7 +42,7 @@ void RTC2_IRQHandler() } #endif -uint64_t BRTCClass::getTickCount(uint32_t msPeriod, uint16_t prescaller) +uint64_t BRTCClass::getTickCount(uint32_t msPeriod, uint32_t prescaller) { uint64_t ticks = msPeriod; ticks *= 32768; @@ -72,8 +72,8 @@ bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool if (!error) { // setup nrf rtc to tick at ms provided uint64_t tick_in_prescaller = 0; + uint64_t ticks = getTickCount(max_ms, 1); uint32_t prescaller = 0; - uint64_t ticks = getTickCount(max_ms, prescaller); do { prescaller++; tick_in_prescaller = ticks / prescaller; @@ -110,6 +110,14 @@ bool BRTCClass::updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t msPeriod, bool if (this->rtc_stm.ch[chid].ms_delay > 0) { NRF_RTC2->CC[chid] = NRF_RTC2->COUNTER + this->rtc_stm.ch[chid].ms_tick; NRF_RTC2->INTENSET = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); + + if (debug) { + Serial.print(chid); + Serial.print(": CC>"); + Serial.print(NRF_RTC2->CC[chid], HEX); + Serial.print(" CNT>"); + Serial.println(NRF_RTC2->COUNTER, HEX); + } } else { NRF_RTC2->INTENCLR = ((RTC_INTENSET_COMPARE0_Enabled << (RTC_INTENSET_COMPARE0_Pos + chid))); } diff --git a/libraries/BRTC/BRTC.h b/libraries/BRTC/BRTC.h index 8124a059..bbe1c438 100644 --- a/libraries/BRTC/BRTC.h +++ b/libraries/BRTC/BRTC.h @@ -84,7 +84,7 @@ class BRTCClass /// @return true /// @return false /// - uint64_t getTickCount(uint32_t ms); + uint64_t getTickCount(uint32_t ms, uint32_t prescaller); bool updateTickCounts(rtc_timer_ch_ids ch_id, uint32_t ms, bool debug = false); }; diff --git a/libraries/BRTC/examples/rtc_tick/rtc_tick.ino b/libraries/BRTC/examples/rtc_tick/rtc_tick.ino index bf8b8c07..e24a48f4 100644 --- a/libraries/BRTC/examples/rtc_tick/rtc_tick.ino +++ b/libraries/BRTC/examples/rtc_tick/rtc_tick.ino @@ -10,7 +10,7 @@ /// #include -bool tick = false; +volatile bool tick = false; uint8_t tickCount = 0; bool timer1expired = false; @@ -18,19 +18,22 @@ void tickHandle() { tick = true; tickCount++; + Serial.print(tickCount); + Serial.println(":tick"); } void timer1Expired() { timer1expired = true; + Serial.println("timer1expired"); } void setup() { Serial.begin(115200); - Serial.println("RTC START"); delay(1000); - BRTC.setPeriodicTimer(10000, tickHandle); + Serial.println("RTC START"); + BRTC.setPeriodicTimer(20 * 60 * 1000, tickHandle, true); } void loop() @@ -38,17 +41,14 @@ void loop() if (tick) { tick = false; - Serial.println("tick"); - if (tickCount >= 2) + if ((tickCount & 0x03) == 0x00) { - tickCount = 0; - BRTC.setOneshotTimer(RTC_TIMER_CHANNEL_ONE_SHOT_1, 2000, timer1Expired); + BRTC.setOneshotTimer(RTC_TIMER_CHANNEL_ONE_SHOT_1, 2000, timer1Expired, true); } } if (timer1expired) { timer1expired = false; - Serial.println("timer1expired"); } __WFE(); __WFI(); diff --git a/variants/Generic/variant.h b/variants/Generic/variant.h index 387ddecd..cfd13649 100644 --- a/variants/Generic/variant.h +++ b/variants/Generic/variant.h @@ -22,9 +22,9 @@ /** Master clock frequency */ #if defined(NRF52_SERIES) -#define VARIANT_MCK (64000000ul) +#define VARIANT_MCK (64000000ul) #else -#define VARIANT_MCK (16000000ul) +#define VARIANT_MCK (16000000ul) #endif /*---------------------------------------------------------------------------- @@ -40,74 +40,74 @@ extern "C" // Number of pins defined in PinDescription array #if GPIO_COUNT == 1 -#define PINS_COUNT (32u) -#define NUM_DIGITAL_PINS (32u) +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (32u) #elif GPIO_COUNT == 2 -#define PINS_COUNT (64u) -#define NUM_DIGITAL_PINS (64u) +#define PINS_COUNT (64u) +#define NUM_DIGITAL_PINS (64u) #else #error "Unsupported GPIO_COUNT" #endif -#define NUM_ANALOG_INPUTS (6u) -#define NUM_ANALOG_OUTPUTS (0u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (0u) // LEDs -#define PIN_LED (13) // P0.13 -#define LED_BUILTIN PIN_LED +#define PIN_LED (13) // P0.13 +#define LED_BUILTIN PIN_LED /* * Analog pins */ -#define PIN_A0 (1) // P0.01 -#define PIN_A1 (2) // P0.02 -#define PIN_A2 (3) // P0.03 -#define PIN_A3 (4) // P0.04 -#define PIN_A4 (5) // P0.05 -#define PIN_A5 (6) // P0.06 - -static const uint8_t A0 = PIN_A0 ; -static const uint8_t A1 = PIN_A1 ; -static const uint8_t A2 = PIN_A2 ; -static const uint8_t A3 = PIN_A3 ; -static const uint8_t A4 = PIN_A4 ; -static const uint8_t A5 = PIN_A5 ; +#define PIN_A0 (1) // P0.01 +#define PIN_A1 (2) // P0.02 +#define PIN_A2 (3) // P0.03 +#define PIN_A3 (4) // P0.04 +#define PIN_A4 (5) // P0.05 +#define PIN_A5 (6) // P0.06 + + static const uint8_t A0 = PIN_A0; + static const uint8_t A1 = PIN_A1; + static const uint8_t A2 = PIN_A2; + static const uint8_t A3 = PIN_A3; + static const uint8_t A4 = PIN_A4; + static const uint8_t A5 = PIN_A5; #if defined(NRF52_SERIES) -#define ADC_RESOLUTION 14 +#define ADC_RESOLUTION 14 #else -#define ADC_RESOLUTION 10 +#define ADC_RESOLUTION 10 #endif /* * Serial interfaces */ // Serial -#define PIN_SERIAL_RX (0) // P0.00 -#define PIN_SERIAL_TX (1) // P0.01 +#define PIN_SERIAL_RX (0) // P0.00 +#define PIN_SERIAL_TX (1) // P0.01 /* * SPI Interfaces */ #define SPI_INTERFACES_COUNT 1 -#define PIN_SPI_MISO (22) // P0.22 -#define PIN_SPI_MOSI (23) // P0.23 -#define PIN_SPI_SCK (24) // P0.24 +#define PIN_SPI_MISO (22) // P0.22 +#define PIN_SPI_MOSI (23) // P0.23 +#define PIN_SPI_SCK (24) // P0.24 -static const uint8_t SS = 25 ; // P0.25 -static const uint8_t MOSI = PIN_SPI_MOSI ; -static const uint8_t MISO = PIN_SPI_MISO ; -static const uint8_t SCK = PIN_SPI_SCK ; + static const uint8_t SS = 25; // P0.25 + static const uint8_t MOSI = PIN_SPI_MOSI; + static const uint8_t MISO = PIN_SPI_MISO; + static const uint8_t SCK = PIN_SPI_SCK; /* * Wire Interfaces */ #define WIRE_INTERFACES_COUNT 1 -#define PIN_WIRE_SDA (20u) // P0.20 -#define PIN_WIRE_SCL (21u) // P0.21 +#define PIN_WIRE_SDA (12u) // P0.20 +#define PIN_WIRE_SCL (13u) // P0.21 -static const uint8_t SDA = PIN_WIRE_SDA; -static const uint8_t SCL = PIN_WIRE_SCL; + static const uint8_t SDA = PIN_WIRE_SDA; + static const uint8_t SCL = PIN_WIRE_SCL; #ifdef __cplusplus } diff --git a/variants/I.ONIX_TypeC/variant.h b/variants/I.ONIX_TypeC/variant.h index 0465065a..7ba65864 100644 --- a/variants/I.ONIX_TypeC/variant.h +++ b/variants/I.ONIX_TypeC/variant.h @@ -67,14 +67,28 @@ static const uint8_t A6 = PIN_A6; #define PIN_SERIAL_RX (28) #define PIN_SERIAL_TX (27) +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (12) +#define PIN_SPI_MOSI (11) +#define PIN_SPI_SCK (13) + +static const uint8_t SS = 10; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + /* * Wire Interfaces */ #define WIRE_INTERFACES_COUNT 1 -#define PIN_WIRE_CTRL (11u) +#define PIN_WIRE_CTRL (17u) #define PIN_WIRE_SDA (12u) -#define PIN_WIRE_SCL (17u) +#define PIN_WIRE_SCL (11u) #ifdef __cplusplus } From 47610b8fd085e4bc9e1e59aa05d8f1e81d095055 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Tue, 20 Sep 2022 11:01:56 +0530 Subject: [PATCH 6/7] eink and qrcode library integration --- cores/nRF5/wiring_constants.h | 1 + cores/nRF5/wiring_digital.c | 9 + libraries/BEINK/BEINK.cpp | 337 + libraries/BEINK/BEINK.h | 117 + libraries/BEINK/example.c.org | 22599 ++++++++++++++++ .../BEINK/examples/beink_demo/beink_demo.ino | 35 + libraries/BEINK/font16.c | 1760 ++ libraries/BEINK/fonts.h | 68 + libraries/BEINK/keywords.txt | 27 + libraries/BEINK/library.properties | 9 + libraries/QRCode/.gitignore | 1 + libraries/QRCode/LICENSE.txt | 26 + libraries/QRCode/README.md | 677 + libraries/QRCode/examples/QRCode/QRCode.ino | 56 + libraries/QRCode/generate_table.py | 62 + libraries/QRCode/keywords.txt | 31 + libraries/QRCode/library.properties | 10 + libraries/QRCode/src/qrcode.c | 876 + libraries/QRCode/src/qrcode.h | 99 + libraries/QRCode/tests/BitBuffer.cpp | 63 + libraries/QRCode/tests/BitBuffer.hpp | 76 + libraries/QRCode/tests/QrCode.cpp | 616 + libraries/QRCode/tests/QrCode.hpp | 314 + libraries/QRCode/tests/QrSegment.cpp | 173 + libraries/QRCode/tests/QrSegment.hpp | 170 + libraries/QRCode/tests/README.md | 12 + libraries/QRCode/tests/run-tests.cpp | 85 + libraries/QRCode/tests/run.sh | 5 + 28 files changed, 28314 insertions(+) create mode 100644 libraries/BEINK/BEINK.cpp create mode 100644 libraries/BEINK/BEINK.h create mode 100644 libraries/BEINK/example.c.org create mode 100644 libraries/BEINK/examples/beink_demo/beink_demo.ino create mode 100644 libraries/BEINK/font16.c create mode 100644 libraries/BEINK/fonts.h create mode 100644 libraries/BEINK/keywords.txt create mode 100644 libraries/BEINK/library.properties create mode 100644 libraries/QRCode/.gitignore create mode 100644 libraries/QRCode/LICENSE.txt create mode 100644 libraries/QRCode/README.md create mode 100644 libraries/QRCode/examples/QRCode/QRCode.ino create mode 100644 libraries/QRCode/generate_table.py create mode 100644 libraries/QRCode/keywords.txt create mode 100644 libraries/QRCode/library.properties create mode 100644 libraries/QRCode/src/qrcode.c create mode 100644 libraries/QRCode/src/qrcode.h create mode 100644 libraries/QRCode/tests/BitBuffer.cpp create mode 100644 libraries/QRCode/tests/BitBuffer.hpp create mode 100644 libraries/QRCode/tests/QrCode.cpp create mode 100644 libraries/QRCode/tests/QrCode.hpp create mode 100644 libraries/QRCode/tests/QrSegment.cpp create mode 100644 libraries/QRCode/tests/QrSegment.hpp create mode 100644 libraries/QRCode/tests/README.md create mode 100644 libraries/QRCode/tests/run-tests.cpp create mode 100644 libraries/QRCode/tests/run.sh diff --git a/cores/nRF5/wiring_constants.h b/cores/nRF5/wiring_constants.h index 2df31617..7937948d 100644 --- a/cores/nRF5/wiring_constants.h +++ b/cores/nRF5/wiring_constants.h @@ -31,6 +31,7 @@ extern "C" { #define INPUT_PULLUP (0x2) #define INPUT_PULLDOWN (0x3) #define OUTPUT_HIGH_DRIVE (0x4) +#define INPUT_PULLUP_SENSE (0x5) #define PI 3.1415926535897932384626433832795 #define HALF_PI 1.5707963267948966192313216916398 diff --git a/cores/nRF5/wiring_digital.c b/cores/nRF5/wiring_digital.c index 977de957..3e3ef060 100644 --- a/cores/nRF5/wiring_digital.c +++ b/cores/nRF5/wiring_digital.c @@ -57,6 +57,15 @@ extern "C" ((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); break; + case INPUT_PULLUP_SENSE: + // Set pin to input mode with pull-up resistor enabled + port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | + ((uint32_t)GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + ((uint32_t)GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | + ((uint32_t)GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | + ((uint32_t)GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos); + break; + case INPUT_PULLDOWN: // Set pin to input mode with pull-down resistor enabled port->PIN_CNF[pin] = ((uint32_t)GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | diff --git a/libraries/BEINK/BEINK.cpp b/libraries/BEINK/BEINK.cpp new file mode 100644 index 00000000..8795f7d2 --- /dev/null +++ b/libraries/BEINK/BEINK.cpp @@ -0,0 +1,337 @@ +/// +/// @file BEINK.cpp +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include "BEINK.h" +#include + +BEINKClass BEINK; + +#define EINK_CMD(cmd_byte) \ + { \ + .cmd = cmd_byte, \ + .data = 0, \ + .data_len = 0, \ + } + +#define EINK_CMD_AND_DATA(cmd_byte, ...) \ + { \ + .cmd = cmd_byte, \ + .data = (uint8_t[]){__VA_ARGS__}, \ + .data_len = sizeof((uint8_t[]){__VA_ARGS__}), \ + } + +struct eink_cmd { + uint8_t cmd; + uint8_t *data; + uint8_t data_len; +}; +static const struct eink_cmd init_ctrl_cmds[] = { + EINK_CMD_AND_DATA(DRIVER_OUTPUT, 0xD3, 0x00, 0x00), + EINK_CMD_AND_DATA(DATA_ENTRY_SEQUENCE, 0x03), // set xy increment + EINK_CMD_AND_DATA(RAM_X_START_END, 0x00, 0x0C), + EINK_CMD_AND_DATA(RAM_Y_START_END, 0x00, 0x00, 0xD3, 0x00), + EINK_CMD_AND_DATA(BORDER_WAVEFORM, 0x05), + EINK_CMD_AND_DATA(DISPLAY_UPDATE_CTRL, 0x00, 0x80), + EINK_CMD_AND_DATA(0x18, 0x80), + EINK_CMD_AND_DATA(DISPLAY_UPDATE_SEQUENCE_CFG, 0xB1), + EINK_CMD(DISPLAY_UPDATE_SEQUENCE_RUN), +}; + +int BEINKClass::eink_wait_for_idle(void) +{ + while (digitalRead(busy_pin) == HIGH) { + } + return 0; +} + +int BEINKClass::eink_send_data(uint8_t *data, uint16_t data_len) +{ + digitalWrite(cs_pin, LOW); + SPI.transfer(data, data_len); + digitalWrite(cs_pin, HIGH); + return 0; +} + +int BEINKClass::eink_send_data(uint8_t data) +{ + eink_send_data(&data, sizeof(data)); + return 0; +} + +int BEINKClass::eink_send_command(uint8_t cmd) +{ + digitalWrite(dc_pin, LOW); + eink_send_data(cmd); + digitalWrite(dc_pin, HIGH); + return 0; +} + +int BEINKClass::eink_hw_rst(void) +{ + digitalWrite(rst_pin, LOW); + delay(1); + digitalWrite(rst_pin, HIGH); + delay(1); + return 0; +} + +int BEINKClass::eink_init_controller(void) +{ + eink_send_command(SW_RESET); + eink_wait_for_idle(); + int cmds = (sizeof(init_ctrl_cmds) / sizeof(init_ctrl_cmds[0])); + for (int i = 0; i < cmds; i++) { + eink_send_command(init_ctrl_cmds[i].cmd); + if (init_ctrl_cmds[i].data) { + eink_send_data(init_ctrl_cmds[i].data, init_ctrl_cmds[i].data_len); + } + } + eink_wait_for_idle(); + return 0; +} + +int BEINKClass::init_hw(void) +{ + pinMode(busy_pin, INPUT); + pinMode(vcc_pin, OUTPUT_HIGH_DRIVE); + pinMode(cs_pin, OUTPUT); + pinMode(rst_pin, OUTPUT); + pinMode(dc_pin, OUTPUT); + // + SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); + SPI.begin(); + // + digitalWrite(cs_pin, HIGH); + digitalWrite(dc_pin, HIGH); + digitalWrite(rst_pin, HIGH); + digitalWrite(vcc_pin, HIGH); + // + return 0; +} + +int BEINKClass::set_xy_window(uint16_t x_start, uint16_t x_end, uint16_t y_start, uint16_t y_end) +{ + uint8_t x_data[] = { + (x_start & 0xFF), + (x_end & 0xFF), + }; + uint8_t y_data[] = { + ((y_start >> 0) & 0xFF), + ((y_start >> 8) & 0xFF), + ((y_end >> 0) & 0xFF), + ((y_end >> 8) & 0xFF), + }; + eink_send_command(RAM_X_START_END); + eink_send_data(x_data, sizeof(x_data)); + eink_send_command(RAM_Y_START_END); + eink_send_data(y_data, sizeof(y_data)); + return 0; +} + +int BEINKClass::set_xy_counter(uint16_t x, uint16_t y) +{ + uint8_t x_data[] = { + x, + }; + uint8_t y_data[] = { + ((y >> 0) & 0xFF), + ((y >> 8) & 0xFF), + }; + eink_send_command(RAM_X_COUNTER); + eink_send_data(x_data, sizeof(x_data)); + eink_send_command(RAM_Y_COUNTER); + eink_send_data(y_data, sizeof(y_data)); + return 0; +} + +int BEINKClass::update(void) +{ + eink_send_command(DISPLAY_UPDATE_SEQUENCE_CFG); + eink_send_data(0xC7); + eink_send_command(DISPLAY_UPDATE_SEQUENCE_RUN); + eink_wait_for_idle(); + return 0; +} + +int BEINKClass::turn_on(void) +{ + init_hw(); + eink_hw_rst(); + eink_init_controller(); + return 0; +} + +int BEINKClass::turn_off(void) +{ + return 0; +} + +int BEINKClass::soft_sleep(void) +{ + eink_send_command(DEEP_SLEEP); + eink_send_data(0x01); + return 0; +} + +int BEINKClass::clear(enum eink_color_id color) +{ + int bts = (width >> 3) * height; + for (int i = 0; i < 2; i++) { + set_xy_window(0, (width >> 3) - 1, 0, height - 1); + set_xy_counter(0, 0); + if (i == 0) { + eink_send_command(BW_RAM_ADDRESS); + } else { + eink_send_command(RED_RAM_ADDRESS); + } + for (int b = 0; b < bts; b++) { + eink_send_data(color == i ? 0xFF : 0x00); + } + } + // eink_update(); + return 0; +} + +int BEINKClass::draw_img(uint8_t *buf, uint16_t pos_x, uint16_t pos_y, uint16_t width, uint16_t height) +{ + int bts = (width >> 3) * height; + for (int i = 0; i < 2; i++) { + set_xy_window(pos_x, (width >> 3) - 1, pos_y, height - 1); + set_xy_counter(pos_x, pos_y); + if (i == 0) { + eink_send_command(BW_RAM_ADDRESS); + } else { + eink_send_command(RED_RAM_ADDRESS); + } + for (int b = 0; b < bts; b++) { + eink_send_data(buf[bts * i + b]); + } + } + // eink_update(); + return 0; +} + +int BEINKClass::set_pixel_in_canvas(uint8_t pixel, uint16_t pos_x, uint16_t pos_y, uint8_t *canvas_buf, uint16_t canvas_width, uint16_t canvas_height) +{ + switch (this->rotate) { + case ROTATE_0: { + } break; + case ROTATE_180: { + pos_x = canvas_width - pos_x; + pos_y = canvas_height - pos_y; + } break; + case ROTATE_90: { + uint16_t temp = pos_x; + pos_x = canvas_width - pos_y; + pos_y = temp; + } break; + case ROTATE_270: { + uint16_t temp = pos_x; + pos_x = pos_y; + pos_y = canvas_height - temp; + } break; + } + // Serial.print(pos_x, HEX); + // Serial.print(":"); + // Serial.print(pos_y, HEX); + // Serial.print(" "); + if (pos_x >= canvas_width || pos_y >= canvas_height) { + return -1; + } + // + if (pixel) { + canvas_buf[(canvas_width * pos_y + pos_x) >> 3] |= (0x80 >> (pos_x & 0x07)); + } else { + canvas_buf[(canvas_width * pos_y + pos_x) >> 3] &= ~(0x80 >> (pos_x & 0x07)); + } +} + +int BEINKClass::print_line(uint16_t pos_x, uint16_t pos_y, char *line) +{ + struct font_data *font = &Font16; + uint16_t char_cnt = strlen(line); + uint16_t canvas_width; + uint16_t canvas_height; + // + switch (this->rotate) { + case ROTATE_0: + case ROTATE_180: + canvas_width = char_cnt * font->Width; + canvas_height = font->Height; + break; + case ROTATE_90: + case ROTATE_270: + canvas_width = font->Height; + canvas_height = char_cnt * font->Width; + break; + } + canvas_width = (canvas_width + 7) & 0xFFF8; + canvas_height = (canvas_height + 7) & 0xFFF8; + uint16_t canvas_size = (canvas_width * canvas_height) >> 3; + uint8_t canvas_buf[canvas_size]; + memset(canvas_buf, 0xFF, canvas_size); + // + uint16_t off_x, off_y; + const uint8_t *char_pixels; + for (int char_idx = 0; char_idx < char_cnt; char_idx++) { + char_pixels = &font->table[(line[char_idx] - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0))]; + for (int char_off_y = 0; char_off_y < font->Height; char_off_y++) { + for (int char_off_x = 0; char_off_x < font->Width; char_off_x++) { + uint8_t bit = char_pixels[char_off_x >> 3] & (0x80 >> (char_off_x & 0x07)); + uint8_t bit_pos_x = (char_idx * font->Width) + char_off_x; + set_pixel_in_canvas(bit == 0, bit_pos_x, char_off_y, canvas_buf, canvas_width, canvas_height); + } + char_pixels += ((font->Width + 7) >> 3); + Serial.println(); + } + Serial.println(); + } + // + set_xy_window(pos_x >> 3, ((canvas_width + pos_x) >> 3) - 1, pos_y, pos_y + canvas_height - 1); + set_xy_counter(pos_x >> 3, pos_y); + eink_send_command(BW_RAM_ADDRESS); + for (int b = 0; b < canvas_size; b++) { + eink_send_data(canvas_buf[b]); + } + // eink_update(); + return 0; +} + +int BEINKClass::print_qr(int pos_x, int pos_y, const char *data) +{ + QRCode qrcode; + uint8_t qrcodeData[qrcode_getBufferSize(qr_version)]; + qrcode_initText(&qrcode, qrcodeData, qr_version, ECC_MEDIUM, data); + uint16_t canvas_width = (qr_block_size * qrcode.size + 7) & 0xFFF8; + uint16_t canvas_height = (qr_block_size * qrcode.size + 7) & 0xFFF8; + uint16_t canvas_size = (canvas_width * canvas_height) >> 3; + uint8_t canvas_buf[canvas_size]; + memset(canvas_buf, 0xFF, canvas_size); + for (uint8_t y = 0; y < qrcode.size; y++) { + for (uint8_t x = 0; x < qrcode.size; x++) { + int qr_bit = qrcode_getModule(&qrcode, x, y); + // Serial.print(qr_bit ? '#' : ' '); + for (int qbl = 0; qbl < qr_block_size; qbl++) { + for (int qbh = 0; qbh < qr_block_size; qbh++) { + set_pixel_in_canvas(qr_bit == 0, qr_block_size * x + qbl, qr_block_size * y + qbh, canvas_buf, canvas_width, canvas_height); + } + } + } + // Serial.println(); + } + set_xy_window(pos_x >> 3, ((canvas_width + pos_x) >> 3) - 1, pos_y, pos_y + canvas_height - 1); + set_xy_counter(pos_x >> 3, pos_y); + eink_send_command(BW_RAM_ADDRESS); + for (int b = 0; b < canvas_size; b++) { + eink_send_data(canvas_buf[b]); + } + // eink_update(); + return 0; +} diff --git a/libraries/BEINK/BEINK.h b/libraries/BEINK/BEINK.h new file mode 100644 index 00000000..757c1cd8 --- /dev/null +++ b/libraries/BEINK/BEINK.h @@ -0,0 +1,117 @@ +/// +/// @file BEINK.h +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#ifndef BEINK_h +#define BEINK_h + +#include +#include +#include +#include "fonts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +// Display resolution +#define EPD_WIDTH 104 +#define EPD_HEIGHT 212 +#define QRCODE_VERSION 2 + +//#define EPD_WIDTH 128 +//#define EPD_HEIGHT 296 + +// commands +#define DRIVER_OUTPUT 0x01 +#define SOURCE_DRIVING_VOLTAGE 0x04 +#define DEEP_SLEEP 0x10 +#define DATA_ENTRY_SEQUENCE 0x11 +#define SW_RESET 0x12 + +#define DISPLAY_UPDATE_SEQUENCE_RUN 0x20 +#define DISPLAY_UPDATE_CTRL 0x21 +#define DISPLAY_UPDATE_SEQUENCE_CFG 0x22 +#define BW_RAM_ADDRESS 0x24 +#define RED_RAM_ADDRESS 0x26 +#define WRITE_VCOM_REGISTER 0x2C +#define WRITE_LUT_REGISTER 0x32 +#define DUMMY_LINE_PERIOD 0x3A +#define GATE_LINE_WIDTH 0x3B +#define BORDER_WAVEFORM 0x3C +#define RAM_X_START_END 0x44 +#define RAM_Y_START_END 0x45 +#define RAM_X_COUNTER 0x4E +#define RAM_Y_COUNTER 0x4F +#define ANALOG_BLOCK 0x74 +#define DIGITAL_BLOCK 0x7E + +#define COLOR_BW 0x01 +#define COLOR_RED 0x02 + +enum eink_color_id { + color_white = 0, + color_red = 1, + color_black = 2, +}; + +enum eink_orientation { + ROTATE_0, + ROTATE_90, + ROTATE_180, + ROTATE_270, +}; + +class BEINKClass { +private: + int width = EPD_WIDTH; + int height = EPD_HEIGHT; + int busy_pin = E_INK_BUSY_PIN; + int vcc_pin = E_INK_VDD_CTRL_PIN; + int cs_pin = E_INK_CS_PIN; + int rst_pin = E_INK_RST_PIN; + int dc_pin = E_INK_DC_PIN; + int qr_version = QRCODE_VERSION; + int qr_block_size = 4; + enum eink_orientation rotate = ROTATE_90; + // + int init_hw(); + int set_xy_counter(uint16_t x, uint16_t y); + int set_xy_window(uint16_t x_start, uint16_t x_end, uint16_t y_start, uint16_t y_end); + int eink_init_controller(void); + int eink_hw_rst(void); + int eink_send_command(uint8_t cmd); + int eink_send_data(uint8_t data); + int eink_send_data(uint8_t *data, uint16_t data_len); + int eink_wait_for_idle(void); + void set_abs_pixel_to_buf(int x, int y, uint8_t *buf, bool invert); + void set_pixel_to_buf(int x, int y, uint8_t *buf, bool invert); + void print_char_to_buf(int x, int y, uint8_t *buf, char ascii_char, struct font_data *font, bool invert); + void print_line_to_buf(int x, int y, uint8_t *buf, const char *p_text, struct font_data *font, bool invert); + int set_pixel_in_canvas(uint8_t pixel, uint16_t pos_x, uint16_t pos_y, uint8_t *canvas_buf, uint16_t canvas_width, uint16_t canvas_height); + +public: + int turn_on(); + int turn_off(); + int soft_sleep(); + int clear(enum eink_color_id color); + int draw_img(uint8_t *buf, uint16_t pos_x = 0, uint16_t pos_y = 0, uint16_t width = EPD_WIDTH, uint16_t height = EPD_HEIGHT); + int print_line(uint16_t line_num, uint16_t pos_y, char *line); + int update(void); + // + int print_qr(int pos_x, int pos_y, const char *data); +}; + +extern BEINKClass BEINK; + +#endif \ No newline at end of file diff --git a/libraries/BEINK/example.c.org b/libraries/BEINK/example.c.org new file mode 100644 index 00000000..0db81315 --- /dev/null +++ b/libraries/BEINK/example.c.org @@ -0,0 +1,22599 @@ +//---------------------------------------------------------------------- +/*EASTRISING TECHNOLOGY CO,.LTD.*/ +// Module : ER-EP0213-1R ER-EP0213-1Y 2.13" 104x212 dots +// Create : JAVEN +// Date : Dec-03-2019 +// Drive IC : ssd1675b +// INTERFACE : 4-wire serial interface +// MCU : stc89Le516 +// VDD : 3.3V +//---------------------------------------------------------------------- + +#include +#include +sbit BUSY = P3 ^ 0; +sbit RES = P3 ^ 1; +sbit DC = P3 ^ 3; +sbit CS1 = P3 ^ 4; +sbit SCK = P3 ^ 5; +sbit SDA = P3 ^ 6; + +sbit int0 = P3 ^ 2; + +bit log = 0; + +#define uchar unsigned char +#define uint unsigned int + +// xx Private macro xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +#define SDA_H (SDA = 1) +#define SDA_L (SDA = 0) +#define SCLK_H (SCK = 1) +#define SCLK_L (SCK = 0) +#define nCS_H (CS1 = 1) +#define nCS_L (CS1 = 0) +#define nDC_H (DC = 1) +#define nDC_L (DC = 0) +#define nRST_H (RES = 1) +#define nRST_L (RES = 0) + +#define DELAY_TIME 2 // DELAY TIME + +#define MODE1 // panel scan direction + +#define PIC_BLACK 252 +#define PIC_WHITE 255 +#define PIC_A 1 +#define PIC_B 2 +#define PIC_C 3 +#define PIC_HLINE 4 +#define PIC_VLINE 5 +#define PIC_R 6 +#define PIC_D 7 +#define PIC_E 8 +#define PIC_F 9 + +const unsigned char code gImage_mb_bw[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X55, + 0X5F, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X8B, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0X99, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0X9B, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X7E, + 0X27, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XB1, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X17, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X78, + 0XB7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X7E, + 0XBD, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X7D, + 0X83, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0XB7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF3, + 0XFF, + 0XF0, + 0X00, + 0X1F, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XCF, + 0XFF, + 0XE0, + 0X00, + 0X0F, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0X3F, + 0XFF, + 0XC0, + 0X00, + 0X07, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7C, + 0XFF, + 0XFF, + 0X81, + 0XFF, + 0X03, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X87, + 0XFF, + 0XC3, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0XDF, + 0XFF, + 0X87, + 0XFF, + 0XC3, + 0XFE, + 0X10, + 0X80, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7B, + 0XDB, + 0XFF, + 0X87, + 0XFF, + 0XC3, + 0XFE, + 0X30, + 0XB9, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XDB, + 0XFF, + 0X87, + 0XFF, + 0XC3, + 0XFE, + 0X10, + 0XA1, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X1B, + 0XFF, + 0X81, + 0XFF, + 0X03, + 0XFE, + 0X09, + 0XA1, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDB, + 0XFF, + 0XC0, + 0X00, + 0X07, + 0XFE, + 0X0A, + 0X91, + 0X5F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XDB, + 0XFF, + 0XE0, + 0X00, + 0X0F, + 0XFE, + 0X04, + 0X89, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7E, + 0X1B, + 0XFF, + 0XF0, + 0X00, + 0X1F, + 0XFE, + 0X02, + 0X86, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7D, + 0XDB, + 0XFF, + 0XFC, + 0X00, + 0XFF, + 0XFE, + 0X09, + 0XE3, + 0XDF, + 0XF0, + 0X00, + 0X00, + 0X7B, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X10, + 0X92, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7B, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X20, + 0X82, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X3F, + 0X82, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X02, + 0X80, + 0XDF, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X04, + 0XBF, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X04, + 0X82, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X84, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0X00, + 0X03, + 0XFE, + 0X08, + 0X88, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0X00, + 0X03, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0X80, + 0X00, + 0X03, + 0XFE, + 0X18, + 0X10, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0X80, + 0X00, + 0X07, + 0XFE, + 0X24, + 0XF0, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X0F, + 0XFE, + 0X25, + 0X10, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X1F, + 0XFE, + 0X25, + 0X10, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X3F, + 0XFE, + 0X25, + 0X10, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X78, + 0X7F, + 0XFF, + 0XFF, + 0XFC, + 0X3F, + 0XFE, + 0X25, + 0X10, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X7F, + 0XFF, + 0XFF, + 0XF8, + 0X7F, + 0XFE, + 0X2A, + 0XE0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X18, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X78, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X01, + 0XFC, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X06, + 0X03, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0X00, + 0X3F, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X7E, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X06, + 0X03, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7C, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X01, + 0XFC, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X03, + 0XF8, + 0X03, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X07, + 0XFC, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X0F, + 0XFE, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X0E, + 0X0F, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X1F, + 0XFF, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X30, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X1F, + 0XFF, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X40, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X1F, + 0XFF, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X80, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X1F, + 0XFF, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X09, + 0X00, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X1F, + 0XFF, + 0X03, + 0XF7, + 0XFF, + 0XFE, + 0X0A, + 0X00, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X70, + 0X0F, + 0XFE, + 0X02, + 0X07, + 0XFF, + 0XFE, + 0X0C, + 0X07, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X78, + 0X07, + 0XFE, + 0X00, + 0X07, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X78, + 0X01, + 0XFC, + 0X00, + 0X07, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X00, + 0X78, + 0X00, + 0X07, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X00, + 0X78, + 0X00, + 0X07, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7E, + 0X00, + 0X78, + 0X00, + 0X07, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X7C, + 0X00, + 0X0F, + 0XFF, + 0XFE, + 0X08, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0XFC, + 0X01, + 0XFF, + 0XFF, + 0XFE, + 0X0F, + 0XFF, + 0X9F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XE0, + 0XFC, + 0X7F, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X01, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XF8, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X08, + 0X01, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X3E, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X00, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0XFF, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X21, + 0X01, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X22, + 0X01, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X21, + 0X01, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0XF9, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X89, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X89, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X89, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X89, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X20, + 0X89, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X1F, + 0XFE, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X08, + 0X1F, + 0XF0, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X10, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X20, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X3F, + 0XFE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X1F, + 0XFC, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X11, + 0X24, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X11, + 0X25, + 0X9F, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X1F, + 0XFE, + 0X9F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X10, + 0X04, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X3F, + 0XFC, + 0X9F, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X9F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X9F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X1F, + 0XF7, + 0X7F, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF1, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X7F, + 0XFF, + 0XFF, + 0XF1, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XBF, + 0XFF, + 0XFF, + 0XEA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X7F, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0X7F, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0X05, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFE, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0X3F, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X86, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0X7D, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0XFB, + 0X3F, + 0XFF, + 0XFF, + 0XFC, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0X7F, + 0XFF, + 0XFF, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF3, + 0X7F, + 0XFF, + 0XFF, + 0XD5, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0X15, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XCF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0X2F, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X7F, + 0XFF, + 0XFF, + 0X40, + 0X3F, + 0XFF, + 0XFF, + 0XF8, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFC, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0X7F, + 0XFF, + 0XFF, + 0X00, + 0X3F, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XEE, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XEC, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XEB, + 0XBF, + 0XFF, + 0XFF, + 0XEA, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0X7F, + 0XFF, + 0XFF, + 0X6A, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X56, + 0XBF, + 0XFF, + 0XFF, + 0XFD, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X9F, + 0XFF, + 0XFF, + 0X16, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X7F, + 0XFF, + 0XFF, + 0X48, + 0X3F, + 0XFF, + 0XFF, + 0XFC, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XFF, + 0XFF, + 0XFF, + 0X56, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XBF, + 0XFF, + 0XFF, + 0XFB, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XBF, + 0XFF, + 0XFF, + 0XFC, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XF2, + 0X7F, + 0XFF, + 0XFF, + 0XEC, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XCF, + 0XFF, + 0X7F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XCF, + 0XEC, + 0X03, + 0X3F, + 0XED, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X2F, + 0XF7, + 0XFB, + 0X7F, + 0XF7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0XEF, + 0XFB, + 0XFB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFC, + 0X0A, + 0X7F, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0XF9, + 0X7F, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X9F, + 0XF7, + 0XFB, + 0X7F, + 0XEF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XEC, + 0X03, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XEF, + 0XDF, + 0XFD, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XDF, + 0XDB, + 0X05, + 0XFF, + 0XFF, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0X7D, + 0XFF, + 0XFE, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X9F, + 0XEF, + 0X7D, + 0XFF, + 0XF9, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFB, + 0X6F, + 0XE0, + 0X00, + 0X3F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XEF, + 0XFF, + 0X7D, + 0XFF, + 0XFF, + 0XF8, + 0X0D, + 0XFF, + 0X7F, + 0X9C, + 0XBF, + 0XFF, + 0XF9, + 0XDF, + 0XFF, + 0X7D, + 0XFF, + 0XF3, + 0XBB, + 0XED, + 0XE1, + 0X4F, + 0XAE, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0XFF, + 0XED, + 0XBB, + 0XED, + 0XF5, + 0XAF, + 0XAA, + 0X1E, + 0X07, + 0XFB, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XB8, + 0X0D, + 0XF5, + 0XAF, + 0XCA, + 0XBD, + 0X77, + 0XFB, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XEC, + 0X3A, + 0XA9, + 0XE1, + 0X47, + 0XEA, + 0X3D, + 0X77, + 0XFA, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X05, + 0XFF, + 0X5F, + 0XCA, + 0XBF, + 0X8F, + 0XF9, + 0XDF, + 0XFF, + 0X7F, + 0XFF, + 0XF0, + 0X7B, + 0XED, + 0XFE, + 0XDF, + 0XAA, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X7F, + 0X7F, + 0XEF, + 0XBB, + 0XED, + 0XE0, + 0X07, + 0XAE, + 0XBF, + 0X83, + 0XFC, + 0X1F, + 0XC1, + 0X7D, + 0X7F, + 0XEF, + 0XB8, + 0X0D, + 0XFE, + 0X5F, + 0XAC, + 0XBF, + 0X7D, + 0XFB, + 0XEF, + 0XED, + 0X45, + 0X7F, + 0XF0, + 0X7F, + 0XFF, + 0XFD, + 0XDF, + 0XFF, + 0XBF, + 0X7D, + 0XFB, + 0XEF, + 0XED, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X83, + 0XFC, + 0X1F, + 0XED, + 0X15, + 0X7F, + 0XFF, + 0XFF, + 0X57, + 0XFF, + 0X7F, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XC1, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0X57, + 0XE1, + 0XBF, + 0XEB, + 0X7F, + 0X73, + 0XFC, + 0X1F, + 0XFF, + 0X54, + 0X3F, + 0XFF, + 0XF8, + 0X01, + 0XF5, + 0X5F, + 0XF3, + 0X7F, + 0X6D, + 0XFB, + 0X6F, + 0XE1, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XF5, + 0X6F, + 0XFB, + 0X7F, + 0X5D, + 0XFB, + 0X6F, + 0XDD, + 0X15, + 0X7F, + 0XFF, + 0XF8, + 0X01, + 0XF5, + 0X77, + 0XC0, + 0X7F, + 0X3B, + 0XFD, + 0X9F, + 0XDD, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0X57, + 0XF5, + 0X6F, + 0XBB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X55, + 0X7F, + 0XFF, + 0XFF, + 0X57, + 0XF5, + 0X5F, + 0XBB, + 0X1F, + 0X7F, + 0XFC, + 0XDF, + 0XF5, + 0X45, + 0X7F, + 0XFF, + 0XFC, + 0X01, + 0XE1, + 0XBF, + 0XF2, + 0X7F, + 0X01, + 0XFB, + 0X6F, + 0XED, + 0X7D, + 0X7F, + 0XFF, + 0XFB, + 0XB7, + 0XFF, + 0X7F, + 0XE9, + 0X7F, + 0X7B, + 0XFB, + 0X6F, + 0XDD, + 0X7F, + 0X7F, + 0XFF, + 0XFB, + 0X77, + 0XFF, + 0X7F, + 0XDB, + 0X7F, + 0XFF, + 0XFC, + 0X1F, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, +}; + +const unsigned char code gImage_mb_red[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XAA, + 0XA8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X55, + 0X55, + 0X54, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X10, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X30, + 0XB9, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X10, + 0XA1, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X09, + 0XA1, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0A, + 0X91, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X04, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X86, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X09, + 0XE3, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X10, + 0X92, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X82, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X82, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X80, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X04, + 0XBF, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X04, + 0X82, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X84, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X88, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X18, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X24, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X25, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X25, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X25, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X25, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X2A, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X18, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X06, + 0X03, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X08, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X08, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X06, + 0X03, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X0E, + 0X0F, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X08, + 0X30, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X08, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X08, + 0X80, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X09, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X0A, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X0C, + 0X07, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X07, + 0XC0, + 0X00, + 0X08, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X01, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X01, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XF1, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XF1, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEA, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X1C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X3F, + 0XD0, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X12, + 0X50, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X12, + 0X51, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X12, + 0X51, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X12, + 0X52, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X12, + 0X52, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X3F, + 0XCF, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X05, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFE, + 0XFC, + 0X3F, + 0XC3, + 0XE0, + 0X00, + 0X00, + 0X12, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0X3C, + 0X3F, + 0X3C, + 0XE0, + 0X00, + 0X00, + 0X22, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X86, + 0XFC, + 0X3E, + 0XFF, + 0X60, + 0X00, + 0X1F, + 0XFF, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X7D, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X20, + 0X42, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0X3C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X10, + 0X82, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X00, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X82, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFD, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0X9D, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XD5, + 0X7C, + 0X3F, + 0X6D, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X15, + 0X7C, + 0X3F, + 0X6D, + 0XE0, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X55, + 0X7C, + 0X3F, + 0X73, + 0XE0, + 0X00, + 0X00, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X40, + 0X3C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X88, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X55, + 0X7C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X8C, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X55, + 0X7C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X88, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X55, + 0X7C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X88, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X00, + 0X3C, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X88, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFC, + 0XFC, + 0X3E, + 0XFF, + 0X60, + 0X00, + 0X00, + 0X88, + 0X80, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFB, + 0XFC, + 0X3F, + 0X3C, + 0XE0, + 0X00, + 0X1F, + 0XFF, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XC3, + 0XE0, + 0X00, + 0X20, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEC, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X10, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEA, + 0XBC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X6A, + 0XBC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X56, + 0XBC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X16, + 0XBC, + 0X3F, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X89, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X48, + 0X3C, + 0X3F, + 0XC7, + 0XE0, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X56, + 0XBC, + 0X3F, + 0XD9, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEA, + 0XBC, + 0X3F, + 0XC7, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEA, + 0XBC, + 0X3F, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XEC, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XFF, + 0XFC, + 0X3F, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, +}; + +const unsigned char code gImage_HStest_bw[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XFC, + 0X07, + 0XDF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X02, + 0X07, + 0XDF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X02, + 0X07, + 0XDF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X02, + 0X07, + 0XE0, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XFC, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XFC, + 0X07, + 0XF0, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X22, + 0X07, + 0XED, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X42, + 0X07, + 0XDB, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X42, + 0X07, + 0XDB, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0X3C, + 0X07, + 0XCC, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XE3, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XCC, + 0X07, + 0XDC, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X32, + 0X07, + 0XDD, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X22, + 0X07, + 0XDC, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X32, + 0X07, + 0XE3, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XCC, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X02, + 0X07, + 0XFE, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X1E, + 0X07, + 0XC1, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XE2, + 0X07, + 0XFF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X02, + 0X07, + 0XFF, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X06, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XE6, + 0X07, + 0XE1, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X24, + 0X07, + 0XDD, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XF8, + 0X07, + 0XE0, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XE2, + 0X07, + 0XE1, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XBE, + 0X07, + 0XE4, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X00, + 0X07, + 0XC0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XFE, + 0X07, + 0XD7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X84, + 0X07, + 0XF7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X88, + 0X07, + 0XF4, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XB0, + 0X07, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X40, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XE1, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0XEC, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X12, + 0X07, + 0XDF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X02, + 0X07, + 0XEF, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X04, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X1C, + 0X07, + 0XDE, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X22, + 0X07, + 0XDD, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X42, + 0X07, + 0XDB, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X82, + 0X07, + 0XD7, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0X0C, + 0X07, + 0XCF, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X00, + 0X07, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XFE, + 0X07, + 0XC0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X04, + 0X07, + 0XDF, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XF7, + 0X7F, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XF6, + 0X7F, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X97, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X6B, + 0X9F, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X5A, + 0X07, + 0XDD, + 0X2F, + 0XFE, + 0XE8, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X53, + 0X07, + 0XD5, + 0X67, + 0XFE, + 0X8C, + 0XBF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X4A, + 0X87, + 0XED, + 0XAB, + 0XFE, + 0X68, + 0XBF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X44, + 0X07, + 0XF5, + 0XDF, + 0XFE, + 0XEA, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XC7, + 0X87, + 0XF9, + 0XC3, + 0XFE, + 0X17, + 0X9F, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X64, + 0X07, + 0XEC, + 0XDF, + 0XFE, + 0XF7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0XC4, + 0X07, + 0XD9, + 0XDF, + 0XFE, + 0XEE, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X07, + 0X40, + 0X87, + 0XC5, + 0XFB, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X5F, + 0X07, + 0XF5, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X42, + 0X07, + 0XED, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X44, + 0X07, + 0XED, + 0XDF, + 0XFF, + 0XF9, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFD, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X06, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X41, + 0X07, + 0XFD, + 0XF7, + 0XFF, + 0XFF, + 0X3F, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X07, + 0X55, + 0X07, + 0XC5, + 0X57, + 0XFF, + 0X86, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X07, + 0XD5, + 0X57, + 0XFE, + 0X7D, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X07, + 0XD5, + 0X57, + 0XFE, + 0XFB, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X7F, + 0X87, + 0XD4, + 0X03, + 0XFF, + 0XFF, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X07, + 0XD5, + 0X57, + 0XFE, + 0X00, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X07, + 0XD5, + 0X57, + 0XFF, + 0XFB, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X07, + 0XD5, + 0X57, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X55, + 0X87, + 0XD5, + 0X53, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X07, + 0X7E, + 0X07, + 0XC4, + 0X0F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X04, + 0X07, + 0XFF, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0XFF, + 0XC0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X86, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0X3F, + 0XE0, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X92, + 0X87, + 0XFB, + 0XCF, + 0XFF, + 0XF6, + 0XBF, + 0XF6, + 0XDB, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X56, + 0X87, + 0XFB, + 0X6B, + 0XFE, + 0X01, + 0XBF, + 0XF7, + 0X5B, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0XD6, + 0X87, + 0XFD, + 0X4B, + 0XFE, + 0XF7, + 0XBF, + 0XF0, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0XA2, + 0X87, + 0XD9, + 0X4B, + 0XFE, + 0XF7, + 0XBF, + 0XF7, + 0X5B, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0XDF, + 0X87, + 0XD2, + 0XEB, + 0XFF, + 0XF7, + 0XBF, + 0XF6, + 0XDB, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0XA2, + 0X87, + 0XE9, + 0X03, + 0XFF, + 0XF7, + 0XBF, + 0XE0, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0XD6, + 0X87, + 0XEA, + 0XEB, + 0XFF, + 0XF7, + 0XFF, + 0XEA, + 0XAB, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X56, + 0X87, + 0XE9, + 0X4B, + 0XFF, + 0XFF, + 0XFF, + 0XEC, + 0XC1, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X92, + 0X87, + 0XFD, + 0X4B, + 0XFF, + 0XFF, + 0XFF, + 0XEA, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X86, + 0X07, + 0XFB, + 0X6B, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X23, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFB, + 0XCF, + 0XFE, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XC0, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XC0, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XDA, + 0XFF, + 0XED, + 0X45, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X08, + 0X07, + 0XFF, + 0XBF, + 0XFE, + 0XDA, + 0XFF, + 0XF0, + 0X11, + 0XFF, + 0XFF, + 0XFF, + 0X07, + 0XF4, + 0X07, + 0XC0, + 0X5F, + 0XFE, + 0XDA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X02, + 0X07, + 0XFF, + 0XEF, + 0XFF, + 0X00, + 0X1F, + 0XE5, + 0X45, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X01, + 0X87, + 0XFF, + 0XF3, + 0XFF, + 0XDA, + 0XFF, + 0XED, + 0X55, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X02, + 0X07, + 0XFF, + 0XEF, + 0XFF, + 0XDA, + 0XFF, + 0XF0, + 0X11, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XF4, + 0X07, + 0XE0, + 0X5F, + 0XFF, + 0XDA, + 0XFF, + 0XFF, + 0XEB, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X08, + 0X07, + 0XDF, + 0XBF, + 0XFF, + 0X80, + 0XFF, + 0XE0, + 0X23, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X01, + 0X87, + 0XFF, + 0XF3, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XA9, + 0XFF, + 0XFF, + 0XFF, + 0X07, + 0XFE, + 0X07, + 0XC0, + 0X0F, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X23, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X08, + 0X07, + 0XFF, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEB, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X10, + 0X07, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XED, + 0XBF, + 0XF7, + 0X2B, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XBF, + 0XED, + 0X81, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X10, + 0X07, + 0XDF, + 0X7F, + 0XFF, + 0XED, + 0XBF, + 0XFB, + 0XAB, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X10, + 0X07, + 0XEF, + 0X7F, + 0XFF, + 0X02, + 0X7F, + 0XE8, + 0X83, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X08, + 0X07, + 0XF7, + 0XBF, + 0XFE, + 0XFE, + 0XFF, + 0XE1, + 0X29, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XE4, + 0X07, + 0XF8, + 0XDF, + 0XFF, + 0XC2, + 0XBF, + 0XEA, + 0X97, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X02, + 0X07, + 0XF7, + 0XEF, + 0XFF, + 0XEE, + 0X7F, + 0XE1, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X01, + 0X87, + 0XEF, + 0XF3, + 0XFF, + 0X80, + 0XFF, + 0XF9, + 0X2B, + 0XFF, + 0XFF, + 0XFF, + 0X05, + 0X02, + 0X07, + 0XD7, + 0XEF, + 0XFF, + 0X6E, + 0X3F, + 0XF7, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XE4, + 0X07, + 0XF8, + 0XDF, + 0XFE, + 0XE2, + 0XFF, + 0XF8, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X08, + 0X07, + 0XF7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X10, + 0X07, + 0XEF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X10, + 0X07, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0XFF, + 0XFF, + 0XE8, + 0XC5, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0X7C, + 0X3F, + 0XE2, + 0X55, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X00, + 0X07, + 0XDF, + 0XFF, + 0XFF, + 0X33, + 0XBF, + 0XFF, + 0XD5, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X00, + 0X07, + 0XEF, + 0XFF, + 0XFF, + 0X8F, + 0XBF, + 0XE8, + 0X91, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X00, + 0X07, + 0XF7, + 0XFF, + 0XFF, + 0XA7, + 0XBF, + 0XE2, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XC0, + 0X07, + 0XF9, + 0XFF, + 0XFF, + 0X78, + 0XBF, + 0XFF, + 0X8B, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X30, + 0X07, + 0XFE, + 0X7F, + 0XFF, + 0X7F, + 0X3F, + 0XFD, + 0X63, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X0F, + 0X87, + 0XFF, + 0X83, + 0XFE, + 0XFF, + 0XBF, + 0XE0, + 0X69, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X30, + 0X07, + 0XFE, + 0X7F, + 0XFE, + 0XCF, + 0X7F, + 0XF5, + 0X63, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0XC0, + 0X07, + 0XF9, + 0XFF, + 0XFF, + 0X99, + 0XBF, + 0XE0, + 0X0B, + 0XFF, + 0XFF, + 0XFF, + 0X01, + 0X00, + 0X07, + 0XF7, + 0XFF, + 0XFE, + 0X7D, + 0XFF, + 0XFD, + 0X6B, + 0XFF, + 0XFF, + 0XFF, + 0X02, + 0X00, + 0X07, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X04, + 0X00, + 0X07, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0X00, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X00, + 0X01, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X66, + 0X67, + 0XFE, + 0X1E, + 0X1E, + 0X1E, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, +}; + +const unsigned char code gImage_HStest_red[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF6, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X97, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X7E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X6B, + 0X9C, + 0X00, + 0X00, + 0X00, + 0XFF, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XE8, + 0X7C, + 0X00, + 0X00, + 0X01, + 0XC3, + 0X80, + 0X02, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X8C, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X81, + 0X80, + 0X02, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X68, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XC3, + 0X80, + 0X02, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XEA, + 0X3C, + 0X00, + 0X00, + 0X00, + 0XFF, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X17, + 0X9C, + 0X00, + 0X00, + 0X00, + 0X7E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XEE, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X7E, + 0X00, + 0X00, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XFF, + 0X80, + 0X01, + 0X22, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X91, + 0X80, + 0X02, + 0X42, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF9, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XB1, + 0X80, + 0X02, + 0X42, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFD, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XBF, + 0X80, + 0X03, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X06, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X86, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XE7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7D, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X01, + 0XCC, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFB, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X02, + 0X32, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X02, + 0X22, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X00, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X02, + 0X32, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFB, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XE7, + 0X00, + 0X01, + 0XCC, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X80, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X7D, + 0X80, + 0X00, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XE1, + 0X80, + 0X03, + 0XE2, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0X3C, + 0X00, + 0X00, + 0X01, + 0X81, + 0X80, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X06, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF6, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X01, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X78, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X00, + 0XFD, + 0X80, + 0X01, + 0XE6, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X8D, + 0X80, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X8D, + 0X80, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X8B, + 0X80, + 0X02, + 0X24, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XFF, + 0X00, + 0X01, + 0XF8, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7F, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XC0, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XE2, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XC0, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XF1, + 0X80, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XF9, + 0X80, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X01, + 0XBE, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X00, + 0X1C, + 0X00, + 0X00, + 0X01, + 0X9F, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XDF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X80, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X20, + 0X00, + 0X03, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X02, + 0X84, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X00, + 0X88, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X23, + 0X80, + 0X00, + 0XB0, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X00, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X2E, + 0X00, + 0X00, + 0X40, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X30, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XEC, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X02, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFE, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XE7, + 0X00, + 0X02, + 0X12, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XC2, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X02, + 0X02, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XEE, + 0X7C, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X01, + 0X04, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X80, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X6E, + 0X3C, + 0X00, + 0X00, + 0X01, + 0X99, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XE2, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XC3, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X1C, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X22, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X8F, + 0X00, + 0X02, + 0X42, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X9F, + 0X80, + 0X02, + 0X82, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XB1, + 0X80, + 0X03, + 0X0C, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X7C, + 0X3C, + 0X00, + 0X00, + 0X01, + 0XE1, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X33, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XC1, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X8F, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X83, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XA7, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X78, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X7F, + 0X3C, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X03, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFF, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X02, + 0X04, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XCF, + 0X7C, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X99, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XFF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7D, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X81, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X81, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF6, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X97, + 0X7C, + 0X00, + 0X00, + 0X00, + 0X25, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X6B, + 0X9C, + 0X00, + 0X00, + 0X02, + 0XAF, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XE8, + 0X7C, + 0X00, + 0X00, + 0X03, + 0XE9, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X8C, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XA9, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X68, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XA7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XEA, + 0X3C, + 0X00, + 0X00, + 0X03, + 0XE3, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X17, + 0X9C, + 0X00, + 0X00, + 0X02, + 0X7A, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0X7C, + 0X00, + 0X00, + 0X02, + 0X2A, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XEE, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XE2, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XEF, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XAF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XA3, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF9, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XA0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFD, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X06, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X2A, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X03, + 0XEA, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X86, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X2A, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7D, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X2A, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFB, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X3F, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0X3C, + 0X00, + 0X00, + 0X01, + 0X3F, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X00, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X2A, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFB, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X2A, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X2A, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XFF, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X07, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X20, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X27, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF6, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X75, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X01, + 0XBC, + 0X00, + 0X00, + 0X00, + 0XF5, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X03, + 0XDD, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X03, + 0X49, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X7F, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X4D, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XF7, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X5D, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XD5, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XF5, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X27, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7F, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X20, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XC0, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XC0, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X0C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XFF, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XF9, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X00, + 0X1C, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X01, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XFB, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XDA, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XE6, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X80, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X0C, + 0X40, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XFF, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0XFF, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X18, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X00, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X03, + 0X0C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XED, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X84, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X02, + 0X7C, + 0X00, + 0X00, + 0X00, + 0XF6, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFE, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X7F, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XC2, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XE1, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XEE, + 0X7C, + 0X00, + 0X00, + 0X01, + 0XC0, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X80, + 0XFC, + 0X00, + 0X00, + 0X02, + 0X61, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X6E, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X3D, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XE2, + 0XFC, + 0X00, + 0X00, + 0X00, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X01, + 0XC4, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0X0C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X7C, + 0X3C, + 0X00, + 0X00, + 0X02, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X33, + 0XBC, + 0X00, + 0X00, + 0X03, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X8F, + 0XBC, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XA7, + 0XBC, + 0X00, + 0X00, + 0X00, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X78, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X7F, + 0X3C, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XFF, + 0XBC, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0XCF, + 0X7C, + 0X00, + 0X00, + 0X00, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0X99, + 0XBC, + 0X00, + 0X00, + 0X01, + 0XC0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0E, + 0X7D, + 0XFC, + 0X00, + 0X00, + 0X01, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X0F, + 0XFF, + 0XFC, + 0X00, + 0X00, + 0X03, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1C, + 0X71, + 0XC7, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, +}; + +const unsigned char code gImage_LGTEST_BW1[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0X87, + 0XE1, + 0XE6, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0X87, + 0XE1, + 0XE6, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X78, + 0X66, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFA, + 0XAA, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X78, + 0X66, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X7E, + 0X1E, + 0X06, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X7E, + 0X1E, + 0X06, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X19, + 0X87, + 0X86, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X19, + 0X87, + 0X86, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X06, + 0X00, + 0X1E, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X06, + 0X00, + 0X1E, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XE7, + 0XE1, + 0XE6, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XE7, + 0XE1, + 0XE6, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X9F, + 0X9F, + 0XFE, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X9F, + 0X9F, + 0XFE, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X61, + 0XF8, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X61, + 0XF8, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE1, + 0XFF, + 0XF9, + 0XF8, + 0X1F, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE1, + 0XFF, + 0XF9, + 0XF8, + 0X1F, + 0X9F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X61, + 0XE1, + 0X9F, + 0X87, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X61, + 0XE1, + 0X9F, + 0X87, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X79, + 0X81, + 0X9E, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X79, + 0X81, + 0X9E, + 0X00, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X7F, + 0X9E, + 0X1F, + 0XE0, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF8, + 0X7F, + 0X9E, + 0X1F, + 0XE0, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE1, + 0XE1, + 0X81, + 0XFE, + 0X18, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE1, + 0XE1, + 0X81, + 0XFE, + 0X18, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF9, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X66, + 0X66, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X66, + 0X66, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFE, + 0X78, + 0X66, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFE, + 0X78, + 0X66, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X79, + 0X86, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X79, + 0X86, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X61, + 0XFE, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X61, + 0XFE, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X60, + 0X1E, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE6, + 0X06, + 0X60, + 0X1E, + 0X60, + 0X67, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFE, + 0X79, + 0X86, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFE, + 0X79, + 0X86, + 0X7F, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X7F, + 0X86, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X00, + 0X7F, + 0X86, + 0X00, + 0X07, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDC, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XD8, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X3F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFC, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF3, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X8F, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC3, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBD, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XF7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBD, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBD, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XD8, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X37, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XB7, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XC7, + 0XFF, + 0XC0, + 0X1F, + 0XFF, + 0X80, + 0X3F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XEF, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0XFF, + 0XCF, + 0X7F, + 0XFF, + 0XFE, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XA7, + 0XFF, + 0XB7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XB7, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X0F, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XEF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0XFF, + 0XBC, + 0XFF, + 0XFF, + 0X80, + 0X3F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XF7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEE, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X03, + 0XFF, + 0XB8, + 0XFF, + 0XFF, + 0XED, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XF7, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XE7, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XC4, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0XFF, + 0XFF, + 0XBB, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XC4, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XD8, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0X3E, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEE, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X80, + 0X3F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEE, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XED, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE7, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBC, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XAF, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X9E, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC4, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X6F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XAF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XDF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XDF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0X9F, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XC0, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XAF, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XBF, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XAF, + 0XFF, + 0XC0, + 0X1F, + 0XFF, + 0XBF, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X1F, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XBF, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XEF, + 0XFF, + 0XCF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFE, + 0XEF, + 0XFF, + 0XB7, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X03, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XC0, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XEF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XB7, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBC, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB7, + 0XBF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XD8, + 0X7F, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XB8, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XE0, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XC4, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBB, + 0X7F, + 0XFF, + 0XBB, + 0XBF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0XFF, + 0XFF, + 0XBB, + 0XBE, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC4, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XFF, + 0XFE, + 0X00, + 0X01, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XBF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XC0, + 0X1F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0X7F, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, + 0XFF, +}; + +const unsigned char code gImage_LGTEST_RED1[2756] = { + /* 0X01,0X01,0XD4,0X00,0X68,0X00, */ + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XDF, + 0XDE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XCF, + 0X9E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XC3, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XF0, + 0X7E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XF8, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X05, + 0X55, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XE3, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XF1, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0X7E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFE, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XCF, + 0X9E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XCF, + 0X9E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X80, + 0X00, + 0XFC, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X80, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1F, + 0XE0, + 0X00, + 0XC0, + 0X1E, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X18, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X24, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X23, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X27, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X24, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X24, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1F, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X1F, + 0XE0, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFF, + 0XFE, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X08, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XC8, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X48, + 0X00, + 0X30, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X38, + 0X00, + 0X48, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X10, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X20, + 0X00, + 0X43, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X58, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X48, + 0X00, + 0X47, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XF0, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X40, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X08, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0XFC, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X08, + 0X00, + 0X3F, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X90, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X50, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X50, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X20, + 0X00, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X60, + 0X00, + 0X30, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X50, + 0X00, + 0X48, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X50, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XE0, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X43, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X10, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X01, + 0X10, + 0X00, + 0X47, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0XFC, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X10, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X44, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X40, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X3F, + 0XE0, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X80, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, + 0X00, +}; + +const unsigned char code pic_black[2756] = { + + /*-- + /*-- 104x212 --*/ + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE7, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x3E, + 0x00, + 0xFC, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF8, + 0x0E, + 0x00, + 0xF8, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFD, + 0xCF, + 0xEE, + 0xFB, + 0xFB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF8, + 0x0F, + 0x8E, + 0xFB, + 0xFB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x3F, + 0x00, + 0xF8, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE7, + 0xFE, + 0x31, + 0xFC, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x3E, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x3F, + 0x07, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xEF, + 0xBE, + 0x03, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xEF, + 0xBE, + 0xDB, + 0xFF, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x3E, + 0x43, + 0xFF, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x7F, + 0x47, + 0xEC, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x3F, + 0x07, + 0xDB, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x3E, + 0x03, + 0xDB, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xEF, + 0xBE, + 0xFB, + 0xC0, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xEF, + 0xBE, + 0xFB, + 0xE0, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x3E, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x7E, + 0x00, + 0xFC, + 0xDF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF8, + 0x4F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x0F, + 0xFF, + 0xFB, + 0x6F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x0F, + 0xFF, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF8, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x3E, + 0x00, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xED, + 0xBE, + 0x00, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE4, + 0x3E, + 0xFE, + 0xFF, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF4, + 0x7E, + 0xFE, + 0xFF, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF4, + 0x7F, + 0x01, + 0xF8, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE4, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xED, + 0xBF, + 0x07, + 0xF8, + 0x09, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE1, + 0x3E, + 0x03, + 0xF8, + 0x09, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF1, + 0x7E, + 0xDB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x43, + 0xFC, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x47, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFB, + 0xEF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF9, + 0xCF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0xFD, + 0xDF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x02, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x02, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE7, + 0x87, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC7, + 0x03, + 0xFF, + 0xFF, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x87, + 0x01, + 0xFF, + 0xFE, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x9E, + 0x39, + 0xFF, + 0xFE, + 0xFB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0xFF, + 0xFE, + 0x73, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x9C, + 0x79, + 0xFF, + 0xFF, + 0x77, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x80, + 0x61, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0xE3, + 0xFF, + 0xFE, + 0x02, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE1, + 0xE7, + 0xFF, + 0xFE, + 0x02, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFC, + 0x3F, + 0xFE, + 0xFB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFE, + 0xFB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x0F, + 0xFE, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x0F, + 0xFF, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x87, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x81, + 0xFF, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x7E, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x7E, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x47, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x43, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0xDB, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x13, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x17, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x3F, + 0xFF, + 0xCF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x0F, + 0xFF, + 0xC3, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x03, + 0xFF, + 0x81, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x01, + 0xFF, + 0x80, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0xFF, + 0xE0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x7F, + 0xF0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x3F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x18, + 0x1F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1C, + 0x0F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1E, + 0x03, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x01, + 0xF0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x80, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xC0, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xF0, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xFC, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE7, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x87, + 0xE0, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x03, + 0xC0, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x03, + 0x80, + 0x00, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x0F, + 0x83, + 0xE0, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x07, + 0xF0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x0F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x0F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x0F, + 0xF8, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x0F, + 0x87, + 0xF0, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x03, + 0x83, + 0xE0, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x80, + 0x00, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xE0, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x80, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF8, + 0x0F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF3, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x03, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x3E, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x7F, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x7F, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x7F, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFE, + 0x3E, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC1, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x03, + 0xFF, + 0x80, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFC, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x0F, + 0xF0, + 0x00, + 0x1F, + 0xE0, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x1F, + 0x80, + 0x20, + 0x03, + 0xF0, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x7C, + 0x0F, + 0xF0, + 0x00, + 0xFC, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0xF8, + 0x7F, + 0xF0, + 0x00, + 0x3E, + 0x00, + 0x07, + 0xF0, + 0x3F, + 0xFF, + 0x8F, + 0xC0, + 0x03, + 0xE1, + 0xFF, + 0xF0, + 0x00, + 0x0F, + 0x80, + 0x07, + 0xC0, + 0x0F, + 0xFF, + 0xC7, + 0xC0, + 0x07, + 0x87, + 0xFF, + 0xF0, + 0x00, + 0x03, + 0xC0, + 0x07, + 0x80, + 0x07, + 0xFF, + 0xE7, + 0xC0, + 0x0F, + 0x1F, + 0xFF, + 0xF0, + 0x00, + 0x01, + 0xE0, + 0x07, + 0x87, + 0x87, + 0x80, + 0x03, + 0xC0, + 0x1E, + 0x3E, + 0x03, + 0xF0, + 0x00, + 0x00, + 0xF0, + 0x07, + 0x0F, + 0xC3, + 0x80, + 0x01, + 0xC0, + 0x3C, + 0x7C, + 0x01, + 0xF0, + 0x00, + 0x00, + 0x78, + 0x07, + 0x1F, + 0xE3, + 0x80, + 0x01, + 0xC0, + 0x78, + 0xFD, + 0xFD, + 0xF0, + 0x00, + 0x00, + 0x3C, + 0x07, + 0x1F, + 0xE3, + 0xFF, + 0xFF, + 0xC0, + 0x73, + 0xFD, + 0xFD, + 0xF0, + 0x00, + 0x00, + 0x1C, + 0x07, + 0x1F, + 0xE3, + 0xFF, + 0xFF, + 0xC0, + 0xE3, + 0xFC, + 0x01, + 0xF0, + 0x00, + 0x00, + 0x0E, + 0x07, + 0x0F, + 0xC3, + 0xFF, + 0xFF, + 0xC1, + 0xC7, + 0xFE, + 0x03, + 0xF0, + 0x00, + 0x00, + 0x0F, + 0x07, + 0x87, + 0x87, + 0xFF, + 0xFF, + 0xC1, + 0xCF, + 0xFF, + 0xFF, + 0xF0, + 0x1F, + 0xF0, + 0x07, + 0x07, + 0x80, + 0x07, + 0xFF, + 0xFF, + 0xC3, + 0x9F, + 0xFC, + 0x01, + 0xF0, + 0x3F, + 0xF0, + 0x03, + 0x87, + 0xC0, + 0x0F, + 0xFF, + 0xFF, + 0xC7, + 0x9F, + 0xFC, + 0x01, + 0xF0, + 0x60, + 0x00, + 0x03, + 0x87, + 0xF0, + 0x3F, + 0xFF, + 0xFF, + 0xC7, + 0x3F, + 0xFF, + 0xDD, + 0xF0, + 0x60, + 0x00, + 0x01, + 0xC7, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC7, + 0x3F, + 0xFF, + 0x1D, + 0xF0, + 0x60, + 0x00, + 0x01, + 0xC7, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xCE, + 0x7F, + 0xFE, + 0x01, + 0xF0, + 0x3F, + 0xF0, + 0x00, + 0xE7, + 0x00, + 0x03, + 0x80, + 0x01, + 0xCE, + 0x7F, + 0xFC, + 0x63, + 0xF0, + 0x3F, + 0xF0, + 0x00, + 0xE7, + 0x00, + 0x03, + 0x80, + 0x01, + 0xDC, + 0x7F, + 0xFD, + 0xFF, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x67, + 0x00, + 0x03, + 0x80, + 0x01, + 0xDC, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x77, + 0xFF, + 0x83, + 0x8F, + 0xF1, + 0xDC, + 0xFF, + 0xFE, + 0x03, + 0xF0, + 0x39, + 0xE0, + 0x00, + 0x77, + 0xFE, + 0x0F, + 0x8F, + 0xF1, + 0xD9, + 0xFF, + 0xFC, + 0x01, + 0xF0, + 0x7B, + 0xF0, + 0x00, + 0x77, + 0xF8, + 0x3F, + 0x8F, + 0xF1, + 0xF9, + 0xFF, + 0xFD, + 0xFD, + 0xF0, + 0x63, + 0x30, + 0x00, + 0x3F, + 0xE0, + 0xFF, + 0x8F, + 0xF1, + 0xF9, + 0xFF, + 0xFD, + 0xDD, + 0xF0, + 0x63, + 0x30, + 0x00, + 0x3F, + 0x83, + 0xFF, + 0x8F, + 0xF1, + 0xF9, + 0xFF, + 0xFC, + 0x11, + 0xF0, + 0x66, + 0x30, + 0x00, + 0x3F, + 0x00, + 0x03, + 0x87, + 0xE1, + 0xF9, + 0xFF, + 0xFE, + 0x13, + 0xF0, + 0x7E, + 0xF0, + 0x00, + 0x3F, + 0x00, + 0x03, + 0xC0, + 0x03, + 0xF9, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x3C, + 0xE0, + 0x00, + 0x3F, + 0x00, + 0x03, + 0xE0, + 0x07, + 0xF9, + 0xFF, + 0xFC, + 0xFF, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x3F, + 0xFF, + 0xFF, + 0xF8, + 0x1F, + 0xF9, + 0xFF, + 0xFC, + 0x07, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x3F, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xF9, + 0xFF, + 0xFF, + 0x01, + 0xF0, + 0x7F, + 0xF0, + 0x00, + 0x3F, + 0x00, + 0x03, + 0x9F, + 0xFF, + 0xF9, + 0xFF, + 0xFF, + 0xB9, + 0xF0, + 0x7F, + 0xF0, + 0x00, + 0x3F, + 0x00, + 0x03, + 0x83, + 0xFF, + 0xF9, + 0xFF, + 0xFF, + 0x01, + 0xF0, + 0x60, + 0x30, + 0x00, + 0x3F, + 0x00, + 0x03, + 0x80, + 0x7F, + 0xF9, + 0xFF, + 0xFC, + 0x07, + 0xF0, + 0x60, + 0x30, + 0x00, + 0x3F, + 0x1F, + 0xFF, + 0xE0, + 0x0F, + 0xF9, + 0xFF, + 0xFC, + 0xFF, + 0xF0, + 0x70, + 0x70, + 0x00, + 0x3F, + 0x1F, + 0xFF, + 0xF0, + 0x01, + 0xF9, + 0xFF, + 0xFF, + 0xFF, + 0xF0, + 0x3F, + 0xE0, + 0x00, + 0x3F, + 0x1F, + 0xFF, + 0xF1, + 0x81, + 0xDD, + 0xFF, + 0xFC, + 0x01, + 0xF0, + 0x1F, + 0xC0, + 0x00, + 0x77, + 0x1F, + 0xFF, + 0xF1, + 0xF1, + 0xDC, + 0xFF, + 0xFC, + 0x01, + 0xF0, + 0x00, + 0x00, + 0x00, + 0x77, + 0x1F, + 0xFF, + 0xF1, + 0x81, + 0xDC, + 0xFF, + 0xFF, + 0xC3, + 0xF0, + 0x60, + 0x00, + 0x00, + 0x77, + 0x1F, + 0xFF, + 0xF0, + 0x01, + 0xDC, + 0xFF, + 0xFE, + 0x1F, + 0xF0, + 0x7C, + 0x00, + 0x00, + 0x67, + 0x1F, + 0xFF, + 0xE0, + 0x0F, + 0xCE, + 0x7F, + 0xFC, + 0x01, + 0xF0, + 0x1F, + 0x80, + 0x00, + 0xE7, + 0xFF, + 0xFF, + 0x80, + 0x7F, + 0xCE, + 0x7F, + 0xFC, + 0x01, + 0xF0, + 0x1B, + 0xF0, + 0x00, + 0xE7, + 0xFF, + 0xFF, + 0x83, + 0xFF, + 0xC7, + 0x3F, + 0xFF, + 0xFF, + 0xF0, + 0x18, + 0x70, + 0x01, + 0xC7, + 0xFF, + 0xF3, + 0x9F, + 0xFF, + 0xC7, + 0x3F, + 0xFC, + 0x01, + 0xF0, + 0x1B, + 0xF0, + 0x01, + 0xC7, + 0xFF, + 0xC3, + 0xFF, + 0xFF, + 0xC3, + 0x9F, + 0xFC, + 0x01, + 0xF0, + 0x1F, + 0x80, + 0x03, + 0x87, + 0xFF, + 0x83, + 0xFF, + 0xF9, + 0xC3, + 0x9F, + 0xFF, + 0xFF, + 0xF0, + 0x7C, + 0x00, + 0x03, + 0x87, + 0xFE, + 0x0F, + 0xFF, + 0xE1, + 0xC1, + 0xCF, + 0xFE, + 0x03, + 0xF0, + 0x60, + 0x00, + 0x07, + 0x07, + 0x00, + 0x3F, + 0xFF, + 0xC1, + 0xC1, + 0xE7, + 0xFC, + 0x01, + 0xF0, + 0x00, + 0x00, + 0x0F, + 0x07, + 0x00, + 0x7F, + 0xFF, + 0x07, + 0xC0, + 0xE3, + 0xFD, + 0xFD, + 0xF0, + 0x00, + 0x00, + 0x0E, + 0x07, + 0x00, + 0x3F, + 0x80, + 0x1F, + 0xC0, + 0x71, + 0xFD, + 0xFD, + 0xF0, + 0x00, + 0x00, + 0x1C, + 0x07, + 0xFE, + 0x0F, + 0x80, + 0x3F, + 0xC0, + 0x78, + 0xFC, + 0x71, + 0xF0, + 0x00, + 0x00, + 0x3C, + 0x07, + 0xFF, + 0x83, + 0x80, + 0x1F, + 0xC0, + 0x3C, + 0x7E, + 0x73, + 0xF0, + 0x00, + 0x00, + 0x78, + 0x07, + 0xFF, + 0xC3, + 0xFF, + 0x07, + 0xC0, + 0x1E, + 0x3F, + 0xFF, + 0xF0, + 0x00, + 0x00, + 0xF0, + 0x07, + 0xFF, + 0xF3, + 0xFF, + 0xC1, + 0xC0, + 0x0F, + 0x1F, + 0xFF, + 0xF0, + 0x00, + 0x01, + 0xE0, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xE1, + 0xC0, + 0x07, + 0xC7, + 0xFF, + 0xF0, + 0x00, + 0x07, + 0xC0, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xF9, + 0xC0, + 0x03, + 0xE1, + 0xFF, + 0xF0, + 0x00, + 0x0F, + 0x80, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0xF8, + 0x7F, + 0xF0, + 0x00, + 0x3E, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x7E, + 0x0F, + 0xF0, + 0x00, + 0xFC, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x1F, + 0x80, + 0x00, + 0x03, + 0xF0, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x07, + 0xF8, + 0x00, + 0x3F, + 0xC0, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x01, + 0xFF, + 0xFF, + 0xFF, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x3F, + 0xFF, + 0xF8, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xC0, + 0x00, + 0x00, + 0x07, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, +}; + +const unsigned char code pic_red[2756] = { + /*-- + /*-- 104x212 --*/ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xCF, + 0xFF, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x0F, + 0xE0, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x0F, + 0xC0, + 0x3E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x0F, + 0x80, + 0x1E, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x1F, + 0x00, + 0x1E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x3F, + 0x06, + 0x0E, + 0x0F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x0F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x0F, + 0x0E, + 0x10, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x10, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7C, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7C, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7C, + 0x3F, + 0x0E, + 0x40, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x78, + 0x3E, + 0x0E, + 0x47, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x38, + 0x3C, + 0x1E, + 0x7F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x7C, + 0x1E, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x7C, + 0x3E, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x00, + 0xFC, + 0xFE, + 0x07, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x83, + 0xFF, + 0xFE, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7B, + 0xFF, + 0xFF, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x0F, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x03, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x7F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x00, + 0x1F, + 0xFE, + 0x1F, + 0xA0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC0, + 0x03, + 0xFE, + 0x1F, + 0xA0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC0, + 0x00, + 0x7E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0x00, + 0x1E, + 0x0B, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0xE0, + 0x0E, + 0x1B, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0xF8, + 0x0E, + 0x16, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0xFF, + 0x0E, + 0x16, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0xF8, + 0x0E, + 0x1D, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0xE0, + 0x0E, + 0x0D, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC3, + 0x00, + 0x1E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC0, + 0x00, + 0x7E, + 0x7F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC0, + 0x03, + 0xFE, + 0x7F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x00, + 0x1F, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x7F, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x03, + 0xFF, + 0xFE, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x0F, + 0xFF, + 0xFE, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7B, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0xE0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x0D, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x1E, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x12, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x40, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x47, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x7F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x38, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x07, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x18, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x18, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0xFE, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x19, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x09, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x0E, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x10, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x0F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7E, + 0x1F, + 0x0E, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0xFF, + 0x0E, + 0x1F, + 0x80, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x1F, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0x80, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x60, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x60, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x7F, + 0x80, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFF, + 0xFF, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFE, + 0x7F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFC, + 0x7F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xFC, + 0x3F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xF8, + 0x3F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xF8, + 0x1F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xF0, + 0x1F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xF0, + 0x0F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xE0, + 0x0F, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xE0, + 0x07, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0xC0, + 0x03, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x80, + 0x03, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x80, + 0x01, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x00, + 0x01, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7F, + 0x00, + 0x00, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x00, + 0x00, + 0xFE, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7E, + 0x00, + 0x00, + 0x7E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x00, + 0x7E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x7C, + 0x00, + 0x00, + 0x3E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x3E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x78, + 0x00, + 0x00, + 0x1E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x70, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x70, + 0x00, + 0x00, + 0x0E, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0x00, + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x60, + 0x00, + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xx DESAY xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void DELAY_100nS(int delaytime) // 30us +{ + int i, j; + + for (i = 0; i < delaytime; i++) + for (j = 0; j < 1; j++) + ; +} + +void DELAY_mS(int delaytime) // 1ms +{ + int i, j; + + for (i = 0; i < delaytime; i++) + for (j = 0; j < 200; j++) + ; +} + +void DELAY_S(int delaytime) // 1s +{ + int i, j, k; + + for (i = 0; i < delaytime; i++) + for (j = 0; j < 1000; j++) + for (k = 0; k < 200; k++) + ; + + for (; log == 1;) + ; +} + +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +// RESET xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void RESET() +{ + nRST_L; + DELAY_mS(1); + nRST_H; + DELAY_mS(1); +} + +// READ BUSY xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void READBUSY() +{ + while (1) + { + _nop_(); + if (BUSY == 0) + break; + } +} + +// WRITE COMMAND xxxxxxxxxxxxxxxxxxx +void SPI4W_WRITECOM(unsigned char INIT_COM) +{ + unsigned char TEMPCOM; + unsigned char scnt; + + TEMPCOM = INIT_COM; + SCLK_H; + nDC_L; + nCS_H; + nCS_L; + for (scnt = 0; scnt < 8; scnt++) + { + if (TEMPCOM & 0x80) + SDA_H; + else + SDA_L; + SCLK_L; + SCLK_H; + TEMPCOM = TEMPCOM << 1; + } + nCS_H; +} + +// WRITE DATA xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void SPI4W_WRITEDATA(unsigned char INIT_DATA) +{ + unsigned char TEMPCOM; + unsigned char scnt; + + TEMPCOM = INIT_DATA; + SCLK_H; + nDC_H; + nCS_H; + nCS_L; + for (scnt = 0; scnt < 8; scnt++) + { + if (TEMPCOM & 0x80) + SDA_H; + else + SDA_L; + SCLK_L; + SCLK_H; + TEMPCOM = TEMPCOM << 1; + } + nCS_H; +} + +// void WriteFlow() +//{ +// unsigned char i; +// +// SPI4W_WRITECOM(0x24); // write RAM +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data0[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data1[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data2[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data3[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data4[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data5[i]); +// for(i=0;i<32;i++) +// SPI4W_WRITEDATA(init_data6[i]); +// for(i=0;i<18;i++) +// SPI4W_WRITEDATA(init_data7[i]); +// } + +// init xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +void INIT_SSD1675() +{ + + SPI4W_WRITECOM(0x01); + SPI4W_WRITEDATA(0xD3); + SPI4W_WRITEDATA(0x00); + SPI4W_WRITEDATA(0x00); + + SPI4W_WRITECOM(0x11); // data enter mode + SPI4W_WRITEDATA(0x03); + SPI4W_WRITECOM(0x44); // set RAM x address start/end, in page 36 + SPI4W_WRITEDATA(0x00); // RAM x address start at 00h; + SPI4W_WRITEDATA(0x0C); + SPI4W_WRITECOM(0x45); // RAM y address + SPI4W_WRITEDATA(0x00); + SPI4W_WRITEDATA(0x00); + SPI4W_WRITEDATA(0xD3); + SPI4W_WRITEDATA(0x00); + + SPI4W_WRITECOM(0x3C); // board + SPI4W_WRITEDATA(0x05); // GS1-->GS1 + + SPI4W_WRITECOM(0x21); // Display update control + SPI4W_WRITEDATA(0x00); + SPI4W_WRITEDATA(0x80); + + // unsigned char temp1,temp2; + SPI4W_WRITECOM(0x18); + SPI4W_WRITEDATA(0X80); + SPI4W_WRITECOM(0x22); + SPI4W_WRITEDATA(0XB1); // Load Temperature and waveform setting. + SPI4W_WRITECOM(0x20); + nCS_H; + READBUSY(); +} + +// �����˯�� xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void enterdeepsleep() +{ + SPI4W_WRITECOM(0x10); + SPI4W_WRITEDATA(0x01); +} + +void set_xy_window(unsigned char xs, unsigned char xe, unsigned int ys, unsigned int ye) +{ + + SPI4W_WRITECOM(0x44); // set RAM x address start/end, in page 36 + SPI4W_WRITEDATA(xs); // RAM x address start at 00h; + SPI4W_WRITEDATA(xe); // RAM x address end at 0fh(12+1)*8->104 + SPI4W_WRITECOM(0x45); // set RAM y address start/end, in page 37 + SPI4W_WRITEDATA(ys); // RAM y address start at 0; + SPI4W_WRITEDATA(ys >> 8); + SPI4W_WRITEDATA(ye); // RAM y address end at + SPI4W_WRITEDATA(ye >> 8); // RAM y address end at +} + +void set_xy_counter(unsigned char x, unsigned int y) +{ + SPI4W_WRITECOM(0x4E); // set RAM x address count + SPI4W_WRITEDATA(x); + SPI4W_WRITECOM(0x4F); // set RAM y address count + SPI4W_WRITEDATA(y); + SPI4W_WRITEDATA(y >> 8); +} + +void Display_update(void) +{ + SPI4W_WRITECOM(0x22); + SPI4W_WRITEDATA(0xC7); // Load LUT from MCU(0x32), Display update + SPI4W_WRITECOM(0x20); + // DELAY_mS(1); + READBUSY(); +} + +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xx ͼƬ��ʾ���� xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void dis_img(unsigned char num) +{ + unsigned int row, col; + unsigned int pcnt; + /***************************************************bw image****************************************************/ + set_xy_window(0, 12, 0, 211); + set_xy_counter(0, 0); + SPI4W_WRITECOM(0x24); + + pcnt = 0; + for (col = 0; col < 212; col++) + { + for (row = 0; row < 13; row++) + { + switch (num) + { + case PIC_A: + + SPI4W_WRITEDATA(gImage_mb_bw[pcnt]); + + break; + + case PIC_B: + SPI4W_WRITEDATA(gImage_HStest_bw[pcnt]); + break; + + case PIC_C: + SPI4W_WRITEDATA(pic_black[pcnt]); + break; + + case PIC_R: + SPI4W_WRITEDATA(0x00); + break; + case PIC_VLINE: + if (col > 148) + SPI4W_WRITEDATA(0xff); + else + SPI4W_WRITEDATA(0x00); + break; + + case PIC_HLINE: + if (row > 8) + SPI4W_WRITEDATA(0xff); + else if (row == 8) + SPI4W_WRITEDATA(0x0f); + else + SPI4W_WRITEDATA(0x00); + /* if((row%2)<1) +SPI4W_WRITEDATA(0xff); + + else + SPI4W_WRITEDATA(0x00);*/ + break; + + case PIC_WHITE: + SPI4W_WRITEDATA(0xff); + break; + + case PIC_BLACK: + SPI4W_WRITEDATA(0x00); + break; + default: + break; + } + pcnt++; + } + } + /* if(num==PIC_BLACK||num==PIC_WHITE||num==PIC_HLINE||num==PIC_VLINE) + { + // SPI4W_WRITECOM(0x21); + // SPI4W_WRITEDATA(0x04); + SPI4W_WRITECOM(0x22); + SPI4W_WRITEDATA(0xc7); + SPI4W_WRITECOM(0x20); + DELAY_mS(1); + READBUSY(); + return; + } + */ + + /***************************************************bw image****************************************************/ + set_xy_window(0, 12, 0, 211); + set_xy_counter(0, 0); + SPI4W_WRITECOM(0x26); + + pcnt = 0; + for (col = 0; col < 212; col++) + { + for (row = 0; row < 13; row++) + { + switch (num) + { + case PIC_A: + + SPI4W_WRITEDATA(gImage_mb_red[pcnt]); + break; + + case PIC_B: + SPI4W_WRITEDATA(gImage_HStest_red[pcnt]); + break; + + case PIC_C: + SPI4W_WRITEDATA(pic_red[pcnt]); + break; + + case PIC_R: + SPI4W_WRITEDATA(0xFF); + break; + case PIC_VLINE: + SPI4W_WRITEDATA(0x00); + break; + case PIC_HLINE: + + SPI4W_WRITEDATA(0x00); + + break; + + case PIC_WHITE: + SPI4W_WRITEDATA(0x00); + break; + + case PIC_BLACK: + SPI4W_WRITEDATA(0x00); + break; + default: + break; + } + pcnt++; + } + } + + Display_update(); +} + +void dis_block(unsigned char xs, unsigned char xe, unsigned int ys, unsigned int ye, unsigned char dat, unsigned char mode) + +{ + unsigned int row, col; + unsigned int pcnt; + /***************************************************bw image****************************************************/ + + set_xy_window(xs, xe, ys, ye); + + set_xy_counter(xs, ye - ys); + SPI4W_WRITECOM(0x24); + + pcnt = 0; + for (col = ys; col <= ye; col++) + { + for (row = xs; row <= xe; row++) + { + + SPI4W_WRITEDATA(dat); + } + pcnt++; + } + + set_xy_window(xs, xe, ys, ye); + set_xy_counter(xs, ye - ys); + SPI4W_WRITECOM(0x26); + + pcnt = 0; + for (col = ys; col <= ye; col++) + { + for (row = xs; row <= xe; row++) + { + if (mode == 0x26) + SPI4W_WRITEDATA(dat); + else + SPI4W_WRITEDATA(0x00); + } + pcnt++; + } + + Display_update(); +} + +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xx main xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +void main(void) +{ + // int i; + + RESET(); + SPI4W_WRITECOM(0x12); // SWRESET + READBUSY(); + + INIT_SSD1675(); + + while (1) + { + + dis_img(PIC_C); + DELAY_S(3); + + SPI4W_WRITECOM(0x21); + SPI4W_WRITEDATA(0x08); + + Display_update(); + DELAY_S(3); + + SPI4W_WRITECOM(0x21); + SPI4W_WRITEDATA(0x00); + + dis_img(PIC_WHITE); + DELAY_S(2); + + /* dis_img(PIC_BLACK); + DELAY_S(2); + + dis_block(4,9,0+5,40+5, 0xff, 0x24); + DELAY_S(2); + + dis_block(4,9,0+5,40+5, 0xff, 0x26); + DELAY_S(2); + + dis_img(PIC_WHITE); + DELAY_S(2); + + + dis_block(0,4,0,40, 0x00, 0x24); + DELAY_S(2); + + dis_block(0,4,0,40, 0xff, 0x26); + DELAY_S(2); + + + + dis_img(PIC_R); + DELAY_S(2); + + dis_block(0,4,0,40, 0x00, 0x24); + DELAY_S(2); + + dis_block(0,4,0,40, 0xff, 0x24); + DELAY_S(2); + + */ + + // dis_img(PIC_VLINE); + // DELAY_S(2); + // dis_img(PIC_HLINE); + // DELAY_S(2); + + dis_img(PIC_A); + DELAY_S(2); + + dis_img(PIC_B); + DELAY_S(2); + } +} \ No newline at end of file diff --git a/libraries/BEINK/examples/beink_demo/beink_demo.ino b/libraries/BEINK/examples/beink_demo/beink_demo.ino new file mode 100644 index 00000000..66e2b492 --- /dev/null +++ b/libraries/BEINK/examples/beink_demo/beink_demo.ino @@ -0,0 +1,35 @@ +/// +/// @file rtc_tick.ino +/// @author Anuj Pathak (anuj@biii.in) +/// @brief +/// @version 0.1 +/// @date 2021-02-09 +/// +/// @copyright Copyright (c) 2021 +/// +/// +#include + +void setup() +{ + Serial.begin(115200); + delay(5000); + BEINK.turn_on(); + Serial.println("BEINK START"); + Serial.println("setting white"); + BEINK.clear(color_white); + Serial.println("white ready"); + // + BEINK.print_line(84, 104, "BIII Tech"); + BEINK.print_line(64, 104, "Kaizen"); + BEINK.print_line(44, 104, "for"); + BEINK.print_line(24, 104, "perfection"); + // + BEINK.print_qr(0, 0, "https://biii.in/"); + BEINK.update(); + Serial.println("done"); +} + +void loop() +{ +} diff --git a/libraries/BEINK/font16.c b/libraries/BEINK/font16.c new file mode 100644 index 00000000..78df46a7 --- /dev/null +++ b/libraries/BEINK/font16.c @@ -0,0 +1,1760 @@ +/** + ****************************************************************************** + * @file font16.c + * @author MCD Application Team + * @version V1.0.0 + * @date 18-February-2014 + * @brief This file provides text font16 for STM32xx-EVAL's LCD driver. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "fonts.h" + +const uint8_t Font16_Table[] = +{ + // @0 ' ' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @32 '!' (11 pixels wide) + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @64 '"' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1D, 0xC0, // ### ### + 0x1D, 0xC0, // ### ### + 0x08, 0x80, // # # + 0x08, 0x80, // # # + 0x08, 0x80, // # # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @96 '#' (11 pixels wide) + 0x00, 0x00, // + 0x0D, 0x80, // ## ## + 0x0D, 0x80, // ## ## + 0x0D, 0x80, // ## ## + 0x0D, 0x80, // ## ## + 0x3F, 0xC0, // ######## + 0x1B, 0x00, // ## ## + 0x3F, 0xC0, // ######## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @128 '$' (11 pixels wide) + 0x04, 0x00, // # + 0x1F, 0x80, // ###### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x38, 0x00, // ### + 0x1E, 0x00, // #### + 0x0F, 0x00, // #### + 0x03, 0x80, // ### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x04, 0x00, // # + 0x04, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @160 '%' (11 pixels wide) + 0x00, 0x00, // + 0x18, 0x00, // ## + 0x24, 0x00, // # # + 0x24, 0x00, // # # + 0x18, 0xC0, // ## ## + 0x07, 0x80, // #### + 0x1E, 0x00, // #### + 0x31, 0x80, // ## ## + 0x02, 0x40, // # # + 0x02, 0x40, // # # + 0x01, 0x80, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @192 '&' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x0F, 0x00, // #### + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x0C, 0x00, // ## + 0x1D, 0x80, // ### ## + 0x37, 0x00, // ## ### + 0x33, 0x00, // ## ## + 0x1D, 0x80, // ### ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @224 ''' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x07, 0x00, // ### + 0x07, 0x00, // ### + 0x02, 0x00, // # + 0x02, 0x00, // # + 0x02, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @256 '(' (11 pixels wide) + 0x00, 0x00, // + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x06, 0x00, // ## + 0x0E, 0x00, // ### + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0E, 0x00, // ### + 0x06, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @288 ')' (11 pixels wide) + 0x00, 0x00, // + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x0C, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x1C, 0x00, // ### + 0x18, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @320 '*' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x3F, 0xC0, // ######## + 0x3F, 0xC0, // ######## + 0x0F, 0x00, // #### + 0x1F, 0x80, // ###### + 0x19, 0x80, // ## ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @352 '+' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x04, 0x00, // # + 0x04, 0x00, // # + 0x04, 0x00, // # + 0x3F, 0x80, // ####### + 0x04, 0x00, // # + 0x04, 0x00, // # + 0x04, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @384 ',' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x04, 0x00, // # + 0x0C, 0x00, // ## + 0x08, 0x00, // # + 0x08, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + + // @416 '-' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x3F, 0x80, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @448 '.' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @480 '/' (11 pixels wide) + 0x00, 0xC0, // ## + 0x00, 0xC0, // ## + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @512 '0' (11 pixels wide) + 0x00, 0x00, // + 0x0E, 0x00, // ### + 0x1B, 0x00, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1B, 0x00, // ## ## + 0x0E, 0x00, // ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @544 '1' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x3E, 0x00, // ##### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x3F, 0xC0, // ######## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @576 '2' (11 pixels wide) + 0x00, 0x00, // + 0x0F, 0x00, // #### + 0x19, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x03, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x18, 0x00, // ## + 0x30, 0x00, // ## + 0x3F, 0x80, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @608 '3' (11 pixels wide) + 0x00, 0x00, // + 0x3F, 0x00, // ###### + 0x61, 0x80, // ## ## + 0x01, 0x80, // ## + 0x03, 0x00, // ## + 0x1F, 0x00, // ##### + 0x03, 0x80, // ### + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x61, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @640 '4' (11 pixels wide) + 0x00, 0x00, // + 0x07, 0x00, // ### + 0x07, 0x00, // ### + 0x0F, 0x00, // #### + 0x0B, 0x00, // # ## + 0x1B, 0x00, // ## ## + 0x13, 0x00, // # ## + 0x33, 0x00, // ## ## + 0x3F, 0x80, // ####### + 0x03, 0x00, // ## + 0x0F, 0x80, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @672 '5' (11 pixels wide) + 0x00, 0x00, // + 0x1F, 0x80, // ###### + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x1F, 0x00, // ##### + 0x11, 0x80, // # ## + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x21, 0x80, // # ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @704 '6' (11 pixels wide) + 0x00, 0x00, // + 0x07, 0x80, // #### + 0x1C, 0x00, // ### + 0x18, 0x00, // ## + 0x30, 0x00, // ## + 0x37, 0x00, // ## ### + 0x39, 0x80, // ### ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x19, 0x80, // ## ## + 0x0F, 0x00, // #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @736 '7' (11 pixels wide) + 0x00, 0x00, // + 0x7F, 0x00, // ####### + 0x43, 0x00, // # ## + 0x03, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @768 '8' (11 pixels wide) + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @800 '9' (11 pixels wide) + 0x00, 0x00, // + 0x1E, 0x00, // #### + 0x33, 0x00, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0x80, // ### ## + 0x01, 0x80, // ## + 0x03, 0x00, // ## + 0x07, 0x00, // ### + 0x3C, 0x00, // #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @832 ':' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @864 ';' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x04, 0x00, // # + 0x08, 0x00, // # + 0x08, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @896 '<' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0xC0, // ## + 0x03, 0x00, // ## + 0x04, 0x00, // # + 0x18, 0x00, // ## + 0x60, 0x00, // ## + 0x18, 0x00, // ## + 0x04, 0x00, // # + 0x03, 0x00, // ## + 0x00, 0xC0, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @928 '=' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0xC0, // ######### + 0x00, 0x00, // + 0x7F, 0xC0, // ######### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @960 '>' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x60, 0x00, // ## + 0x18, 0x00, // ## + 0x04, 0x00, // # + 0x03, 0x00, // ## + 0x00, 0xC0, // ## + 0x03, 0x00, // ## + 0x04, 0x00, // # + 0x18, 0x00, // ## + 0x60, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @992 '?' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x01, 0x80, // ## + 0x07, 0x00, // ### + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1024 '@' (11 pixels wide) + 0x00, 0x00, // + 0x0E, 0x00, // ### + 0x11, 0x00, // # # + 0x21, 0x00, // # # + 0x21, 0x00, // # # + 0x27, 0x00, // # ### + 0x29, 0x00, // # # # + 0x29, 0x00, // # # # + 0x27, 0x00, // # ### + 0x20, 0x00, // # + 0x11, 0x00, // # # + 0x0E, 0x00, // ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1056 'A' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x3F, 0x00, // ###### + 0x0F, 0x00, // #### + 0x09, 0x00, // # # + 0x19, 0x80, // ## ## + 0x19, 0x80, // ## ## + 0x1F, 0x80, // ###### + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x79, 0xE0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1088 'B' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x00, // ####### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x7F, 0x00, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1120 'C' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x40, // ##### # + 0x30, 0xC0, // ## ## + 0x60, 0x40, // ## # + 0x60, 0x00, // ## + 0x60, 0x00, // ## + 0x60, 0x00, // ## + 0x60, 0x40, // ## # + 0x30, 0x80, // ## # + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1152 'D' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x00, // ####### + 0x31, 0x80, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x31, 0x80, // ## ## + 0x7F, 0x00, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1184 'E' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x80, // ######## + 0x30, 0x80, // ## # + 0x30, 0x80, // ## # + 0x32, 0x00, // ## # + 0x3E, 0x00, // ##### + 0x32, 0x00, // ## # + 0x30, 0x80, // ## # + 0x30, 0x80, // ## # + 0x7F, 0x80, // ######## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1216 'F' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0xC0, // ######### + 0x30, 0x40, // ## # + 0x30, 0x40, // ## # + 0x32, 0x00, // ## # + 0x3E, 0x00, // ##### + 0x32, 0x00, // ## # + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x7C, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1248 'G' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1E, 0x80, // #### # + 0x31, 0x80, // ## ## + 0x60, 0x80, // ## # + 0x60, 0x00, // ## + 0x60, 0x00, // ## + 0x67, 0xC0, // ## ##### + 0x61, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1280 'H' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3F, 0x80, // ####### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x7B, 0xC0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1312 'I' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x3F, 0xC0, // ######## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x3F, 0xC0, // ######## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1344 'J' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0xC0, // ####### + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x63, 0x00, // ## ## + 0x63, 0x00, // ## ## + 0x63, 0x00, // ## ## + 0x3E, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1376 'K' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x33, 0x00, // ## ## + 0x36, 0x00, // ## ## + 0x3C, 0x00, // #### + 0x3E, 0x00, // ##### + 0x33, 0x00, // ## ## + 0x31, 0x80, // ## ## + 0x79, 0xC0, // #### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1408 'L' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7E, 0x00, // ###### + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x40, // ## # + 0x18, 0x40, // ## # + 0x18, 0x40, // ## # + 0x7F, 0xC0, // ######### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1440 'M' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0xE0, 0xE0, // ### ### + 0x60, 0xC0, // ## ## + 0x71, 0xC0, // ### ### + 0x7B, 0xC0, // #### #### + 0x6A, 0xC0, // ## # # ## + 0x6E, 0xC0, // ## ### ## + 0x64, 0xC0, // ## # ## + 0x60, 0xC0, // ## ## + 0xFB, 0xE0, // ##### ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1472 'N' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x73, 0xC0, // ### #### + 0x31, 0x80, // ## ## + 0x39, 0x80, // ### ## + 0x3D, 0x80, // #### ## + 0x35, 0x80, // ## # ## + 0x37, 0x80, // ## #### + 0x33, 0x80, // ## ### + 0x31, 0x80, // ## ## + 0x79, 0x80, // #### ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1504 'O' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1536 'P' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x00, // ####### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x7E, 0x00, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1568 'Q' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x0C, 0xC0, // ## ## + 0x1F, 0x80, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1600 'R' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x00, // ####### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3E, 0x00, // ##### + 0x33, 0x00, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x7C, 0xE0, // ##### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1632 'S' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x80, // ###### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x38, 0x00, // ### + 0x1F, 0x00, // ##### + 0x03, 0x80, // ### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1664 'T' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x80, // ######## + 0x4C, 0x80, // # ## # + 0x4C, 0x80, // # ## # + 0x4C, 0x80, // # ## # + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x3F, 0x00, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1696 'U' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1728 'V' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x0A, 0x00, // # # + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1760 'W' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0xFB, 0xE0, // ##### ##### + 0x60, 0xC0, // ## ## + 0x64, 0xC0, // ## # ## + 0x6E, 0xC0, // ## ### ## + 0x6E, 0xC0, // ## ### ## + 0x2A, 0x80, // # # # # + 0x3B, 0x80, // ### ### + 0x3B, 0x80, // ### ### + 0x31, 0x80, // ## ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1792 'X' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x1B, 0x00, // ## ## + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x1B, 0x00, // ## ## + 0x31, 0x80, // ## ## + 0x7B, 0xC0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1824 'Y' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x79, 0xE0, // #### #### + 0x30, 0xC0, // ## ## + 0x19, 0x80, // ## ## + 0x0F, 0x00, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x1F, 0x80, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1856 'Z' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x3F, 0x80, // ####### + 0x21, 0x80, // # ## + 0x23, 0x00, // # ## + 0x06, 0x00, // ## + 0x04, 0x00, // # + 0x0C, 0x00, // ## + 0x18, 0x80, // ## # + 0x30, 0x80, // ## # + 0x3F, 0x80, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1888 '[' (11 pixels wide) + 0x00, 0x00, // + 0x07, 0x80, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x07, 0x80, // #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1920 '\' (11 pixels wide) + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x06, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x00, 0xC0, // ## + 0x00, 0xC0, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1952 ']' (11 pixels wide) + 0x00, 0x00, // + 0x1E, 0x00, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x1E, 0x00, // #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @1984 '^' (11 pixels wide) + 0x04, 0x00, // # + 0x0A, 0x00, // # # + 0x0A, 0x00, // # # + 0x11, 0x00, // # # + 0x20, 0x80, // # # + 0x20, 0x80, // # # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2016 '_' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0xFF, 0xE0, // ########### + + // @2048 '`' (11 pixels wide) + 0x08, 0x00, // # + 0x04, 0x00, // # + 0x02, 0x00, // # + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2080 'a' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x1F, 0x80, // ###### + 0x31, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0xC0, // ### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2112 'b' (11 pixels wide) + 0x00, 0x00, // + 0x70, 0x00, // ### + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x37, 0x00, // ## ### + 0x39, 0x80, // ### ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x39, 0x80, // ### ## + 0x77, 0x00, // ### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2144 'c' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1E, 0x80, // #### # + 0x31, 0x80, // ## ## + 0x60, 0x80, // ## # + 0x60, 0x00, // ## + 0x60, 0x80, // ## # + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2176 'd' (11 pixels wide) + 0x00, 0x00, // + 0x03, 0x80, // ### + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x1D, 0x80, // ### ## + 0x33, 0x80, // ## ### + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0xC0, // ### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2208 'e' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x60, 0xC0, // ## ## + 0x7F, 0xC0, // ######### + 0x60, 0x00, // ## + 0x30, 0xC0, // ## ## + 0x1F, 0x80, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2240 'f' (11 pixels wide) + 0x00, 0x00, // + 0x07, 0xE0, // ###### + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x3F, 0x80, // ####### + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x3F, 0x80, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2272 'g' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1D, 0xC0, // ### ### + 0x33, 0x80, // ## ### + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0x80, // ### ## + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + + // @2304 'h' (11 pixels wide) + 0x00, 0x00, // + 0x70, 0x00, // ### + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x37, 0x00, // ## ### + 0x39, 0x80, // ### ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x7B, 0xC0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2336 'i' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x00, 0x00, // + 0x1E, 0x00, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x3F, 0xC0, // ######## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2368 'j' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x00, 0x00, // + 0x3F, 0x00, // ###### + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x03, 0x00, // ## + 0x3E, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + + // @2400 'k' (11 pixels wide) + 0x00, 0x00, // + 0x70, 0x00, // ### + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x37, 0x80, // ## #### + 0x36, 0x00, // ## ## + 0x3C, 0x00, // #### + 0x3C, 0x00, // #### + 0x36, 0x00, // ## ## + 0x33, 0x00, // ## ## + 0x77, 0xC0, // ### ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2432 'l' (11 pixels wide) + 0x00, 0x00, // + 0x1E, 0x00, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x3F, 0xC0, // ######## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2464 'm' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x7F, 0x80, // ######## + 0x36, 0xC0, // ## ## ## + 0x36, 0xC0, // ## ## ## + 0x36, 0xC0, // ## ## ## + 0x36, 0xC0, // ## ## ## + 0x36, 0xC0, // ## ## ## + 0x76, 0xE0, // ### ## ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2496 'n' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x77, 0x00, // ### ### + 0x39, 0x80, // ### ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x7B, 0xC0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2528 'o' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x00, // ##### + 0x31, 0x80, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x60, 0xC0, // ## ## + 0x31, 0x80, // ## ## + 0x1F, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2560 'p' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x77, 0x00, // ### ### + 0x39, 0x80, // ### ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x30, 0xC0, // ## ## + 0x39, 0x80, // ### ## + 0x37, 0x00, // ## ### + 0x30, 0x00, // ## + 0x30, 0x00, // ## + 0x7C, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + + // @2592 'q' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1D, 0xC0, // ### ### + 0x33, 0x80, // ## ### + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x61, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0x80, // ### ## + 0x01, 0x80, // ## + 0x01, 0x80, // ## + 0x07, 0xC0, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + + // @2624 'r' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0x80, // #### ### + 0x1C, 0xC0, // ### ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x7F, 0x00, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2656 's' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x1F, 0x80, // ###### + 0x31, 0x80, // ## ## + 0x3C, 0x00, // #### + 0x1F, 0x00, // ##### + 0x03, 0x80, // ### + 0x31, 0x80, // ## ## + 0x3F, 0x00, // ###### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2688 't' (11 pixels wide) + 0x00, 0x00, // + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x7F, 0x00, // ####### + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x00, // ## + 0x18, 0x80, // ## # + 0x0F, 0x00, // #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2720 'u' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x73, 0x80, // ### ### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x33, 0x80, // ## ### + 0x1D, 0xC0, // ### ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2752 'v' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x31, 0x80, // ## ## + 0x31, 0x80, // ## ## + 0x1B, 0x00, // ## ## + 0x1B, 0x00, // ## ## + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2784 'w' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0xF1, 0xE0, // #### #### + 0x60, 0xC0, // ## ## + 0x64, 0xC0, // ## # ## + 0x6E, 0xC0, // ## ### ## + 0x3B, 0x80, // ### ### + 0x3B, 0x80, // ### ### + 0x31, 0x80, // ## ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2816 'x' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x7B, 0xC0, // #### #### + 0x1B, 0x00, // ## ## + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x0E, 0x00, // ### + 0x1B, 0x00, // ## ## + 0x7B, 0xC0, // #### #### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2848 'y' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x79, 0xE0, // #### #### + 0x30, 0xC0, // ## ## + 0x19, 0x80, // ## ## + 0x19, 0x80, // ## ## + 0x0B, 0x00, // # ## + 0x0F, 0x00, // #### + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x3E, 0x00, // ##### + 0x00, 0x00, // + 0x00, 0x00, // + + // @2880 'z' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x3F, 0x80, // ####### + 0x21, 0x80, // # ## + 0x03, 0x00, // ## + 0x0E, 0x00, // ### + 0x18, 0x00, // ## + 0x30, 0x80, // ## # + 0x3F, 0x80, // ####### + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2912 '{' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x18, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x0C, 0x00, // ## + 0x06, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2944 '|' (11 pixels wide) + 0x00, 0x00, // + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @2976 '}' (11 pixels wide) + 0x00, 0x00, // + 0x0C, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x03, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x06, 0x00, // ## + 0x0C, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + + // @3008 '~' (11 pixels wide) + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x18, 0x00, // ## + 0x24, 0x80, // # # # + 0x03, 0x00, // ## + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // + 0x00, 0x00, // +}; + +struct font_data Font16 = { + Font16_Table, + 11, /* Width */ + 16, /* Height */ +}; + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/BEINK/fonts.h b/libraries/BEINK/fonts.h new file mode 100644 index 00000000..74df9f64 --- /dev/null +++ b/libraries/BEINK/fonts.h @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * @file fonts.h + * @author MCD Application Team + * @version V1.0.0 + * @date 18-February-2014 + * @brief Header for fonts.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FONTS_H +#define __FONTS_H + +/* Max size of bitmap will based on a font24 (17x24) */ +#define MAX_HEIGHT_FONT 24 +#define MAX_WIDTH_FONT 17 +#define OFFSET_BITMAP 54 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +struct font_data { + const uint8_t *table; + uint16_t Width; + uint16_t Height; +}; + +extern struct font_data Font16; + +#ifdef __cplusplus +} +#endif + +#endif /* __FONTS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/BEINK/keywords.txt b/libraries/BEINK/keywords.txt new file mode 100644 index 00000000..aef76896 --- /dev/null +++ b/libraries/BEINK/keywords.txt @@ -0,0 +1,27 @@ +####################################### +# Syntax Coloring Map BEINK +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +BEINK KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +setConfig KEYWORD2 +start KEYWORD2 +stop KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +eBPWM_0 LITERAL1 +eBPWM_1 LITERAL1 +eBPWM_2 LITERAL1 +eBPWM_CH_0 LITERAL1 +eBPWM_CH_1 LITERAL1 +eBPWM_CH_2 LITERAL1 +eBPWM_CH_3 LITERAL1 diff --git a/libraries/BEINK/library.properties b/libraries/BEINK/library.properties new file mode 100644 index 00000000..d10dcd90 --- /dev/null +++ b/libraries/BEINK/library.properties @@ -0,0 +1,9 @@ +name=BEINK +version=1.0 +author=biii.in +maintainer=biii.in +sentence=Basic BEINK library +paragraph= +category=LCD +url= +architectures=nRF5 \ No newline at end of file diff --git a/libraries/QRCode/.gitignore b/libraries/QRCode/.gitignore new file mode 100644 index 00000000..e43b0f98 --- /dev/null +++ b/libraries/QRCode/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/libraries/QRCode/LICENSE.txt b/libraries/QRCode/LICENSE.txt new file mode 100644 index 00000000..d59dd4da --- /dev/null +++ b/libraries/QRCode/LICENSE.txt @@ -0,0 +1,26 @@ +The MIT License (MIT) + +This library is written and maintained by Richard Moore. +Major parts were derived from Project Nayuki's library. + +Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) +Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/libraries/QRCode/README.md b/libraries/QRCode/README.md new file mode 100644 index 00000000..3fc59d0a --- /dev/null +++ b/libraries/QRCode/README.md @@ -0,0 +1,677 @@ +QRCode +====== + +A simple library for generating [QR codes](https://en.wikipedia.org/wiki/QR_code) in C, +optimized for processing and memory constrained systems. + +**Features:** + +- Stack-based (no heap necessary; but you can use heap if you want) +- Low-memory foot print (relatively) +- Compile-time stripping of unecessary logic and constants +- MIT License; do with this as you please + + +Installing +---------- + +To install this library, download and save it to your Arduino libraries directory. + +Rename the directory to QRCode (if downloaded from GitHub, the filename may be +qrcode-master; library names may not contain the hyphen, so it must be renamed) + + +API +--- + +**Generate a QR Code** + +```c +// The structure to manage the QR code +QRCode qrcode; + +// Allocate a chunk of memory to store the QR code +uint8_t qrcodeBytes[qrcode_getBufferSize()]; + +qrcode_initText(&qrcode, qrcodeBytes, 3, ECC_LOW, "HELLO WORLD"); +``` + +**Draw a QR Code** + +How a QR code is used will vary greatly from project to project. For example: + +- Display on an OLED screen (128x64 nicely supports 2 side-by-side version 3 QR codes) +- Print as a bitmap on a thermal printer +- Store as a BMP (or with a some extra work, possibly a PNG) on an SD card + +The following example prints a QR code to the Serial Monitor (it likely will +not be scannable, but is just for demonstration purposes). + +```c +for (uint8 y = 0; y < qrcode.size; y++) { + for (uint8 x = 0; x < qrcode.size; x++) { + if (qrcode_getModule(&qrcode, x, y) { + Serial.print("**"); + } else { + Serial.print(" "); + } + } + Serial.print("\n"); +} +``` + + +What is Version, Error Correction and Mode? +------------------------------------------- + +A QR code is composed of many little squares, called **modules**, which represent +encoded data, with additional error correction (allowing partially damaged QR +codes to still be read). + +The **version** of a QR code is a number between 1 and 40 (inclusive), which indicates +the size of the QR code. The width and height of a QR code are always equal (it is +square) and are equal to `4 * version + 17`. + +The level of **error correction** is a number between 0 and 3 (inclusive), or can be +one of the symbolic names ECC_LOW, ECC_MEDIUM, ECC_QUARTILE and ECC_HIGH. Higher +levels of error correction sacrifice data capacity, but allow a larger portion of +the QR code to be damaged or unreadable. + +The **mode** of a QR code is determined by the data being encoded. Each mode is encoded +internally using a compact representation, so lower modes can contain more data. + +- **NUMERIC:** numbers (`0-9`) +- **ALPHANUMERIC:** uppercase letters (`A-Z`), numbers (`0-9`), the space (` `), dollar sign (`$`), percent sign (`%`), asterisk (`*`), plus (`+`), minus (`-`), decimal point (`.`), slash (`/`) and colon (`:`). +- **BYTE:** any character + + +Data Capacities +--------------- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VersionSizeError CorrectionMode
NumericAlphanumericByte
121 x 21LOW412517
MEDIUM342014
QUARTILE271611
HIGH17107
225 x 25LOW774732
MEDIUM633826
QUARTILE482920
HIGH342014
329 x 29LOW1277753
MEDIUM1016142
QUARTILE774732
HIGH583524
433 x 33LOW18711478
MEDIUM1499062
QUARTILE1116746
HIGH825034
537 x 37LOW255154106
MEDIUM20212284
QUARTILE1448760
HIGH1066444
641 x 41LOW322195134
MEDIUM255154106
QUARTILE17810874
HIGH1398458
745 x 45LOW370224154
MEDIUM293178122
QUARTILE20712586
HIGH1549364
849 x 49LOW461279192
MEDIUM365221152
QUARTILE259157108
HIGH20212284
953 x 53LOW552335230
MEDIUM432262180
QUARTILE312189130
HIGH23514398
1057 x 57LOW652395271
MEDIUM513311213
QUARTILE364221151
HIGH288174119
1161 x 61LOW772468321
MEDIUM604366251
QUARTILE427259177
HIGH331200137
1265 x 65LOW883535367
MEDIUM691419287
QUARTILE489296203
HIGH374227155
1369 x 69LOW1022619425
MEDIUM796483331
QUARTILE580352241
HIGH427259177
1473 x 73LOW1101667458
MEDIUM871528362
QUARTILE621376258
HIGH468283194
1577 x 77LOW1250758520
MEDIUM991600412
QUARTILE703426292
HIGH530321220
1681 x 81LOW1408854586
MEDIUM1082656450
QUARTILE775470322
HIGH602365250
1785 x 85LOW1548938644
MEDIUM1212734504
QUARTILE876531364
HIGH674408280
1889 x 89LOW17251046718
MEDIUM1346816560
QUARTILE948574394
HIGH746452310
1993 x 93LOW19031153792
MEDIUM1500909624
QUARTILE1063644442
HIGH813493338
2097 x 97LOW20611249858
MEDIUM1600970666
QUARTILE1159702482
HIGH919557382
21101 x 101LOW22321352929
MEDIUM17081035711
QUARTILE1224742509
HIGH969587403
22105 x 105LOW240914601003
MEDIUM18721134779
QUARTILE1358823565
HIGH1056640439
23109 x 109LOW262015881091
MEDIUM20591248857
QUARTILE1468890611
HIGH1108672461
24113 x 113LOW281217041171
MEDIUM21881326911
QUARTILE1588963661
HIGH1228744511
25117 x 117LOW305718531273
MEDIUM23951451997
QUARTILE17181041715
HIGH1286779535
26121 x 121LOW328319901367
MEDIUM254415421059
QUARTILE18041094751
HIGH1425864593
27125 x 125LOW351721321465
MEDIUM270116371125
QUARTILE19331172805
HIGH1501910625
28129 x 129LOW366922231528
MEDIUM285717321190
QUARTILE20851263868
HIGH1581958658
29133 x 133LOW390923691628
MEDIUM303518391264
QUARTILE21811322908
HIGH16771016698
30137 x 137LOW415825201732
MEDIUM328919941370
QUARTILE23581429982
HIGH17821080742
31141 x 141LOW441726771840
MEDIUM348621131452
QUARTILE247314991030
HIGH18971150790
32145 x 145LOW468628401952
MEDIUM369322381538
QUARTILE267016181112
HIGH20221226842
33149 x 149LOW496530092068
MEDIUM390923691628
QUARTILE280517001168
HIGH21571307898
34153 x 153LOW525331832188
MEDIUM413425061722
QUARTILE294917871228
HIGH23011394958
35157 x 157LOW552933512303
MEDIUM434326321809
QUARTILE308118671283
HIGH23611431983
36161 x 161LOW583635372431
MEDIUM458827801911
QUARTILE324419661351
HIGH252415301051
37165 x 165LOW615337292563
MEDIUM477528941989
QUARTILE341720711423
HIGH262515911093
38169 x 169LOW647939272699
MEDIUM503930542099
QUARTILE359921811499
HIGH273516581139
39173 x 173LOW674340872809
MEDIUM531332202213
QUARTILE379122981579
HIGH292717741219
40177 x 177LOW708942962953
MEDIUM559633912331
QUARTILE399324201663
HIGH305718521273
+ + +Special Thanks +-------------- + +A HUGE thank you to [Project Nayuki](https://www.nayuki.io/) for the +[QR code C++ library](https://github.com/nayuki/QR-Code-generator/tree/master/cpp) +which was critical in development of this library. + + +License +------- + +MIT License. diff --git a/libraries/QRCode/examples/QRCode/QRCode.ino b/libraries/QRCode/examples/QRCode/QRCode.ino new file mode 100644 index 00000000..9f6a6558 --- /dev/null +++ b/libraries/QRCode/examples/QRCode/QRCode.ino @@ -0,0 +1,56 @@ +/** + * QRCode + * + * A quick example of generating a QR code. + * + * This prints the QR code to the serial monitor as solid blocks. Each module + * is two characters wide, since the monospace font used in the serial monitor + * is approximately twice as tall as wide. + * + */ + +#include "qrcode.h" + +void setup() { + Serial.begin(115200); + + // Start time + uint32_t dt = millis(); + + // Create the QR code + QRCode qrcode; + uint8_t qrcodeData[qrcode_getBufferSize(3)]; + qrcode_initText(&qrcode, qrcodeData, 3, 0, "HELLO WORLD"); + + // Delta time + dt = millis() - dt; + Serial.print("QR Code Generation Time: "); + Serial.print(dt); + Serial.print("\n"); + + // Top quiet zone + Serial.print("\n\n\n\n"); + + for (uint8_t y = 0; y < qrcode.size; y++) { + + // Left quiet zone + Serial.print(" "); + + // Each horizontal module + for (uint8_t x = 0; x < qrcode.size; x++) { + + // Print each module (UTF-8 \u2588 is a solid block) + Serial.print(qrcode_getModule(&qrcode, x, y) ? "\u2588\u2588": " "); + + } + + Serial.print("\n"); + } + + // Bottom quiet zone + Serial.print("\n\n\n\n"); +} + +void loop() { + +} diff --git a/libraries/QRCode/generate_table.py b/libraries/QRCode/generate_table.py new file mode 100644 index 00000000..d5d4003b --- /dev/null +++ b/libraries/QRCode/generate_table.py @@ -0,0 +1,62 @@ +Data = [ + ["1", "41", "25", "17", "34", "20", "14","27", "16", "11","17", "10", "7"], + ["2", "77", "47", "32", "63", "38", "26", "48", "29", "20", "34", "20", "14"], + ["3", "127", "77", "53", "101", "61", "42", "77", "47", "32", "58", "35", "24"], + ["4", "187", "114", "78", "149", "90", "62", "111", "67", "46", "82", "50", "34"], + ["5", "255", "154", "106", "202", "122", "84", "144", "87", "60", "106", "64", "44"], + ["6", "322", "195", "134", "255", "154", "106", "178", "108", "74", "139", "84", "58"], + ["7", "370", "224", "154", "293", "178", "122", "207", "125", "86", "154", "93", "64"], + ["8", "461", "279", "192", "365", "221", "152", "259", "157", "108", "202", "122", "84"], + ["9", "552", "335", "230", "432", "262", "180", "312", "189", "130", "235", "143", "98"], + ["10", "652", "395", "271", "513", "311", "213", "364", "221", "151", "288", "174", "119"], + ["11", "772", "468", "321", "604", "366", "251", "427", "259", "177", "331", "200", "137"], + ["12", "883", "535", "367", "691", "419", "287", "489", "296", "203", "374", "227", "155"], + ["13", "1022", "619", "425", "796", "483", "331", "580", "352", "241", "427", "259", "177"], + ["14", "1101", "667", "458", "871", "528", "362", "621", "376", "258", "468", "283", "194"], + ["15", "1250", "758", "520", "991", "600", "412", "703", "426", "292", "530", "321", "220"], + ["16", "1408", "854", "586", "1082", "656", "450", "775", "470", "322", "602", "365", "250"], + ["17", "1548", "938", "644", "1212", "734", "504", "876", "531", "364", "674", "408", "280"], + ["18", "1725", "1046", "718", "1346", "816", "560", "948", "574", "394", "746", "452", "310"], + ["19", "1903", "1153", "792", "1500", "909", "624", "1063", "644", "442", "813", "493", "338"], + ["20", "2061", "1249", "858", "1600", "970", "666", "1159", "702", "482", "919", "557", "382"], + ["21", "2232", "1352", "929", "1708", "1035", "711", "1224", "742", "509", "969", "587", "403"], + ["22", "2409", "1460", "1003", "1872", "1134", "779", "1358", "823", "565", "1056", "640", "439"], + ["23", "2620", "1588", "1091", "2059", "1248", "857", "1468", "890", "611", "1108", "672", "461"], + ["24", "2812", "1704", "1171", "2188", "1326", "911", "1588", "963", "661", "1228", "744", "511"], + ["25", "3057", "1853", "1273", "2395", "1451", "997", "1718", "1041", "715", "1286", "779", "535"], + ["26", "3283", "1990", "1367", "2544", "1542", "1059", "1804", "1094", "751", "1425", "864", "593"], + ["27", "3517", "2132", "1465", "2701", "1637", "1125", "1933", "1172", "805", "1501", "910", "625"], + ["28", "3669", "2223", "1528", "2857", "1732", "1190", "2085", "1263", "868", "1581", "958", "658"], + ["29", "3909", "2369", "1628", "3035", "1839", "1264", "2181", "1322", "908", "1677", "1016", "698"], + ["30", "4158", "2520", "1732", "3289", "1994", "1370", "2358", "1429", "982", "1782", "1080", "742"], + ["31", "4417", "2677", "1840", "3486", "2113", "1452", "2473", "1499", "1030", "1897", "1150", "790"], + ["32", "4686", "2840", "1952", "3693", "2238", "1538", "2670", "1618", "1112", "2022", "1226", "842"], + ["33", "4965", "3009", "2068", "3909", "2369", "1628", "2805", "1700", "1168", "2157", "1307", "898"], + ["34", "5253", "3183", "2188", "4134", "2506", "1722", "2949", "1787", "1228", "2301", "1394", "958"], + ["35", "5529", "3351", "2303", "4343", "2632", "1809", "3081", "1867", "1283", "2361", "1431", "983"], + ["36", "5836", "3537", "2431", "4588", "2780", "1911", "3244", "1966", "1351", "2524", "1530", "1051"], + ["37", "6153", "3729", "2563", "4775", "2894", "1989", "3417", "2071", "1423", "2625", "1591", "1093"], + ["38", "6479", "3927", "2699", "5039", "3054", "2099", "3599", "2181", "1499", "2735", "1658", "1139"], + ["39", "6743", "4087", "2809", "5313", "3220", "2213", "3791", "2298", "1579", "2927", "1774", "1219"], + ["40", "7089", "4296", "2953", "5596", "3391", "2331", "3993", "2420", "1663", "3057", "1852", "1273"], +] +Template = ''' + %s + %s + LOW%s%s%s + + + MEDIUM%s%s%s + + + QUARTILE%s%s%s + + + HIGH%s%s%s + ''' + +for data in Data: + data = data[:] + size = 4 * int(data[0]) + 17 + data.insert(1, "%d x %d" % (size, size)) + print Template % tuple(data) diff --git a/libraries/QRCode/keywords.txt b/libraries/QRCode/keywords.txt new file mode 100644 index 00000000..013f8953 --- /dev/null +++ b/libraries/QRCode/keywords.txt @@ -0,0 +1,31 @@ + +# Datatypes (KEYWORD1) + +bool KEYWORD1 +uint8_t KEYWORD1 +QRCode KEYWORD1 + + +# Methods and Functions (KEYWORD2) + +qrcode_getBufferSize KEYWORD2 +qrcode_initText KEYWORD2 +qrcode_initBytes KEYWORD2 +qrcode_getModule KEYWORD2 + + +# Instances (KEYWORD2) + + +# Constants (LITERAL1) + +false LITERAL1 +true LITERAL1 + +ECC_LOW LITERAL1 +ECC_MEDIUM LITERAL1 +ECC_QUARTILE LITERAL1 +ECC_HIGH LITERAL1 +MODE_NUMERIC LITERAL1 +MODE_ALPHANUMERIC LITERAL1 +MODE_BYTE LITERAL1 diff --git a/libraries/QRCode/library.properties b/libraries/QRCode/library.properties new file mode 100644 index 00000000..01fdca25 --- /dev/null +++ b/libraries/QRCode/library.properties @@ -0,0 +1,10 @@ +name=QRCode +version=0.0.1 +author=Richard Moore +maintainer=Richard Moore +sentence=A simple QR code generation library. +paragraph=A simple QR code generation library. +category=Other +url=https://github.com/ricmoo/qrcode/ +architectures=* +includes=qrcode.h diff --git a/libraries/QRCode/src/qrcode.c b/libraries/QRCode/src/qrcode.c new file mode 100644 index 00000000..0b441b3a --- /dev/null +++ b/libraries/QRCode/src/qrcode.c @@ -0,0 +1,876 @@ +/** + * The MIT License (MIT) + * + * This library is written and maintained by Richard Moore. + * Major parts were derived from Project Nayuki's library. + * + * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) + * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was + * heavily inspired and compared against. + * + * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp + */ + +#include "qrcode.h" + +#include +#include + +#pragma mark - Error Correction Lookup tables + +#if LOCK_VERSION == 0 + +static const uint16_t NUM_ERROR_CORRECTION_CODEWORDS[4][40] = { + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + { 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium + { 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low + { 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High + { 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile +}; + +static const uint8_t NUM_ERROR_CORRECTION_BLOCKS[4][40] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + // 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + { 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium + { 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low + { 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High + { 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile +}; + +static const uint16_t NUM_RAW_DATA_MODULES[40] = { + // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 208, 359, 567, 807, 1079, 1383, 1568, 1936, 2336, 2768, 3232, 3728, 4256, 4651, 5243, 5867, 6523, + // 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 7211, 7931, 8683, 9252, 10068, 10916, 11796, 12708, 13652, 14628, 15371, 16411, 17483, 18587, + // 32, 33, 34, 35, 36, 37, 38, 39, 40 + 19723, 20891, 22091, 23008, 24272, 25568, 26896, 28256, 29648 +}; + +// @TODO: Put other LOCK_VERSIONS here +#elif LOCK_VERSION == 3 + +static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = { + 26, 15, 44, 36 +}; + +static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = { + 1, 1, 2, 2 +}; + +static const uint16_t NUM_RAW_DATA_MODULES = 567; + +#else + +#error Unsupported LOCK_VERSION (add it...) + +#endif + + +static int max(int a, int b) { + if (a > b) { return a; } + return b; +} + +/* +static int abs(int value) { + if (value < 0) { return -value; } + return value; +} +*/ + + +#pragma mark - Mode testing and conversion + +static int8_t getAlphanumeric(char c) { + + if (c >= '0' && c <= '9') { return (c - '0'); } + if (c >= 'A' && c <= 'Z') { return (c - 'A' + 10); } + + switch (c) { + case ' ': return 36; + case '$': return 37; + case '%': return 38; + case '*': return 39; + case '+': return 40; + case '-': return 41; + case '.': return 42; + case '/': return 43; + case ':': return 44; + } + + return -1; +} + +static bool isAlphanumeric(const char *text, uint16_t length) { + while (length != 0) { + if (getAlphanumeric(text[--length]) == -1) { return false; } + } + return true; +} + + +static bool isNumeric(const char *text, uint16_t length) { + while (length != 0) { + char c = text[--length]; + if (c < '0' || c > '9') { return false; } + } + return true; +} + + +#pragma mark - Counting + +// We store the following tightly packed (less 8) in modeInfo +// <=9 <=26 <= 40 +// NUMERIC ( 10, 12, 14); +// ALPHANUMERIC ( 9, 11, 13); +// BYTE ( 8, 16, 16); +static char getModeBits(uint8_t version, uint8_t mode) { + // Note: We use 15 instead of 16; since 15 doesn't exist and we cannot store 16 (8 + 8) in 3 bits + // hex(int("".join(reversed([('00' + bin(x - 8)[2:])[-3:] for x in [10, 9, 8, 12, 11, 15, 14, 13, 15]])), 2)) + unsigned int modeInfo = 0x7bbb80a; + +#if LOCK_VERSION == 0 || LOCK_VERSION > 9 + if (version > 9) { modeInfo >>= 9; } +#endif + +#if LOCK_VERSION == 0 || LOCK_VERSION > 26 + if (version > 26) { modeInfo >>= 9; } +#endif + + char result = 8 + ((modeInfo >> (3 * mode)) & 0x07); + if (result == 15) { result = 16; } + + return result; +} + + +#pragma mark - BitBucket + +typedef struct BitBucket { + uint32_t bitOffsetOrWidth; + uint16_t capacityBytes; + uint8_t *data; +} BitBucket; + +/* +void bb_dump(BitBucket *bitBuffer) { + printf("Buffer: "); + for (uint32_t i = 0; i < bitBuffer->capacityBytes; i++) { + printf("%02x", bitBuffer->data[i]); + if ((i % 4) == 3) { printf(" "); } + } + printf("\n"); +} +*/ + +static uint16_t bb_getGridSizeBytes(uint8_t size) { + return (((size * size) + 7) / 8); +} + +static uint16_t bb_getBufferSizeBytes(uint32_t bits) { + return ((bits + 7) / 8); +} + +static void bb_initBuffer(BitBucket *bitBuffer, uint8_t *data, int32_t capacityBytes) { + bitBuffer->bitOffsetOrWidth = 0; + bitBuffer->capacityBytes = capacityBytes; + bitBuffer->data = data; + + memset(data, 0, bitBuffer->capacityBytes); +} + +static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) { + bitGrid->bitOffsetOrWidth = size; + bitGrid->capacityBytes = bb_getGridSizeBytes(size); + bitGrid->data = data; + + memset(data, 0, bitGrid->capacityBytes); +} + +static void bb_appendBits(BitBucket *bitBuffer, uint32_t val, uint8_t length) { + uint32_t offset = bitBuffer->bitOffsetOrWidth; + for (int8_t i = length - 1; i >= 0; i--, offset++) { + bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7)); + } + bitBuffer->bitOffsetOrWidth = offset; +} +/* +void bb_setBits(BitBucket *bitBuffer, uint32_t val, int offset, uint8_t length) { + for (int8_t i = length - 1; i >= 0; i--, offset++) { + bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7)); + } +} +*/ +static void bb_setBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool on) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + uint8_t mask = 1 << (7 - (offset & 0x07)); + if (on) { + bitGrid->data[offset >> 3] |= mask; + } else { + bitGrid->data[offset >> 3] &= ~mask; + } +} + +static void bb_invertBit(BitBucket *bitGrid, uint8_t x, uint8_t y, bool invert) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + uint8_t mask = 1 << (7 - (offset & 0x07)); + bool on = ((bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0); + if (on ^ invert) { + bitGrid->data[offset >> 3] |= mask; + } else { + bitGrid->data[offset >> 3] &= ~mask; + } +} + +static bool bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) { + uint32_t offset = y * bitGrid->bitOffsetOrWidth + x; + return (bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0; +} + + +#pragma mark - Drawing Patterns + +// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical +// properties, calling applyMask(m) twice with the same value is equivalent to no change at all. +// This means it is possible to apply a mask, undo it, and try another mask. Note that a final +// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). +static void applyMask(BitBucket *modules, BitBucket *isFunction, uint8_t mask) { + uint8_t size = modules->bitOffsetOrWidth; + + for (uint8_t y = 0; y < size; y++) { + for (uint8_t x = 0; x < size; x++) { + if (bb_getBit(isFunction, x, y)) { continue; } + + bool invert = 0; + switch (mask) { + case 0: invert = (x + y) % 2 == 0; break; + case 1: invert = y % 2 == 0; break; + case 2: invert = x % 3 == 0; break; + case 3: invert = (x + y) % 3 == 0; break; + case 4: invert = (x / 3 + y / 2) % 2 == 0; break; + case 5: invert = x * y % 2 + x * y % 3 == 0; break; + case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; + case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; + } + bb_invertBit(modules, x, y, invert); + } + } +} + +static void setFunctionModule(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y, bool on) { + bb_setBit(modules, x, y, on); + bb_setBit(isFunction, x, y, true); +} + +// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y). +static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) { + uint8_t size = modules->bitOffsetOrWidth; + + for (int8_t i = -4; i <= 4; i++) { + for (int8_t j = -4; j <= 4; j++) { + uint8_t dist = max(abs(i), abs(j)); // Chebyshev/infinity norm + int16_t xx = x + j, yy = y + i; + if (0 <= xx && xx < size && 0 <= yy && yy < size) { + setFunctionModule(modules, isFunction, xx, yy, dist != 2 && dist != 4); + } + } + } +} + +// Draws a 5*5 alignment pattern, with the center module at (x, y). +static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) { + for (int8_t i = -2; i <= 2; i++) { + for (int8_t j = -2; j <= 2; j++) { + setFunctionModule(modules, isFunction, x + j, y + i, max(abs(i), abs(j)) != 1); + } + } +} + +// Draws two copies of the format bits (with its own error correction code) +// based on the given mask and this object's error correction level field. +static void drawFormatBits(BitBucket *modules, BitBucket *isFunction, uint8_t ecc, uint8_t mask) { + + uint8_t size = modules->bitOffsetOrWidth; + + // Calculate error correction code and pack bits + uint32_t data = ecc << 3 | mask; // errCorrLvl is uint2, mask is uint3 + uint32_t rem = data; + for (int i = 0; i < 10; i++) { + rem = (rem << 1) ^ ((rem >> 9) * 0x537); + } + + data = data << 10 | rem; + data ^= 0x5412; // uint15 + + // Draw first copy + for (uint8_t i = 0; i <= 5; i++) { + setFunctionModule(modules, isFunction, 8, i, ((data >> i) & 1) != 0); + } + + setFunctionModule(modules, isFunction, 8, 7, ((data >> 6) & 1) != 0); + setFunctionModule(modules, isFunction, 8, 8, ((data >> 7) & 1) != 0); + setFunctionModule(modules, isFunction, 7, 8, ((data >> 8) & 1) != 0); + + for (int8_t i = 9; i < 15; i++) { + setFunctionModule(modules, isFunction, 14 - i, 8, ((data >> i) & 1) != 0); + } + + // Draw second copy + for (int8_t i = 0; i <= 7; i++) { + setFunctionModule(modules, isFunction, size - 1 - i, 8, ((data >> i) & 1) != 0); + } + + for (int8_t i = 8; i < 15; i++) { + setFunctionModule(modules, isFunction, 8, size - 15 + i, ((data >> i) & 1) != 0); + } + + setFunctionModule(modules, isFunction, 8, size - 8, true); +} + + +// Draws two copies of the version bits (with its own error correction code), +// based on this object's version field (which only has an effect for 7 <= version <= 40). +static void drawVersion(BitBucket *modules, BitBucket *isFunction, uint8_t version) { + + int8_t size = modules->bitOffsetOrWidth; + +#if LOCK_VERSION != 0 && LOCK_VERSION < 7 + return; + +#else + if (version < 7) { return; } + + // Calculate error correction code and pack bits + uint32_t rem = version; // version is uint6, in the range [7, 40] + for (uint8_t i = 0; i < 12; i++) { + rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + } + + uint32_t data = version << 12 | rem; // uint18 + + // Draw two copies + for (uint8_t i = 0; i < 18; i++) { + bool bit = ((data >> i) & 1) != 0; + uint8_t a = size - 11 + i % 3, b = i / 3; + setFunctionModule(modules, isFunction, a, b, bit); + setFunctionModule(modules, isFunction, b, a, bit); + } + +#endif +} + +static void drawFunctionPatterns(BitBucket *modules, BitBucket *isFunction, uint8_t version, uint8_t ecc) { + + uint8_t size = modules->bitOffsetOrWidth; + + // Draw the horizontal and vertical timing patterns + for (uint8_t i = 0; i < size; i++) { + setFunctionModule(modules, isFunction, 6, i, i % 2 == 0); + setFunctionModule(modules, isFunction, i, 6, i % 2 == 0); + } + + // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) + drawFinderPattern(modules, isFunction, 3, 3); + drawFinderPattern(modules, isFunction, size - 4, 3); + drawFinderPattern(modules, isFunction, 3, size - 4); + +#if LOCK_VERSION == 0 || LOCK_VERSION > 1 + + if (version > 1) { + + // Draw the numerous alignment patterns + + uint8_t alignCount = version / 7 + 2; + uint8_t step; + if (version != 32) { + step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2 + } else { // C-C-C-Combo breaker! + step = 26; + } + + uint8_t alignPositionIndex = alignCount - 1; + uint8_t alignPosition[alignCount]; + + alignPosition[0] = 6; + + uint8_t size = version * 4 + 17; + for (uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) { + alignPosition[alignPositionIndex--] = pos; + } + + for (uint8_t i = 0; i < alignCount; i++) { + for (uint8_t j = 0; j < alignCount; j++) { + if ((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) || (i == alignCount - 1 && j == 0)) { + continue; // Skip the three finder corners + } else { + drawAlignmentPattern(modules, isFunction, alignPosition[i], alignPosition[j]); + } + } + } + } + +#endif + + // Draw configuration data + drawFormatBits(modules, isFunction, ecc, 0); // Dummy mask value; overwritten later in the constructor + drawVersion(modules, isFunction, version); +} + + +// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire +// data area of this QR Code symbol. Function modules need to be marked off before this is called. +static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *codewords) { + + uint32_t bitLength = codewords->bitOffsetOrWidth; + uint8_t *data = codewords->data; + + uint8_t size = modules->bitOffsetOrWidth; + + // Bit index into the data + uint32_t i = 0; + + // Do the funny zigzag scan + for (int16_t right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair + if (right == 6) { right = 5; } + + for (uint8_t vert = 0; vert < size; vert++) { // Vertical counter + for (int j = 0; j < 2; j++) { + uint8_t x = right - j; // Actual x coordinate + bool upwards = ((right & 2) == 0) ^ (x < 6); + uint8_t y = upwards ? size - 1 - vert : vert; // Actual y coordinate + if (!bb_getBit(isFunction, x, y) && i < bitLength) { + bb_setBit(modules, x, y, ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0); + i++; + } + // If there are any remainder bits (0 to 7), they are already + // set to 0/false/white when the grid of modules was initialized + } + } + } +} + + + +#pragma mark - Penalty Calculation + +#define PENALTY_N1 3 +#define PENALTY_N2 3 +#define PENALTY_N3 40 +#define PENALTY_N4 10 + +// Calculates and returns the penalty score based on state of this QR Code's current modules. +// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. +// @TODO: This can be optimized by working with the bytes instead of bits. +static uint32_t getPenaltyScore(BitBucket *modules) { + uint32_t result = 0; + + uint8_t size = modules->bitOffsetOrWidth; + + // Adjacent modules in row having same color + for (uint8_t y = 0; y < size; y++) { + + bool colorX = bb_getBit(modules, 0, y); + for (uint8_t x = 1, runX = 1; x < size; x++) { + bool cx = bb_getBit(modules, x, y); + if (cx != colorX) { + colorX = cx; + runX = 1; + + } else { + runX++; + if (runX == 5) { + result += PENALTY_N1; + } else if (runX > 5) { + result++; + } + } + } + } + + // Adjacent modules in column having same color + for (uint8_t x = 0; x < size; x++) { + bool colorY = bb_getBit(modules, x, 0); + for (uint8_t y = 1, runY = 1; y < size; y++) { + bool cy = bb_getBit(modules, x, y); + if (cy != colorY) { + colorY = cy; + runY = 1; + } else { + runY++; + if (runY == 5) { + result += PENALTY_N1; + } else if (runY > 5) { + result++; + } + } + } + } + + uint16_t black = 0; + for (uint8_t y = 0; y < size; y++) { + uint16_t bitsRow = 0, bitsCol = 0; + for (uint8_t x = 0; x < size; x++) { + bool color = bb_getBit(modules, x, y); + + // 2*2 blocks of modules having same color + if (x > 0 && y > 0) { + bool colorUL = bb_getBit(modules, x - 1, y - 1); + bool colorUR = bb_getBit(modules, x, y - 1); + bool colorL = bb_getBit(modules, x - 1, y); + if (color == colorUL && color == colorUR && color == colorL) { + result += PENALTY_N2; + } + } + + // Finder-like pattern in rows and columns + bitsRow = ((bitsRow << 1) & 0x7FF) | color; + bitsCol = ((bitsCol << 1) & 0x7FF) | bb_getBit(modules, y, x); + + // Needs 11 bits accumulated + if (x >= 10) { + if (bitsRow == 0x05D || bitsRow == 0x5D0) { + result += PENALTY_N3; + } + if (bitsCol == 0x05D || bitsCol == 0x5D0) { + result += PENALTY_N3; + } + } + + // Balance of black and white modules + if (color) { black++; } + } + } + + // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% + uint16_t total = size * size; + for (uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) { + result += PENALTY_N4; + } + + return result; +} + + +#pragma mark - Reed-Solomon Generator + +static uint8_t rs_multiply(uint8_t x, uint8_t y) { + // Russian peasant multiplication + // See: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication + uint16_t z = 0; + for (int8_t i = 7; i >= 0; i--) { + z = (z << 1) ^ ((z >> 7) * 0x11D); + z ^= ((y >> i) & 1) * x; + } + return z; +} + +static void rs_init(uint8_t degree, uint8_t *coeff) { + memset(coeff, 0, degree); + coeff[degree - 1] = 1; + + // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), + // drop the highest term, and store the rest of the coefficients in order of descending powers. + // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). + uint16_t root = 1; + for (uint8_t i = 0; i < degree; i++) { + // Multiply the current product by (x - r^i) + for (uint8_t j = 0; j < degree; j++) { + coeff[j] = rs_multiply(coeff[j], root); + if (j + 1 < degree) { + coeff[j] ^= coeff[j + 1]; + } + } + root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D) + } +} + +static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8_t length, uint8_t *result, uint8_t stride) { + // Compute the remainder by performing polynomial division + + //for (uint8_t i = 0; i < degree; i++) { result[] = 0; } + //memset(result, 0, degree); + + for (uint8_t i = 0; i < length; i++) { + uint8_t factor = data[i] ^ result[0]; + for (uint8_t j = 1; j < degree; j++) { + result[(j - 1) * stride] = result[j * stride]; + } + result[(degree - 1) * stride] = 0; + + for (uint8_t j = 0; j < degree; j++) { + result[j * stride] ^= rs_multiply(coeff[j], factor); + } + } +} + + + +#pragma mark - QrCode + +static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) { + int8_t mode = MODE_BYTE; + + if (isNumeric((char*)text, length)) { + mode = MODE_NUMERIC; + bb_appendBits(dataCodewords, 1 << MODE_NUMERIC, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_NUMERIC)); + + uint16_t accumData = 0; + uint8_t accumCount = 0; + for (uint16_t i = 0; i < length; i++) { + accumData = accumData * 10 + ((char)(text[i]) - '0'); + accumCount++; + if (accumCount == 3) { + bb_appendBits(dataCodewords, accumData, 10); + accumData = 0; + accumCount = 0; + } + } + + // 1 or 2 digits remaining + if (accumCount > 0) { + bb_appendBits(dataCodewords, accumData, accumCount * 3 + 1); + } + + } else if (isAlphanumeric((char*)text, length)) { + mode = MODE_ALPHANUMERIC; + bb_appendBits(dataCodewords, 1 << MODE_ALPHANUMERIC, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_ALPHANUMERIC)); + + uint16_t accumData = 0; + uint8_t accumCount = 0; + for (uint16_t i = 0; i < length; i++) { + accumData = accumData * 45 + getAlphanumeric((char)(text[i])); + accumCount++; + if (accumCount == 2) { + bb_appendBits(dataCodewords, accumData, 11); + accumData = 0; + accumCount = 0; + } + } + + // 1 character remaining + if (accumCount > 0) { + bb_appendBits(dataCodewords, accumData, 6); + } + + } else { + bb_appendBits(dataCodewords, 1 << MODE_BYTE, 4); + bb_appendBits(dataCodewords, length, getModeBits(version, MODE_BYTE)); + for (uint16_t i = 0; i < length; i++) { + bb_appendBits(dataCodewords, (char)(text[i]), 8); + } + } + + //bb_setBits(dataCodewords, length, 4, getModeBits(version, mode)); + + return mode; +} + +static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) { + + // See: http://www.thonky.com/qr-code-tutorial/structure-final-message + +#if LOCK_VERSION == 0 + uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1]; + uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1]; + uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1]; +#else + uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc]; + uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc]; + uint16_t moduleCount = NUM_RAW_DATA_MODULES; +#endif + + uint8_t blockEccLen = totalEcc / numBlocks; + uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks; + uint8_t shortBlockLen = moduleCount / 8 / numBlocks; + + uint8_t shortDataBlockLen = shortBlockLen - blockEccLen; + + uint8_t result[data->capacityBytes]; + memset(result, 0, sizeof(result)); + + uint8_t coeff[blockEccLen]; + rs_init(blockEccLen, coeff); + + uint16_t offset = 0; + uint8_t *dataBytes = data->data; + + + // Interleave all short blocks + for (uint8_t i = 0; i < shortDataBlockLen; i++) { + uint16_t index = i; + uint8_t stride = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) { + result[offset++] = dataBytes[index]; + +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + if (blockNum == numShortBlocks) { stride++; } +#endif + index += stride; + } + } + + // Version less than 5 only have short blocks +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + { + // Interleave long blocks + uint16_t index = shortDataBlockLen * (numShortBlocks + 1); + uint8_t stride = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) { + result[offset++] = dataBytes[index]; + + if (blockNum == 0) { stride++; } + index += stride; + } + } +#endif + + // Add all ecc blocks, interleaved + uint8_t blockSize = shortDataBlockLen; + for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) { + +#if LOCK_VERSION == 0 || LOCK_VERSION >= 5 + if (blockNum == numShortBlocks) { blockSize++; } +#endif + rs_getRemainder(blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks); + dataBytes += blockSize; + } + + memcpy(data->data, result, data->capacityBytes); + data->bitOffsetOrWidth = moduleCount; +} + +// We store the Format bits tightly packed into a single byte (each of the 4 modes is 2 bits) +// The format bits can be determined by ECC_FORMAT_BITS >> (2 * ecc) +static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0); + + +#pragma mark - Public QRCode functions + +uint16_t qrcode_getBufferSize(uint8_t version) { + return bb_getGridSizeBytes(4 * version + 17); +} + +// @TODO: Return error if data is too big. +int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length) { + uint8_t size = version * 4 + 17; + qrcode->version = version; + qrcode->size = size; + qrcode->ecc = ecc; + qrcode->modules = modules; + + uint8_t eccFormatBits = (ECC_FORMAT_BITS >> (2 * ecc)) & 0x03; + +#if LOCK_VERSION == 0 + uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1]; + uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1]; +#else + version = LOCK_VERSION; + uint16_t moduleCount = NUM_RAW_DATA_MODULES; + uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits]; +#endif + + struct BitBucket codewords; + uint8_t codewordBytes[bb_getBufferSizeBytes(moduleCount)]; + bb_initBuffer(&codewords, codewordBytes, (int32_t)sizeof(codewordBytes)); + + // Place the data code words into the buffer + int8_t mode = encodeDataCodewords(&codewords, data, length, version); + + if (mode < 0) { return -1; } + qrcode->mode = mode; + + // Add terminator and pad up to a byte if applicable + uint32_t padding = (dataCapacity * 8) - codewords.bitOffsetOrWidth; + if (padding > 4) { padding = 4; } + bb_appendBits(&codewords, 0, padding); + bb_appendBits(&codewords, 0, (8 - codewords.bitOffsetOrWidth % 8) % 8); + + // Pad with alternate bytes until data capacity is reached + for (uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8); padByte ^= 0xEC ^ 0x11) { + bb_appendBits(&codewords, padByte, 8); + } + + BitBucket modulesGrid; + bb_initGrid(&modulesGrid, modules, size); + + BitBucket isFunctionGrid; + uint8_t isFunctionGridBytes[bb_getGridSizeBytes(size)]; + bb_initGrid(&isFunctionGrid, isFunctionGridBytes, size); + + // Draw function patterns, draw all codewords, do masking + drawFunctionPatterns(&modulesGrid, &isFunctionGrid, version, eccFormatBits); + performErrorCorrection(version, eccFormatBits, &codewords); + drawCodewords(&modulesGrid, &isFunctionGrid, &codewords); + + // Find the best (lowest penalty) mask + uint8_t mask = 0; + int32_t minPenalty = INT32_MAX; + for (uint8_t i = 0; i < 8; i++) { + drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, i); + applyMask(&modulesGrid, &isFunctionGrid, i); + int penalty = getPenaltyScore(&modulesGrid); + if (penalty < minPenalty) { + mask = i; + minPenalty = penalty; + } + applyMask(&modulesGrid, &isFunctionGrid, i); // Undoes the mask due to XOR + } + + qrcode->mask = mask; + + // Overwrite old format bits + drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, mask); + + // Apply the final choice of mask + applyMask(&modulesGrid, &isFunctionGrid, mask); + + return 0; +} + +int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data) { + return qrcode_initBytes(qrcode, modules, version, ecc, (uint8_t*)data, strlen(data)); +} + +bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) { + if (x < 0 || x >= qrcode->size || y < 0 || y >= qrcode->size) { + return false; + } + + uint32_t offset = y * qrcode->size + x; + return (qrcode->modules[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0; +} + +/* +uint8_t qrcode_getHexLength(QRCode *qrcode) { + return ((qrcode->size * qrcode->size) + 7) / 4; +} + +void qrcode_getHex(QRCode *qrcode, char *result) { + +} +*/ diff --git a/libraries/QRCode/src/qrcode.h b/libraries/QRCode/src/qrcode.h new file mode 100644 index 00000000..6a5745e5 --- /dev/null +++ b/libraries/QRCode/src/qrcode.h @@ -0,0 +1,99 @@ +/** + * The MIT License (MIT) + * + * This library is written and maintained by Richard Moore. + * Major parts were derived from Project Nayuki's library. + * + * Copyright (c) 2017 Richard Moore (https://github.com/ricmoo/QRCode) + * Copyright (c) 2017 Project Nayuki (https://www.nayuki.io/page/qr-code-generator-library) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Special thanks to Nayuki (https://www.nayuki.io/) from which this library was + * heavily inspired and compared against. + * + * See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp + */ + + +#ifndef __QRCODE_H_ +#define __QRCODE_H_ + +#ifndef __cplusplus +typedef unsigned char bool; +static const bool false = 0; +static const bool true = 1; +#endif + +#include + + +// QR Code Format Encoding +#define MODE_NUMERIC 0 +#define MODE_ALPHANUMERIC 1 +#define MODE_BYTE 2 + + +// Error Correction Code Levels +#define ECC_LOW 0 +#define ECC_MEDIUM 1 +#define ECC_QUARTILE 2 +#define ECC_HIGH 3 + + +// If set to non-zero, this library can ONLY produce QR codes at that version +// This saves a lot of dynamic memory, as the codeword tables are skipped +#ifndef LOCK_VERSION +#define LOCK_VERSION 0 +#endif + + +typedef struct QRCode { + uint8_t version; + uint8_t size; + uint8_t ecc; + uint8_t mode; + uint8_t mask; + uint8_t *modules; +} QRCode; + + +#ifdef __cplusplus +extern "C"{ +#endif /* __cplusplus */ + + + +uint16_t qrcode_getBufferSize(uint8_t version); + +int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data); +int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length); + +bool qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __QRCODE_H_ */ diff --git a/libraries/QRCode/tests/BitBuffer.cpp b/libraries/QRCode/tests/BitBuffer.cpp new file mode 100644 index 00000000..4b48cb7a --- /dev/null +++ b/libraries/QRCode/tests/BitBuffer.cpp @@ -0,0 +1,63 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#include +#include "BitBuffer.hpp" + + +qrcodegen::BitBuffer::BitBuffer() : + data(), + bitLength(0) {} + + +int qrcodegen::BitBuffer::getBitLength() const { + return bitLength; +} + + +std::vector qrcodegen::BitBuffer::getBytes() const { + return data; +} + + +void qrcodegen::BitBuffer::appendBits(uint32_t val, int len) { + if (len < 0 || len > 32 || (len < 32 && (val >> len) != 0)) + throw "Value out of range"; + size_t newBitLen = bitLength + len; + while (data.size() * 8 < newBitLen) + data.push_back(0); + for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit + data.at(bitLength >> 3) |= ((val >> i) & 1) << (7 - (bitLength & 7)); +} + + +void qrcodegen::BitBuffer::appendData(const QrSegment &seg) { + size_t newBitLen = bitLength + seg.bitLength; + while (data.size() * 8 < newBitLen) + data.push_back(0); + for (int i = 0; i < seg.bitLength; i++, bitLength++) { // Append bit by bit + int bit = (seg.data.at(i >> 3) >> (7 - (i & 7))) & 1; + data.at(bitLength >> 3) |= bit << (7 - (bitLength & 7)); + } +} diff --git a/libraries/QRCode/tests/BitBuffer.hpp b/libraries/QRCode/tests/BitBuffer.hpp new file mode 100644 index 00000000..ee38907e --- /dev/null +++ b/libraries/QRCode/tests/BitBuffer.hpp @@ -0,0 +1,76 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#pragma once + +#include +#include +#include "QrSegment.hpp" + + +namespace qrcodegen { + +/* + * An appendable sequence of bits. Bits are packed in big endian within a byte. + */ +class BitBuffer { + + /*---- Fields ----*/ +private: + + std::vector data; + int bitLength; + + + + /*---- Constructor ----*/ +public: + + // Creates an empty bit buffer (length 0). + BitBuffer(); + + + + /*---- Methods ----*/ +public: + + // Returns the number of bits in the buffer, which is a non-negative value. + int getBitLength() const; + + + // Returns a copy of all bytes, padding up to the nearest byte. + std::vector getBytes() const; + + + // Appends the given number of bits of the given value to this sequence. + // If 0 <= len <= 31, then this requires 0 <= val < 2^len. + void appendBits(uint32_t val, int len); + + + // Appends the data of the given segment to this bit buffer. + void appendData(const QrSegment &seg); + +}; + +} diff --git a/libraries/QRCode/tests/QrCode.cpp b/libraries/QRCode/tests/QrCode.cpp new file mode 100644 index 00000000..cdb42462 --- /dev/null +++ b/libraries/QRCode/tests/QrCode.cpp @@ -0,0 +1,616 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#include +#include +#include +#include +#include +#include "BitBuffer.hpp" +#include "QrCode.hpp" + + +qrcodegen::QrCode::Ecc::Ecc(int ord, int fb) : + ordinal(ord), + formatBits(fb) {} + + +const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::LOW (0, 1); +const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::MEDIUM (1, 0); +const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::QUARTILE(2, 3); +const qrcodegen::QrCode::Ecc qrcodegen::QrCode::Ecc::HIGH (3, 2); + + +qrcodegen::QrCode qrcodegen::QrCode::encodeText(const char *text, int version, const Ecc &ecl) { + std::vector segs(QrSegment::makeSegments(text)); + return encodeSegments(segs, ecl, version, version, -1, false); +} + + +qrcodegen::QrCode qrcodegen::QrCode::encodeBinary(const std::vector &data, const Ecc &ecl) { + std::vector segs; + segs.push_back(QrSegment::makeBytes(data)); + return encodeSegments(segs, ecl); +} + + +qrcodegen::QrCode qrcodegen::QrCode::encodeSegments(const std::vector &segs, const Ecc &ecl, + int minVersion, int maxVersion, int mask, bool boostEcl) { + if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7) + throw "Invalid value"; + + // Find the minimal version number to use + int version, dataUsedBits; + for (version = minVersion; ; version++) { + int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available + dataUsedBits = QrSegment::getTotalBits(segs, version); + if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) + break; // This version number is found to be suitable + if (version >= maxVersion) // All versions in the range could not fit the given data + throw "Data too long"; + } + if (dataUsedBits == -1) + throw "Assertion error"; + + // Increase the error correction level while the data still fits in the current version number + const Ecc *newEcl = &ecl; + if (boostEcl) { + if (dataUsedBits <= getNumDataCodewords(version, Ecc::MEDIUM ) * 8) newEcl = &Ecc::MEDIUM ; + if (dataUsedBits <= getNumDataCodewords(version, Ecc::QUARTILE) * 8) newEcl = &Ecc::QUARTILE; + if (dataUsedBits <= getNumDataCodewords(version, Ecc::HIGH ) * 8) newEcl = &Ecc::HIGH ; + } + + // Create the data bit string by concatenating all segments + int dataCapacityBits = getNumDataCodewords(version, *newEcl) * 8; + BitBuffer bb; + for (size_t i = 0; i < segs.size(); i++) { + const QrSegment &seg(segs.at(i)); + bb.appendBits(seg.mode.modeBits, 4); + bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version)); + bb.appendData(seg); + } + + // Add terminator and pad up to a byte if applicable + bb.appendBits(0, std::min(4, dataCapacityBits - bb.getBitLength())); + bb.appendBits(0, (8 - bb.getBitLength() % 8) % 8); + + // Pad with alternate bytes until data capacity is reached + for (uint8_t padByte = 0xEC; bb.getBitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) + bb.appendBits(padByte, 8); + if (bb.getBitLength() % 8 != 0) + throw "Assertion error"; + + // Create the QR Code symbol + return QrCode(version, *newEcl, bb.getBytes(), mask); +} + + +qrcodegen::QrCode::QrCode(int ver, const Ecc &ecl, const std::vector &dataCodewords, int mask) : + // Initialize scalar fields + version(ver), + size(1 <= ver && ver <= 40 ? ver * 4 + 17 : -1), // Avoid signed overflow undefined behavior + errorCorrectionLevel(ecl) { + + // Check arguments + if (ver < 1 || ver > 40 || mask < -1 || mask > 7) + throw "Value out of range"; + + std::vector row(size); + for (int i = 0; i < size; i++) { + modules.push_back(row); + isFunction.push_back(row); + } + + // Draw function patterns, draw all codewords, do masking + drawFunctionPatterns(); + const std::vector allCodewords(appendErrorCorrection(dataCodewords)); + drawCodewords(allCodewords); + this->mask = handleConstructorMasking(mask); +} + + +qrcodegen::QrCode::QrCode(const QrCode &qr, int mask) : + // Copy scalar fields + version(qr.version), + size(qr.size), + errorCorrectionLevel(qr.errorCorrectionLevel) { + + // Check arguments + if (mask < -1 || mask > 7) + throw "Mask value out of range"; + + // Handle grid fields + modules = qr.modules; + isFunction = qr.isFunction; + + // Handle masking + applyMask(qr.mask); // Undo old mask + this->mask = handleConstructorMasking(mask); +} + + +int qrcodegen::QrCode::getMask() const { + return mask; +} + + +int qrcodegen::QrCode::getModule(int x, int y) const { + if (0 <= x && x < size && 0 <= y && y < size) + return modules.at(y).at(x) ? 1 : 0; + else + return 0; // Infinite white border +} + + +std::string qrcodegen::QrCode::toSvgString(int border) const { + if (border < 0) + throw "Border must be non-negative"; + std::ostringstream sb; + sb << "\n"; + sb << "\n"; + sb << "\n"; + sb << "\t\n"; + sb << "\t\n"; + sb << "\n"; + return sb.str(); +} + + +void qrcodegen::QrCode::drawFunctionPatterns() { + // Draw the horizontal and vertical timing patterns + for (int i = 0; i < size; i++) { + setFunctionModule(6, i, i % 2 == 0); + setFunctionModule(i, 6, i % 2 == 0); + } + + // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) + drawFinderPattern(3, 3); + drawFinderPattern(size - 4, 3); + drawFinderPattern(3, size - 4); + + // Draw the numerous alignment patterns + const std::vector alignPatPos(getAlignmentPatternPositions(version)); + int numAlign = alignPatPos.size(); + for (int i = 0; i < numAlign; i++) { + for (int j = 0; j < numAlign; j++) { + if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)) + continue; // Skip the three finder corners + else + drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j)); + } + } + + // Draw configuration data + drawFormatBits(0); // Dummy mask value; overwritten later in the constructor + drawVersion(); +} + + +void qrcodegen::QrCode::drawFormatBits(int mask) { + // Calculate error correction code and pack bits + int data = errorCorrectionLevel.formatBits << 3 | mask; // errCorrLvl is uint2, mask is uint3 + int rem = data; + for (int i = 0; i < 10; i++) + rem = (rem << 1) ^ ((rem >> 9) * 0x537); + data = data << 10 | rem; + data ^= 0x5412; // uint15 + if (data >> 15 != 0) + throw "Assertion error"; + + // Draw first copy + for (int i = 0; i <= 5; i++) + setFunctionModule(8, i, ((data >> i) & 1) != 0); + setFunctionModule(8, 7, ((data >> 6) & 1) != 0); + setFunctionModule(8, 8, ((data >> 7) & 1) != 0); + setFunctionModule(7, 8, ((data >> 8) & 1) != 0); + for (int i = 9; i < 15; i++) + setFunctionModule(14 - i, 8, ((data >> i) & 1) != 0); + + // Draw second copy + for (int i = 0; i <= 7; i++) + setFunctionModule(size - 1 - i, 8, ((data >> i) & 1) != 0); + for (int i = 8; i < 15; i++) + setFunctionModule(8, size - 15 + i, ((data >> i) & 1) != 0); + setFunctionModule(8, size - 8, true); +} + + +void qrcodegen::QrCode::drawVersion() { + if (version < 7) + return; + + // Calculate error correction code and pack bits + int rem = version; // version is uint6, in the range [7, 40] + for (int i = 0; i < 12; i++) + rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + int data = version << 12 | rem; // uint18 + if (data >> 18 != 0) + throw "Assertion error"; + + // Draw two copies + for (int i = 0; i < 18; i++) { + bool bit = ((data >> i) & 1) != 0; + int a = size - 11 + i % 3, b = i / 3; + setFunctionModule(a, b, bit); + setFunctionModule(b, a, bit); + } +} + + +void qrcodegen::QrCode::drawFinderPattern(int x, int y) { + for (int i = -4; i <= 4; i++) { + for (int j = -4; j <= 4; j++) { + int dist = std::max(std::abs(i), std::abs(j)); // Chebyshev/infinity norm + int xx = x + j, yy = y + i; + if (0 <= xx && xx < size && 0 <= yy && yy < size) + setFunctionModule(xx, yy, dist != 2 && dist != 4); + } + } +} + + +void qrcodegen::QrCode::drawAlignmentPattern(int x, int y) { + for (int i = -2; i <= 2; i++) { + for (int j = -2; j <= 2; j++) + setFunctionModule(x + j, y + i, std::max(std::abs(i), std::abs(j)) != 1); + } +} + + +void qrcodegen::QrCode::setFunctionModule(int x, int y, bool isBlack) { + modules.at(y).at(x) = isBlack; + isFunction.at(y).at(x) = true; +} + + +std::vector qrcodegen::QrCode::appendErrorCorrection(const std::vector &data) const { + if (data.size() != static_cast(getNumDataCodewords(version, errorCorrectionLevel))) + throw "Invalid argument"; + + // Calculate parameter numbers + int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[errorCorrectionLevel.ordinal][version]; + int totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[errorCorrectionLevel.ordinal][version]; + if (totalEcc % numBlocks != 0) + throw "Assertion error"; + int blockEccLen = totalEcc / numBlocks; + int numShortBlocks = numBlocks - getNumRawDataModules(version) / 8 % numBlocks; + int shortBlockLen = getNumRawDataModules(version) / 8 / numBlocks; + + // Split data into blocks and append ECC to each block + std::vector > blocks; + const ReedSolomonGenerator rs(blockEccLen); + for (int i = 0, k = 0; i < numBlocks; i++) { + std::vector dat; + dat.insert(dat.begin(), data.begin() + k, data.begin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1))); + k += dat.size(); + const std::vector ecc(rs.getRemainder(dat)); + if (i < numShortBlocks) + dat.push_back(0); + dat.insert(dat.end(), ecc.begin(), ecc.end()); + blocks.push_back(dat); + } + + // Interleave (not concatenate) the bytes from every block into a single sequence + std::vector result; + for (int i = 0; static_cast(i) < blocks.at(0).size(); i++) { + for (int j = 0; static_cast(j) < blocks.size(); j++) { + // Skip the padding byte in short blocks + if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) + result.push_back(blocks.at(j).at(i)); + } + } + if (result.size() != static_cast(getNumRawDataModules(version) / 8)) + throw "Assertion error"; + return result; +} + + +void qrcodegen::QrCode::drawCodewords(const std::vector &data) { + if (data.size() != static_cast(getNumRawDataModules(version) / 8)) + throw "Invalid argument"; + + size_t i = 0; // Bit index into the data + // Do the funny zigzag scan + for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair + if (right == 6) + right = 5; + for (int vert = 0; vert < size; vert++) { // Vertical counter + for (int j = 0; j < 2; j++) { + int x = right - j; // Actual x coordinate + bool upwards = ((right & 2) == 0) ^ (x < 6); + int y = upwards ? size - 1 - vert : vert; // Actual y coordinate + if (!isFunction.at(y).at(x) && i < data.size() * 8) { + modules.at(y).at(x) = ((data.at(i >> 3) >> (7 - (i & 7))) & 1) != 0; + i++; + } + // If there are any remainder bits (0 to 7), they are already + // set to 0/false/white when the grid of modules was initialized + } + } + } + if (static_cast(i) != data.size() * 8) + throw "Assertion error"; +} + + +void qrcodegen::QrCode::applyMask(int mask) { + if (mask < 0 || mask > 7) + throw "Mask value out of range"; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + bool invert; + switch (mask) { + case 0: invert = (x + y) % 2 == 0; break; + case 1: invert = y % 2 == 0; break; + case 2: invert = x % 3 == 0; break; + case 3: invert = (x + y) % 3 == 0; break; + case 4: invert = (x / 3 + y / 2) % 2 == 0; break; + case 5: invert = x * y % 2 + x * y % 3 == 0; break; + case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; + case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; + default: throw "Assertion error"; + } + modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x)); + } + } +} + + +int qrcodegen::QrCode::handleConstructorMasking(int mask) { + if (mask == -1) { // Automatically choose best mask + int32_t minPenalty = INT32_MAX; + for (int i = 0; i < 8; i++) { + drawFormatBits(i); + applyMask(i); + int penalty = getPenaltyScore(); + if (penalty < minPenalty) { + mask = i; + minPenalty = penalty; + } + applyMask(i); // Undoes the mask due to XOR + } + } + if (mask < 0 || mask > 7) + throw "Assertion error"; + drawFormatBits(mask); // Overwrite old format bits + applyMask(mask); // Apply the final choice of mask + return mask; // The caller shall assign this value to the final-declared field +} + + +int qrcodegen::QrCode::getPenaltyScore() const { + int result = 0; + + // Adjacent modules in row having same color + for (int y = 0; y < size; y++) { + bool colorX = modules.at(y).at(0); + for (int x = 1, runX = 1; x < size; x++) { + if (modules.at(y).at(x) != colorX) { + colorX = modules.at(y).at(x); + runX = 1; + } else { + runX++; + if (runX == 5) + result += PENALTY_N1; + else if (runX > 5) + result++; + } + } + } + // Adjacent modules in column having same color + for (int x = 0; x < size; x++) { + bool colorY = modules.at(0).at(x); + for (int y = 1, runY = 1; y < size; y++) { + if (modules.at(y).at(x) != colorY) { + colorY = modules.at(y).at(x); + runY = 1; + } else { + runY++; + if (runY == 5) + result += PENALTY_N1; + else if (runY > 5) + result++; + } + } + } + + // 2*2 blocks of modules having same color + for (int y = 0; y < size - 1; y++) { + for (int x = 0; x < size - 1; x++) { + bool color = modules.at(y).at(x); + if ( color == modules.at(y).at(x + 1) && + color == modules.at(y + 1).at(x) && + color == modules.at(y + 1).at(x + 1)) + result += PENALTY_N2; + } + } + + // Finder-like pattern in rows + for (int y = 0; y < size; y++) { + for (int x = 0, bits = 0; x < size; x++) { + bits = ((bits << 1) & 0x7FF) | (modules.at(y).at(x) ? 1 : 0); + if (x >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated + result += PENALTY_N3; + } + } + // Finder-like pattern in columns + for (int x = 0; x < size; x++) { + for (int y = 0, bits = 0; y < size; y++) { + bits = ((bits << 1) & 0x7FF) | (modules.at(y).at(x) ? 1 : 0); + if (y >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated + result += PENALTY_N3; + } + } + + // Balance of black and white modules + int black = 0; + for (int y = 0; y < size; y++) { + for (int x = 0; x < size; x++) { + if (modules.at(y).at(x)) + black++; + } + } + int total = size * size; + // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% + for (int k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++) + result += PENALTY_N4; + return result; +} + + +std::vector qrcodegen::QrCode::getAlignmentPatternPositions(int ver) { + if (ver < 1 || ver > 40) + throw "Version number out of range"; + else if (ver == 1) + return std::vector(); + else { + int numAlign = ver / 7 + 2; + int step; + if (ver != 32) + step = (ver * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2 + else // C-C-C-Combo breaker! + step = 26; + + std::vector result; + int size = ver * 4 + 17; + for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) + result.insert(result.begin(), pos); + result.insert(result.begin(), 6); + return result; + } +} + + +int qrcodegen::QrCode::getNumRawDataModules(int ver) { + if (ver < 1 || ver > 40) + throw "Version number out of range"; + int result = (16 * ver + 128) * ver + 64; + if (ver >= 2) { + int numAlign = ver / 7 + 2; + result -= (25 * numAlign - 10) * numAlign - 55; + if (ver >= 7) + result -= 18 * 2; // Subtract version information + } + return result; +} + + +int qrcodegen::QrCode::getNumDataCodewords(int ver, const Ecc &ecl) { + if (ver < 1 || ver > 40) + throw "Version number out of range"; + return getNumRawDataModules(ver) / 8 - NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver]; +} + + +/*---- Tables of constants ----*/ + +const int qrcodegen::QrCode::PENALTY_N1 = 3; +const int qrcodegen::QrCode::PENALTY_N2 = 3; +const int qrcodegen::QrCode::PENALTY_N3 = 40; +const int qrcodegen::QrCode::PENALTY_N4 = 10; + + +const int16_t qrcodegen::QrCode::NUM_ERROR_CORRECTION_CODEWORDS[4][41] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + {-1, 7, 10, 15, 20, 26, 36, 40, 48, 60, 72, 80, 96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300, 312, 336, 360, 390, 420, 450, 480, 510, 540, 570, 570, 600, 630, 660, 720, 750}, // Low + {-1, 10, 16, 26, 36, 48, 64, 72, 88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560, 588, 644, 700, 728, 784, 812, 868, 924, 980, 1036, 1064, 1120, 1204, 1260, 1316, 1372}, // Medium + {-1, 13, 22, 36, 52, 72, 96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810, 870, 952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040}, // Quartile + {-1, 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430}, // High +}; + +const int8_t qrcodegen::QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = { + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low + {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium + {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile + {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High +}; + + +qrcodegen::QrCode::ReedSolomonGenerator::ReedSolomonGenerator(int degree) : + coefficients() { + if (degree < 1 || degree > 255) + throw "Degree out of range"; + + // Start with the monomial x^0 + coefficients.resize(degree); + coefficients.at(degree - 1) = 1; + + // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), + // drop the highest term, and store the rest of the coefficients in order of descending powers. + // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). + int root = 1; + for (int i = 0; i < degree; i++) { + // Multiply the current product by (x - r^i) + for (size_t j = 0; j < coefficients.size(); j++) { + coefficients.at(j) = multiply(coefficients.at(j), static_cast(root)); + if (j + 1 < coefficients.size()) + coefficients.at(j) ^= coefficients.at(j + 1); + } + root = (root << 1) ^ ((root >> 7) * 0x11D); // Multiply by 0x02 mod GF(2^8/0x11D) + } +} + + +std::vector qrcodegen::QrCode::ReedSolomonGenerator::getRemainder(const std::vector &data) const { + // Compute the remainder by performing polynomial division + std::vector result(coefficients.size()); + for (size_t i = 0; i < data.size(); i++) { + uint8_t factor = data.at(i) ^ result.at(0); + result.erase(result.begin()); + result.push_back(0); + for (size_t j = 0; j < result.size(); j++) + result.at(j) ^= multiply(coefficients.at(j), factor); + } + return result; +} + + +uint8_t qrcodegen::QrCode::ReedSolomonGenerator::multiply(uint8_t x, uint8_t y) { + // Russian peasant multiplication + int z = 0; + for (int i = 7; i >= 0; i--) { + z = (z << 1) ^ ((z >> 7) * 0x11D); + z ^= ((y >> i) & 1) * x; + } + if (z >> 8 != 0) + throw "Assertion error"; + return static_cast(z); +} diff --git a/libraries/QRCode/tests/QrCode.hpp b/libraries/QRCode/tests/QrCode.hpp new file mode 100644 index 00000000..dd4dcc28 --- /dev/null +++ b/libraries/QRCode/tests/QrCode.hpp @@ -0,0 +1,314 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#pragma once + +#include +#include +#include +#include "QrSegment.hpp" + + +namespace qrcodegen { + +/* + * Represents an immutable square grid of black and white cells for a QR Code symbol, and + * provides static functions to create a QR Code from user-supplied textual or binary data. + * This class covers the QR Code model 2 specification, supporting all versions (sizes) + * from 1 to 40, all 4 error correction levels, and only 3 character encoding modes. + */ +class QrCode { + + /*---- Public helper enumeration ----*/ +public: + + /* + * Represents the error correction level used in a QR Code symbol. + */ + class Ecc { + // Constants declared in ascending order of error protection. + public: + const static Ecc LOW, MEDIUM, QUARTILE, HIGH; + + // Fields. + public: + const int ordinal; // (Public) In the range 0 to 3 (unsigned 2-bit integer). + const int formatBits; // (Package-private) In the range 0 to 3 (unsigned 2-bit integer). + + // Constructor. + private: + Ecc(int ord, int fb); + }; + + + + /*---- Public static factory functions ----*/ +public: + + /* + * Returns a QR Code symbol representing the given Unicode text string at the given error correction level. + * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode + * code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output. + * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. + */ + static QrCode encodeText(const char *text, int version, const Ecc &ecl); + + + /* + * Returns a QR Code symbol representing the given binary data string at the given error correction level. + * This function always encodes using the binary segment mode, not any text mode. The maximum number of + * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output. + * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. + */ + static QrCode encodeBinary(const std::vector &data, const Ecc &ecl); + + + /* + * Returns a QR Code symbol representing the given data segments with the given encoding parameters. + * The smallest possible QR Code version within the given range is automatically chosen for the output. + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and binary) to encode text more efficiently. + * This function is considered to be lower level than simply encoding text or binary data. + */ + static QrCode encodeSegments(const std::vector &segs, const Ecc &ecl, + int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters + + + + /*---- Instance fields ----*/ + + // Public immutable scalar parameters +public: + + /* This QR Code symbol's version number, which is always between 1 and 40 (inclusive). */ + const int version; + + /* The width and height of this QR Code symbol, measured in modules. + * Always equal to version × 4 + 17, in the range 21 to 177. */ + const int size; + + /* The error correction level used in this QR Code symbol. */ + const Ecc &errorCorrectionLevel; + + /* The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer). + * Note that even if a constructor was called with automatic masking requested + * (mask = -1), the resulting object will still have a mask value between 0 and 7. */ +private: + int mask; + + // Private grids of modules/pixels (conceptually immutable) +private: + std::vector > modules; // The modules of this QR Code symbol (false = white, true = black) + std::vector > isFunction; // Indicates function modules that are not subjected to masking + + + + /*---- Constructors ----*/ +public: + + /* + * Creates a new QR Code symbol with the given version number, error correction level, binary data array, + * and mask number. This is a cumbersome low-level constructor that should not be invoked directly by the user. + * To go one level up, see the encodeSegments() function. + */ + QrCode(int ver, const Ecc &ecl, const std::vector &dataCodewords, int mask); + + + /* + * Creates a new QR Code symbol based on the given existing object, but with a potentially + * different mask pattern. The version, error correction level, codewords, etc. of the newly + * created object are all identical to the argument object; only the mask may differ. + */ + QrCode(const QrCode &qr, int mask); + + + + /*---- Public instance methods ----*/ +public: + + int getMask() const; + + + /* + * Returns the color of the module (pixel) at the given coordinates, which is either 0 for white or 1 for black. The top + * left corner has the coordinates (x=0, y=0). If the given coordinates are out of bounds, then 0 (white) is returned. + */ + int getModule(int x, int y) const; + + + /* + * Based on the given number of border modules to add as padding, this returns a + * string whose contents represents an SVG XML file that depicts this QR Code symbol. + * Note that Unix newlines (\n) are always used, regardless of the platform. + */ + std::string toSvgString(int border) const; + + + + /*---- Private helper methods for constructor: Drawing function modules ----*/ +private: + + void drawFunctionPatterns(); + + + // Draws two copies of the format bits (with its own error correction code) + // based on the given mask and this object's error correction level field. + void drawFormatBits(int mask); + + + // Draws two copies of the version bits (with its own error correction code), + // based on this object's version field (which only has an effect for 7 <= version <= 40). + void drawVersion(); + + + // Draws a 9*9 finder pattern including the border separator, with the center module at (x, y). + void drawFinderPattern(int x, int y); + + + // Draws a 5*5 alignment pattern, with the center module at (x, y). + void drawAlignmentPattern(int x, int y); + + + // Sets the color of a module and marks it as a function module. + // Only used by the constructor. Coordinates must be in range. + void setFunctionModule(int x, int y, bool isBlack); + + + /*---- Private helper methods for constructor: Codewords and masking ----*/ +private: + + // Returns a new byte string representing the given data with the appropriate error correction + // codewords appended to it, based on this object's version and error correction level. + std::vector appendErrorCorrection(const std::vector &data) const; + + + // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire + // data area of this QR Code symbol. Function modules need to be marked off before this is called. + void drawCodewords(const std::vector &data); + + + // XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical + // properties, calling applyMask(m) twice with the same value is equivalent to no change at all. + // This means it is possible to apply a mask, undo it, and try another mask. Note that a final + // well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). + void applyMask(int mask); + + + // A messy helper function for the constructors. This QR Code must be in an unmasked state when this + // method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed. + // This method applies and returns the actual mask chosen, from 0 to 7. + int handleConstructorMasking(int mask); + + + // Calculates and returns the penalty score based on state of this QR Code's current modules. + // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. + int getPenaltyScore() const; + + + + /*---- Private static helper functions ----*/ +private: + + // Returns a set of positions of the alignment patterns in ascending order. These positions are + // used on both the x and y axes. Each value in the resulting array is in the range [0, 177). + // This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes. + static std::vector getAlignmentPatternPositions(int ver); + + + // Returns the number of raw data modules (bits) available at the given version number. + // These data modules are used for both user data codewords and error correction codewords. + // This stateless pure function could be implemented as a 40-entry lookup table. + static int getNumRawDataModules(int ver); + + + // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any + // QR Code of the given version number and error correction level, with remainder bits discarded. + // This stateless pure function could be implemented as a (40*4)-cell lookup table. + static int getNumDataCodewords(int ver, const Ecc &ecl); + + + /*---- Private tables of constants ----*/ +private: + + // For use in getPenaltyScore(), when evaluating which mask is best. + static const int PENALTY_N1; + static const int PENALTY_N2; + static const int PENALTY_N3; + static const int PENALTY_N4; + + static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4][41]; + static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41]; + + + + /*---- Private helper class ----*/ +private: + + /* + * Computes the Reed-Solomon error correction codewords for a sequence of data codewords + * at a given degree. Objects are immutable, and the state only depends on the degree. + * This class exists because the divisor polynomial does not need to be recalculated for every input. + */ + class ReedSolomonGenerator { + + /*-- Immutable field --*/ + private: + + // Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which + // is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. + std::vector coefficients; + + + /*-- Constructor --*/ + public: + + /* + * Creates a Reed-Solomon ECC generator for the given degree. This could be implemented + * as a lookup table over all possible parameter values, instead of as an algorithm. + */ + ReedSolomonGenerator(int degree); + + + /*-- Method --*/ + public: + + /* + * Computes and returns the Reed-Solomon error correction codewords for the given sequence of data codewords. + * The returned object is always a new byte array. This method does not alter this object's state (because it is immutable). + */ + std::vector getRemainder(const std::vector &data) const; + + + /*-- Static function --*/ + private: + + // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result + // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. + static uint8_t multiply(uint8_t x, uint8_t y); + + }; + +}; + +} diff --git a/libraries/QRCode/tests/QrSegment.cpp b/libraries/QRCode/tests/QrSegment.cpp new file mode 100644 index 00000000..2ae22428 --- /dev/null +++ b/libraries/QRCode/tests/QrSegment.cpp @@ -0,0 +1,173 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#include +#include "BitBuffer.hpp" +#include "QrSegment.hpp" + + +qrcodegen::QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) : + modeBits(mode) { + numBitsCharCount[0] = cc0; + numBitsCharCount[1] = cc1; + numBitsCharCount[2] = cc2; +} + + +int qrcodegen::QrSegment::Mode::numCharCountBits(int ver) const { + if ( 1 <= ver && ver <= 9) return numBitsCharCount[0]; + else if (10 <= ver && ver <= 26) return numBitsCharCount[1]; + else if (27 <= ver && ver <= 40) return numBitsCharCount[2]; + else throw "Version number out of range"; +} + + +const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::NUMERIC (0x1, 10, 12, 14); +const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13); +const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::BYTE (0x4, 8, 16, 16); +const qrcodegen::QrSegment::Mode qrcodegen::QrSegment::Mode::KANJI (0x8, 8, 10, 12); + + + +qrcodegen::QrSegment qrcodegen::QrSegment::makeBytes(const std::vector &data) { + return QrSegment(Mode::BYTE, data.size(), data, data.size() * 8); +} + + +qrcodegen::QrSegment qrcodegen::QrSegment::makeNumeric(const char *digits) { + BitBuffer bb; + int accumData = 0; + int accumCount = 0; + int charCount = 0; + for (; *digits != '\0'; digits++, charCount++) { + char c = *digits; + if (c < '0' || c > '9') + throw "String contains non-numeric characters"; + accumData = accumData * 10 + (c - '0'); + accumCount++; + if (accumCount == 3) { + bb.appendBits(accumData, 10); + accumData = 0; + accumCount = 0; + } + } + if (accumCount > 0) // 1 or 2 digits remaining + bb.appendBits(accumData, accumCount * 3 + 1); + return QrSegment(Mode::NUMERIC, charCount, bb.getBytes(), bb.getBitLength()); +} + + +qrcodegen::QrSegment qrcodegen::QrSegment::makeAlphanumeric(const char *text) { + BitBuffer bb; + int accumData = 0; + int accumCount = 0; + int charCount = 0; + for (; *text != '\0'; text++, charCount++) { + char c = *text; + if (c < ' ' || c > 'Z') + throw "String contains unencodable characters in alphanumeric mode"; + accumData = accumData * 45 + ALPHANUMERIC_ENCODING_TABLE[c - ' ']; + accumCount++; + if (accumCount == 2) { + bb.appendBits(accumData, 11); + accumData = 0; + accumCount = 0; + } + } + if (accumCount > 0) // 1 character remaining + bb.appendBits(accumData, 6); + return QrSegment(Mode::ALPHANUMERIC, charCount, bb.getBytes(), bb.getBitLength()); +} + + +std::vector qrcodegen::QrSegment::makeSegments(const char *text) { + // Select the most efficient segment encoding automatically + std::vector result; + if (*text == '\0'); // Leave the vector empty + else if (QrSegment::isNumeric(text)) + result.push_back(QrSegment::makeNumeric(text)); + else if (QrSegment::isAlphanumeric(text)) + result.push_back(QrSegment::makeAlphanumeric(text)); + else { + std::vector bytes; + for (; *text != '\0'; text++) + bytes.push_back(static_cast(*text)); + result.push_back(QrSegment::makeBytes(bytes)); + } + return result; +} + + +qrcodegen::QrSegment::QrSegment(const Mode &md, int numCh, const std::vector &b, int bitLen) : + mode(md), + numChars(numCh), + data(b), + bitLength(bitLen) { + if (numCh < 0 || bitLen < 0 || b.size() != static_cast((bitLen + 7) / 8)) + throw "Invalid value"; +} + + +int qrcodegen::QrSegment::getTotalBits(const std::vector &segs, int version) { + if (version < 1 || version > 40) + throw "Version number out of range"; + int result = 0; + for (size_t i = 0; i < segs.size(); i++) { + const QrSegment &seg(segs.at(i)); + int ccbits = seg.mode.numCharCountBits(version); + // Fail if segment length value doesn't fit in the length field's bit-width + if (seg.numChars >= (1 << ccbits)) + return -1; + result += 4 + ccbits + seg.bitLength; + } + return result; +} + + +bool qrcodegen::QrSegment::isAlphanumeric(const char *text) { + for (; *text != '\0'; text++) { + char c = *text; + if (c < ' ' || c > 'Z' || ALPHANUMERIC_ENCODING_TABLE[c - ' '] == -1) + return false; + } + return true; +} + + +bool qrcodegen::QrSegment::isNumeric(const char *text) { + for (; *text != '\0'; text++) { + char c = *text; + if (c < '0' || c > '9') + return false; + } + return true; +} + + +const int8_t qrcodegen::QrSegment::ALPHANUMERIC_ENCODING_TABLE[59] = { + // SP, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, // ASCII codes 32 to 64 + 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, -1, // Array indices 0 to 32 + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, // Array indices 33 to 58 + // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, // ASCII codes 65 to 90 +}; diff --git a/libraries/QRCode/tests/QrSegment.hpp b/libraries/QRCode/tests/QrSegment.hpp new file mode 100644 index 00000000..87ac55cc --- /dev/null +++ b/libraries/QRCode/tests/QrSegment.hpp @@ -0,0 +1,170 @@ +/* + * QR Code generator library (C++) + * + * Copyright (c) Project Nayuki + * https://www.nayuki.io/page/qr-code-generator-library + * + * (MIT License) + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +#pragma once + +#include +#include + + +namespace qrcodegen { + +/* + * Represents a character string to be encoded in a QR Code symbol. Each segment has + * a mode, and a sequence of characters that is already encoded as a sequence of bits. + * Instances of this class are immutable. + * This segment class imposes no length restrictions, but QR Codes have restrictions. + * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. + * Any segment longer than this is meaningless for the purpose of generating QR Codes. + */ +class QrSegment { + + /*---- Public helper enumeration ----*/ + + /* + * The mode field of a segment. Immutable. Provides methods to retrieve closely related values. + */ +public: + class Mode { + + /*-- Constants --*/ + public: + + static const Mode NUMERIC; + static const Mode ALPHANUMERIC; + static const Mode BYTE; + static const Mode KANJI; + + + /*-- Fields --*/ + + /* (Package-private) An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object. */ + public: + const int modeBits; + + private: + int numBitsCharCount[3]; + + + /*-- Constructor --*/ + + private: + Mode(int mode, int cc0, int cc1, int cc2); + + + /*-- Method --*/ + + /* + * (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number. + */ + public: + int numCharCountBits(int ver) const; + + }; + + + + /*---- Public static factory functions ----*/ +public: + + /* + * Returns a segment representing the given binary data encoded in byte mode. + */ + static QrSegment makeBytes(const std::vector &data); + + + /* + * Returns a segment representing the given string of decimal digits encoded in numeric mode. + */ + static QrSegment makeNumeric(const char *digits); + + + /* + * Returns a segment representing the given text string encoded in alphanumeric mode. The characters allowed are: + * 0 to 9, A to Z (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ + static QrSegment makeAlphanumeric(const char *text); + + + /* + * Returns a list of zero or more segments to represent the given text string. + * The result may use various segment modes and switch modes to optimize the length of the bit stream. + */ + static std::vector makeSegments(const char *text); + + + /*---- Public static helper functions ----*/ +public: + + /* + * Tests whether the given string can be encoded as a segment in alphanumeric mode. + */ + static bool isAlphanumeric(const char *text); + + + /* + * Tests whether the given string can be encoded as a segment in numeric mode. + */ + static bool isNumeric(const char *text); + + + + /*---- Instance fields ----*/ +public: + + /* The mode indicator for this segment. */ + const Mode mode; + + /* The length of this segment's unencoded data, measured in characters. Always zero or positive. */ + const int numChars; + + /* The bits of this segment packed into a byte array in big endian. */ + const std::vector data; + + /* The length of this segment's encoded data, measured in bits. Satisfies ceil(bitLength / 8) = data.size(). */ + const int bitLength; + + + /*---- Constructor ----*/ +public: + + /* + * Creates a new QR Code data segment with the given parameters and data. + */ + QrSegment(const Mode &md, int numCh, const std::vector &b, int bitLen); + + + // Package-private helper function. + static int getTotalBits(const std::vector &segs, int version); + + + /*---- Private constant ----*/ +private: + + /* Maps shifted ASCII codes to alphanumeric mode character codes. */ + static const int8_t ALPHANUMERIC_ENCODING_TABLE[59]; + +}; + +} diff --git a/libraries/QRCode/tests/README.md b/libraries/QRCode/tests/README.md new file mode 100644 index 00000000..ce157a3e --- /dev/null +++ b/libraries/QRCode/tests/README.md @@ -0,0 +1,12 @@ +Testing +======= + +The testcases work by using the Nayuki QR code generating library, generating a QR code +in both libraries and comparing them. + +Running +------- + +``` +./run.sh +``` diff --git a/libraries/QRCode/tests/run-tests.cpp b/libraries/QRCode/tests/run-tests.cpp new file mode 100644 index 00000000..13565d4a --- /dev/null +++ b/libraries/QRCode/tests/run-tests.cpp @@ -0,0 +1,85 @@ +#include +#include + +#include "../src/qrcode.h" +#include "QrCode.hpp" + +static uint32_t check(const qrcodegen::QrCode &nayuki, QRCode *ricmoo) { + uint32_t wrong = 0; + + if (nayuki.size != ricmoo->size) { wrong += (1 << 20); } + + int border = 4; + for (int y = -border; y < nayuki.size + border; y++) { + for (int x = -border; x < nayuki.size + border; x++) { + if (!!nayuki.getModule(x, y) != qrcode_getModule(ricmoo, x, y)) { + wrong++; + } + } + } + + return wrong; +} + +int main() { + std::clock_t t0, totalNayuki, totalRicMoo; + + int total = 0, passed = 0; + for (char version = 1; version <= 40; version++) { + if (LOCK_VERSION != 0 && LOCK_VERSION != version) { continue; } + + for (char ecc = 0; ecc < 4; ecc++) { + const qrcodegen::QrCode::Ecc *errCorLvl; + switch (ecc) { + case 0: + errCorLvl = &qrcodegen::QrCode::Ecc::LOW; + break; + case 1: + errCorLvl = &qrcodegen::QrCode::Ecc::MEDIUM; + break; + case 2: + errCorLvl = &qrcodegen::QrCode::Ecc::QUARTILE; + break; + case 3: + errCorLvl = &qrcodegen::QrCode::Ecc::HIGH; + break; + } + + for (char tc = 0; tc < 3; tc++) { + char *data; + switch(tc) { + case 0: + data = (char*)"HELLO"; + break; + case 1: + data = (char*)"Hello"; + break; + case 2: + data = (char*)"1234"; + break; + } + t0 = std::clock(); + const qrcodegen::QrCode nayuki = qrcodegen::QrCode::encodeText(data, version, *errCorLvl); + totalNayuki += std::clock() - t0; + + t0 = std::clock(); + QRCode ricmoo; + uint8_t ricmooBytes[qrcode_getBufferSize(version)]; + qrcode_initText(&ricmoo, ricmooBytes, version, ecc, data); + totalRicMoo += std::clock() - t0; + + uint32_t badModules = check(nayuki, &ricmoo); + if (badModules) { + printf("Failed test case: version=%d, ecc=%d, data=\"%s\", faliured=%d\n", version, ecc, data, badModules); + } else { + passed++; + } + + total++; + } + } + } + + printf("Tests complete: %d passed (out of %d)\n", passed, total); + printf("Timing: Nayuki=%lu, RicMoo=%lu\n", totalNayuki, totalRicMoo); +} diff --git a/libraries/QRCode/tests/run.sh b/libraries/QRCode/tests/run.sh new file mode 100644 index 00000000..ff7be5fb --- /dev/null +++ b/libraries/QRCode/tests/run.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +clang++ run-tests.cpp QrCode.cpp QrSegment.cpp BitBuffer.cpp ../src/qrcode.c -o test && ./test +clang++ run-tests.cpp QrCode.cpp QrSegment.cpp BitBuffer.cpp ../src/qrcode.c -o test -D LOCK_VERSION=3 && ./test + From bd75f600dd515026a2878c08e3f8cc814e7f23d5 Mon Sep 17 00:00:00 2001 From: Anuj Pathak Date: Thu, 18 Jan 2024 10:33:09 +0530 Subject: [PATCH 7/7] typec2.1 --- README.md | 6 ++ boards.txt | 32 ++++++++ libraries/BEINK/BEINK.cpp | 4 +- .../BEINK/examples/beink_demo/beink_demo.ino | 4 +- variants/I.ONIX_TypeC2.1/pins_arduino.h | 17 ++++ variants/I.ONIX_TypeC2.1/variant.cpp | 55 +++++++++++++ variants/I.ONIX_TypeC2.1/variant.h | 77 +++++++++++++++++++ variants/I.ONIX_TypeC2/variant.h | 1 + 8 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 variants/I.ONIX_TypeC2.1/pins_arduino.h create mode 100644 variants/I.ONIX_TypeC2.1/variant.cpp create mode 100644 variants/I.ONIX_TypeC2.1/variant.h diff --git a/README.md b/README.md index 0595d25f..08e90101 100644 --- a/README.md +++ b/README.md @@ -223,3 +223,9 @@ The following tools are used: * [GCC ARM Embedded](https://launchpad.net/gcc-arm-embedded) as the compiler * A [forked](https://github.com/sandeepmistry/openocd-code-nrf5) version of [OpenOCD](http://openocd.org) to flash sketches + + +openocd.exe -d2 -f interface/stlink-v2.cfg -f target/nrf52.cfg -c "transport select hla_swd; set WORKAREASIZE 0x4000;" -c "init; halt; nrf51 mass_erase; program s132_nrf52_2.0.1_softdevice.hex; reset; exit;" +openocd.exe -d2 -f interface/stlink-v2.cfg -f target/nrf52.cfg -c "transport select hla_swd; set WORKAREASIZE 0x4000;" -c "init; halt; program beink_demo.ino.I.ONIX_TypeC2.hex; reset; exit;" +openocd.exe -d2 -f interface/stlink-v2.cfg -f target/nrf52.cfg -c "transport select hla_swd; set WORKAREASIZE 0x4000;" -c "init; halt; program mprls_simple_test.ino.I.ONIX_TypeC2.hex; reset; exit;" +openocd.exe -d2 -f interface/stlink-v2.cfg -f target/nrf52.cfg -c "transport select hla_swd; set WORKAREASIZE 0x4000;" -c "init; halt; program sleep_wake_test.ino.I.ONIX_TypeC2.hex; reset; exit;" diff --git a/boards.txt b/boards.txt index 6ada89ca..5159040a 100644 --- a/boards.txt +++ b/boards.txt @@ -1224,3 +1224,35 @@ IonixTypeC2.menu.lfclk.lfrc=RC Oscillator IonixTypeC2.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC IonixTypeC2.menu.lfclk.lfsynt=Synthesized IonixTypeC2.menu.lfclk.lfsynt.build.lfclk_flags=-DUSE_LFSYNT + +IonixTypeC2_1.name=I.ONIX TypeC2.1 + +IonixTypeC2_1.upload.tool=sandeepmistry:openocd +IonixTypeC2_1.upload.target=nrf52 +IonixTypeC2_1.upload.maximum_size=524288 + +IonixTypeC2_1.bootloader.tool=sandeepmistry:openocd + +IonixTypeC2_1.build.mcu=cortex-m4 +IonixTypeC2_1.build.f_cpu=64000000 +IonixTypeC2_1.build.board=NRF52_DK +IonixTypeC2_1.build.core=nRF5 +IonixTypeC2_1.build.variant=I.ONIX_TypeC2.1 +IonixTypeC2_1.build.variant_system_lib= +IonixTypeC2_1.build.extra_flags=-DNRF52 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC2_1.build.float_flags=-mfloat-abi=hard -mfpu=fpv4-sp-d16 +IonixTypeC2_1.build.ldscript=nrf52_xxaa.ld + +IonixTypeC2_1.menu.softdevice.s132=S132 +IonixTypeC2_1.menu.softdevice.s132.softdevice=s132 +IonixTypeC2_1.menu.softdevice.s132.softdeviceversion=2.0.1 +IonixTypeC2_1.menu.softdevice.s132.upload.maximum_size=409600 +IonixTypeC2_1.menu.softdevice.s132.build.extra_flags=-DNRF52 -DS132 -DNRF51_S132 -DCONFIG_NFCT_PINS_AS_GPIOS +IonixTypeC2_1.menu.softdevice.s132.build.ldscript=armgcc_s132_nrf52832_xxaa.ld + +IonixTypeC2_1.menu.lfclk.lfxo=Crystal Oscillator +IonixTypeC2_1.menu.lfclk.lfxo.build.lfclk_flags=-DUSE_LFXO +IonixTypeC2_1.menu.lfclk.lfrc=RC Oscillator +IonixTypeC2_1.menu.lfclk.lfrc.build.lfclk_flags=-DUSE_LFRC +IonixTypeC2_1.menu.lfclk.lfsynt=Synthesized +IonixTypeC2_1.menu.lfclk.lfsynt.build.lfclk_flags=-DUSE_LFSYNT diff --git a/libraries/BEINK/BEINK.cpp b/libraries/BEINK/BEINK.cpp index 8795f7d2..1747e6ad 100644 --- a/libraries/BEINK/BEINK.cpp +++ b/libraries/BEINK/BEINK.cpp @@ -289,9 +289,9 @@ int BEINKClass::print_line(uint16_t pos_x, uint16_t pos_y, char *line) set_pixel_in_canvas(bit == 0, bit_pos_x, char_off_y, canvas_buf, canvas_width, canvas_height); } char_pixels += ((font->Width + 7) >> 3); - Serial.println(); + // Serial.println(); } - Serial.println(); + // Serial.println(); } // set_xy_window(pos_x >> 3, ((canvas_width + pos_x) >> 3) - 1, pos_y, pos_y + canvas_height - 1); diff --git a/libraries/BEINK/examples/beink_demo/beink_demo.ino b/libraries/BEINK/examples/beink_demo/beink_demo.ino index 66e2b492..e0c5c815 100644 --- a/libraries/BEINK/examples/beink_demo/beink_demo.ino +++ b/libraries/BEINK/examples/beink_demo/beink_demo.ino @@ -13,10 +13,12 @@ void setup() { Serial.begin(115200); - delay(5000); + // delay(5000); BEINK.turn_on(); Serial.println("BEINK START"); Serial.println("setting white"); + BEINK.clear(color_red); + BEINK.update(); BEINK.clear(color_white); Serial.println("white ready"); // diff --git a/variants/I.ONIX_TypeC2.1/pins_arduino.h b/variants/I.ONIX_TypeC2.1/pins_arduino.h new file mode 100644 index 00000000..3ef4d4a9 --- /dev/null +++ b/variants/I.ONIX_TypeC2.1/pins_arduino.h @@ -0,0 +1,17 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// API compatibility +#include "variant.h" diff --git a/variants/I.ONIX_TypeC2.1/variant.cpp b/variants/I.ONIX_TypeC2.1/variant.cpp new file mode 100644 index 00000000..02d405b6 --- /dev/null +++ b/variants/I.ONIX_TypeC2.1/variant.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + + This library 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 2.1 of the License, or (at your option) any later version. + + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" + +const uint32_t g_ADigitalPinMap[] = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 +}; diff --git a/variants/I.ONIX_TypeC2.1/variant.h b/variants/I.ONIX_TypeC2.1/variant.h new file mode 100644 index 00000000..e8c86b84 --- /dev/null +++ b/variants/I.ONIX_TypeC2.1/variant.h @@ -0,0 +1,77 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + This library 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 2.1 of the License, or (at your option) any later version. + This library 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_NRF52_DK_ +#define _VARIANT_NRF52_DK_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (32u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) + +// Serial +#define PIN_SERIAL_RX (24) +#define PIN_SERIAL_TX (22) + +// Wire +#define WIRE_INTERFACES_COUNT 1 +#define PIN_WIRE_SDA (6u) +#define PIN_WIRE_SCL (5u) + +// SPI +#define SPI_INTERFACES_COUNT 1 +#define PIN_SPI_MISO (12) +#define PIN_SPI_MOSI (14) +#define PIN_SPI_SCK (15) + +// USER NAMES +#define LP_BUZZ_PIN (11u) +#define LPCOMP_PIN (28u) +#define USR_BTN_PIN (25u) +#define BLUE_LED_PIN (23u) +#define MPR_VDD_CTRL_PIN (4u) +#define MPR_WIRE_SDA_PIN PIN_WIRE_SDA +#define MPR_WIRE_SCL_PIN PIN_WIRE_SCL +#define E_INK_BUSY_PIN (19u) +#define E_INK_RST_PIN (18u) +#define E_INK_DC_PIN (17u) +#define E_INK_CS_PIN (16u) +#define E_INK_SCL_PIN PIN_SPI_SCK +#define E_INK_SDA_PIN PIN_SPI_MOSI +#define E_INK_VDD_CTRL_PIN (13u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif diff --git a/variants/I.ONIX_TypeC2/variant.h b/variants/I.ONIX_TypeC2/variant.h index d208ab20..f75298cd 100644 --- a/variants/I.ONIX_TypeC2/variant.h +++ b/variants/I.ONIX_TypeC2/variant.h @@ -49,6 +49,7 @@ extern "C" { #define PIN_SPI_SCK (15) // USER NAMES +#define LP_BUZZ_PIN (11u) #define LPCOMP_PIN (26u) #define USR_BTN_PIN (25u) #define BLUE_LED_PIN (23u)