Firmware enhancements for HSP_RPC_GUI 3.0.1

Dependencies:   USBDevice

Fork of HSP_RPC_GUI by Maxim Integrated

This command can be used to import the project to your local environment

This command can be used to compile the code and produce the HSP_RPC_GUI_3_0_1.bin

Quote:

mbed compile -t GCC_ARM -m MAX32620HSP

This link may be used to install the mbed command-line-interface (cli) if needed

Files at this revision

API Documentation at this revision

Comitter:
jbradshaw
Date:
Tue Apr 25 10:47:10 2017 -0500
Parent:
2:d483f896c7a9
Commit message:
Removed Bulk Erasing, instead a small number of bytes are sampled from each and every page to determine if sector is "dirty", if so sector is erased
Prevents device from sleeping when the firmware detects a series of binary flash page RPC transfers, this increases flash page transfers by %450
when 200mS elapse with the last flash page transfer, normal sleep behaviour is resumed

Changed in this revision

HSP/Devices/S25FS256/S25FS512.cpp Show annotated file Show diff for this revision Revisions of this file
HSP/Devices/S25FS256/S25FS512.h Show annotated file Show diff for this revision Revisions of this file
HSP/Devices/S25FS256/S25FS512_RPC.cpp Show annotated file Show diff for this revision Revisions of this file
HSP/LoggingService/Logging_RPC.cpp Show annotated file Show diff for this revision Revisions of this file
HSP/RpcServer/RpcServer.cpp Show annotated file Show diff for this revision Revisions of this file
HSP/RpcServer/RpcServer.h Show annotated file Show diff for this revision Revisions of this file
HSP/Test/Test_S25FS512.cpp Show annotated file Show diff for this revision Revisions of this file
HSP/main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/HSP/Devices/S25FS256/S25FS512.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/Devices/S25FS256/S25FS512.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -124,6 +124,7 @@
 	return reg_write_read_multiple_quad(cmdArray,5,flashBuffer,0);
 }
 
+//******************************************************************************
 int8_t S25FS512::writeAnyRegister4Wire(uint32_t address, uint8_t data) {
   uint8_t cmdArray[5];
   cmdArray[0] = 0x71;
@@ -133,6 +134,7 @@
   cmdArray[4] = data;
   return reg_write_read_multiple_4Wire(cmdArray, 5, flashBuffer, 5);
 }
+
 //******************************************************************************
 int8_t 	S25FS512::writeRegisters(void) {
 	uint8_t cmdArray[3];
@@ -144,7 +146,6 @@
 	return 0;
 }
 
-
 //******************************************************************************
 int8_t S25FS512::readAnyRegister(uint32_t address, uint8_t *data, uint32_t length) {
 	uint8_t cmdArray[4];
@@ -269,6 +270,41 @@
 }
 
 //******************************************************************************
+int8_t S25FS512::quadIoRead_PartialPage(uint32_t address, uint8_t *buffer, uint32_t numberOfBytesInPage) {
+	uint8_t cmdArray[5];
+	uint8_t *ptr;
+	uint8_t last;
+	uint32_t packetSize;
+	uint32_t xferCount;
+	cmdArray[0] = 0xEC; //0xEB;
+	cmdArray[1] = (address >> 24) & 0xFF;
+	cmdArray[2] = (address >> 16) & 0xFF;
+	cmdArray[3] = (address >> 8) & 0xFF;
+	cmdArray[4] = (address >> 0) & 0xFF;
+	//reg_write_read_multiple_quad(cmdArray,4,flashBuffer,32);
+	ptr = buffer;
+	last = 0;
+	// only send the command
+	reg_write_read_multiple_quad_last(cmdArray, 5, ptr, 0, 0);
+	//wait_ms(1);
+	reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 5, 0);
+	//wait_ms(1);
+
+	xferCount = 0;
+	do { 
+		packetSize = 64;
+		if ((xferCount + packetSize) > numberOfBytesInPage) {
+			packetSize = numberOfBytesInPage;
+			last = 1;
+		}
+		reg_write_read_multiple_quad_last(cmdArray,0,ptr,packetSize, 0);
+		xferCount += packetSize;
+		ptr += packetSize;
+	} while (last != 1);
+	return 0;
+}
+
+//******************************************************************************
 int8_t S25FS512::checkBusy(void) {
 	uint8_t cmdArray[5];
 	cmdArray[0] = 0x05;
@@ -294,7 +330,7 @@
 
 //******************************************************************************
 int8_t S25FS512::parameterSectorErase(uint32_t address) {
-	uint8_t cmdArray[5];
+	uint8_t cmdArray[5];	
 	cmdArray[0] = 0x21;     //0x20 (P4E), 0x21 (4P4E)
 	cmdArray[1] = (address >> 24) & 0xFF;
 	cmdArray[2] = (address >> 16) & 0xFF;
@@ -413,11 +449,10 @@
 	waitTillNotBusy();
 	wait_us(100);
 	wren();
-	wait_us(100);
+	wait_us(200);
 	parameterSectorErase(address);
 	wait_us(100);
 	waitTillNotBusy();
-	wait_us(100);
 	return 0;
 }
 
@@ -426,21 +461,10 @@
 	waitTillNotBusy();
 	wait_us(100);
 	wren();
-	wait_us(100);
-
-  if (address < 0x20000) { //0x8000) {
-    parameterSectorErase(address);
-  } else {
+	wait_us(200);
     sectorErase(address);
-  }  
-	//if (address < 0x20000) {
-		//parameterSectorErase(address);
-	//} else {
-		//sectorErase(address);
-	//}
 	wait_us(100);
 	waitTillNotBusy();
-	wait_us(100);
 	return 0;
 }
 
