SparkFun Forums 

Where electronics enthusiasts find answers.

Open source ARM Debugger
By alarsen
#18173
Hi,
the flash timing of an at91sam7 is incorrectly set (written to the read-only FSR instead of to the FMR, zero wait-states regardless of clock speed).
This only hurts when the target runs faster than the default 32kHz CPU clock.

The patch below fixes this.
Cheers
Anders
Code: Select all
Fix the timing calculations and write the result to the correct register.

Signed-off-by: Anders Larsen <al@alarsen.net>
---
 src/flash/at91sam7.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

Index: b/src/flash/at91sam7.c
===================================================================
--- a/src/flash/at91sam7.c
+++ b/src/flash/at91sam7.c
@@ -206,7 +206,7 @@ void at91sam7_read_clock_info(flash_bank
 /* Setup the timimg registers for nvbits or normal flash */
 void at91sam7_set_flash_mode(flash_bank_t *bank,int mode)
 {
-	u32 fmcn, fmr;
+	u32 fmr, fmcn = 0, fws = 0;
 	at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
 	target_t *target = at91sam7_info->target;
 	
@@ -220,12 +220,14 @@ void at91sam7_set_flash_mode(flash_bank_
 			fmcn = (at91sam7_info->mck_freq/666666ul)+1;
 
 		/* Only allow fmcn=0 if clock period is > 30 us. */
-		if (at91sam7_info->mck_freq <= 33333)
+		if (at91sam7_info->mck_freq <= 33333333ul)
 			fmcn = 0;
+		else
+			fws = 1;
 
 		DEBUG("fmcn: %i", fmcn); 
-		fmr = fmcn<<16;
-		target->type->write_memory(target, MC_FSR, 4, 1, (u8 *)&fmr);
+		fmr = fmcn << 16 | fws << 8;
+		target->type->write_memory(target, MC_FMR, 4, 1, (u8 *)&fmr);
 	}
 	at91sam7_info->flashmode = mode;		
 }
By Dominic
#18177
Hello Anders,

sorry I didn't reply sooner (I've receieved your mails, just didn't have time to answer yet).

I'll add both patches to the next svn revision, thanks a lot.

Regards,

Dominic
By alarsen
#18178
Hi Dominic,
no problem - I just wanted to publish the bug (and the fix) before somebody else got bitten.
Cheers
Anders
By mlu
#18202
Hello Anders and thanks.

Strange that this obvious error survived so long, I have actually used the code to flash an AT91SAM7S running from both 12MHz crystal and the 48MHz PLL for USB and it has worked.
I think the patch needs another fix, since the condition for settng FMCN to 0 is 30uS clock cycle = 33kHz, but the condition for allowing FWS = 0 is a frequency of 30 MHz.
So your code works correctly if the clock is above 33MHz and below 33kHz
Code: Select all
(working copy)
--- /home/lundin/delad/arbete/animatronics/arm7/openocd/trunk/src/flash/at91sam7.c      (revision 92)
+++ /home/lundin/delad/arbete/animatronics/arm7/openocd/trunk/src/flash/at91sam7.c     @@ -220,10 +220,11 @@
                      /* main clocks in 1.5uS */
                      fmcn = (at91sam7_info->mck_freq/666666ul)+1;
 
-              /* Only allow fmcn=0 if clock period is > 30 us. */
-              if (at91sam7_info->mck_freq <= 33333333ul)
+              /* Only allow fmcn=0 if clock period is > 30 us = 33kHz. */
+              if (at91sam7_info->mck_freq <= 33333ul)
                      fmcn = 0;
-              else
+              /* Only allow fws=0 if clock frequency is < 30 MHz. */
+              if (at91sam7_info->mck_freq > 30000000ul)
                      fws = 1;
 
               DEBUG("fmcn: %i", fmcn); 
Greetings
Magnus
By alarsen
#18227
Hello Magnus,
oops - you're right, my patch was incorrect wrt FMCN :oops:
Could the reason you haven't experienced problems with 48MHz possibly be that your own code has set FMR correctly?
Cheers
Anders