Martyn Gilbertson / M24SR
Revision:
3:5ebf4b2c51a1
Parent:
2:de5aea7f83cd
Child:
4:11526ba25edb
--- a/M24SR.cpp	Wed Jul 31 09:33:56 2019 +0100
+++ b/M24SR.cpp	Thu Aug 29 12:38:46 2019 +0100
@@ -232,15 +232,86 @@
 }
 
 
+M24SR::status_t M24SR::set_rf_enable(bool enable)
+{
+	status_t ret;
+	uint8_t old_state;
+	uint8_t new_state = enable;
+
+	if (  (ret = get_session(1)) != M24SR_SUCCESS )
+	{
+		// printf("Error opening session %4.4X\n", ret);
+		return ret;
+	}
+
+	if ( (ret = select_type((uint8_t*)SELECT_APPLICATION_COMMAND, 7, 0x0400, CMD_MASK_SELECT_APPLICATION)) != M24SR_SUCCESS)
+	{
+		// printf("Error Select Application %4.4X\n", ret );
+		return ret;
+	}
+
+	if ( (ret = select_type((uint8_t*)SYSTEM_FILE_ID_BYTES, 2, 0x000C, CMD_MASK_SELECT_CC_FILE)) != M24SR_SUCCESS)
+	{
+		// printf("Error select System file\r\n");
+		return ret;
+	}
+
+
+	// get GPO state
+	if ( (ret = read_binary( 0x0006, 1, (uint8_t*)&old_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error read System File %4.4X\n", ret );
+		return ret;
+	}
+
+	//printf("New State: %2.2X Old State: %2.2X\n", new_state, old_state);
+
+	if (old_state == new_state)
+	{
+		return M24SR_SUCCESS;
+	}
+
+	verify(_password);
+
+	// write new GPO state
+	if ( (ret = update_binary( 0x0006, 1, (uint8_t*)&new_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error update System File %4.4X\n", ret );
+		return ret;
+	}
+
+	// verify GPO state
+	if ( (ret = read_binary( 0x0006, 1, (uint8_t*)&old_state )) != M24SR_SUCCESS )
+	{
+		//printf("Error read System File %4.4X\n", ret );
+		return ret;
+	}
+
+	if (old_state != new_state)
+	{
+		//printf("Error updating GPO State\r\n");
+		return M24SR_UNSUCESSFUL_UPDATING;
+	}
+
+
+	deselect();
+	//printf("Updated GPO State:%2.2X", gpo_state);
+
+	return ret;
+}
+
 
 M24SR::status_t M24SR::session_start(bool parse_header)
 {
 	status_t ret;
 
-	_ndef_hdr_size = 0;
 	_session_open = false;
 	_ndef_size = 0; // no ndef file set
 	_write_bytes = 0; // clear write bytes
+	_ndef_hdr_size = 0; // clear header size
+
+	// disable RF until session_end
+	set_rf_enable(false);
 
 	/*
 	1. Start session
@@ -256,13 +327,13 @@
 		return ret;
 	}
 
-	if ( (ret = select_type((uint8_t*)SELECT_APPLICATION_COMMAND, 7, 0x0400, CMD_MASK_SELECT_APPLICATION)) != M24SR_SUCCESS)
+	if ( (ret = select_type((uint8_t*)SELECT_APPLICATION_COMMAND, 7, 0x0400, CMD_MASK_SELECT_APPLICATION)) != M24SR_SUCCESS )
 	{
 		// printf("Error Select Application %4.4X\n", ret );
 		return ret;
 	}
 
-	if ( (ret = select_type((uint8_t*)CC_FILE_ID_BYTES, 2, 0x000C, CMD_MASK_SELECT_CC_FILE)) != M24SR_SUCCESS)
+	if ( (ret = select_type((uint8_t*)CC_FILE_ID_BYTES, 2, 0x000C, CMD_MASK_SELECT_CC_FILE)) != M24SR_SUCCESS )
 	{
 		// printf("Error read CC file\r\n");
 		return ret;
@@ -277,13 +348,13 @@
 		return ret;
 	}
 
-	if ( (ret = select_type((uint8_t*)&ndef_id, 2, 0x000C, CMD_MASK_SELECT_NDEF_FILE ) )  != M24SR_SUCCESS)
+	if ( (ret = select_type((uint8_t*)&ndef_id, 2, 0x000C, CMD_MASK_SELECT_NDEF_FILE ) )  != M24SR_SUCCESS )
 	{
 		// printf("Error Select NDEF File %4.4X\n", ret );
 		return ret;
 	}
 
-	if (parse_header == true)
+	if ( parse_header == true )
 	{
 		/** Get NDEF Header info used for reading */
 		ret = parse_ndef_header();
@@ -303,12 +374,15 @@
 	}
 
 	_session_open = false;
-	_ndef_hdr_size = 0;
 	_ndef_size = 0;
 	_write_bytes = 0;
+	_ndef_hdr_size = 0;
 
 	deselect();
 
+	// re-enable RF
+	set_rf_enable(true);
+
 	return M24SR_SUCCESS;
 }
 
@@ -372,8 +446,7 @@
 
 M24SR::status_t M24SR::write(uint16_t addr, const char* data, uint16_t size)
 {
-	// write in blocks of MAX_PAYLOAD
-	status_t ret;
+	M24SR::status_t ret;
 
 	if ( _session_open == false )
 	{
@@ -381,7 +454,7 @@
 	}
 
 	// start a write session if not already started by using the _write_bytes to maintain header size
-	if (_write_bytes == 0)
+	if (_ndef_hdr_size == 0)
 	{
 		// build NDEF header to determine header size
 		write_ndef_header(false);
@@ -432,6 +505,7 @@
 	{
 		return ret;
 	}
+
 #endif // #if (M24SR_WRITE_CONTINOUS)
 
 	return M24SR_SUCCESS;
@@ -677,19 +751,40 @@
     const uint8_t M24SR_OPENSESSION_COMMAND = 0x26;
     const uint8_t M24SR_KILLSESSION_COMMAND = 0x52;
 
-	status_t status;
+	status_t ret;
 
-	/* Insure no access will be done just after open session */
-	/* The only way here is to poll I2C to know when M24SR is ready */
-	/* GPO can not be use with KillSession command */
-	if ( _i2c.write(M24SR_DEFAULT_ADDRESS, (const char*) & (force == 1 ? M24SR_OPENSESSION_COMMAND : M24SR_KILLSESSION_COMMAND), 1) == 0 )
+	// if there is an RF session on-going then retry a few times to KILL, once an actual session is started RF is disabled
+	uint8_t retry = 3;
+	while (retry--)
 	{
-		status = io_poll_i2c();
-	}else{
-		status = M24SR_IO_ERROR_I2CTIMEOUT;
+		// force kill session before we open it
+		if (force == 1)
+		{
+			if ( _i2c.write(M24SR_DEFAULT_ADDRESS, (const char*) &M24SR_KILLSESSION_COMMAND, 1) == 0 )
+			{
+				ret = io_poll_i2c();
+			}else{
+				ret = M24SR_IO_ERROR_I2CTIMEOUT;
+			}
+		}
+
+		// open session
+		if ( _i2c.write(M24SR_DEFAULT_ADDRESS, (const char*) &M24SR_OPENSESSION_COMMAND, 1) == 0 )
+		{
+			ret = io_poll_i2c();
+		}else{
+			ret = M24SR_IO_ERROR_I2CTIMEOUT;
+		}
+
+		if (ret == M24SR_SUCCESS)
+		{
+			break;
+		}else{
+			//printf("Error starting session %X... Remaining Retries (%u)\r\n", ret, retry );
+		}
 	}
 
-    return status;
+    return ret;
 }