@@ -490,4 +514,12 @@
 	return status;
 }
 
+//******************************************************************************
+int8_t S25FS512::readPartialPage_Helper(uint32_t pageNumber, uint8_t *buffer, uint32_t count) {
+	int8_t status = 0;
+	waitTillNotBusy();
+	status = quadIoRead_PartialPage((uint32_t)(pageNumber << 8), (uint8_t *)buffer, count);
+	return status;
+}
 
+
--- a/HSP/Devices/S25FS256/S25FS512.h	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/Devices/S25FS256/S25FS512.h	Tue Apr 25 10:47:10 2017 -0500
@@ -37,6 +37,22 @@
 #include "QuadSpiInterface.h"
 
 
+#define ADDRESS_INC_4K      0x1000
+#define ADDRESS_INC_32K     0x8000
+#define ADDRESS_INC_64K     0x10000
+
+#define ADDRESS_4K_START        0x0
+#define ADDRESS_4K_END          0x8000  
+  
+#define ADDRESS_32K_START       0x8000
+#define ADDRESS_32k_END         0x10000  
+  
+#define ADDRESS_64K_START       0x10000
+#define ADDRESS_64k_END         0x2000000  
+
+#define SIZE_OF_EXTERNAL_FLASH  0x2000000 // 33,554,432 Bytes
+#define SIZE_OF_PAGE            0x100
+
 #define IOMUX_IO_ENABLE              1
 
 #define S25FS512_SPI_PORT            1
@@ -139,6 +155,8 @@
 
   void test_verifyPage0Empty(uint8_t *ptr, int currentPage, int pagesWrittenTo);
 
+  int8_t readPartialPage_Helper(uint32_t pageNumber, uint8_t *buffer, uint32_t count);
+
 private:
   void disableInterrupt(uint8_t state);
   int8_t reg_write_read_multiple_quad_last(uint8_t *dataIn, uint8_t numberIn, uint8_t *dataOut, uint8_t numberOut, uint8_t last);
@@ -161,6 +179,7 @@
   void waitTillNotBusy(void);
   int8_t sectorErase(uint32_t address);
   int8_t parameterSectorErase(uint32_t address);
+  int8_t quadIoRead_PartialPage(uint32_t address, uint8_t *buffer, uint32_t numberOfBytesInPage);
 
   uint8_t flashBuffer[257 + 10];
 };
--- a/HSP/Devices/S25FS256/S25FS512_RPC.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/Devices/S25FS256/S25FS512_RPC.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -36,6 +36,7 @@
 #include "StringInOut.h"
 #include "StringHelper.h"
 #include "Peripherals.h"
