View Full Version : Discussion begining to arm7 lpc2148 programming for uav auto pilot
layra
May 22, 2008, 06:05 AM
hi there
i'd like to know how to get the c reference book for the arm lpc2148 and that for the project of paparazzi uav.
had any one programmed arm
i would be thankful for any information
Here's a link to a downloadable book for using the ARM LPC21xx family:
http://www.hitex.co.uk/arm/lpc2000book/
I don't know if there's a C reference book for ARM. C is portable, so you would just have to read a general C book.
MX
layra
May 23, 2008, 03:58 AM
well thanks a lot ,but i already have this book ,and i have already learned c language
but my question is how to deal with all these arm features as the pll ,interrupts, timers.....etc with the c code.
example how can i set a pin to input or output in c language ?
is there any lybraries that i could use?
where should i begin from?
FAKHREALAM
May 23, 2008, 09:36 AM
well thanks a lot ,but i already have this book ,and i have already learned c language
but my question is how to deal with all these arm features as the pll ,interrupts, timers.....etc with the c code.
example how can i set a pin to input or output in c language ?
is there any lybraries that i could use?
where should i begin from?
Please do the google, you will find some examples, I think Hitech provide examples too. Here is the simple code to set I/O pin for LPC2106. You need to check the the data sheet for register address and the do some like this LPC2148 (check the data and change the address if they are not same in last define). Its just an example for you to see how LPC series works.
/* pin as out put */
void init_cs_pin_po_7 (void)
{
//Uses GPIO pins P0.7
PINSEL0 &= 0x0000ff7f;
IODIR |= 0x00000080;
}
/* SCLK */
void spi_clr_clk (void)
{
IOCLR = SCLK_BIT_MASK;
}
/* CS (set low) */
void spi_enable_cs (void)
{
IOCLR = CS_BIT_MASK;
}
/* CS (set high) */
void spi_disable_cs (void)
{
IOSET = CS_BIT_MASK;
}
/************************************************** *************************
**
** GPIO
**
************************************************** *************************/
__IO_REG32_BIT(IOPIN, 0xE0028000,__READ,__gpio_bits);
__IO_REG32_BIT(IOSET, 0xE0028004,__READ_WRITE,__gpio_bits);
__IO_REG32_BIT(IODIR, 0xE0028008,__READ_WRITE,__gpio_bits);
__IO_REG32_BIT(IOCLR, 0xE002800C,__WRITE,__gpio_bits);
You can get LPC doc from web that tell you how to initialize PLL, INTERRUPT, SPI, UART AND I2C. If I get chance I will post the link.
samir140
May 24, 2008, 04:29 AM
link?
layra
May 26, 2008, 04:11 AM
Please do the google, you will find some examples, I think Hitech provide examples too. Here is the simple code to set I/O pin for LPC2106. You need to check the the data sheet for register address and the do some like this LPC2148 (check the data and change the address if they are not same in last define). Its just an example for you to see how LPC series works.
/* pin as out put */
void init_cs_pin_po_7 (void)
{
//Uses GPIO pins P0.7
PINSEL0 &= 0x0000ff7f;
IODIR |= 0x00000080;
}
/* SCLK */
void spi_clr_clk (void)
{
IOCLR = SCLK_BIT_MASK;
}
/* CS (set low) */
void spi_enable_cs (void)
{
IOCLR = CS_BIT_MASK;
}
/* CS (set high) */
void spi_disable_cs (void)
{
IOSET = CS_BIT_MASK;
}
/************************************************** *************************
**
** GPIO
**
************************************************** *************************/
__IO_REG32_BIT(IOPIN, 0xE0028000,__READ,__gpio_bits);
__IO_REG32_BIT(IOSET, 0xE0028004,__READ_WRITE,__gpio_bits);
__IO_REG32_BIT(IODIR, 0xE0028008,__READ_WRITE,__gpio_bits);
__IO_REG32_BIT(IOCLR, 0xE002800C,__WRITE,__gpio_bits);
You can get LPC doc from web that tell you how to initialize PLL, INTERRUPT, SPI, UART AND I2C. If I get chance I will post the link.
well thanks a lot for ur explanation it gives me an idea where to begin the problem now is that i need to get a deep explanation of these features inorder to be able to use them in the program, so if u know a link or a book it will be a great thing and thaks again
eddymoore
May 26, 2008, 11:56 AM
Layra,
There is no substitute for working through the problems yourself. Setting up any peripheral is not that complicated (except perhaps for USB) on the LPC2xxx parts. It is just a question of reading the datasheet. We (a friend and I) have recently got an NXPLPC2148 based flight computer up and running from scratch in a couple of days, using almost all the peripherals (inc USB), a FAT32 filesystem on an SD card (using FatFS library and having written our own SPI port drivers to their specification), and various other things, having not used ARMs before. We did it by finding example code from other people (the file section of the LPC2000 yahoo group is good for this) and going through it with reference to the datasheet to see what it all means and what the registers do. From there we developed our own drivers as necessary. The rest is just normal hardware-independent C.
I sympathize with the preconception that you need to do lots of study and gain lots of understanding before you get your hands dirty with actually hardware - I felt the same. But actually it was really quite easy to get up and running without any 'formal' study. If you have ever used any other microcontrollers like PICs or AVRs, you should have no problem. These chips involve a little more set-up, but it is readily comprehensible if you find a startup file (usually assembler, sometimes C) and study it with the datasheet. They are simpler than they might at first seem.
So be brave - have a go at actually trying to implement your goals as you go along - it is easier than you think and you will learn much faster!
If you have a specific question about the use of a particular peripheral, by all means ask it, but do not fear that you won't be able to achieve anything without the prior study. You will!
Incidentally, we would be nowhere without a debugger. We use Crossworks for development, and the environment, especially the debugger integration, has made it a pleasure to use.
Best of luck,
Ed
FAKHREALAM
May 26, 2008, 03:25 PM
well thanks a lot for ur explanation it gives me an idea where to begin the problem now is that i need to get a deep explanation of these features inorder to be able to use them in the program, so if u know a link or a book it will be a great thing and thaks again
Here is few links and code. You just have to start and go forward, it will take some time but you will do that. Its the way of learning.
http://www.newmicros.com/discussion/archive/index.php/t-876.html
http://www.embeddedrelated.com/groups/lpc2000/35.php?searchfor=philips&by
http://www.testech-elect.com/iar/download/iar_ewarm_sample_download_list.htm
#include <LPC21xx.h>
void main(void)
{
unsigned int i;
// Make P0.6 an output
IO0DIR |= (1<<6);
while (1) {
IO0SET = (1<<6);
for (i=0; i<500000; i++);
IO0CLR = (1<<6);
for (i=0; i<500000; i++);
}
}
/************************************************** *********************/
/* This file is part of the uVision/ARM development tools */
/* Copyright KEIL ELEKTRONIK GmbH 2002-2005 */
/************************************************** *********************/
/* */
/* STARTUP.S: Startup file for Philips LPC2000 device series */
/* */
/************************************************** *********************/
/*
//*** <<< Use Configuration Wizard in Context Menu >>> ***
*/
/*
* The STARTUP.S code is executed after CPU Reset. This file may be
* translated with the following SET symbols. In uVision these SET
* symbols are entered under Options - ASM - Set.
*
* REMAP: when set the startup code initializes the register MEMMAP
* which overwrites the settings of the CPU configuration pins. The
* startup and interrupt vectors are remapped from:
* 0x00000000 default setting (not remapped)
* 0x80000000 when EXTMEM_MODE is used
* 0x40000000 when RAM_MODE is used
*
* EXTMEM_MODE: when set the device is configured for code execution
* from external memory starting at address 0x80000000. The startup
* vectors are located to 0x80000000.
*
* RAM_MODE: when set the device is configured for code execution
* from on-chip RAM starting at address 0x40000000. The startup
* vectors are located to 0x40000000.
*/
// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F
I_Bit EQU 0x80 /* when I bit is set, IRQ is disabled */
F_Bit EQU 0x40 /* when F bit is set, FIQ is disabled */
/*
// <h> Stack Configuration (Stack Sizes in Bytes)
// <o0> Undefined Mode <0x0-0xFFFFFFFF:4>
// <o1> Supervisor Mode <0x0-0xFFFFFFFF:4>
// <o2> Abort Mode <0x0-0xFFFFFFFF:4>
// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:4>
// <o4> Interrupt Mode <0x0-0xFFFFFFFF:4>
// <o5> User/System Mode <0x0-0xFFFFFFFF:4>
// </h>
*/
UND_Stack_Size EQU 0x00000004
SVC_Stack_Size EQU 0x00000004
ABT_Stack_Size EQU 0x00000004
FIQ_Stack_Size EQU 0x00000004
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00000400
AREA STACK, DATA, READWRITE, ALIGN=2
DS (USR_Stack_Size+3)&~3 ; Stack for User/System Mode
DS (SVC_Stack_Size+3)&~3 ; Stack for Supervisor Mode
DS (IRQ_Stack_Size+3)&~3 ; Stack for Interrupt Mode
DS (FIQ_Stack_Size+3)&~3 ; Stack for Fast Interrupt Mode
DS (ABT_Stack_Size+3)&~3 ; Stack for Abort Mode
DS (UND_Stack_Size+3)&~3 ; Stack for Undefined Mode
Top_Stack:
// VPBDIV definitions
VPBDIV EQU 0xE01FC100 /* VPBDIV Address */
/*
// <e> VPBDIV Setup
// <i> Peripheral Bus Clock Rate
// <o1.0..1> VPBDIV: VPB Clock
// <0=> VPB Clock = CPU Clock / 4
// <1=> VPB Clock = CPU Clock
// <2=> VPB Clock = CPU Clock / 2
// <o1.4..5> XCLKDIV: XCLK Pin
// <0=> XCLK Pin = CPU Clock / 4
// <1=> XCLK Pin = CPU Clock
// <2=> XCLK Pin = CPU Clock / 2
// </e>
*/
VPBDIV_SETUP EQU 0
VPBDIV_Val EQU 0x00000000
// Phase Locked Loop (PLL) definitions
PLL_BASE EQU 0xE01FC080 /* PLL Base Address */
PLLCON_OFS EQU 0x00 /* PLL Control Offset*/
PLLCFG_OFS EQU 0x04 /* PLL Configuration Offset */
PLLSTAT_OFS EQU 0x08 /* PLL Status Offset */
PLLFEED_OFS EQU 0x0C /* PLL Feed Offset */
PLLCON_PLLE EQU (1<<0) /* PLL Enable */
PLLCON_PLLC EQU (1<<1) /* PLL Connect */
PLLCFG_MSEL EQU (0x1F<<0) /* PLL Multiplier */
PLLCFG_PSEL EQU (0x03<<5) /* PLL Divider */
PLLSTAT_PLOCK EQU (1<<10) /* PLL Lock Status */
/*
// <e> PLL Setup
// <i> Phase Locked Loop
// <i> CCLK - Processor Clock
// <i> Fcco - PLL Oscillator
// <o1.0..4> MSEL: PLL Multiplier Selection
// <1-32><#-1>
// <i> PLL Multiplier "M" Value
// <i> CCLK = M * Fosc
// <o1.5..6> PSEL: PLL Divider Selection
// <0=> 1 <1=> 2 <2=> 4 <3=> 8
// <i> PLL Divider "P" Value
// <i> Fcco = CCLK * 2 * P
// <i> 156MHz <= Fcco <= 320MHz
// </e>
*/
PLL_SETUP EQU 1
PLLCFG_Val EQU 0x00000024
// Memory Accelerator Module (MAM) definitions
MAM_BASE EQU 0xE01FC000 /* MAM Base Address */
MAMCR_OFS EQU 0x00 /* MAM Control Offset*/
MAMTIM_OFS EQU 0x04 /* MAM Timing Offset */
/*
// <e> MAM Setup
// <i> Memory Accelerator Module
// <o1.0..1> MAM Control
// <0=> Disabled
// <1=> Partially Enabled
// <2=> Fully Enabled
// <i> Mode
// <o2.0..2> MAM Timing
// <0=> Reserved <1=> 1 <2=> 2 <3=> 3
// <4=> 4 <5=> 5 <6=> 6 <7=> 7
// <i> Fetch Cycles
// </e>
*/
MAM_SETUP EQU 1
MAMCR_Val EQU 0x00000002
MAMTIM_Val EQU 0x00000004
// External Memory Controller (EMC) definitions
EMC_BASE EQU 0xFFE00000 /* EMC Base Address */
BCFG0_OFS EQU 0x00 /* BCFG0 Offset */
BCFG1_OFS EQU 0x04 /* BCFG1 Offset */
BCFG2_OFS EQU 0x08 /* BCFG2 Offset */
BCFG3_OFS EQU 0x0C /* BCFG3 Offset */
/*
// <e> External Memory Controller (EMC)
*/
EMC_SETUP EQU 0
/*
// <e> Bank Configuration 0 (BCFG0)
// <o1.0..3> IDCY: Idle Cycles <0-15>
// <o1.5..9> WST1: Wait States 1 <0-31>
// <o1.11..15> WST2: Wait States 2 <0-31>
// <o1.10> RBLE: Read Byte Lane Enable
// <o1.26> WP: Write Protect
// <o1.27> BM: Burst ROM
// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
// <2=> 32-bit <3=> Reserved
// </e>
*/
BCFG0_SETUP EQU 0
BCFG0_Val EQU 0x0000FBEF
/*
// <e> Bank Configuration 1 (BCFG1)
// <o1.0..3> IDCY: Idle Cycles <0-15>
// <o1.5..9> WST1: Wait States 1 <0-31>
// <o1.11..15> WST2: Wait States 2 <0-31>
// <o1.10> RBLE: Read Byte Lane Enable
// <o1.26> WP: Write Protect
// <o1.27> BM: Burst ROM
// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
// <2=> 32-bit <3=> Reserved
// </e>
*/
BCFG1_SETUP EQU 0
BCFG1_Val EQU 0x0000FBEF
/*
// <e> Bank Configuration 2 (BCFG2)
// <o1.0..3> IDCY: Idle Cycles <0-15>
// <o1.5..9> WST1: Wait States 1 <0-31>
// <o1.11..15> WST2: Wait States 2 <0-31>
// <o1.10> RBLE: Read Byte Lane Enable
// <o1.26> WP: Write Protect
// <o1.27> BM: Burst ROM
// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
// <2=> 32-bit <3=> Reserved
// </e>
*/
BCFG2_SETUP EQU 0
BCFG2_Val EQU 0x0000FBEF
/*
// <e> Bank Configuration 3 (BCFG3)
// <o1.0..3> IDCY: Idle Cycles <0-15>
// <o1.5..9> WST1: Wait States 1 <0-31>
// <o1.11..15> WST2: Wait States 2 <0-31>
// <o1.10> RBLE: Read Byte Lane Enable
// <o1.26> WP: Write Protect
// <o1.27> BM: Burst ROM
// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit
// <2=> 32-bit <3=> Reserved
// </e>
*/
BCFG3_SETUP EQU 0
BCFG3_Val EQU 0x0000FBEF
/*
// </e> End of EMC
*/
// External Memory Pins definitions
PINSEL2 EQU 0xE002C014 /* PINSEL2 Address */
PINSEL2_Val EQU 0x0E6149E4 /* CS0..3, OE, WE, BLS0..3,
D0..31, A2..23, JTAG Pins */
// Starupt Code must be linked first at Address at which it expects to run.
$IF (EXTMEM_MODE)
CODE_BASE EQU 0x80000000
$ELSEIF (RAM_MODE)
CODE_BASE EQU 0x40000000
$ELSE
CODE_BASE EQU 0x00000000
$ENDIF
AREA STARTUPCODE, CODE, AT CODE_BASE // READONLY, ALIGN=4
PUBLIC __startup
EXTERN CODE32 (?C?INIT)
__startup PROC CODE32
// Pre-defined interrupt handlers that may be directly
// overwritten by C interrupt functions
EXTERN CODE32 (Undef_Handler?A)
EXTERN CODE32 (SWI_Handler?A)
EXTERN CODE32 (PAbt_Handler?A)
EXTERN CODE32 (DAbt_Handler?A)
EXTERN CODE32 (IRQ_Handler?A)
EXTERN CODE32 (FIQ_Handler?A)
// Exception Vectors
// Mapped to Address 0.
// Absolute addressing mode must be used.
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP /* Reserved Vector */
; LDR PC,IRQ_Addr
LDR PC,[PC, #-0x0FF0] /* Vector from VicVectAddr */
LDR PC,FIQ_Addr
Reset_Addr: DD Reset_Handler
Undef_Addr: DD Undef_Handler?A
SWI_Addr: DD SWI_Handler?A
PAbt_Addr: DD PAbt_Handler?A
DAbt_Addr: DD DAbt_Handler?A
DD 0 /* Reserved Address */
IRQ_Addr: DD IRQ_Handler?A
FIQ_Addr: DD FIQ_Handler?A
// Reset Handler
Reset_Handler:
$IF (EXTMEM_MODE)
LDR R0, =PINSEL2
LDR R1, =PINSEL2_Val
STR R1, [R0]
$ENDIF
IF (EMC_SETUP != 0)
LDR R0, =EMC_BASE
IF (BCFG0_SETUP != 0)
LDR R1, =BCFG0_Val
STR R1, [R0, #BCFG0_OFS]
ENDIF
IF (BCFG1_SETUP != 0)
LDR R1, =BCFG1_Val
STR R1, [R0, #BCFG1_OFS]
ENDIF
IF (BCFG2_SETUP != 0)
LDR R1, =BCFG2_Val
STR R1, [R0, #BCFG2_OFS]
ENDIF
IF (BCFG3_SETUP != 0)
LDR R1, =BCFG3_Val
STR R1, [R0, #BCFG3_OFS]
ENDIF
ENDIF
IF (VPBDIV_SETUP != 0)
LDR R0, =VPBDIV
LDR R1, =VPBDIV_Val
STR R1, [R0]
ENDIF
IF (PLL_SETUP != 0)
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55
// Configure and Enable PLL
MOV R3, #PLLCFG_Val
STR R3, [R0, #PLLCFG_OFS]
MOV R3, #PLLCON_PLLE
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
// Wait until PLL Locked
PLL_Loop: LDR R3, [R0, #PLLSTAT_OFS]
ANDS R3, R3, #PLLSTAT_PLOCK
BEQ PLL_Loop
// Switch to PLL Clock
MOV R3, #(PLLCON_PLLE | PLLCON_PLLC)
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
ENDIF
IF (MAM_SETUP != 0)
LDR R0, =MAM_BASE
MOV R1, #MAMTIM_Val
STR R1, [R0, #MAMTIM_OFS]
MOV R1, #MAMCR_Val
STR R1, [R0, #MAMCR_OFS]
ENDIF
// Memory Mapping
MEMMAP EQU 0xE01FC040 /* Memory Mapping Control */
$IF (REMAP)
LDR R0, =MEMMAP
$IF (EXTMEM_MODE)
MOV R1, #3
$ELSEIF (RAM_MODE)
MOV R1, #2
$ELSE
MOV R1, #1
$ENDIF
STR R1, [R0]
$ENDIF
// Setup Stack for each mode
LDR R0, =Top_Stack
// Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
// Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
// Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
// Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
// Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
// Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
// Enter the C code
LDR R0,=?C?INIT
TST R0,#1 ; Bit-0 set: INIT is Thumb
LDREQ LR,=exit?A ; ARM Mode
LDRNE LR,=exit?T ; Thumb Mode
BX R0
ENDP
PUBLIC exit?A
exit?A PROC CODE32
B exit?A
ENDP
PUBLIC exit?T
exit?T PROC CODE16
exit: B exit?T
ENDP
END
layra
May 27, 2008, 05:51 AM
Here is few links and code. You just have to start and go forward, it will take some time but you will do that. Its the way of learning.
http://www.newmicros.com/discussion/archive/index.php/t-876.html
http://www.embeddedrelated.com/groups/lpc2000/35.php?searchfor=philips&by
http://www.testech-elect.com/iar/download/iar_ewarm_sample_download_list.htm
#include <LPC21xx.h>
void main(void)
{
unsigned int i;
// Make P0.6 an output
IO0DIR |= (1<<6);
while (1) {
IO0SET = (1<<6);
for (i=0; i<500000; i++);
IO0CLR = (1<<6);
for (i=0; i<500000; i++);
}
}
/************************************************** *********************/
/* This file is part of the uVision/ARM development tools */
/* Copyright KEIL ELEKTRONIK GmbH 2002-2005 */
/************************************************** *********************/
/* */
/* STARTUP.S: Startup file for Philips LPC2000 device series */
/* */
/************************************************** *********************/
/*
//*** <<< Use Configuration Wizard in Context Menu >>> ***
*/
\
\
\
\
\
/*
*
END
Thanks alot FAKHREALAM it was a useful thing what u wrote (as usual) ,i made my first program on the olimex board and downloaded it to the flash through the Philips utility using the serial port ,i compiled the project onthe Eclipse platform along with the Yagarto tool chain since it's a free utility ,but it seems that i can't make debugging through the serial port ,i've got the olimex Jtag Wiggler (parallel port) and i read that i can debug through it using the open OCD but i don't know how so if u may help (again) i'll be thankful.
thank u again.
layra
May 27, 2008, 05:54 AM
Layra,
There is no substitute for working through the problems yourself. Setting up any peripheral is not that complicated (except perhaps for USB) on the LPC2xxx parts. It is just a question of reading the datasheet. We (a friend and I) have recently got an NXPLPC2148 based flight computer up and running from scratch in a couple of days, using almost all the peripherals (inc USB), a FAT32 filesystem on an SD card (using FatFS library and having written our own SPI port drivers to their specification), and various other things, having not used ARMs before. We did it by finding example code from other people (the file section of the LPC2000 yahoo group is good for this) and going through it with reference to the datasheet to see what it all means and what the registers do. From there we developed our own drivers as necessary. The rest is just normal hardware-independent C.
I sympathize with the preconception that you need to do lots of study and gain lots of understanding before you get your hands dirty with actually hardware - I felt the same. But actually it was really quite easy to get up and running without any 'formal' study. If you have ever used any other microcontrollers like PICs or AVRs, you should have no problem. These chips involve a little more set-up, but it is readily comprehensible if you find a startup file (usually assembler, sometimes C) and study it with the datasheet. They are simpler than they might at first seem.
So be brave - have a go at actually trying to implement your goals as you go along - it is easier than you think and you will learn much faster!
If you have a specific question about the use of a particular peripheral, by all means ask it, but do not fear that you won't be able to achieve anything without the prior study. You will!
Incidentally, we would be nowhere without a debugger. We use Crossworks for development, and the environment, especially the debugger integration, has made it a pleasure to use.
Best of luck,
Ed
i wonder about the debugging ,would u tell me about ur experience in this domain,and another thing is there a simulator or emulator for the arm lpc2148 with c language ?
thanks...
eddymoore
May 27, 2008, 06:20 PM
Hi Layra,
I'm not sure how helpful I can be in this post. It's qualification is that I have no qualifications (I am a student) and am new to embedded engineering.
The debugger built into Crossworks (Rowley.co.uk) allows us to peak into the microcontroller as it operates. In our code, we can put a breakpoint (by just double clicking the mouse) next to a certain line of the program, and have the code run up until that point, at which point it will pause the microcontroller and we can have a look at all the registers. Note: This is all made possible by the JTAG - the programming and debugging tool. We use the one that came with Crossworks (The crossconnect lite) but there are many available and they're all mostly compatible with each other, as far as I know (someone more experienced might like to call me up on that).
So an example of using it in a basic way might be like this:
We plugged a Lassen iQ GPS into one of the serial ports on the ARM. We wanted to see that it worked fine, that the USART peripheral on the arm was set up correctly, that the PCB we'd made was fine, and so on, so we simply set up an array of some number of bytes (512, but it doesn't really matter) and told the serial port to keep receiving bytes and putting them in that array until it was full. We put a breakpoint on the instruction after this, so that it would stop the code once the array was full up.
We ran the code, waited for it to fill up (you can see whether or not it is running or paused or whatever in the Crossworks IDE) and then had a look at all the values in that array, and saw if they made sense (with reference to the Lassen iQ datasheet).
As it happened, we saw that they didn't and a quick analysis revealed that we should be on 'odd' parity, rather than no parity. A quick change to the relevant register on the ARM (in the USART chapter of the ARM datasheet) and we were all set.
There are several alternative ways we could have done that - if we had a spare serial port we could have sent all of the bytes onto the computer through the terminal. However, we didn't have a spare.
Where the debugger really came into its own was in developing the USB part (which then allowed us to connect to the computer terminal through USB, and so reduced the need for a debugger). We wanted to write a bit of code, test to see what it does what we expect, write a bit more, test again, and so on. It has been a great help in that respect.
Crossworks comes with a simulator for the ARM core, however I have not used it, nor any other simulator, so i don't feel qualified to give you any advice.
There is an open source debugger (gdb) however I have very limited experience with it. I would say it was significantly harder to use for a new person than the one built into crossworks, but I'm sure more competent and experienced people have no problem!
All the best,
Ed
layra
May 28, 2008, 07:40 AM
hi Eddy
i see that u have the Crosswork software for the arm (not like the one i use).
we r working on the free softwares like the eclipse and many other external utilities that could be attached to it.I am also a student so i don't have a clear idea about debugging in embedded system thing (but iam on the way to that).
I want o ask u if r using a toolkit ready board ,or u made ur own pcb board ?
and how did u make it ,any design or explanation coz i want to build my own board for the project .
see u,
bye..
eddymoore
May 29, 2008, 12:47 PM
Hi Layra,
We built our own pcb - it is very much a version 1 (version two, whilst the same size, will hopefully be a lot more dense and more capable). You can see a couple of pictures of it here:
http://www.flickr.com/photos/25036435@N00/2501001643/
http://www.flickr.com/photos/25036435@N00/2501001535/
It is a two layer PCB which we designed with the free version of EagleCAD. We made a schematic and then began to lay it out. We start by positioning all the 'big stuff' that doesn't have much flexibility in where we can put it - the headers, the GSM module, and the GPS module. Once they are in, we start on smaller stuff on the other side. SD card holder was put where it was for convenience, and everything else was placed in about as neat a way as we could.
This takes several iterations and it helps to have a friend to do it with who can spot when you do stupid routing that you're too focussed to notice. Swapping every hour or so on the actual 'driving' with the mouse (whilst the other looks and advises) irons out a lot of problems, we found.
We use ground planes on both sides - but we put them in last, once all the routing of the main signals is done. Again, you will spot silly mistakes at this stage and maybe adjust a whole load of routes to be more logical. You will spend hours routing, say, the JTAG (which seems to need to connect to pins that are on all sides of the LPC - very frustrating!) and then decide actually it would be more logical to have it somewhere else.
It is a frustrating process, but putting the time in helps. I must say, I was very suprised when we finished soldering everything and tried powering it up and downloading a trial program to blink the LEDs under an RTOS, and it worked first time. My partner put in several hours before sending the boards off double checking everything and his commitment really paid off. It has made us very excited about the version two, once we have tested this board very thoroughly (it must survive in a near-vacuum, at -50 degrees celcius, in thunder clouds, and so on - we need it to be reliable!). Logical silk-screen works too. Silly logos are a bonus.
Back to programming - we use a real time operating system called TNKernal, and it has been a joy to use. It really has sped up development for us, especially when the nature of what we are doing with these balloon trips is very experimental - being able to code and integrate new stuff quickly has been a great help. I had never used an RTOS before, and I am really glad that we are for this.
I keep feeling guilty offering advice on this when there are so many more experienced people on here, but I guess the best advice is always to keep it simple, and think about reliability. All the software you code should be designed such that it can't hang up (using the state-machine type flow diagrams that they teach you in computer science 101 and you then forget when it comes to actually programming). Have watchdog timers, and use them. Log events if you have memory - it's so useful for analysis afterwards and subsequently improving reliability.
SPI is a nice protocol. Simple and fast.
Testing points are useful, especially if dealing with analogue signals. Just a bit of wire you can solder into a via and hang a scope probe off will do.
We have a noisy end and a not-so-noisy end on the pcb. The not-so-noisy end has accelerometers, GPS, and so on, the noisy end has the gsm modem, and will have the 10mW telemetry radio on the v2. The ground planes will be split to try and isolate these areas a bit more.
You may notice we don't have decoupling capacitors on the power input to the arm. This is unforgivable, and my fault as I got distracted. They will be there on v2.
Be prepared to make a v2! Our v2 is basically everything we can find wrong with v1 fixed, + a radio and a battery charging/monitoring circuit with current and voltage feedback for the logs. We want to keep it incremental. We certainly want to be able to keep the same code, pretty much. Don't be too tempted to start all over, just increment.
Code sensibly - I have a 'hardware_specific.c' and associated header file. All the drivers and startup stuff goes in there. That way, if/when we upgrade to a more powerful processor, like an ARM9 of Analog Blackfin, we just have to re-write that file, not any of the actual main flight code. It also means other people in our team can contribute code more easily by sending generic c which we can put in with only a few tweaks.
I'm just sort of writing stuff down as it comes into my head - sorry for the lack of structure.
We knew we would probably be making a v2, so we didn't go crazy on the features on v1. This is more of a proof of concept, to get a code-base up and running, and to test in our environmental chamber (which is actually just a biscuit tin which we put liquid nitrogen into) and so on, so we can be more confident about the version 2 which will actually fly, once tested, in fairly critical experiments.
Also, you may aswell break out pins and ports even if you don't intend to use them. Unless you're making a product with a very specific task, then it's probably quite experimental and more of a project, so you may aswell give yourself some flexibility for the future if you can.
Enough verbal diarrhea!
Ed
FAKHREALAM
May 30, 2008, 03:09 PM
hi there
i'd like to know how to get the c reference book for the arm lpc2148 and that for the project of paparazzi uav.
had any one programmed arm
i would be thankful for any information
Here is few links to NXP LPC series, you can find app notes and code, kind of very good for all of us.
http://www.standardics.nxp.com/support/documents/microcontrollers/all/?scope=LPC2106&type=user http://www.standardics.nxp.com/support/documents/microcontrollers/all/?scope=LPC2106http://www.nxp.com/#/homepage/cb=[t=p,p=/50809/45994]|pp=[t=pfp,i=45994]
I am no using any debugger (only using COM1 for ISP), using MY OSD BOARD to display debug info on VIDEO DISPLAY using LPC SPI port.
Fakhre Alam
vBulletin® Copyright ©2000-2009, Jelsoft Enterprises Ltd.