Skip to content

Commit

Permalink
Synchronized Arduino library with main NurMicroApi
Browse files Browse the repository at this point in the history
NordicID NurMicroApi library v1.0.2 for Arduino
  • Loading branch information
TuroRantanen committed Jun 13, 2018
1 parent 07f900c commit 94507d2
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 15 deletions.
2 changes: 1 addition & 1 deletion arduino/NurMicroApi/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ https://github.com/NordicID/nur_nurapi_micro

This code is provided under MIT license:

Copyright (c) 2017 Nordic ID.
Copyright (c) 2017 - 2018 Nordic ID.

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,
Expand Down
2 changes: 1 addition & 1 deletion arduino/NurMicroApi/library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=NurMicroApi
version=1.0.1
version=1.0.2
author=NordicID
maintainer=NordicID <support@nordicid.com>
sentence=Allows an Arduino board with UART capabilites to use Nordic ID NUR module based UHF RFID readers.
Expand Down
264 changes: 260 additions & 4 deletions arduino/NurMicroApi/src/NurMicroApi.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,10 @@ static void ParseModuleSetupResponse(struct NUR_API_HANDLE *hNurApi, DWORD flags
GETMEMBER(NUR_SETUP_AUTOPERIOD, periodSetup);
GETMEMBER(NUR_SETUP_PERANTPOWER, antPower);
GETMEMBER(NUR_SETUP_PERANTOFFSET, powerOffset);
GETMEMBER(NUR_SETUP_ANTMASKEX, antennaMaskEx);
GETMEMBER(NUR_SETUP_AUTOTUNE, autotune);
GETMEMBER(NUR_SETUP_PERANTPOWER_EX, antPowerEx);
GETMEMBER(NUR_SETUP_RXSENS, rxSensitivity);

// Copy response back to main response struct
nurMemcpy(&hNurApi->resp->loadsetup, &resp, sizeof(resp));
Expand Down Expand Up @@ -729,6 +733,10 @@ int NURAPICONV NurApiSetModuleSetup(struct NUR_API_HANDLE *hNurApi, struct NUR_C
ADDMEMBER(NUR_SETUP_AUTOPERIOD, periodSetup);
ADDMEMBER(NUR_SETUP_PERANTPOWER, antPower);
ADDMEMBER(NUR_SETUP_PERANTOFFSET, powerOffset);
ADDMEMBER(NUR_SETUP_ANTMASKEX, antennaMaskEx);
ADDMEMBER(NUR_SETUP_AUTOTUNE, autotune);
ADDMEMBER(NUR_SETUP_PERANTPOWER_EX, antPowerEx);
ADDMEMBER(NUR_SETUP_RXSENS, rxSensitivity);

error = NurApiXchPacket(hNurApi, NUR_CMD_LOADSETUP2, payloadSize, DEF_TIMEOUT);
if (error == NUR_SUCCESS || error == NUR_ERROR_INVALID_PARAMETER)
Expand Down Expand Up @@ -778,23 +786,58 @@ int NURAPICONV NurApiInventoryEx(struct NUR_API_HANDLE *hNurApi,
{
WORD payloadSize = params ? sizeof(struct NUR_CMD_INVENTORYEX_PARAMS) : 0;
if (payloadSize > 0) {
int n;
WORD copySize = payloadSize - sizeof(params->filters);
nurMemcpy(TxPayloadDataPtr, params, copySize);
payloadSize = copySize;

if (params->filterCount > 0) {
nurMemcpy(TxPayloadDataPtr + copySize, params->filters, params->filterCount*sizeof(struct NUR_CMD_INVENTORYEX_FILTER));
for (n=0; n<params->filterCount; n++)
{
copySize = 9; // "Header" size.
// Calculate filter bytes from bit length
copySize += ((params->filters[n].maskbitlen / 8) + ((params->filters[n].maskbitlen % 8) != 0));
nurMemcpy(TxPayloadDataPtr + payloadSize, &params->filters[n], copySize);
payloadSize += copySize;
}

payloadSize = copySize + (params->filterCount*sizeof(struct NUR_CMD_INVENTORYEX_FILTER));
}
return NurApiXchPacket(hNurApi, NUR_CMD_INVENTORYEX, payloadSize, DEF_LONG_TIMEOUT);
}

NUR_API int NURAPICONV NurApiGetInventoryReadConfig(struct NUR_API_HANDLE *hNurApi)
{
return NurApiXchPacket(hNurApi, NUR_CMD_INVENTORYREAD, 0, DEF_TIMEOUT);
}

int NURAPICONV NurApiSetInventoryReadConfig(struct NUR_API_HANDLE *hNurApi,
struct NUR_CMD_IRCONFIG_PARAMS *params)
{
WORD payloadSize;
if (params->active) {
payloadSize = params ? sizeof(struct NUR_CMD_IRCONFIG_PARAMS) : 0;
if (payloadSize > 0) {
nurMemcpy(TxPayloadDataPtr, params, payloadSize);
}
} else {
payloadSize = 1;
TxPayloadDataPtr[0] = params->active;
}
return NurApiXchPacket(hNurApi, NUR_CMD_INVENTORYREAD, payloadSize, DEF_TIMEOUT);
}

int NURAPICONV NurApiClearTags(struct NUR_API_HANDLE *hNurApi)
{
return NurApiXchPacket(hNurApi, NUR_CMD_CLEARIDBUF, 0, DEF_TIMEOUT);
}

int NURAPICONV NurApiSetExtCarrier(struct NUR_API_HANDLE *hNurApi, BOOL on)
{
int error;
PacketDwordPos(TxPayloadDataPtr, on, 0);

error = NurApiXchPacket(hNurApi, NUR_CMD_CARRIER, 4, DEF_TIMEOUT);
return error;
}

#define SZ_META_PREPEND_IR 12

int NURAPICONV ParseIdBuffer(struct NUR_API_HANDLE *hNurApi, pFetchTagsFunction tagFunc, BYTE *buffer, DWORD bufferLen, BOOL includeMeta, BOOL includeIrData)
Expand Down Expand Up @@ -928,6 +971,7 @@ int NURAPICONV NurApiTraceTag(struct NUR_API_HANDLE *hNurApi, struct NUR_CMD_TRA
RETLOGERROR(NUR_ERROR_INVALID_PARAMETER);
}

// BitLengthToByteLength
maskdataLen = ((params->maskbitlen / 8) + ((params->maskbitlen % 8) != 0));

PacketByte(payloadBuffer, params->flags, &payloadSize);
Expand Down Expand Up @@ -1177,6 +1221,218 @@ int NURAPICONV NurApiGetGPIOStatus(struct NUR_API_HANDLE *hNurApi, int gpio)
return NurApiXchPacket(hNurApi, NUR_CMD_GETGPIO, sizeof(*getState), DEF_TIMEOUT);
}

int NURAPICONV NurApiEnterBoot(struct NUR_API_HANDLE *hNurApi)
{
return NurApiXchPacket(hNurApi, NUR_CMD_ENTERBOOT, 0, DEF_TIMEOUT);
}

int NURAPICONV NurApiModuleRestart(struct NUR_API_HANDLE *hNurApi)
{
return NurApiXchPacket(hNurApi, NUR_CMD_RESTART, 0, DEF_TIMEOUT);
}

int NURAPICONV NurApiGetMode(struct NUR_API_HANDLE *hNurApi, char *mode)
{
int error = NurApiXchPacket(hNurApi, NUR_CMD_GETMODE, 0, DEF_TIMEOUT);
if (error == NUR_SUCCESS) {
*mode = hNurApi->resp->mode.type;
}
return error;
}

static const DWORD crc32Table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};

DWORD NURAPICONV NurCRC32(DWORD crc, const BYTE *buf, DWORD len)
{
crc ^= 0xFFFFFFFF;
while (len--) {
crc = (crc >> 8) ^ crc32Table[(crc ^ *buf++) & 0xFF];
}
return crc ^ 0xFFFFFFFF;
}

#define NUR_PROGRAM_RETRIES 5

int NURAPICONV NurApiProgramBuffer(struct NUR_API_HANDLE *hNurApi, pProgramProgressFunction prgFn, WORD startPage, BYTE validateCmd, BYTE *buffer, DWORD bufferLen)
{
int error = 0;
DWORD numPages = 0;
DWORD numPagesReminder = 0;
DWORD writePos = 0;
DWORD pageSize;
DWORD i = 0;
WORD currentPage = startPage;
int writeRetries = NUR_PROGRAM_RETRIES;
DWORD appCRC = 0;

struct NUR_PRGPROGRESS_DATA notificationData;
struct NUR_CMD_PAGEWRITE_PARAMS *pagewriteParams = (struct NUR_CMD_PAGEWRITE_PARAMS *)TxPayloadDataPtr;
struct NUR_CMD_APPVALIDATE_PARAMS *appValidateParams = (struct NUR_CMD_APPVALIDATE_PARAMS *)TxPayloadDataPtr;

numPages = bufferLen / NUR_FLASH_PAGE_SIZE;
numPagesReminder = bufferLen % NUR_FLASH_PAGE_SIZE;
if (numPagesReminder > 0)
numPages++;

notificationData.error = 0;
notificationData.totalPages = numPages;
notificationData.curPage = -1;
if (prgFn && (*prgFn)(hNurApi, &notificationData) != 0) {
return NUR_ERROR_NOT_READY;
}

while (writePos < bufferLen)
{
notificationData.curPage = currentPage - startPage;
if (prgFn && (*prgFn)(hNurApi, &notificationData) != 0) {
return NUR_ERROR_NOT_READY;
}

pageSize = bufferLen - writePos;
if (pageSize > NUR_FLASH_PAGE_SIZE)
pageSize = NUR_FLASH_PAGE_SIZE;

memcpy(pagewriteParams->data, &buffer[writePos], pageSize);

if (pageSize < NUR_FLASH_PAGE_SIZE) {
// Pad with 0xFF
for (i = pageSize; i < NUR_FLASH_PAGE_SIZE; i++) {
pagewriteParams->data[i] = 0xFF;
}
}

pagewriteParams->pagetowrite = currentPage;
pagewriteParams->crc = NurCRC32(0, pagewriteParams->data, NUR_FLASH_PAGE_SIZE);

// XOR w/ crc
for (i=0; i<NUR_FLASH_PAGE_SIZE; i += 4) {
DWORD dwData = BytesToDword(&pagewriteParams->data[i]);
dwData = (dwData ^ pagewriteParams->crc);
PacketDwordPos(pagewriteParams->data, dwData, i);
}

writeRetries = NUR_PROGRAM_RETRIES;
while (writeRetries-- > 0) {
error = NurApiXchPacket(hNurApi, NUR_CMD_PAGEWRITE, sizeof(*pagewriteParams), DEF_TIMEOUT);
// TEST: Simulated write error @ page 100
/*if (notificationData.curPage == 100 && writeRetries == NUR_PROGRAM_RETRIES)
{
error = NUR_ERROR_PAGE_PROGRAM;
}*/
if (error == NUR_SUCCESS) {
break;
}
}

if (error != NUR_SUCCESS) {
break;
}

currentPage++;
writePos += pageSize;
}

if (error == NUR_SUCCESS && validateCmd != 0)
{
appCRC = NurCRC32(0, buffer, bufferLen);
appValidateParams->appcrc = appCRC;
appValidateParams->appsize = bufferLen;

writeRetries = NUR_PROGRAM_RETRIES;
while (writeRetries-- > 0) {
error = NurApiXchPacket(hNurApi, validateCmd, sizeof(*appValidateParams), DEF_TIMEOUT);
if (error == NUR_SUCCESS) {
break;
}
}
}

if (error != NUR_SUCCESS) {
notificationData.error = error;
} else {
notificationData.curPage = notificationData.totalPages;
}
if (prgFn)
(*prgFn)(hNurApi, &notificationData);

return error;
}

int NURAPICONV NurApiProgramApp(struct NUR_API_HANDLE *hNurApi, pProgramProgressFunction prgFn, BYTE *buffer, DWORD bufferLen)
{
return NurApiProgramBuffer(hNurApi, prgFn, NUR_APP_FIRST_PAGE, NUR_CMD_APPVALIDATE, buffer, bufferLen);
}

int NURAPICONV NurApiProgramBootloader(struct NUR_API_HANDLE *hNurApi, pProgramProgressFunction prgFn, BYTE *buffer, DWORD bufferLen)
{
return NurApiProgramBuffer(hNurApi, prgFn, NUR_BL_FIRST_PAGE, NUR_CMD_BLVALIDATE, buffer, bufferLen);
}

/*
Unaligned member access.
*/
Expand Down
Loading

0 comments on commit 94507d2

Please sign in to comment.