+#include "RpcServer.h"
 
 int S25FS512_Reset(char argStrs[32][32], char replyStrs[32][32]) {
   uint32_t reply[1];
@@ -103,6 +104,9 @@
   uint32_t endPage;
   uint32_t page;
 
+  // indicate that we are doing a flash binary transfer
+  RPC_TransferingFlashPages();
+
   ProcessArgs32(argStrs, args, sizeof(args) / sizeof(uint32_t));
   startPage = args[0];
   endPage = args[1];
--- a/HSP/LoggingService/Logging_RPC.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/LoggingService/Logging_RPC.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -37,6 +37,7 @@
 #include "DataLoggingService.h"
 #include "Peripherals.h"
 #include "Logging.h"
+#include "S25FS512.h"
 
 extern char loggingMissionCmds[4096];
 uint32_t missionCmdIndex;
@@ -161,31 +162,89 @@
   return 0;
 }
 
-#define SECTOR_SIZE_256K 0x10000
-#define PAGE_INC_256K 0x400
-#define SECTOR_SIZE_4K 0x1000
-#define PAGE_INC_4K 0x10
-#define TOTAL_SECTOR_NUMBER 263
-
-
-#define ADDRESS_INC_4K      0x1000
-#define ADDRESS_INC_32K     0x8000
-#define ADDRESS_INC_64K     0x10000
+//
+// small helper function to determine if the X number of a page are FF (empty)
+//
+static bool isPartialPageEmpty(uint8_t *ptr, int count) {
+	int i;
+	for (i = 0; i < count; i++) {
+		if (ptr[i] != 0xFF) return false;
+	}
+	return true;
+}
 
-#define ADDRESS_4K_START      0x0
-#define ADDRESS_4K_END        0x8000  
-  
-#define ADDRESS_32K_START     0x8000
-#define ADDRESS_32k_END       0x10000  
-  
-#define ADDRESS_64K_START     0x10000
-#define ADDRESS_64k_END       0x2000000  
-
-#define SIZE_OF_EXTERNAL_FLASH  0x2000000 // 33,554,432 Bytes
+//
+// define the different sector sizes in flash
+//
+typedef enum {
+  e4K,
+  e32K,
+  e64K
+} loggingFlashArea_t;
 
 //******************************************************************************
 int Logging_EraseWrittenSectors(char argStrs[32][32], char replyStrs[32][32]) {
-  Peripherals::s25FS512()->bulkErase_Helper();
+  uint32_t i;
+  uint8_t data[512];
+  uint32_t address;
+  uint32_t pageNumber;
+  bool pageEmpty;
+  uint32_t pagesToScan;
+  loggingFlashArea_t currentArea;
+  uint32_t currentAreaSize;
+  //Peripherals::s25FS512()->bulkErase_Helper();
+
+  //
+  // quickly scan through the first few bytes of a page and continue this through a sector
+  // this will determine if the sector needs to be erased or can be skipped
+  //
+  currentArea = e4K;
+  address = 0;
+  // interate through the entire flash
+  while (address < SIZE_OF_EXTERNAL_FLASH) {
+    // determine the size of the current area 
+    switch (currentArea) {
+      case e4K: 
+        currentAreaSize = ADDRESS_INC_4K;
+        break;
+      case e32K: 
+        currentAreaSize = ADDRESS_INC_32K;
+        break;
+      default: 
+        currentAreaSize = ADDRESS_INC_64K;
+        break;
+    }
+    pagesToScan = currentAreaSize / SIZE_OF_PAGE;
+    pageNumber = address >> 8;
+    pageEmpty = true;
+    // scan the first few bytes in each page for this area
+    for (i = 0; i < pagesToScan; i++) {
+      Peripherals::s25FS512()->readPartialPage_Helper(pageNumber + i, data, 4);
+      pageEmpty = isPartialPageEmpty(data, 4);
+      if (pageEmpty == false) break;
+    }
+    // if we detected data then erase this sector
+    if (pageEmpty == false) {
+      switch (currentArea) {
+        case e4K: 
+          Peripherals::s25FS512()->parameterSectorErase_Helper(address); 
+          break;
+        default: 
+          Peripherals::s25FS512()->sectorErase_Helper(address); 
+          break;
+      }
+    } 
+    // update the address with the current area size
+    address += currentAreaSize;
+    // determine the new area in flash
+    if (address < ADDRESS_4K_END) {  
+      currentArea = e4K;
+    } else if (address == ADDRESS_32K_START) {  
+        currentArea = e32K;
+      } else { 
+          currentArea = e64K;
+        }    
+  }
   return 0;
 }
 
