We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Okay... admittedly this is slightly off topic, since I don't think it really has anything to do with the KEIL tools per se, but I am using KEIL tools on this project. I originally posted this on AT91.COM, but since that forum gets so little traffic I'm cross posting here hoping that someone can help.
I created an ASSERT macro for my project and noticed something funny. Basically, my ASSERT macro dumps the expression, filename and line number out the debug UART and then attempts to reset the micro by writing to the reset controller. Sometimes the macro works, sometimes it doesn't. When it doesn't work, the symptom is that the micro does not appear to come out of reset. After much investigation and trial and error I tried to reset the micro using a different method. I called the reset vector as shown below:
((void(*)(void))0x100000)(); // reset vector is 0x100000
Using the above method to reset the micro seems to make my ASSERT macro work rock solid.
My question is, does anyone know about any problems or common mistakes with getting the processor to reset via the RSTC...? Here's how I used the RSTC to reset the micro:
typedef volatile unsigned int * pMR; // pointer to microcontroller register #define RSTC_CR (*((pMR) 0xFFFFFD00)) #define RSTC_CR_PROCRST ((unsigned int)1 << 0) #define RSTC_CR_PERRST ((unsigned int)1 << 2) #define RSTC_KEY(x) ((unsigned int)(x) << 24) RSTC_CR = RSTC_CR_PROCRST | RSTC_CR_PERRST | RSTC_KEY(0xA5);
Can anyone tell me whether they see something wrong with how I'm trying to reset the micro as shown above, or how I should do it differently...?
Thanks !!
I'm wondering if there's a relation between the above problem and another problem I've been experiencing for some time now. The other problem is that sometimes after I do a build and load the code into my target via KEIL's ULINK tool it just won't run. When this happens I usually try something like:
1 - loading it again 2 - doing a build all and try again 3 - toggle the hardware reset switch input and try again 4 - cycle power on the target and try again 5 - cycle power on the ULINK and try again 6 - restart the KEIL IDE and try again 7 - revert to a prior working version of the code and try again 8 - load the code into the board via the debugger and single step into it 9 - etc., etc., etc.
Sometimes any one of the above will make the problem go away, but eventually, the very code that wouldn't load and run will load and run just fine. The oddest case is when all the easy steps don't fix the problem, I then try things with the debugger and everything works fine. After that, I can once again just load code and run with no problems.
I currently don't suspect my hardware, as the stuff around the micro (i.e., the crystal & cap's, JTAG interface, RESET input, etc.) were directly copied from an ATMEL eval board
Has anyone else experienced problems reliably loading and running code on an AT91SAM7 part using KEIL's ULINK tool?
Does anyone have any suggestions to make loading and running code via the ULINK reliable?
HELP... (please)... Dave.
Hmmm... I tried the code on an (similarly configured) ATMEL eval board and guess what...? The code runs just fine. So, I found another (different design) SAM7S256 based board and guess what...? The code runs just fine on that board too. Something tells me I've probably got a hardware problem after all. I guess that's good news.
After much hardware investigation, the only difference I could find between AT91SAM7S256 boards that worked and those that didn't was the date code of the microcontroller.
I found that if I put different date code chips on my boards (that weren't working reliably) they started working just fine. Unfortunately, the date codes for the parts that work (0604) are earlier than the ones that don't work (0621). That's not good.
0604 = 4th week of 2006 0621 = 21st week of 2006
My local ATMEL FAE and distributor are bringing me a few different date code parts for me to try to see what happens. Hopefully some of them will be fairly current.
I realize this has nothing to do with KEIL tools, but I'd just like to get closure for this thread.
You are of course aware that jumping to a reset vector does not reset a microprocessor? It only restarts the software.
After a real reset, all interrupts are disabled and any pheripherals are in a default state.
If you jump to the reset vector, the initialization code may fail, since it makes assumptions about the processor state. You might get interrupts, while the init code hasn't yet finished setting up all interrupt vectors, resulting in a crash.
Very good points... thanks!! And yes, I am aware of them. However, for this trivial test project, no interrupts were ever enabled. The only thing the program did was:
1 - enable the external hardware reset input 2 - configure one I/O pin as an output 3 - toggle that I/O pin a few times 4 - assert the software controlled reset input to the reset controller.
This code failed on all but one of the SAM7S256 boards I've got (once they ran for a while and warmed up). The point of jumping to the reset vector rather than asserting the reset input to the reset controller was to help isolate the problem to the reset controller, or something associated with coming out of a hardware reset, as opposed to something with just running code from FLASH.
I certainly do appreciate your insightful response.
Dave.
The SAM7S datasheet provides a bit in the reset controller's status register (SRCMP) to provide a method to tell if any part of a software generated reset is in progress or not. The text goes on to state that when this bit is cleared, it's okay to write to the reset controller's registers. This implies that it's not okay to write to the reset controller's mode register if any part of a software generated reset is still active.
Why bring this up? Okay, I know this is a stretch, but it looks like the very first part of the KEIL generated startup code in SAM7.s writes to the reset controller's mode register. It would seem logical that if the SAM7S is executing code, no part of any software generated reset could still be active, but maybe that's not the case.
Now for the request for help...
I'm not an ARM assembly language programmer (yet). Can someone show me how to modify the default KEIL SAM7.s file to include a loop that waits for the SRCMP bit in the reset controller's status register to be clear before advancing (to the part that writes to the reset controller's mode register)?
I'd sure appreciate it. It'd be easy to test to see if that fixes my RSTC problem.
Thanks, Dave.
P.S. I have received additional different date code parts (much newer than the parts I had), and all date code parts I've tested to date have this problem (once the chips warm up enough, which is usually somewhere between 85°F and 100°F). Even chips I earlier thought did not have this problem. A fair amount of the chips I have won't show this symptom till they've been warmed up using a heat gun. It usually takes only 2 or 3 seconds of heat from a heat gun to make the chips fail. A couple of the chips had to be warmed to ~ 145°F before they failed.
I'd sure like to get to the bottom of this one !!
ATMEL tech support in Rousset informed me that the configuration wizard generated code for this part was flawed in the part where it switched MCK. The datasheet requires a certain procedure to correctly switch MCK, which was not done in the code generated by KEIL's configuration wizard. When I changed my code per Rousset's suggestions, my temperature sensitivity problems appear to have been fixed, and the reset controller appears to now work flawlessly.
I've forwarded Rousset's suggestion to KEIL's tech support in the form of a bug report.
Here's Rousset's comments:
Here is an extract from the datasheet (PMC section): If a new value for CSS field corresponds to PLL Clock, – Program the PRES field in the PMC_MCKR register. – Wait for the MCKRDY bit to be set in the PMC_SR register. – Program the CSS field in the PMC_MCKR register. – Wait for the MCKRDY bit to be set in the PMC_SR register.
However, they do not program correctly the PMC. They have programmed the MCKR in one time and they have forgotten to wait the MCKRDY flag which is mandatory to be sure they system clock has correctly switched on...
So, it should be more:
PMC_MCKR_Val1 EQU 0x00000004 PMC_MCKR_Val2 EQU 0x00000007 PMC_MCKRDY EQU (1<<3) ; MCK Ready Status ; Program 1st PRES field LDR R1, =PMC_MCKR_Val1 STR R1, [R0, #PMC_MCKR] ; Wait until MCK is stabilized MCK_Loop1 LDR R2, [R0, #PMC_SR] ANDS R2, R2, #PMC_MCKRDY BEQ MCK_Loop1 ; Then program CSS field LDR R1, =PMC_MCKR_Val2 STR R1, [R0, #PMC_MCKR] ; Wait until MCK is stabilized MCK_Loop2 LDR R2, [R0, #PMC_SR] ANDS R2, R2, #PMC_MCKRDY BEQ MCK_Loop2