cancel
Showing results for 
Search instead for 
Did you mean: 

ST25DV NACK on writing to dynamic registers.

Waller.George
Associate III

I'm currently writing a custom application using the STM32CubeExpansion_NFC4_V1.2.0 as inspiration. I'm trying to enable the mailbox operation however when I go to write the enable bit in the ST25DV_MB_MODE_REG I get a NACK and the bit is not set in the register. I'm using the Mailbox example from the above firmware expansion pack. I'm using X-NUCLEO-NFC04A1 and NULCEO-F746G development boards.

All functions previous to writing in to the dynamic register work and are verified with reads.

In the datasheet for the device it says a byte write maybe inhibited in the following conditions:

• Byte is in user memory and is write protected with LOCK_CCFILE register.

• Byte is in user memory and is write protected with I2CSS register, and I2C security session is closed.

• Byte is in user memory and fast transfer mode is activated.

• Byte is in system memory and is a Read Only register.

• Byte is in system memory and I2C security session is closed.

• Byte is in fast transfer mode’s mailbox and is not the first Byte of mailbox.

• Byte is in fast transfer mode’s mailbox and mailbox is busy.

• Byte is in fast transfer mode’s mailbox and fast transfer mode is not activated.

• Byte is in dynamic registers area and is a Read Only register

The way I see it, only the last condition is met however this register is writable - at least this bit is.

Is there something I've missed or could check?

This is my code:

uint8_t NFCWriteDataReg(uint8_t * value, uint16_t reg)
{
	if(NFCWrite(0, value, reg, 1) == ST25DV_OKAY)
		return ST25DV_OKAY;
 
	return ST25DV_ERROR;
}
 
uint8_t NFCWrite(uint8_t sys, uint8_t * data, uint16_t addr, uint16_t len)
{
	// Get the correct address
	uint8_t dev_addr = ST25DV_SYST_ADDR ? ST25DV_ADDR_SYST_I2C : ST25DV_ADDR_DATA_I2C;
 
	if(HAL_I2C_Mem_Write(&NFC_I2C_H, dev_addr, addr, I2C_MEMADD_SIZE_16BIT, data, len, 100) == HAL_OK)
		return ST25DV_OKAY;
 
	return ST25DV_ERROR;
}

uint8_t NFCEnableMailboxDynamic()
{
	// Set the enable bit
	uint8_t reg_value = ST25DV_MB_CTRL_DYN_MBEN_MASK;
 
	// Write MB_CTRL_DYN register
	return NFCWriteDataReg(&reg_value, ST25DV_MB_CTRL_DYN_REG);
}
uint8_t NFCEnterMailboxMode()
{
	// Store the result here
	uint8_t mode;
 
	// 1. Get the current mode
	if(NFCGetMailboxMode(&mode) == ST25DV_ERROR) return ST25DV_ERROR;
 
	// If we're not already in mailbox mode
	if(mode != ST25DV_ENABLED)
	{
		 // 2. Get the current security status
		if(NFCGetSecuritySessionDynamic(&mode) == ST25DV_ERROR) return ST25DV_ERROR;
 
		// If the session is closed, open one
		if(mode == ST25DV_SESSION_CLOSED)
		{
			// 3. Gain security access (may not be correct password)
			password.lsb = 0;
			password.msb = 0;
 
			// Present the password
			if(NFCPresentI2CPassword(password) == ST25DV_ERROR) return ST25DV_ERROR;
		}
 
		 // 4. Set mailbox mode
		if(NFCEnableMailbox() == ST25DV_ERROR) return ST25DV_ERROR;
 
		 // 5. Remove security access
		password.lsb = 123;
		password.msb = 123;
 
		// Present the wrong password
		if(NFCPresentI2CPassword(password) == ST25DV_ERROR) return ST25DV_ERROR;
	}
 
	// 6. Enable the mailbox in the dynamic register
	if(NFCEnableMailboxDynamic() == ST25DV_ERROR) return ST25DV_ERROR;
 
	return ST25DV_OKAY;
}

1 ACCEPTED SOLUTION

Accepted Solutions
JL. Lebon
ST Employee

​Hello George,

The procedure you are using is correct.

There are 3 conditions to be met in order to being able to write into MB_CTRL_Dyn: VCC>1.5V, MB_MODE=1 and RF is not busy. I guess you are fulfilling the 3 conditions, so it should work.

I suspect is that the device address may be incorrect.

Dynamic registers are accessed using the "user data" device address (A6h), not the system device address (AEh) as for system configuration registers.

In your NFC_Write() function, initialization of dev_addr looks strange to me. Shouldn't it be:

"dev_addr = sys ? ST25DV_ADDR_SYST_I2C : ST25DV_ADDR_DATA_I2C " ?

Can you please check that you are using device address A6h to write into MB_CTRL_Dyn register ?

Best regards.

View solution in original post

3 REPLIES 3
JL. Lebon
ST Employee

​Dear George,

I'm sorry but I'm not 100% sure I understand what your problem is:

  • In the title, you say "ST25DV NACK on writing to dynamic registers"
  • And after in the text you say "when I go to write the enable bit in the ST25DV_MB_MODE_REG I get a NACK"

So, is your problem writing in the static configuration register MB_MODE (@000Dh) or writing in the dynamic register MB_CTRL_Dyn (@2006h) ?

May be a suggestion to help debugging: can you try to read the value of the static configuration register MB_MODE (@000Dh) before trying to change value of the dynamic MB_CTRL_Dyn register ? Usually, the main reason of no being able to change value of the dynamic register is that the MB_MODE register bit 0 is not set to 1.

Best regards.

Waller.George
Associate III

Hi Lebon,

Apologies, I do mean I was having the issue with the dynamic register ST25DV_MB_CTRL_DYN_REG and not ST25DV_MB_MODE_REG.

I have read the ST25DV_MB_MODE_REG to make sure it's set correctly and it is.

Thanks

JL. Lebon
ST Employee

​Hello George,

The procedure you are using is correct.

There are 3 conditions to be met in order to being able to write into MB_CTRL_Dyn: VCC>1.5V, MB_MODE=1 and RF is not busy. I guess you are fulfilling the 3 conditions, so it should work.

I suspect is that the device address may be incorrect.

Dynamic registers are accessed using the "user data" device address (A6h), not the system device address (AEh) as for system configuration registers.

In your NFC_Write() function, initialization of dev_addr looks strange to me. Shouldn't it be:

"dev_addr = sys ? ST25DV_ADDR_SYST_I2C : ST25DV_ADDR_DATA_I2C " ?

Can you please check that you are using device address A6h to write into MB_CTRL_Dyn register ?

Best regards.