--- a/HSP/RpcServer/RpcServer.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/RpcServer/RpcServer.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -72,6 +72,10 @@
 /// and loggin status
 Device_Logging *MAX30205_1_Logging;
 
+///Defines a timer to detect if a series of binary pages are being transfered via RPC
+Timer rpcFlashPagesTransferTimer;
+bool rpcFlashPagesTransferTimer_running;
+
 //******************************************************************************
 fifo_t *GetUSBIncomingFifo(void) { return &fifo; }
 
@@ -86,6 +90,28 @@
 }
 
 //******************************************************************************
+bool RPC_IsTransferingFlashPages(void) {
+  if (rpcFlashPagesTransferTimer_running == true) {
+    if (rpcFlashPagesTransferTimer.read_ms() < 200) {
+      return true;
+    } else {
+      rpcFlashPagesTransferTimer.stop();
+      rpcFlashPagesTransferTimer_running = false;
+    }
+  }
+  return false;
+}
+
+//******************************************************************************
+void RPC_TransferingFlashPages(void) {
+  if (rpcFlashPagesTransferTimer_running == false) {
+    rpcFlashPagesTransferTimer.start();
+    rpcFlashPagesTransferTimer_running = true;
+  }
+  rpcFlashPagesTransferTimer.reset();
+}
+
+//******************************************************************************
 int System_ReadBuildTime(char argStrs[32][32], char replyStrs[32][32]) {
   // strcpy(replyStrs[0],buildTime);
   // strcpy(replyStrs[1],"\0");
@@ -127,6 +153,8 @@
   MAX30205_0_Logging = new Device_Logging();
   MAX30205_1_Logging = new Device_Logging();
 
+  rpcFlashPagesTransferTimer_running = false;
+
   fifo_init(&fifo, fifoBuffer, sizeof(fifoBuffer));
   fifo_init(&fifoStreamOut, streamOutBuffer,
             sizeof(streamOutBuffer) / sizeof(uint32_t));
--- a/HSP/RpcServer/RpcServer.h	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/RpcServer/RpcServer.h	Tue Apr 25 10:47:10 2017 -0500
@@ -50,17 +50,30 @@
 void RPC__call(char *request, char *reply);
 fifo_t *GetUSBIncomingFifo(void);
 fifo_t *GetStreamOutFifo(void);
+
 /**
 * @brief Batch process RPC commands
 */
 void RPC_ProcessCmds(char *cmds);
+
 /**
 * @brief Initialize the RPC server with all of the commands that it supports
 */
 void RPC_init(void);
+
 /**
 * @brief Initialize the RPC server with all of the commands that it supports
 */
 void RPC_call(char *request, char *reply);
 
+/**
+* @brief Query to determine if flash pages are being transfered via RPC
+*/
+bool RPC_IsTransferingFlashPages(void);
+
+/**
+* @brief Called to indicate that a flash page is being transfered via RPC, this reset a timer to detect multiple page transfers over time
+*/
+void RPC_TransferingFlashPages(void) ;
+
 #endif // _RPCSERVER_H_ 
--- a/HSP/Test/Test_S25FS512.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/Test/Test_S25FS512.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -33,11 +33,6 @@
 #include "Test_S25FS512.h"
 #include "Test_Utilities.h"
 
-
-#define SIZE_OF_EXTERNAL_FLASH  0x2000000 // 33,554,432 Bytes
-/// number of pages 
-#define NUMBER_OF_PAGES ((SIZE_OF_EXTERNAL_FLASH / 256) - 1)
-
 //******************************************************************************
 void test_S25FS512(void (*outputString)(const char *)) {
   char tempStr[32];
--- a/HSP/main.cpp	Fri Apr 21 18:10:37 2017 -0500
+++ b/HSP/main.cpp	Tue Apr 25 10:47:10 2017 -0500
@@ -263,7 +263,12 @@
     }
     // process any logging or streaming requests
     LoggingService_ServiceRoutine();
-    // allow for ble processing
-    ble.waitForEvent();
+    // determine if we are doing a large USB transfer of flash datalog sensor data 
+    //   skip updating the ble and sleeping, this conditional branch increases download
+    //   rates by about %450 (time to download 32M flash from 90 minutes to about 20 minutes)
+    if (RPC_IsTransferingFlashPages() == false) { 
+      // allow for ble processing
+      ble.waitForEvent();
+    }
   }
 }