On 04/19/2013 11:47 AM, Steve McKown wrote:
> Hi,
> 
> openocd cannot program the PK20DX256VLL7 uC on the Freescale Kinetis 
> TWR-K20D72M eval board via its onboard OSBDM JTAG interface.  I'm using 
> openocd trunk at commit 2cb4862, and OSBDM firmware version 31.32.  Host 
> system is Ubuntu 12.04 32-bit.
> 
> As mentioned in a prior msg to the list, this newer firmware presents a 
> different USB VID:PID.  I tested with the necessary patch to work around 
> this issue.
> 
> The openocd error on flash_write is:
> 
> Error: ftfx command failed FSTAT: A0 FCCOB: 0B000000 01000000 00000000
> Error: error writing to flash at address 0x00000000 at offset 0x00000000
> 
> The K20P100M72SF1RM data sheet (Rev 1.1, Dec 2012), in the FTFL section 
> documenting the Program Section command (28.4.11.8) indicates that only 
> the lower half of available FlexRAM is usable for programming flash. 
> With some extra debug in kinetis_write(), it looks like openocd is 
> trying to write a 2 KB section, violating this limit.  I think the data 
> sheet means that on this processor only 1 KB of FlexRAM is usable for 
> Program Section operations.
> 
> I don't actually know if this hypothesis is true.  I can program this 
> part if I hack kinetis_write() to force the longword programming method, 
> however.  I'm hoping this report might be useful for someone else with 
> more knowledge in this area.
> 
> Thanks,
> Steve

Thanks for the report Steve.  Alex Austin has reported the same issue, here is 
his approach to solving: http://openocd.zylin.com/#/c/1198/

The difficulty lies in determining the amount of FlexRAM available in the 
Kinetis part.

Ideally we would identify the amount of FlexRAM by inspecting some definitive 
register field(s).  I've attached a patch that assumes the FlexNVM size is the 
same as half the FlexRAM size (which is logical, but not yet verified by 
Freescale).  This seems to only make a difference on the "SF1" parts so it 
should cover your case.  I don't have any K20 Kinetis parts, but if you care to 
try the patch, I can confirm it does not break my "SF2" and "SF3" K60 parts, 
and then push the solution through Gerrit.

Chris Kilgour
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index 494c266..8eef8d9 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -365,23 +365,27 @@ static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
 
 	/* program section command */
 	if (fallback == 0) {
-		unsigned prog_section_bytes = kinfo->sector_size >> 8;
-		for (i = 0; i < count; i += kinfo->sector_size) {
-			/*
-			 * The largest possible Kinetis "section" is
-			 * 16 bytes.  A full Kinetis sector is always
-			 * 256 "section"s.
-			 */
+		/*
+		 * Kinetis uses different terms for the granularity of
+		 * sector writes, e.g. "phrase" or "128 bits".  We use
+		 * the generic term "chunk". The largest possible
+		 * Kinetis "chunk" is 16 bytes (128 bits).
+		 */
+		unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
+                /* assume the NVM sector size is half the FlexRAM size */
+                unsigned prog_size_bytes = MIN( kinfo->sector_size,
+                                                kinetis_flash_params[kinfo->granularity].nvm_sector_size_bytes );
+		for (i = 0; i < count; i += prog_size_bytes) {
 			uint8_t residual_buffer[16];
 			uint8_t ftfx_fstat;
-			uint32_t section_count = 256;
+			uint32_t section_count = prog_size_bytes / prog_section_chunk_bytes;
 			uint32_t residual_wc = 0;
 
 			/*
 			 * Assume the word count covers an entire
 			 * sector.
 			 */
-			wc = kinfo->sector_size / 4;
+			wc = prog_size_bytes / 4;
 
 			/*
 			 * If bytes to be programmed are less than the
@@ -390,21 +394,21 @@ static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
 			 * residual buffer so that a full "section"
 			 * may always be programmed.
 			 */
-			if ((count - i) < kinfo->sector_size) {
+			if ((count - i) < prog_size_bytes) {
 				/* number of bytes to program beyond full section */
-				unsigned residual_bc = (count-i) % prog_section_bytes;
+				unsigned residual_bc = (count-i) % prog_section_chunk_bytes;
 
 				/* number of complete words to copy directly from buffer */
 				wc = (count - i) / 4;
 
 				/* number of total sections to write, including residual */
-				section_count = DIV_ROUND_UP((count-i), prog_section_bytes);
+				section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
 
 				/* any residual bytes delivers a whole residual section */
-				residual_wc = (residual_bc ? prog_section_bytes : 0)/4;
+				residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
 
 				/* clear residual buffer then populate residual bytes */
-				(void) memset(residual_buffer, 0xff, prog_section_bytes);
+				(void) memset(residual_buffer, 0xff, prog_section_chunk_bytes);
 				(void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
 			}
 
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to