<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>NFC中的主题 Re: Current reading</title>
    <link>https://community.nxp.com/t5/NFC/Current-reading/m-p/914487#M5530</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Joohee&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Could you please look at the next community post.&lt;/P&gt;&lt;P&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/thread/504499"&gt;https://community.nxp.com/thread/504499&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Mario&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Wed, 03 Jul 2019 01:15:55 GMT</pubDate>
    <dc:creator>mario_castaneda</dc:creator>
    <dc:date>2019-07-03T01:15:55Z</dc:date>
    <item>
      <title>Current reading</title>
      <link>https://community.nxp.com/t5/NFC/Current-reading/m-p/914486#M5529</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;Hello, everyone.&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;I want to read the current of a sensor using the NHS 3152.&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;I already had a NHS 3152 starter kit.&amp;nbsp;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;NHS 3152 has a temperature sensor and android applications.&amp;nbsp;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;Therefore, I used this app_demo_dp_tlogger, and modify the code from measuring the temperature to current.&amp;nbsp;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;And, I want to receive the current level to my phone.&amp;nbsp;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;I have some questions.&amp;nbsp;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;First,&amp;nbsp;What parts should I change the code to read current instead the temperature?&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;&lt;STRONG&gt;[I2D code]&lt;/STRONG&gt;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;"&lt;SPAN class="" style="color: #604020;"&gt;int&lt;/SPAN&gt; i2dValue;&lt;/P&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;SPAN class="" style="color: #604020;"&gt;int&lt;/SPAN&gt; i2dNativeValue;&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00502.html#ga426cc484a31e59241f87215e5e452c56" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_IOCON_SetPinConfig&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga9f6e80f81c74d0d95a79e92ed670f1b3" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_IOCON&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00502.html#gga42905d0e658c71f0b5a26aac076744ccaaa8dab798188f438f1be2d78f9a92a38" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;IOCON_ANA0_4&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00502.html#ga21f911561fcda012327bf35bae68dcb6" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;IOCON_FUNC_1&lt;/A&gt;); &lt;SPAN class="" style="color: #800000;"&gt;/* Set pin function to analog */&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gad518b273bd146471c614acea2b1826ae" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_Init&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga3f980cfee3275ab3d70c40f6f82dad03" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_Setup&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gga3f226bc8872ea6ecf8d76db4f8aa0e97a5fac743cebde209eeddc3b3fafd2785f" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_SINGLE_SHOT&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gga5da253032922d07bec098c33ffbc1f26ae50f9dbfbad74bcf6a308fa843bd81f7" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_SCALER_GAIN_10_1&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ggaf9326ad36f93529cf1be391045434564aaedfc9aa118a5471f09834b6fe41bfb2" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_CONVERTER_GAIN_HIGH&lt;/A&gt;, 100);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga761880802e47268a34ee868e1662d467" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_SetMuxInput&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gga6c6de114cceca05c1e2999a122869cf9a6858c959edf8ab7f1478d8f25926379b" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_INPUT_ANA0_4&lt;/A&gt;);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga5613c4c5f56cb486cd8e47085c6c73bf" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_Start&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;SPAN class="" style="color: #e08000;"&gt;while&lt;/SPAN&gt; (!(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga6b80fd3aa5c1695b0b956e6db2a81ce7" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_ReadStatus&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;) &amp;amp; &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ggaac6212fbdcab54c14244b7cb119da0faabc0df1d9fe81a04a08f4cf6adcc7f783" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_STATUS_CONVERSION_DONE&lt;/A&gt;)) {&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;; &lt;SPAN class="" style="color: #800000;"&gt;/* wait */&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;}&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;i2dNativeValue = &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga4d49f11cb74f6827f73b10451f597431" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_GetValue&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;i2dValue = &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ga1634319f58abab7c85ce00b4f6da1d9d" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_NativeToPicoAmpere&lt;/A&gt;(i2dNativeValue, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gga5da253032922d07bec098c33ffbc1f26ae50f9dbfbad74bcf6a308fa843bd81f7" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_SCALER_GAIN_10_1&lt;/A&gt;, &lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#ggaf9326ad36f93529cf1be391045434564aaedfc9aa118a5471f09834b6fe41bfb2" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;I2D_CONVERTER_GAIN_HIGH&lt;/A&gt;, 100);&lt;/DIV&gt;&lt;DIV class="" style="color: #000000; text-indent: -53px; padding-left: 53px;"&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00500.html#gaeb5fd194c3f8e54b46a0172dbe91e3e8" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;Chip_I2D_DeInit&lt;/A&gt;(&lt;A _jive_internal="true" href="https://community.nxp.com/discussion/a00479.html#ga6a31945447a24a60c34be316b2d549df" style="color: #4665a2; font-weight: normal; text-decoration: none;"&gt;NSS_I2D&lt;/A&gt;);"&lt;/DIV&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;&lt;/P&gt;&lt;P style="color: #51626f; background-color: #ffffff; border: 0px; font-size: 14px;"&gt;[maintlogger code]&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt; * Copyright (c), NXP Semiconductors&lt;BR /&gt; * (C)NXP B.V. 2014-2018&lt;BR /&gt; * All rights are reserved. Reproduction in whole or in part is prohibited without&lt;BR /&gt; * the written consent of the copyright owner. NXP reserves the right to make&lt;BR /&gt; * changes without notice at any time. NXP makes no warranty, expressed, implied or&lt;BR /&gt; * statutory, including but not limited to any implied warranty of merchantability&lt;BR /&gt; * or fitness for any particular purpose, or that the use will not infringe any&lt;BR /&gt; * third party patent, copyright or trademark. NXP must not be liable for any loss&lt;BR /&gt; * or damage arising from its use.&lt;BR /&gt; */&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;#include &amp;lt;string.h&amp;gt;&lt;BR /&gt;#include "board.h"&lt;BR /&gt;#include "ndeft2t/ndeft2t.h"&lt;BR /&gt;#include "compress/compress.h"&lt;BR /&gt;#include "storage/storage.h"&lt;BR /&gt;#include "event/event.h"&lt;BR /&gt;#include "event_tag.h"&lt;BR /&gt;#include "temperature.h"&lt;BR /&gt;#include "msghandler.h"&lt;BR /&gt;#include "msghandler_protocol.h"&lt;BR /&gt;#include "memory.h"&lt;BR /&gt;#include "timer.h"&lt;BR /&gt;#include "validate.h"&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Use the define @c APP_MAINTAIN_SWD_CONNECTION to start debugging without the risk of losing the debug connection due&lt;BR /&gt; * to power-off or deep power down.&lt;BR /&gt; * When this is enabled, measurements are still taken according to the configuration, and communication is always&lt;BR /&gt; * possible, both via SWD and via NFC.&lt;BR /&gt; *&lt;BR /&gt; * Enable this in a debug build configuration only, and during development and debugging only!&lt;BR /&gt; *&lt;BR /&gt; * @c APP_MAINTAIN_SWD_CONNECTION can also be defined in your Project settings.&lt;BR /&gt; * Under LPCXPresso: Project &amp;gt; Properties &amp;gt; C/C++ Build &amp;gt; Settings &amp;gt; Tool Settings &amp;gt; MCU C Compiler &amp;gt; Symbols&lt;BR /&gt; * @note When this define is enabled, #APP_NO_MEASUREMENT_IN_NFC_FIELD is ignored.&lt;BR /&gt; */&lt;BR /&gt;#undef APP_MAINTAIN_SWD_CONNECTION&lt;BR /&gt;#if defined(APP_MAINTAIN_SWD_CONNECTION)&lt;BR /&gt; #define USEPLACEHOLDER false&lt;BR /&gt;#elif defined(APP_NO_MEASUREMENT_IN_NFC_FIELD)&lt;BR /&gt; #define USEPLACEHOLDER true&lt;BR /&gt;#else&lt;BR /&gt; #define USEPLACEHOLDER false&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * @def APP_NO_MEASUREMENT_IN_NFC_FIELD&lt;BR /&gt; * We can do a proper temperature measurement while in an NFC field, but the resulting value is not&lt;BR /&gt; * representative as the NFC field will heat up the IC quickly and significantly.&lt;BR /&gt; * Instead, a placeholder value can be used, but this requires careful interpretation on the host side.&lt;BR /&gt; * The define @c APP_NO_MEASUREMENT_IN_NFC_FIELD allows you to switch between two different approaches:&lt;BR /&gt; * - Always make a proper measurement regardless of the presence of the NFC field&lt;BR /&gt; * This is the default behavior.&lt;BR /&gt; * - Do _not_ make a measurement when an NFC field is present but instead store a placeholder value.&lt;BR /&gt; * Define @c APP_NO_MEASUREMENT_IN_NFC_FIELD in your Project settings.&lt;BR /&gt; * Under LPCXPresso: Project &amp;gt; Properties &amp;gt; C/C++ Build &amp;gt; Settings &amp;gt; Tool Settings &amp;gt; MCU C Compiler &amp;gt; Symbols&lt;BR /&gt; * Take care to add this to all build configurations you want them added to.&lt;BR /&gt; */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * @def BOARD_ENABLE_WAKEUP&lt;BR /&gt; * Define @c BOARD_ENABLE_WAKEUP in your board header file.&lt;BR /&gt; * This define serves two purposes:&lt;BR /&gt; * - We can accept a configuration, but defer logging until a start trigger is given. That trigger is either receiving a&lt;BR /&gt; * separate start command - #APP_MSG_ID_START - or detecting the WAKEUP pin is pulled low. The latter can be enabled&lt;BR /&gt; * or disabled.&lt;BR /&gt; * The define @c BOARD_ENABLE_WAKEUP allows you to switch between two different approaches:&lt;BR /&gt; * - When undefined: Do _not_ allow to start via the WAKEUP-pin.&lt;BR /&gt; * - When defined: Monitor the WAKEUP pin when a configuration as been given but the start is delayed indefinitely -&lt;BR /&gt; * using the parameter #APP_MSG_DELAY_START_INDEFINITELY. When the WAKEUP pin detects a low, a first measurement&lt;BR /&gt; * is made.&lt;BR /&gt; * .&lt;BR /&gt; * - The temperature logger Demo PCBs have a button attached to the WAKEUP pin. This define enables a check -&lt;BR /&gt; * performed at startup only - on the WAKEUP pin. When the pin is actively pulled low - by pushing the button and&lt;BR /&gt; * holding it down - execution is then paused until the pin is high again. The implementation is done in #ResetISR,&lt;BR /&gt; * and provides a break-in possibility for a debugger connected via SWD to halt the ARM core before the SWD&lt;BR /&gt; * functionality is (possibly) turned off in firmware.&lt;BR /&gt; * .&lt;BR /&gt; */&lt;/P&gt;&lt;P&gt;#if !(MEMORY_FIRSTUNUSEDEEPROMOFFSET &amp;lt; EVENT_EEPROM_FIRST_ROW*64)&lt;BR /&gt; #error The SW memory map as defined through the default diversity settings and those overridden in app_sel.h is wrong. Fix it.&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;#if !(EVENT_EEPROM_LAST_ROW &amp;lt; STORAGE_EEPROM_FIRST_ROW)&lt;BR /&gt; #error The SW memory map as defined through the default diversity settings and those overridden in app_sel.h is wrong. Fix it.&lt;BR /&gt;#endif&lt;BR /&gt;#if !(ALON_WORD_SIZE &amp;lt;= STORAGE_CONFIG_ALON_REGISTER)&lt;BR /&gt; #error The SW memory map as defined through the default diversity settings and those overridden in app_sel.h is wrong. Fix it.&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Just assign a reasonable number. It must accommodate for all the overhead that comes with the complete ndef&lt;BR /&gt; * message, plus it must be a multiple of 4.&lt;BR /&gt; */&lt;BR /&gt;#define MAX_COMMAND_MESSAGE_SIZE 0x44&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * In seconds.&lt;BR /&gt; * Allow the - assumed - corresponding host to issue a first command in the given time window.&lt;BR /&gt; * A few seconds also allows for easier grabbing hold of a debug session.&lt;BR /&gt; */&lt;BR /&gt;#define FIRST_HOST_TIMEOUT 3&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * In seconds.&lt;BR /&gt; * We're assuming the host will continually exchange commands and responses. If after some timeout no command&lt;BR /&gt; * has been received, we abort communication and shut down. When a field is still present, we will automatically&lt;BR /&gt; * wake up again from Deep Power Down and refresh the NFC shared memory with a new initial message.&lt;BR /&gt; * This way we prevent a possible hang-up when both sides are waiting indefinitely for an NDEF message to be&lt;BR /&gt; * written by the other side.&lt;BR /&gt; * No need to set the timeout too strict: set it reasonably long enough to never hamper any execution flow,&lt;BR /&gt; * while still being short enough to re-enable communication from a user perspective.&lt;BR /&gt; */&lt;BR /&gt;#define HOST_TIMEOUT 20&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * In seconds.&lt;BR /&gt; * From what was observed, the power off/power on/(re-)select sequence takes place in the order of a few 100ms&lt;BR /&gt; * at most. Waiting a full second seems more than enough to also take small changes in physical placement into&lt;BR /&gt; * account.&lt;BR /&gt; */&lt;BR /&gt;#define LAST_HOST_TIMEOUT 1&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * In seconds.&lt;BR /&gt; * No need to set the watchdog timeout too strict: set it long enough to never hamper any execution flow,&lt;BR /&gt; * while still being short enough to re-enable communication from a user perspective.&lt;BR /&gt; * Just ensure it is higher than #HOST_TIMEOUT.&lt;BR /&gt; */&lt;BR /&gt;#define WATCHDOG_TIMEOUT (HOST_TIMEOUT + 5)&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;void App_FieldStatusCb(bool isPresent);&lt;BR /&gt;void App_MsgAvailableCb(void);&lt;BR /&gt;void App_MsgReadCb(void);&lt;BR /&gt;int App_CompressCb(int eepromByteOffset, int bitCount, void * pOut);&lt;BR /&gt;int App_DecompressCb(const uint8_t * pData, int bitCount, void * pOut);&lt;/P&gt;&lt;P&gt;static void Init(void);&lt;BR /&gt;static void InitApp(void);&lt;BR /&gt;static void DeInit(const bool waitBeforeDisconnect);&lt;BR /&gt;static void ExecuteMeasurementMode(const bool usePlaceholder);&lt;BR /&gt;static bool ExecuteCommunicationMode(void);&lt;BR /&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt;static void CheckExternalTrigger(void);&lt;BR /&gt;#endif&lt;BR /&gt;static bool GenerateNextAutomaticCommand(void);&lt;/P&gt;&lt;P&gt;int main(void); /**&amp;lt; Application's main entry point. Declared here since it is referenced in ResetISR. */&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * - Set to @c true in #App_MsgAvailableCb when a new NDEF message is available.&lt;BR /&gt; * - Set to @c false in the loop #ExecuteCommunicationMode when the new NDEF message is read out.&lt;BR /&gt; * .&lt;BR /&gt; */&lt;BR /&gt;static volatile bool sMessageAvailable = false;&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * - Set to @c true in #App_MsgReadCb when a current NDEF message in NCF shared memory is read by the NFC tag reader.&lt;BR /&gt; * - Set to @c false in the loop #ExecuteCommunicationMode when the new NDEF message is written.&lt;BR /&gt; */&lt;BR /&gt;static volatile bool sMessageRead = false;&lt;/P&gt;&lt;P&gt;/** Set to @c true to reset the command sequence as generated by #GenerateNextAutomaticCommand */&lt;BR /&gt;static bool sResetAutomaticCommandGeneration = true;&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Handler for (ARM) Reset Interrupt.&lt;BR /&gt; * Implements and overrides the WEAK function in the startup module.&lt;BR /&gt; */&lt;BR /&gt;void ResetISR(void)&lt;BR /&gt;{&lt;BR /&gt; /* Increasing the system clock as soon as possible to reduce the startup time:&lt;BR /&gt; * the NFC tag reader times out&lt;BR /&gt; * - on Android after ~40ms (although some phones will wait up to 100 ms)&lt;BR /&gt; * - on iOS after ~16ms&lt;BR /&gt; *&lt;BR /&gt; * Setting the clock to 2MHz is the maximum: when&lt;BR /&gt; * - running without a battery&lt;BR /&gt; * - at 4MHz&lt;BR /&gt; * - when the field is provided by some phones (e.g. S5)&lt;BR /&gt; * a voltage drop to below 1.2V was observed - effectively resetting the chip.&lt;BR /&gt; */&lt;BR /&gt; Chip_Clock_System_SetClockFreq(2 * 1000 * 1000);&lt;/P&gt;&lt;P&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt; /* Chip nor board library have been initialized yet. We therefore directly use the registers. */&lt;BR /&gt; NSS_SYSCON-&amp;gt;SYSAHBCLKCTRL |= CLOCK_PERIPHERAL_IOCON; /* Enable the IOCON clock. */&lt;BR /&gt; NSS_SYSCON-&amp;gt;SYSAHBCLKCTRL |= CLOCK_PERIPHERAL_GPIO; /* Enable the GPIO clock. */&lt;BR /&gt; NSS_IOCON-&amp;gt;REG[0] = (IOCON_FUNC_0 | IOCON_RMODE_PULLUP); /* Enable pull-up on the WAKEUP pin (0). */&lt;BR /&gt; NSS_GPIO-&amp;gt;DIR &amp;amp;= ~(1UL &amp;lt;&amp;lt; 0); /* Just to be sure: configure the WAKEUP pin (0) as input. */&lt;BR /&gt; while (!(NSS_GPIO-&amp;gt;DATA[1 &amp;lt;&amp;lt; 0])) {&lt;BR /&gt; ; /* Wait for as long as the WAKEUP pin (0) is low. */&lt;BR /&gt; }&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;Startup_VarInit();&lt;BR /&gt; main();&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt;/**&lt;BR /&gt; * Handler for PIO0_0 / WAKEUP pin.&lt;BR /&gt; * Implements and overrides the WEAK function in the startup module.&lt;BR /&gt; */&lt;BR /&gt;void PIO0_0_IRQHandler(void)&lt;BR /&gt;{&lt;BR /&gt; Chip_SysCon_StartLogic_ClearStatus(SYSCON_STARTSOURCE_PIO0_0);&lt;BR /&gt; if (Memory_IsReadyToStart()) {&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_STARTING);&lt;BR /&gt; /* Configure the time to make a first measurement: start the RTC-down counter.&lt;BR /&gt; * A first measurement will then be made in the main context, not under this interrupt.&lt;BR /&gt; * Cheat a bit: assume 'within 1 second' is as good as 'immediately'.&lt;BR /&gt; */&lt;BR /&gt; Timer_StartMeasurementTimeout(1);&lt;BR /&gt; }&lt;BR /&gt;}&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Called under interrupt.&lt;BR /&gt; * @see NDEFT2T_FIELD_STATUS_CB&lt;BR /&gt; * @see pNdeft2t_FieldStatus_Cb_t&lt;BR /&gt; */&lt;BR /&gt;void App_FieldStatusCb(bool isPresent)&lt;BR /&gt;{&lt;BR /&gt; if (isPresent) {&lt;BR /&gt; Timer_StartHostTimeout(HOST_TIMEOUT);&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; /* A PCD (Proximity Coupled Device, i.e. the NFC tag reader) can do very strange things, a.o. power off the&lt;BR /&gt; * field and immediately power on the field again, or 10+ times select the same device as part of its illogic&lt;BR /&gt; * procedure to select a PICC (Proximity Integrated Circuit Card, i.e. the NFC tag) and start communicating&lt;BR /&gt; * with it. (I'm primarily pointing to NFC-enabled Android phones now.)&lt;BR /&gt; * Instead of deciding to Power-off or go to Deep Power Down immediately, it is more robust to additionally&lt;BR /&gt; * check if during a small interval no NFC field is started again.&lt;BR /&gt; * The loop in ExecuteCommunicationMode() may thus not look at the NFC interrupt status, but at the result of&lt;BR /&gt; * the timer interrupt.&lt;BR /&gt; */&lt;BR /&gt; Timer_StartHostTimeout(LAST_HOST_TIMEOUT);&lt;BR /&gt; }&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Called under interrupt.&lt;BR /&gt; * @see NDEFT2T_MSG_AVAILABLE_CB&lt;BR /&gt; * @see pNdeft2t_MsgAvailable_Cb_t&lt;BR /&gt; */&lt;BR /&gt;void App_MsgAvailableCb(void)&lt;BR /&gt;{&lt;BR /&gt; sMessageAvailable = true;&lt;BR /&gt; Timer_StartHostTimeout(HOST_TIMEOUT);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Called under interrupt.&lt;BR /&gt; * @see NDEFT2T_MSG_READ_CB&lt;BR /&gt; * @see pNdeft2t_MsgRead_Cb_t&lt;BR /&gt; */&lt;BR /&gt;void App_MsgReadCb(void)&lt;BR /&gt;{&lt;BR /&gt; sMessageRead = true;&lt;BR /&gt; Timer_StartHostTimeout(HOST_TIMEOUT);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Connects the compress module with the storage module. Provides compression of data.&lt;BR /&gt; * @see STORAGE_COMPRESS_CB&lt;BR /&gt; * @see pStorage_CompressCb_t&lt;BR /&gt; */&lt;BR /&gt;int App_CompressCb(int eepromByteOffset, int bitCount, void * pOut)&lt;BR /&gt;{&lt;BR /&gt; ASSERT(bitCount == STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS);&lt;BR /&gt; (void)bitCount; /* suppress [-Wunused-parameter]: its value is known to be STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS. */&lt;BR /&gt; uint8_t data[STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES];&lt;BR /&gt; Chip_EEPROM_Read(NSS_EEPROM, eepromByteOffset, data, STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES);&lt;BR /&gt; int length = Compress_Encode(data, STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES, pOut, STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES);&lt;BR /&gt; return length * 8;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Connects the compress module with the storage module. Provides decompression of data.&lt;BR /&gt; * @see STORAGE_DECOMPRESS_CB&lt;BR /&gt; * @see pStorage_DecompressCb_t&lt;BR /&gt; */&lt;BR /&gt;int App_DecompressCb(const uint8_t * pData, int bitCount, void * pOut)&lt;BR /&gt;{&lt;BR /&gt; int length = Compress_Decode(pData, STORAGE_IDIVUP(bitCount, 8), pOut, STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES);&lt;BR /&gt; return (length == STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES) ? STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS : 0;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/* ------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * - Initializes drivers and modules. Initialization is expected to be done once per complete active lifetime.&lt;BR /&gt; * - Calls #InitApp.&lt;BR /&gt; * .&lt;BR /&gt; */&lt;BR /&gt;static void Init(void)&lt;BR /&gt;{&lt;BR /&gt; Board_Init();&lt;/P&gt;&lt;P&gt;#ifndef DEBUG&lt;BR /&gt; Chip_WWDT_Start(WATCHDOG_TIMEOUT);&lt;BR /&gt; /* The watchdog will be fed - by calling Chip_WWDT_Feed - in ExecuteCommunicationMode in a while loop when the NFC&lt;BR /&gt; * field is present. A reset will then occur when in either the main contect or in an interrupt too many seconds are&lt;BR /&gt; * spent, i.e. when it is stuck somewhere.&lt;BR /&gt; */&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;(void)Temperature_Measure(TSEN_7BITS, false);&lt;/P&gt;&lt;P&gt;Chip_NFC_Init(NSS_NFC);&lt;BR /&gt; NDEFT2T_Init();&lt;BR /&gt; Chip_EEPROM_Init(NSS_EEPROM);&lt;/P&gt;&lt;P&gt;Timer_Init();&lt;BR /&gt; InitApp();&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Initializes and configures APP modules. Initialization is expected to be done multiple times per complete active&lt;BR /&gt; * lifetime (always going through the cycle @c #DeInitAp - @c InitApp) when #APP_MAINTAIN_SWD_CONNECTION is defined.&lt;BR /&gt; */&lt;BR /&gt;static void InitApp(void)&lt;BR /&gt;{&lt;BR /&gt; bool accepted = Memory_Init();&lt;BR /&gt; AppMsgInit(accepted);&lt;/P&gt;&lt;P&gt;sResetAutomaticCommandGeneration = true;&lt;BR /&gt; /* Trigger the generation of a multi-record message as initial response. Do this unconditionally:&lt;BR /&gt; * - it's a tiny bit faster&lt;BR /&gt; * - it will allow tag readers who tap later, while the IC is still awake, to start the communication properly.&lt;BR /&gt; */&lt;BR /&gt; GenerateNextAutomaticCommand();&lt;/P&gt;&lt;P&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt; if (Memory_IsReadyToStart()) {&lt;BR /&gt; NVIC_EnableIRQ(PIO0_0_IRQn); /* PIO0_0_IRQHandler is called when this interrupt fires. */&lt;BR /&gt; Chip_SysCon_StartLogic_SetEnabledMask(SYSCON_STARTSOURCE_PIO0_0);&lt;BR /&gt; }&lt;BR /&gt;#endif&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * De-initializes APP modules. De-Initialization is expected to be done multiple times per complete active&lt;BR /&gt; * lifetime (always going through the cycle @c DeInitApp - #InitApp) when #APP_MAINTAIN_SWD_CONNECTION is defined.&lt;BR /&gt; */&lt;BR /&gt;static void DeInitApp(void)&lt;BR /&gt;{&lt;BR /&gt; Memory_DeInit();&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * - Calls #DeInitApp&lt;BR /&gt; * - Cleanly closes everything down, decides which low power state to go to - Deep Power Down or Power-off, and enters&lt;BR /&gt; * that state using the correctly determined parameters.&lt;BR /&gt; * .&lt;BR /&gt; * @note Wake-up conditions other than a reset pulse or the presence of an NFC field - both of which cannot be disabled&lt;BR /&gt; * nor require configuration - must have been set beforehand.&lt;BR /&gt; * @param waitBeforeDisconnect Present to aid the SW developer. If @c true, it will wait - not sleep - for a couple of&lt;BR /&gt; * seconds before disconnecting the battery. The argument has no effect if Deep Power Down mode is selected.&lt;BR /&gt; * The extra time window allows for easier breaking in using SWD, allowing time to halt the core and flash new&lt;BR /&gt; * firmware. However, it will @c not touch any PIO, or ensure that SWD functionality is offered.&lt;BR /&gt; * The default value should be @c false, i.e. go to Power-off state without delay: typical user behavior is to bring&lt;BR /&gt; * the IC in and out the NFC field quickly, before stabilizing on a correct position. Having a time penalty of several&lt;BR /&gt; * seconds - during which the host SW may already have made several decisions about the use and state of the IC -&lt;BR /&gt; * diminishes the user experience.&lt;BR /&gt; */&lt;BR /&gt;static void DeInit(const bool waitBeforeDisconnect)&lt;BR /&gt;{&lt;BR /&gt; /* Before (possibly) going to DPD mode, we need to determine whether switching must be enabled. We enable switching&lt;BR /&gt; * when the battery is low, to ensure we can use the NFC interface as power supply in case the battery dies while&lt;BR /&gt; * in DPD mode.&lt;BR /&gt; * It is assumed that when the BOD detector indicates a battery voltage of 1.8 V or higher, the time spent in DPD&lt;BR /&gt; * mode is not enough to drain the battery to a value below 1.72 V.&lt;BR /&gt; */&lt;BR /&gt; bool bod;&lt;BR /&gt; Chip_PMU_SetBODEnabled(true);&lt;BR /&gt; bod = ((Chip_PMU_GetStatus() &amp;amp; PMU_STATUS_BROWNOUT) != 0);&lt;BR /&gt; Chip_PMU_SetBODEnabled(false);&lt;BR /&gt; if (bod) {&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_BOD);&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;bool isReadyToStart = Memory_IsReadyToStart();&lt;BR /&gt; bool isMonitoring = Memory_IsMonitoring();&lt;BR /&gt; bool isFull = Memory_IsFull();&lt;/P&gt;&lt;P&gt;DeInitApp();&lt;BR /&gt; Chip_EEPROM_DeInit(NSS_EEPROM);&lt;BR /&gt; NDEFT2T_DeInit();&lt;/P&gt;&lt;P&gt;if (isReadyToStart) {&lt;BR /&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt; Chip_PMU_SetWakeupPinEnabled(true);&lt;BR /&gt;#endif&lt;BR /&gt; Chip_PMU_PowerMode_EnterDeepPowerDown(bod);&lt;BR /&gt; /* This function never returns. */&lt;BR /&gt; }&lt;BR /&gt; else if (isMonitoring || isFull) {&lt;BR /&gt; /* When full, we still want to keep track of time. The timer is not stopped in ExecuteMeasurementMode when&lt;BR /&gt; * a measurement cannot be stored, so we will still wake up periodically (making a futile attempts at storing a&lt;BR /&gt; * new measurement), and can then decide on the correct argument value for&lt;BR /&gt; * Chip_PMU_PowerMode_EnterDeepPowerDown.&lt;BR /&gt; */&lt;BR /&gt; Chip_PMU_PowerMode_EnterDeepPowerDown(bod);&lt;BR /&gt; /* This function never returns. */&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; if (waitBeforeDisconnect) {&lt;BR /&gt; Chip_Clock_System_BusyWait_ms(3000); /* Give some extra time to intervene via SWD. */&lt;BR /&gt; }&lt;BR /&gt; Chip_PMU_Switch_OpenVDDBat();&lt;BR /&gt; /* Normally, this function never returns. However, when providing power via SWD or any other PIO this will not&lt;BR /&gt; * work - current is flowing through the bondpad ring via the SWD pin, still powering a small part of the&lt;BR /&gt; * VDD_ALON domain.&lt;BR /&gt; * This situation is not covered by HW design: we can't rely on anything being functional or even harmless.&lt;BR /&gt; * Just ensure nothing happens, and wait until all power is gone.&lt;BR /&gt; */&lt;BR /&gt; }&lt;BR /&gt; for(;;);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt;static void CheckExternalTrigger(void)&lt;BR /&gt;{&lt;BR /&gt; if (Memory_IsReadyToStart()) {&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_STARTING);&lt;BR /&gt; ExecuteMeasurementMode(false);&lt;BR /&gt; }&lt;BR /&gt;}&lt;BR /&gt;#endif&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * To be used in 'automatic' mode, where the NFC tag reader does not issue any command, but instead continually reads&lt;BR /&gt; * the NFC shared memory, expecting the firmware to timely update the contents. That is done by waiting for a 'message&lt;BR /&gt; * read' callback issued by NDEFT2T - #App_MsgReadCb, and then create a next command ourselves and feed it to&lt;BR /&gt; * #AppMsgHandleCommand.&lt;BR /&gt; * @return @c true when a command was generated and presented to #AppMsgHandleCommand; @c false otherwise.&lt;BR /&gt; * @note The generation of new commands can be reset by setting #sResetAutomaticCommandGeneration to @c true.&lt;BR /&gt; */&lt;BR /&gt;static bool GenerateNextAutomaticCommand(void)&lt;BR /&gt;{&lt;BR /&gt; static const uint8_t sGetConfigCommand[2] = {APP_MSG_ID_GETCONFIG, 0}; /* Used when sIndex &amp;lt;= 1 */&lt;BR /&gt; static const uint8_t sGetResponseCommand[2] = {MSG_ID_GETRESPONSE, 0}; /* Used when sIndex == 4 */&lt;BR /&gt; static uint8_t sGetMeasurementsCommand[4] = {APP_MSG_ID_GETMEASUREMENTS, 0, 0, 0}; /* Used when sIndex == 2 */&lt;BR /&gt; static int sIndex = 0;&lt;BR /&gt; static int sOffset = 0;&lt;/P&gt;&lt;P&gt;const uint8_t * pData;&lt;BR /&gt; int length;&lt;/P&gt;&lt;P&gt;if (sResetAutomaticCommandGeneration) {&lt;BR /&gt; sResetAutomaticCommandGeneration = false;&lt;BR /&gt; NDEFT2T_EnableAutomaticMode();&lt;BR /&gt; sIndex = 0;&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;switch (sIndex) {&lt;BR /&gt; case 0:&lt;BR /&gt; pData = sGetConfigCommand;&lt;BR /&gt; length = sizeof(sGetConfigCommand);&lt;/P&gt;&lt;P&gt;sOffset = Storage_GetCount(); /* Prepare the next call */&lt;BR /&gt; sIndex++;&lt;BR /&gt; break;&lt;/P&gt;&lt;P&gt;case 1:&lt;BR /&gt; /* See comment in App_FieldStatusCb. On Android, there are multiple NFC_INT_TARGETREAD interrupts before&lt;BR /&gt; * the low-level NFC selection process is finished and the NFC connection is kept stable on the tag reader&lt;BR /&gt; * side. For the ARM, this means it better keeps the first message stable until it can be sure&lt;BR /&gt; * the message has been read and handled by the final and intended application.&lt;BR /&gt; * After trial and error, it seems that allowing/enforcing one extra redundant read is a safe value.&lt;BR /&gt; */&lt;BR /&gt; pData = NULL;&lt;BR /&gt; length = 0;&lt;BR /&gt; sIndex++;&lt;BR /&gt; break;&lt;/P&gt;&lt;P&gt;case 2:&lt;BR /&gt; /* Correct offset for this call. */&lt;BR /&gt; if (sOffset &amp;gt;= APP_MSG_MAX_NR_OF_VALUES_IN_GETMEASUREMENTS_RESPONSE) {&lt;BR /&gt; sOffset -= APP_MSG_MAX_NR_OF_VALUES_IN_GETMEASUREMENTS_RESPONSE;&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; sOffset = 0;&lt;BR /&gt; }&lt;BR /&gt; sGetMeasurementsCommand[2] = (uint8_t)(sOffset &amp;amp; 0x00FF);&lt;BR /&gt; sGetMeasurementsCommand[3] = (uint8_t)((sOffset &amp;gt;&amp;gt; 8) &amp;amp; 0x00FF);&lt;BR /&gt; pData = sGetMeasurementsCommand;&lt;BR /&gt; length = sizeof(sGetMeasurementsCommand);&lt;BR /&gt; sIndex++;&lt;BR /&gt; break;&lt;/P&gt;&lt;P&gt;case 3:&lt;BR /&gt; /* For an unknown reason, immediately retrieving the next measurements will at times result in gaps:&lt;BR /&gt; * iOS logs will then show a read-out sequence of message ... n-2, n-1, n, n, n+2, n+3, ...&lt;BR /&gt; * The "easiest" solution is then to provide the data twice as slow.&lt;BR /&gt; */&lt;BR /&gt; pData = NULL;&lt;BR /&gt; length = 0;&lt;BR /&gt; /* Prepare the next call */&lt;BR /&gt; if (sOffset == 0) {&lt;BR /&gt; sIndex++;&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; sIndex--;&lt;BR /&gt; }&lt;BR /&gt; break;&lt;/P&gt;&lt;P&gt;case 4:&lt;BR /&gt; pData = sGetResponseCommand;&lt;BR /&gt; length = sizeof(sGetResponseCommand);&lt;BR /&gt; sIndex++;&lt;BR /&gt; break;&lt;/P&gt;&lt;P&gt;default:&lt;BR /&gt; pData = NULL;&lt;BR /&gt; length = 0;&lt;BR /&gt; break;&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;if (pData &amp;amp;&amp;amp; length) {&lt;BR /&gt; AppMsgHandleCommand(length, pData);&lt;BR /&gt; }&lt;BR /&gt; return (pData &amp;amp;&amp;amp; length);&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Perform all actions required when one measurement is due.&lt;BR /&gt; * @param usePlaceholder Indicates whether a placeholder must be stored (@c true) or a proper temperature measurement&lt;BR /&gt; * must be performed (@c false).&lt;BR /&gt; */&lt;BR /&gt;static void ExecuteMeasurementMode(const bool usePlaceholder)&lt;BR /&gt;{&lt;BR /&gt; /* Entering this function means we are logging or are about to make a first measurement. In the latter case the&lt;BR /&gt; * state is still APP_MSG_EVENT_STARTING. Calling the function below redundantly does no harm.&lt;BR /&gt; */&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_LOGGING);&lt;/P&gt;&lt;P&gt;/* First prepare the next wake-up moment. */&lt;BR /&gt; const MEMORY_CONFIG_T * config = Memory_GetConfig();&lt;BR /&gt; ASSERT(config-&amp;gt;status &amp;amp; APP_MSG_EVENT_LOGGING);&lt;BR /&gt; uint32_t startTime = 0;&lt;BR /&gt; Event_GetByTag(EVENT_TAG_LOGGING, (uint32_t)&amp;amp;startTime);&lt;BR /&gt; ASSERT(startTime != 0);&lt;BR /&gt; int elapsed = Chip_RTC_Time_GetValue(NSS_RTC) - (int)startTime;&lt;BR /&gt; /* runningTime: enter if running indefinitely.&lt;BR /&gt; * startTime: enter if logging state is not yet reached.&lt;BR /&gt; * elapsed: enter if time is not expired&lt;BR /&gt; */&lt;BR /&gt; if ((config-&amp;gt;cmd.runningTime == 0) || ((elapsed &amp;gt;= 0) &amp;amp;&amp;amp; (elapsed &amp;lt; (int)config-&amp;gt;cmd.runningTime))) {&lt;BR /&gt; /* The RTC consists of two timers. The down counter is used to leave Deep power down mode, but stops when it&lt;BR /&gt; * reaches 0. The up counter is never stopped. The time spent during booting, measuring temperature and&lt;BR /&gt; * reaching this point is not tracked by the down counter, but can be detected using the up counter.&lt;BR /&gt; * When we see an accumulated untracked time of more than 1 second (and thus we enter the if block below),&lt;BR /&gt; * we reduce the sleep time with 1 second. On average, we're then still on track.&lt;BR /&gt; *&lt;BR /&gt; * The check (deviation &amp;gt; 1) is performed as =&amp;gt; (elapsed - sampleCount * interval &amp;gt; 1)&lt;BR /&gt; */&lt;BR /&gt; int interval = (int)config-&amp;gt;cmd.interval;&lt;BR /&gt; if ((Storage_GetCount() * interval) + 1 &amp;lt; elapsed) {&lt;BR /&gt; if (interval &amp;gt; 1) {&lt;BR /&gt; interval--;&lt;BR /&gt; }&lt;BR /&gt; }&lt;BR /&gt; Timer_StartMeasurementTimeout(interval);&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; if (elapsed &amp;lt; 0) {&lt;BR /&gt; /* This block should never be entered: there is no logical scenario in which the program counter ends up in&lt;BR /&gt; * here. The only reason why elasped can be negative, is when the RTC timer got reset, which indicates a&lt;BR /&gt; * BOD or a reset pulse. In Memory_Init, this would then be detected, and the state adjusted accordingly:&lt;BR /&gt; * a call to this function would then never be triggered.&lt;BR /&gt; * Still, we're here now. And there is no sense in making further measurements. Just do nothing. Safest&lt;BR /&gt; * seems just to mark this end state and error condition - again, as it should be superfluous.&lt;BR /&gt; */&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_STOPPED | APP_MSG_EVENT_BOD);&lt;BR /&gt; }&lt;BR /&gt; else {&lt;BR /&gt; /* Enough time spent logging and monitoring. Do not schedule a new measurement. */&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_STOPPED | APP_MSG_EVENT_EXPIRED);&lt;BR /&gt; }&lt;BR /&gt; Timer_StopMeasurementTimeout();&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;/* Only now make the measurement. */&lt;BR /&gt; Temperature_Reset();&lt;BR /&gt; if (!usePlaceholder) {&lt;BR /&gt; Temperature_Measure(TSEN_10BITS, false);&lt;BR /&gt; }&lt;BR /&gt; int data = Temperature_Get();&lt;BR /&gt; if (Storage_Write((STORAGE_TYPE *)&amp;amp;data, 1) != 1) {&lt;BR /&gt; /* Either compression failed; either storage is full. */&lt;BR /&gt; Memory_AddToState(APP_MSG_EVENT_STOPPED | APP_MSG_EVENT_FULL);&lt;BR /&gt; /* There are two possibilities here:&lt;BR /&gt; * - either we just stop, save the battery and go to power-off. No need to stop the timer, since power-off is&lt;BR /&gt; * imminent.&lt;BR /&gt; * - Or we continue to keep track of time, in which case it is most prudent to still wake up periodically so we&lt;BR /&gt; * can decide correctly on the value of the enableSwitching parameter of Chip_PMU_PowerMode_EnterDeepPowerDown.&lt;BR /&gt; * Either way, no need to call Timer_StopMeasurementTimeout here.&lt;BR /&gt; */&lt;BR /&gt; }&lt;BR /&gt; if (!usePlaceholder) {&lt;BR /&gt; Validate_Temperature((STORAGE_TYPE)data);&lt;BR /&gt; }&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/**&lt;BR /&gt; * Implements a while loop, waiting for an NDEF message in the NFC shared memory. the Ndeft2t module is used for this.&lt;BR /&gt; * When a message is detected, it is parsed as a 'command' in the msg module and a response is written in the NFC shared&lt;BR /&gt; * memory.&lt;BR /&gt; * This function returns when either&lt;BR /&gt; * - no message is received in a reasonable time limit&lt;BR /&gt; * - at least one message has been received (and answered to), and later the NFC field is removed.&lt;BR /&gt; * @return @c true when at least one message has been received (valid or not); @c false otherwise.&lt;BR /&gt; * @note When the RTC down counter reaches zero, #ExecuteMeasurementMode is called.&lt;BR /&gt; */&lt;BR /&gt;static bool ExecuteCommunicationMode(void)&lt;BR /&gt;{&lt;BR /&gt; __attribute__ ((section(".noinit"))) __attribute__((aligned (4)))&lt;BR /&gt; static uint8_t sData[MAX_COMMAND_MESSAGE_SIZE];&lt;/P&gt;&lt;P&gt;__attribute__ ((section(".noinit"))) __attribute__((aligned (4)))&lt;BR /&gt; static uint8_t sNdefInstance[NDEFT2T_INSTANCE_SIZE];&lt;/P&gt;&lt;P&gt;bool messageReceived = false;&lt;/P&gt;&lt;P&gt;/* Safest is to just try to communicate. It will be stopped or restarted using the callbacks provided by the&lt;BR /&gt; * NDEFT2T module. By using Timer_CheckHostTimeout in the while loop below, the while loop will be&lt;BR /&gt; * stopped when the field has been removed.&lt;BR /&gt; */&lt;BR /&gt; Timer_StartHostTimeout(FIRST_HOST_TIMEOUT);&lt;/P&gt;&lt;P&gt;#ifndef DEBUG&lt;BR /&gt; Chip_WWDT_Feed();&lt;BR /&gt;#endif&lt;BR /&gt; /* Wait for a command. Send responses based on these commands. */&lt;BR /&gt; while (!Timer_CheckHostTimeout()) {&lt;BR /&gt; /* Do not call Chip_PMU_PowerMode_EnterSleep here: an interrupt can have occurred between the check above&lt;BR /&gt; * and the call below, resulting in an everlasting while loop.&lt;BR /&gt; */&lt;BR /&gt; if (sMessageAvailable) {&lt;BR /&gt; sMessageAvailable = false;&lt;BR /&gt; messageReceived = true;&lt;BR /&gt; if (NDEFT2T_GetMessage(sNdefInstance, sData, sizeof(sData))) {&lt;BR /&gt; const uint8_t * data;&lt;BR /&gt; int length;&lt;BR /&gt; NDEFT2T_PARSE_RECORD_INFO_T recordInfo;&lt;BR /&gt; while (NDEFT2T_GetNextRecord(sNdefInstance, &amp;amp;recordInfo)) {&lt;BR /&gt; if (recordInfo.type == NDEFT2T_RECORD_TYPE_MIME) {&lt;BR /&gt; data = NDEFT2T_GetRecordPayload(sNdefInstance, &amp;amp;length);&lt;BR /&gt; AppMsgHandleCommand(length, data);&lt;BR /&gt; }&lt;BR /&gt; }&lt;BR /&gt; }&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;if (sMessageRead) {&lt;BR /&gt; GenerateNextAutomaticCommand();&lt;BR /&gt; sMessageRead = false;&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;if (Timer_CheckMeasurementTimeout()) {&lt;BR /&gt; ExecuteMeasurementMode(USEPLACEHOLDER);&lt;BR /&gt; }&lt;BR /&gt;#ifndef DEBUG&lt;BR /&gt; if ((Chip_NFC_GetStatus(NSS_NFC) &amp;amp; NFC_STATUS_SEL) != 0) {&lt;BR /&gt; /* Only feed when NFC is still detected. This to avoid a hang where the while loop, checking on&lt;BR /&gt; * Timer_CheckHostTimeout is never ending.&lt;BR /&gt; */&lt;BR /&gt; Chip_WWDT_Feed();&lt;BR /&gt; }&lt;BR /&gt;#endif&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;return messageReceived;&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;/* -------------------------------------------------------------------------------- */&lt;/P&gt;&lt;P&gt;int main(void)&lt;BR /&gt;{&lt;BR /&gt; Init();&lt;/P&gt;&lt;P&gt;PMU_DPD_WAKEUPREASON_T wakeup = Chip_PMU_PowerMode_GetDPDWakeupReason();&lt;BR /&gt; bool waitBeforeDisconnect = (wakeup == PMU_DPD_WAKEUPREASON_NONE);&lt;BR /&gt; if (wakeup == PMU_DPD_WAKEUPREASON_RTC) {&lt;BR /&gt; ExecuteMeasurementMode(false);&lt;BR /&gt; }&lt;BR /&gt;#ifdef BOARD_ENABLE_WAKEUP&lt;BR /&gt; else if (wakeup == PMU_DPD_WAKEUPREASON_WAKEUPPIN) {&lt;BR /&gt; CheckExternalTrigger();&lt;BR /&gt; }&lt;BR /&gt;#endif&lt;BR /&gt; else {&lt;BR /&gt; /* An NFC field may be present, or not. There is no guaranteed way to detect this, since the case&lt;BR /&gt; * 'connecting the battery due to the presence of an NFC field' is not captured in a register, only&lt;BR /&gt; * 'leaving Deep Power Down due to the presence of an NFC field'.&lt;BR /&gt; * Also, the IC might be started due to a reset pulse, but an NFC field may now have become present.&lt;BR /&gt; * We can't also look at the momentary status, since if an NFC field is present and the NFC reader is in the&lt;BR /&gt; * process of selecting this IC, the field may be suspended for a few milliseconds just now.&lt;BR /&gt; * Or, it may be completely gone by now.&lt;BR /&gt; * There is too much uncertainty: safest is to just try to communicate.&lt;BR /&gt; */&lt;/P&gt;&lt;P&gt;#if defined(APP_MAINTAIN_SWD_CONNECTION)&lt;BR /&gt; /* Avoid the use the Deep Power Down and Power-off low-power states and maintain a debugging connection over&lt;BR /&gt; * SWD. Current consumption does not have focus here.&lt;BR /&gt; */&lt;BR /&gt; for (;;) {&lt;BR /&gt; ExecuteCommunicationMode();&lt;BR /&gt; DeInitApp();&lt;BR /&gt; InitApp();&lt;BR /&gt; }&lt;BR /&gt;#else&lt;BR /&gt; /* Normal operation. Use the Deep Power Down and Power-off low-power states and preserve battery as much as&lt;BR /&gt; * possible.&lt;BR /&gt; */&lt;BR /&gt; if (ExecuteCommunicationMode()) {&lt;BR /&gt; waitBeforeDisconnect = false;&lt;BR /&gt; }&lt;BR /&gt;#endif&lt;BR /&gt; }&lt;/P&gt;&lt;P&gt;DeInit(waitBeforeDisconnect); /* Does not return. */&lt;BR /&gt; return 0;&lt;BR /&gt;}&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 27 Jun 2019 17:33:45 GMT</pubDate>
      <guid>https://community.nxp.com/t5/NFC/Current-reading/m-p/914486#M5529</guid>
      <dc:creator>joohee710610</dc:creator>
      <dc:date>2019-06-27T17:33:45Z</dc:date>
    </item>
    <item>
      <title>Re: Current reading</title>
      <link>https://community.nxp.com/t5/NFC/Current-reading/m-p/914487#M5530</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Joohee&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Could you please look at the next community post.&lt;/P&gt;&lt;P&gt;&lt;A _jive_internal="true" href="https://community.nxp.com/thread/504499"&gt;https://community.nxp.com/thread/504499&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;Mario&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 03 Jul 2019 01:15:55 GMT</pubDate>
      <guid>https://community.nxp.com/t5/NFC/Current-reading/m-p/914487#M5530</guid>
      <dc:creator>mario_castaneda</dc:creator>
      <dc:date>2019-07-03T01:15:55Z</dc:date>
    </item>
  </channel>
</rss>

