# Question about NFC on Ameba RTL8195AM Dev Board

**URL:** https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969
**Category:** SDK
**Created:** [December 10, 2021, 10:54am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969 "2021-12-10T10:54:37Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![walkerfleck](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.amebaiot.com/walkerfleck/32/739_2.png) [@walkerfleck](https://forum.amebaiot.com/u/walkerfleck)
#### Post date: [December 10, 2021, 10:54am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/1 "2021-12-10T10:54:37Z")

</div>

Hi  
I want to test NFC function on RTL8195AM Dev Board.

I have questions about NFC:

1. There are no example code, so I searched the package, found that there is nfc\_api.c. I write some test code for NFC, it did not working, I quote my code here:

```auto
#include "FreeRTOS.h"
#include "task.h"
#include "diag.h"
#include "device.h"
#include "main.h"
#include "log_uart_api.h"
#include "nfc_api.h"

nfctag_t nfcobj;
uint32_t nfcvalue;

void my_nfc_event_cb(void *arg, void *buf, unsigned int page) {
    int i;
    printf("\n\rNFC Event[%d] : ", page);
    for(i=0;i<32;i++) {
        printf("%02X ", ((unsigned char *)buf)[i]);
    }
    printf("\n\r");
}

void nfc_thread(void* arg) {
    // ----------------------------------------------------
    // Initial NFC Reader
    printf("\n\rInitializing NFC ...\n\r");
    nfc_init(&nfcobj, &nfcvalue);
    while (1) {
        printf("\n\rNFC Reading...\n\r");
        nfc_read(&nfcobj, my_nfc_event_cb, NULL);
        vTaskDelay(1500);
    }
}

//========================================================================================================
void main(void) {
    // ----------------------------------------------------
	/* Initialize log uart and at command service */
	console_init();
	if(xTaskCreate(nfc_thread, ((const char*)"init"), 512 + 768, NULL, tskIDLE_PRIORITY + 3 + PRIORITIE_OFFSET, NULL) != pdPASS)
		printf("\n\r%s xTaskCreate(nfc_thread) failed", __FUNCTION__ );

    // ----------------------------------------------------
    // FreeRTOS main loop
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
	#ifdef PLATFORM_FREERTOS
	vTaskStartScheduler();
	#endif
#else
	RtlConsolTaskRom(NULL);
#endif
}

```

1. I found that R19 and R20 near the antenna are not connected, I guess the antenna is not powered. Should I soldering them directly?

 ![image](https://us1.discourse-cdn.com/flex016/uploads/ameba/original/1X/d38947d3be87a716b01e78e11e32a5df034f1d99.jpeg)

Thanks for your help!

---

<div class="post-metadata">

### Author: ![wyy](https://avatars.discourse-cdn.com/v4/letter/w/bc8723/32.png) [@wyy](https://forum.amebaiot.com/u/wyy)
#### Post date: [December 10, 2021, 2:35pm UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/2 "2021-12-10T14:35:42Z")

</div>

@walkerfleck

nfc example for the SDK can be found [here](https://github.com/ambiot/amb1_sdk/blob/master/project/realtek_ameba1_va0_example/example_sources/nfc/src/main.c).

yes, you will need to solder the leads to the nfc antenna for the example to work.

---

<div class="post-metadata">

### Author: ![walkerfleck](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.amebaiot.com/walkerfleck/32/739_2.png) [@walkerfleck](https://forum.amebaiot.com/u/walkerfleck)
#### Post date: [December 13, 2021, 4:25am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/3 "2021-12-13T04:25:57Z")

</div>

Hi @wyy

Thanks, it is informative to me.  
I have another question by the way, I found the example code is using thread, I suppose that it needs RtOS to run. I also found RtOS is needed for wifi functions, according to my test, the bare-metal mode seem not work for wifi APIs. Is that true that FreeRTOS is needed for some SDK functions?

---

<div class="post-metadata">

### Author: ![wyy](https://avatars.discourse-cdn.com/v4/letter/w/bc8723/32.png) [@wyy](https://forum.amebaiot.com/u/wyy)
#### Post date: [December 13, 2021, 4:45am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/4 "2021-12-13T04:45:34Z")

</div>

yes, bare-metal should work for the simpler peripheral functions (e.g. SPI, UART), but anything involving networking would probably need the RTOS.

---

<div class="post-metadata">

### Author: ![walkerfleck](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.amebaiot.com/walkerfleck/32/739_2.png) [@walkerfleck](https://forum.amebaiot.com/u/walkerfleck)
#### Post date: [December 13, 2021, 1:48pm UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/5 "2021-12-13T13:48:12Z")

</div>

Hi @wyy

I spent a lot of time to test the nfc example in GCC environment, there was a linking problem, which said the \_\_get\_IPSR() function is missing in cmsis.o. I googled for answer and added the function for it:

```auto
#pragma diag_suppress 994
__attribute__ ((naked))
uint32_t __get_IPSR(void)
{
   __asm(" MRS R0, IPSR\n");
}
// Restore warnings about any non-void function not returning a value
#pragma diag_default 994

```

After image built, I flashed the image successfully. But the system hung and no response.  
The UART log stopped like this:  
 ![image](https://us1.discourse-cdn.com/flex016/uploads/ameba/original/1X/d04c40f02289c720fd5946d813b62b3836114633.png)

I even can’t use the GDB, it hung after I entered “step” command at the first line of main().

Can’t figure out how to identify the problem.

---

<div class="post-metadata">

### Author: ![wyy](https://avatars.discourse-cdn.com/v4/letter/w/bc8723/32.png) [@wyy](https://forum.amebaiot.com/u/wyy)
#### Post date: [December 15, 2021, 2:33am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/6 "2021-12-15T02:33:59Z")

</div>

Hi @walkerfleck

It seems to be an issue with the CMSIS\_OS API layer, the \_\_get\_IPSR function is already defined, but it cant seem to find it.

After getting rid of all CMSIS\_OS function calls and replacing with FreeRTOS, I managed to get it working with my phone. It should also be possible to change the example to use no RTOS at all.

```auto
/*
 * Routines to access hardware
 *
 * Copyright (c) 2015 Realtek Semiconductor Corp.
 *
 * This module is a confidential and proprietary property of RealTek and
 * possession or use of this module requires written permission of RealTek.
 */

#include "FreeRTOS.h"
#include "task.h"

#include "diag.h"
#include "main.h"

#include "nfc_api.h"
#include "flash_api.h"

#define NFC_RESTORE_DEFAULT (0)

#define NFC_MAX_PAGE_NUM 36
nfctag_t nfctag;
unsigned int nfc_tag_content[NFC_MAX_PAGE_NUM];
unsigned char nfc_tag_dirty[NFC_MAX_PAGE_NUM];

#define RTK_NFC_UID 0x58
unsigned char nfc_default_uid[7] = {
    RTK_NFC_UID, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06
};

unsigned int evt = 0;

#define FLASH_APP_NFC_BASE 0x85000
flash_t flash_nfc;

void nfc_event_listener(void *arg, unsigned int event) {
    switch(event) {
        case NFC_EV_READER_PRESENT:
            DiagPrintf("NFC_EV_READER_PRESENT\r\n");
            break;
        case NFC_EV_READ:
            DiagPrintf("NFC_EV_READ\r\n");
            break;
        case NFC_EV_WRITE:
            DiagPrintf("NFC_EV_WRITE\r\n");
            break;
        case NFC_EV_ERR:
            DiagPrintf("NFC_EV_ERR\r\n");
            break;
        case NFC_EV_CACHE_READ:
            DiagPrintf("NFC_EV_CACHE_READ\r\n");
            break;
    }
}

/**
 * This callback function is called several times if tag is being written multiple pages.
 * DO NOT put heavy task here otherwise it will block tag write and cause timeout failure.
 **/
void nfc_write_listener(void *arg, unsigned int page, unsigned int pgdat) {
    nfc_tag_content[page] = pgdat;
    nfc_tag_dirty[page] = 1;
    evt |= NFC_EV_WRITE;
}

int is_valid_nfc_uid() {
    int valid_content = 1;

    unsigned char uid[7];
    unsigned char bcc[2];

    uid[0] = (unsigned char)((nfc_tag_content[0] & 0x000000FF) >> 0);
    uid[1] = (unsigned char)((nfc_tag_content[0] & 0x0000FF00) >> 8);
    uid[2] = (unsigned char)((nfc_tag_content[0] & 0x00FF0000) >> 16);
    bcc[0] = (unsigned char)((nfc_tag_content[0] & 0xFF000000) >> 24);
    uid[3] = (unsigned char)((nfc_tag_content[1] & 0x000000FF) >> 0);
    uid[4] = (unsigned char)((nfc_tag_content[1] & 0x0000FF00) >> 8);
    uid[5] = (unsigned char)((nfc_tag_content[1] & 0x00FF0000) >> 16);
    uid[6] = (unsigned char)((nfc_tag_content[1] & 0xFF000000) >> 24);
    bcc[1] = (unsigned char)((nfc_tag_content[2] & 0x000000FF) >> 0);

    // verify Block Check Character
    if (bcc[0] != (0x88 ^ uid[0] ^ uid[1] ^ uid[2])) {
        valid_content = 0;
    }
    if (bcc[1] != (uid[3] ^ uid[4] ^ uid[5] ^ uid[6])) {
        valid_content = 0;
    }

    return valid_content;
}

unsigned int generate_default_tag_content() {
    unsigned int page_size = 0;

    memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int));

    // calculate Block Check Character
    unsigned char bcc[2];
    bcc[0] = 0x88 ^ nfc_default_uid[0] ^ nfc_default_uid[1] ^ nfc_default_uid[2];
    bcc[1] = nfc_default_uid[3] ^ nfc_default_uid[4] ^ nfc_default_uid[5] ^ nfc_default_uid[6];

    // generate header
    nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[0]) << 0 |
                                   ((unsigned int)nfc_default_uid[1]) << 8 |
                                   ((unsigned int)nfc_default_uid[2]) << 16 |
                                   ((unsigned int) bcc[0]) << 24;
    nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[3]) << 0 |
                                   ((unsigned int)nfc_default_uid[4]) << 8 |
                                   ((unsigned int)nfc_default_uid[5]) << 16 |
                                   ((unsigned int)nfc_default_uid[6]) << 24;
    nfc_tag_content[page_size++] = ((unsigned int) bcc[1]) << 0;
    nfc_tag_content[page_size++] = 0x001211E1;

    // Init tag content as NDEF will-known text message "HELLO WORLD!" in little endian
    nfc_tag_content[page_size++] = 0x01d11303;
    nfc_tag_content[page_size++] = 0x6502540f;
    nfc_tag_content[page_size++] = 0x4c45486e;
    nfc_tag_content[page_size++] = 0x57204f4c;
    nfc_tag_content[page_size++] = 0x444c524f;
    nfc_tag_content[page_size++] = 0x0000fe21;

    return page_size;
}

void nfc_load_tag_content_from_flash() {
    int i, address, page_size;

    memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int));
    memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM);

    for (i = 0, address = FLASH_APP_NFC_BASE; i < NFC_MAX_PAGE_NUM; i++, address+=4) {
        flash_read_word(&flash_nfc, address, &nfc_tag_content[i]);
    }

    if (!is_valid_nfc_uid() || NFC_RESTORE_DEFAULT) {
        DiagPrintf("Invalid tag content, restore to default value\r\n");
        page_size = generate_default_tag_content();

        // update to flash
        flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE);
        for (i = 0, address = FLASH_APP_NFC_BASE; i < page_size; i++, address += 4) {
            flash_write_word(&flash_nfc, address, nfc_tag_content[i]);
        }
    }

}

void nfc_store_tag_content() {
    int i, address;
    int modified_page_count;

    // dump the modified tag content
    modified_page_count = 0;
    for (i = 4; i < NFC_MAX_PAGE_NUM && nfc_tag_dirty[i]; i++) {
        modified_page_count++;
        DiagPrintf("page:%02d data:%08x\r\n", i, nfc_tag_content[i]);
    }

    // update to cache from page 4
    nfc_cache_write(&nfctag, &(nfc_tag_content[4]), 4, modified_page_count);

    modified_page_count += 4; // we also need update tag header to flash which has size 4
    flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE);
    for (i = 0, address = FLASH_APP_NFC_BASE; i < modified_page_count; i++, address += 4) {
        flash_write_word(&flash_nfc, address, nfc_tag_content[i]);
    }

}

void nfc_task(void const *arg) {
    int i;
    //osEvent evt;

    nfc_load_tag_content_from_flash();

    nfc_init(&nfctag, nfc_tag_content);
    nfc_event(&nfctag, nfc_event_listener, NULL, 0xFF);
    nfc_write(&nfctag, nfc_write_listener, NULL);

    evt &= ~NFC_EV_WRITE;

    while(1) {
        if (evt & NFC_EV_WRITE) {
            //osDelay(300);
            vTaskDelay(300/portTICK_RATE_MS);

            nfc_store_tag_content();

            memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM);
            evt &= ~NFC_EV_WRITE;
        }
    }
}

/**
  * @brief Main program.
  * @param None
  * @retval None
  */
void main(void)
{
    xTaskCreate(nfc_task, ((const char*)"nfc_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL);

    DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_);

    //3 3)Enable Schedule, Start Kernel
#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED
    #ifdef PLATFORM_FREERTOS
    vTaskStartScheduler();
    #endif
#else
    RtlConsolTaskRom(NULL);
#endif

    while(1);
}

```

---

<div class="post-metadata">

### Author: ![walkerfleck](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.amebaiot.com/walkerfleck/32/739_2.png) [@walkerfleck](https://forum.amebaiot.com/u/walkerfleck)
#### Post date: [December 17, 2021, 4:34am UTC](https://forum.amebaiot.com/t/question-about-nfc-on-ameba-rtl8195am-dev-board/969/7 "2021-12-17T04:34:05Z")

</div>

Yeah, It’s the issue from CMSIS\_OS API, it worked from my side also, after I removed all CMSIS\_OS API calls.

Thanks a lot!
