I am newcomer for ARM-based 32-bit microcontroller. Recently, I started to learn this type of MCU using the following development environment:
Software: Windows XP (32-bit), Eclipse (Helios), yagarto-bu-2.20.1_gcc-4.5.1-c-c++_nl-1.18.0_gdb-7.1_eabi_20100813, yagarto-tools-20100703-setup
Hardware: Phyton TB2-LPC210X evaluation board, ARM-USB-OCD debugger
The current problem is I don’t know if the firmware has been really programmed/loaded into the MCU or the MCU is already damaged, because I can not see the LED on.
From the schematics of Phyton TB2-LPC210X evaluation board, a LED is connected to P0.7, BSL jumper is connected to P0.14, and a button is connected to P0.16. I found it is the same as Olimex’s eva board for LPC2106. The only difference is on my board, it uses an oscillator 16 MHz instead of 12MHz.
Source code:
Refer to the demo2106_blink_flash in OpenOCD-projects 1.00.zip. I believe many developers have seen this code before. In the code, I made two changes, one is just to turn on the LED, the other is PLLCFG=0x31; which is based on P = 4, and M = 2.
/* *********************************************************
Function declarations
********************************************************* */
void Initialize(void);
void feed(void);
void IRQ_Routine (void) attribute ((interrupt(“IRQ”)));
void FIQ_Routine (void) attribute ((interrupt(“FIQ”)));
void SWI_Routine (void) attribute ((interrupt(“SWI”)));
void UNDEF_Routine (void) attribute ((interrupt(“UNDEF”)));
/**********************************************************
Header files
**********************************************************/
#include “LPC210x.h”
/**********************************************************
MAIN
**********************************************************/
int main (void) {
int j; // loop counter (stack variable)
int i;
// Initialize the system
Initialize();
// set io pins for led P0.7
IODIR |= 0x00000080; // pin P0.7 is an output, everything else is input after reset
IOSET = 0x00000080; // led off
IOCLR = 0x00000080; // led on
// endless loop to toggle the red LED P0.7
while (1)
{
//if ((IOPIN & 0x00008000)) IOSET = 0x00000080;
//else
{
IOCLR = 0x00000080;
//for (j = 0; j < 300000; j++ ); // wait 500 msec
//IOSET = 0x00000080;
for (j = 0; j < 2000000; j++ );
}
for (i = 0; i < 100; i++);
}
return 0;
}
/**********************************************************
Initialize
**********************************************************/
#define PLOCK 0x400
void Initialize(void)
{
// Setting the Phased Lock Loop (PLL)
// ----------------------------------
//
// Olimex LPC-P2106 has a 14.7456 mhz crystal
//
// We’d like the LPC2106 to run at 53.2368 mhz (has to be an even multiple of crystal)
//
// According to the Philips LPC2106 manual: M = cclk / Fosc where: M = PLL multiplier (bits 0-4 of PLLCFG)
// cclk = 53236800 hz
// Fosc = 14745600 hz
//
// Solving: M = 53236800 / 14745600 = 3.6103515625
// M = 4 (round up)
//
// Note: M - 1 must be entered into bits 0-4 of PLLCFG (assign 3 to these bits)
//
//
// The Current Controlled Oscilator (CCO) must operate in the range 156 mhz to 320 mhz
//
// According to the Philips LPC2106 manual: Fcco = cclk * 2 * P where: Fcco = CCO frequency
// cclk = 53236800 hz
// P = PLL divisor (bits 5-6 of PLLCFG)
//
// Solving: Fcco = 53236800 * 2 * P
// P = 2 (trial value)
// Fcco = 53236800 * 2 * 2
// Fcc0 = 212947200 hz (good choice for P since it’s within the 156 mhz to 320 mhz range
//
// From Table 19 (page 48) of Philips LPC2106 manual P = 2, PLLCFG bits 5-6 = 1 (assign 1 to these bits)
//
// Finally: PLLCFG = 0 01 00011 = 0x23
//
// Final note: to load PLLCFG register, we must use the 0xAA followed 0x55 write sequence to the PLLFEED register
// this is done in the short function feed() below
//
// Setting Multiplier and Divider values
//PLLCFG=0x23;
PLLCFG=0x31;
feed();
// Enabling the PLL */
PLLCON=0x1;
feed();
// Wait for the PLL to lock to set frequency
while(!(PLLSTAT & PLOCK)) ;
// Connect the PLL as the clock source
PLLCON=0x3;
feed();
// Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case)
MAMCR=0x2;
MAMTIM=0x4;
// Setting peripheral Clock (pclk) to System Clock (cclk)
VPBDIV=0x1;
}
void feed(void)
{
PLLFEED=0xAA;
PLLFEED=0x55;
}
/* Stubs for various interrupts (may be replaced later) */
/* ---------------------------------------------------- */
void IRQ_Routine (void) {
while (1) ;
}
void FIQ_Routine (void) {
while (1) ;
}
void SWI_Routine (void) {
while (1) ;
}
void UNDEF_Routine (void) {
while (1) ;
}
I created an empty make project, and imported the source code for demolpc2106_blink_flash into workspace, and did above two modifications. Then, I build the project, it is successful and generate main.bin, main.out and so on.
Then, I want to program the MCU using this main.bin. Obviously, the methods in previous version of using OpenOCD can not be directly used, though it is very informative. So, I go to this forum and read other’s post first. I found some articles are very good and helpful. So, I generate the following cfg file for programming the MCU.
interface ft2232
ft2232_device_desc “Olimex OpenOCD JTAG”
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003
jtag_khz 15000
jtag_nsrst_delay 200
jtag_ntrst_delay 200
set CPU_TYPE arm
set CPU_NAME arm7tdmi-s
set CPU_ARCH armv4t
set CPU_MAX_ADDRESS 0xFFFFFFFF
set CPU_NBITS 32
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME lpc2106
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x4f1f0f0f
}
#use combined on interfaces or targets that can’t set TRST/SRST separately
#reset_config trst_and_srst separate
reset_config trst_and_srst srst_pulls_trst
reset delays
jtag_nsrst_delay 100
jtag_ntrst_delay 100
jtag_khz 1000
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi-s_r4
64kB of internal SRAM
$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0
128kB of internal Flash
flash bank lpc2000 0 0 <target#> [calc_checksum]
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME lpc2000 0x0 0x20000 0 0 $_TARGETNAME lpc2000_v1 16000
Run the flashing script on reset event
$_TARGETNAME configure -event reset-init {
soft_reset_halt
arm7_9 dcc_downloads enable
arm7_9 fast_memory_access enable
wait_halt
flash probe 0
#flash protect 0 0 1 off
flash erase_sector 0 0 0
flash write_bank 0 main.bin 0x0
resume
}
#Forces execution of the reset and init events, then quit
init
reset init
shutdown
Then the console screen displays,
Open On-Chip Debugger 0.4.0 (2010-02-22-19:05)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.berlios.de/doc/doxygen/bugs.html
15000 kHz
jtag_nsrst_delay: 200
jtag_ntrst_delay: 200
trst_and_srst srst_pulls_trst srst_gates_jtag trst_push_pull srst_open_drain
jtag_nsrst_delay: 100
jtag_ntrst_delay: 100
1000 kHz
Info : clock speed 1000 kHz
Info : JTAG tap: lpc2106.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Info : Embedded ICE version 4
Info : lpc2106.cpu: hardware has 2 breakpoint/watchpoint units
Info : JTAG tap: lpc2106.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)
Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
target state: halted
target halted in Thumb state due to debug-request, current mode: Supervisor
cpsr: 0x400000f3 pc: 0x7fffe252
requesting target halt and executing a soft reset
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x400000d3 pc: 0x00000000
dcc downloads are enabled
fast memory access is enabled
flash ‘lpc2000’ found at 0x00000000
wrote 684 bytes from file main.bin to flash bank 0 at offset 0x00000000 in 0.265620s (2.515 kb/s)
shutdown command invoked
It seems the binary image has been written into the flash memory of the MCU, however, the LED connected to P0.7 is not on.
This is my whole story and I hope any one can point out where I made mistakes. Thanks so much.