I am trying to write a custom bluetooth address to the NVDS on a QN9080. The nvds_init function always returns error code 1, NVDS_FAIL. The nvds_init function gets called from the hardware_init function. This happens in my code as well as in the glucose sensor example application. Is there a compiler switch I need to turn on or something else I need to do in order to make the NVDS work?
已解决! 转到解答。
Hi Rick,
Could you please rebuild your SDK? We fixed some bugs and we updated the SDK.
Please let me know if you still have this issue.
Regards,
Mario
Hi Rick,
Did you change the nvds address location?
As you can see there is defined in the nvds.h file.
However, if you want to change the bd_address, you could use the nvds_put API.
uint8_t nvds_put(uint8_t tag, nvds_tag_len_t length, uint8_t *buf);
You could change the bd_addres using the NVDS Configurator.
C:\NXP\QN908x Programming Tool
Please let me know if you still have issues.
Regards,
Mario
Thanks for responding, Mario.
I am using the CFG_NVDS_ADDRESS and CFG_NVDS_BACKUP_ADDRESS definitions from nvds.h. The nvds_init function is failing in the glucose sensor example project. I haven't modified the project code or the map file for that project.
My goal is to change bd_address at runtime using nvds_put. However, nvds_put always fails after nvds_init fails. The NVDS Configurator isn't going to work my use case.
How can I tell why the nvds_init function is failing? It returns error code 1, which is a pretty generic error code for NVDS_FAIL.
Hi Rick,
Could you please try to use the QN908x programming tool and reset the NVDS tags?
Then, could you please try to use the nvds_put and let me if you still have issues with this.
Regards,
Mario
Mario,
Thanks for the suggestion. I am trying to use NVDS on my PCB, which doesn't support a COM interface. Is there a way to run the NVDS Configurator through the SWD interface using a PEMicro Multilink?
I tried using the glucose sensor project QN9080 DK demo board and found that the nvds_init call did not fail on that board. I am using the exact same project on my board and on the demo board, but the nvds_init call only fails on my board. Is there a hardware requirement for using NVDS?
I saw another post that discussed API compatibility issues on some QN9080 chips. The picture below shows the chip from the demo board on the left and the chip on my PCB on the right. Are there any known issues with the chip I am using?
Regards,
Rick
Hi Rick,
The return fail is because the NVDS is empty and it needs some information for a correct startup.
1. Could you please use the QN908X Programming tool and burn the default values in your MCU.
You could connect to the QN9080 with UART or SPI pins.
Please let me know if your board doesn't have access to these pins.
Regards,
Mario
Hi Rick,
Please add the code below to restore the data.
/************************************************************************************
* Private type definitions and macros
************************************************************************************/
#define NVDS_START_STORAGE_AREA_ADDRESS_OFFSET 4
/************************************************************************************
* Private memory declarations
************************************************************************************/
extern struct nvds_env_tag nvds_env;
extern const struct nvds_if fw_nvds_api;
/* NVDS MAGIC WORD */
const uint8_t nvds_magic_word[] = {0x4e, 0x56, 0x44, 0x53};
/* NVDS DEFAULT DATA */
const uint8_t nvds_default_data[] = {
/* Here is the magic */ 0x01, 0x06, 0x06, 0x00, 0x70, 0x00, 0x00, 0xbe, 0x7c, 0x08, 0xff, 0xff,
0x02, 0x06, 0x07, 0x00, 0x4e, 0x58, 0x50, 0x20, 0x42, 0x4c, 0x45, 0xff, 0x03, 0x06, 0x02, 0x00,
0x64, 0x00, 0xff, 0xff, 0x05, 0x06, 0x02, 0x00, 0x84, 0x03, 0xff, 0xff, 0x10, 0x06, 0x01, 0x00,
0x08, 0xff, 0xff, 0xff, 0x11, 0x06, 0x01, 0x00, 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
/************************************************************************************
*************************************************************************************
* Private functions prototypes
*************************************************************************************
************************************************************************************/
uint8_t nvds_get(uint8_t tag, uint16_t *lengthPtr, uint8_t *buf);
uint8_t nvds_put(uint8_t tag, nvds_tag_len_t length, uint8_t *buf);
static uint8_t nvds_restore_default(void);
* Private functions
*************************************************************************************
************************************************************************************/
static uint8_t nvds_restore_default(void)
{
struct nvds_env_tag nvds_env_local = nvds_env;
uint8_t status = NVDS_OK;
nvds_env_local.nvds_space = (uint8_t*)CFG_NVDS_ADDRESS;
#ifdef NVDS_RESTORE_BACKUP_AREA
nvds_env_local.nvds_backup = (uint8_t*)CFG_NVDS_BACKUP_ADDRESS;
#endif
nvds_env_local.total_size = CFG_NVDS_SIZE;
/* clear the device */
if(NULL != fw_nvds_api.erase)
{
fw_nvds_api.erase((uint32_t)nvds_env_local.nvds_space, nvds_env_local.total_size);
#ifdef NVDS_RESTORE_BACKUP_AREA
fw_nvds_api.erase((uint32_t)nvds_env_local.nvds_backup, nvds_env_local.total_size);
#endif
}
else
{
status = NVDS_FAIL;
}
/* rewrite the NVDS with default data */
if(NULL != fw_nvds_api.write)
{
fw_nvds_api.write((uint32_t)nvds_env_local.nvds_space + NVDS_START_STORAGE_AREA_ADDRESS_OFFSET,
sizeof(nvds_default_data), (uint8_t*)nvds_default_data);
#ifdef NVDS_RESTORE_BACKUP_AREA
/* rewrite the NVDS backup with default data */
fw_nvds_api.write((uint32_t)nvds_env_local.nvds_backup + NVDS_START_STORAGE_AREA_ADDRESS_OFFSET,
sizeof(nvds_default_data), (uint8_t*)nvds_default_data);
#endif
/* Write the magic number */
fw_nvds_api.write((uint32_t)nvds_env_local.nvds_space,
(uint32_t)sizeof(nvds_magic_word),
(uint8_t*)nvds_magic_word);
#ifdef NVDS_RESTORE_BACKUP_AREA
/* Write the magic number */
fw_nvds_api.write((uint32_t)nvds_env_local.nvds_backup,
(uint32_t)sizeof(nvds_magic_word),
(uint8_t*)nvds_magic_word);
#endif
}
else
{
status = NVDS_FAIL;
}
return status;
}
Call the nvds_restore_default function in the hardware_init().
Please let me know if you still have the issue.
Regards,
Mario
Mario,
I don't have fw_nvds_api defined anywhere in my application or in the glucose sensor application. Should that be defined somewhere in my application already? If so, how should I set up the function pointers in the struct? I assume I can point some of the function pointers to the functions defined in nvds_h, but I am not sure how to set up the read, write and erase function pointers.
Hi Rick,
The fw_nvds_api is defined in the fw_symbols_gcc.h.
Should that be defined somewhere in my application already?
No, just change the board.c file with the next API.
nvds_restore_default
Did you change the board.c file? Are you able to compile?
Regards,
Mario
Mario,
I changed board.c before my previous post, but the compile fails because fw_nvds_api is missing. It is not defined in fw_symbols_gcc.h. I am using version 2.2.0 of SDK_2.2_QN908XCDK. The manifest version is 3.0.0.
Rick
Mario,
I ran the glucose sensor application on my board. The first time through, nvds_init failed, but the nvds_restore_default function passed and the second call to nvds_init passed as well. On subsequent runs, the first call to nvds_init passes. Thanks!!
The downloaded SDK has the same version as my old one. Is that expected? Also, the release notes didn't provide any details about what was changed. Do you have any documentation about the difference between old and new implementation of SDK_2.2_QN908XCDK?
Thanks,
Rick