LPC1114 assembler startup and blinky - please help

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1114 assembler startup and blinky - please help

1,186 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Mon Sep 13 08:21:06 MST 2010
Hi there,

see below my humble efforts to create a (very) simple assembler program, that starts and toggles P0.7 on the LPC1114  ... at least that's what it should do.

The code assembles and links without error and also runs flawlessly in the simulator (all Keil µVision 4), it nicely sets Pin0.7 to output and toggles forever.

However it does not run on the chip once downloaded (tried with XPresso and flash magic, checksum provided).

So now I am at the end of my knowledge and it would be very cool if somebody from NXP (or anybody) could help me, veeeery coool :)

So here it goes, vectors included for completeness:
;*****************************************************************************
;try to blink a LED
;
;******************************************************************************

PRESERVE8
THUMB
AREARESET, CODE

bit_7EQU 0x00000080
PIN0_7EQU0x50000000 :OR: bit_7   ; pin mask for PIO0DATA_pin7
GPIO0DIREQU 0x50008000; port direction registers

EXPORT__Vectors  ; ...

__Vectors   DCD     0x10000200; Top of Stack   
DCD     Reset_Handler       ; Reset_Handler
                DCD     Reset_Handler       ; NMI Handler
                DCD     Reset_Handler   ; Hard Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0xEFFFFBBD; Checksum = 2' complement of sum of location 0..6
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     Reset_Handler      ; SVCall Handler
                DCD     0                       ; Reserved
                DCD     0                 ; Reserved
                DCD     Reset_Handler; PendSV Handler
                DCD     Reset_Handler       ; SysTick Handler

                ; External Interrupts
                DCD     Reset_Handler         ; 16+ 0: Wakeup PIO0.0
                DCD     Reset_Handler         ; 16+ 1: Wakeup PIO0.1
                DCD     Reset_Handler         ; 16+ 2: Wakeup PIO0.2
                DCD     Reset_Handler         ; 16+ 3: Wakeup PIO0.3
                DCD     Reset_Handler         ; 16+ 4: Wakeup PIO0.4
                DCD     Reset_Handler         ; 16+ 5: Wakeup PIO0.5
                DCD     Reset_Handler         ; 16+ 6: Wakeup PIO0.6
                DCD     Reset_Handler         ; 16+ 7: Wakeup PIO0.7
                DCD     Reset_Handler         ; 16+ 8: Wakeup PIO0.8
                DCD     Reset_Handler         ; 16+ 9: Wakeup PIO0.9
                DCD     Reset_Handler         ; 16+10: Wakeup PIO0.10
                DCD     Reset_Handler         ; 16+11: Wakeup PIO0.11
                DCD     Reset_Handler         ; 16+12: Wakeup PIO1.0
                DCD     0                         ; 16+13: Reserved
                DCD     Reset_Handler           ; 16+14: SSP1
                DCD     Reset_Handler            ; 16+15: I2C
                DCD     Reset_Handler      ; 16+16: 16-bit Counter-Timer 0
                DCD     Reset_Handler      ; 16+17: 16-bit Counter-Timer 1
                DCD     Reset_Handler      ; 16+18: 32-bit Counter-Timer 0
                DCD     Reset_Handler      ; 16+19: 32-bit Counter-Timer 1
                DCD     Reset_Handler           ; 16+20: SSP0
                DCD     Reset_Handler           ; 16+21: UART
                DCD     0                         ; 16+22: Reserved
                DCD     0                         ; 16+24: Reserved
                DCD     Reset_Handler            ; 16+24: A/D Converter
                DCD     Reset_Handler            ; 16+25: Watchdog Timer
                DCD     Reset_Handler            ; 16+26: Brown Out Detect
                DCD     0                         ; 16+27: Reserved
                DCD     Reset_Handler        ; 16+28: PIO INT3
                DCD     Reset_Handler        ; 16+29: PIO INT2
                DCD     Reset_Handler        ; 16+30: PIO INT1
                DCD     Reset_Handler        ; 16+31: PIO INT0

EXPORT Reset_Handler

;-----------------------------------------------------
Reset_Handler     ; this assembles to location 0x000000C1  (1 for thumb)

Main   ; here we are :)

ldrr0, =GPIO0DIR
ldrr1, =bit_7     ; set bit 7 in direction register (all others will be cleared)
strr1, [r0]; set to output, store to direction register

ldrr0, =PIN0_7   ; load pinmask address for pin0_7, this is interesting
movs  r2, #0

Loop
   strr1, [r0]; set hi, r1 holds bit_7 (0x00000080)
strr2, [r0]   ; set lo, r2 = 0
  
bLoop

END
;------------- that was it, see below the .hex output ----------
:020000040000FA
:1000000000020010C1000000C1000000C10000009B
:10001000000000000000000000000000BDFBFFEF3A
:10002000000000000000000000000000C10000000F
:100030000000000000000000C1000000C10000003E
:10004000C1000000C1000000C1000000C1000000AC
:10005000C1000000C1000000C1000000C10000009C
:10006000C1000000C1000000C1000000C10000008C
:10007000C100000000000000C1000000C10000003D
:10008000C1000000C1000000C1000000C10000006C
:10009000C1000000C10000000000000000000000DE
:1000A000C1000000C1000000C1000000000000000D
:1000B000C1000000C1000000C1000000C10000003C
:1000C0000348044901600448002201600260FCE723
:0C00D00000800050800000008000005004
:04000005000000C136
:00000001FF


Thanks for your help,

Chucky :)
0 Kudos
Reply
24 Replies

974 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed Sep 21 07:38:29 MST 2011
http://knowledgebase.nxp.com/showpost.php?p=8192&postcount=11
0 Kudos
Reply

974 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by nsalzman on Wed Sep 21 06:49:54 MST 2011
I know that this is an old thread but I will try posting here before starting a new one. 

Does anyone have a simple (like Blinky) working assembly only project, preferably one that works with the LPC1769, that they can post here?  In other words, something that is just assembly and not an assembly file or subroutine included as part of a C project.  I have found a chunk of assembly code that compiles fine as a .s file, but I can not figure out how to get a linker file going with it or actually get the program to run on the board.  I don't know if you are still around Chucky or still have the code that you described in this post, but if you could post that project it would be great.  Thanks in advance.
0 Kudos
Reply

974 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by qili on Tue Sep 14 17:44:18 MST 2010

Quote:
If you look at the blinky example, the first (real) thing it does is:

/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);



Chuck is right about that. That is not necessary.

for example, the following code works just fine, without explicitly setting SYSAHBCLKCTRL.


/*
===============================================================================
 Name        : main.c
 Author      : 
 Version     :
 Copyright   : Copyright (C)
 Description : main definition
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC13xx.h"
#endif

// TODO: insert other include files here

// TODO: insert other definitions and declarations here
#define LED_PORTLPC_GPIO0->DATA//FIOPIN for Keil
#define LED_DDRLPC_GPIO0->DIR//FIODIR for Keil
#define LED(1<<7)
#define DLY_MS1000//delay time, in ms

volatile unsigned long SysTickCnt=0;      /* SysTick Counter                    */

void SysTick_Handler (void) {           /* SysTick Interrupt Handler (1ms)    */
SysTickCnt++;
}

void Delay (unsigned long tick) {       /* Delay Function                     */
  unsigned long systick;
  //unsigned long tick_cnt = tick;

  systick = SysTickCnt;//systickcnt has the start-up time
  while ((SysTickCnt - systick) < tick);
}

void mcu_init(void) {
SystemInit();//reset mcu
/* Generate interrupt each 1 ms   */
    SysTick_Config(SystemCoreClock/1000 - 1);//=SystemFrequency for Keil

LED_PORT &=~(LED);//clear led
LED_DDR |= (LED);//led as output
}

int main(void) {
unsigned char i;
mcu_init();//reset mcu
while (1) {
for (i=0; i<0xff; i++) {
LED_PORT ^= (LED);
Delay(i<<1);//delay some time
}
for (i=0xff; i>0x00; i--) {
LED_PORT ^= (LED);
Delay(i<<1);//delay some time
}
}
}
0 Kudos
Reply

974 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 15:33:54 MST 2010
Chucky veeeeeery happy now :):):):)
0 Kudos
Reply

974 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 10:39:08 MST 2010
I have it.

My code is correct, the download also works.

The problem was... I was using the GPIO0DATA mask register and messed up the address :rolleyes:

PIN0_7 EQU0x50000000 :OR: bit_7 ; pin mask

I ored with bit 7, however you must shift 2 bits to the left to get the mask address correctly, so it has to look like this:

PIN0_7 EQU0x50000000 :OR: bit_9 ; pin mask for bit 7 (shifted 2 bits left in order to get correct mask address)

That was my mistake, and btw. the Keil simulator has a bug, because the wrong line did the right thing  :eek:

The trouble was my insecurity about Cortex-M0, I should have looked into my code instead of asking for help.

Anyway, the nasty sucker toggles @ 6MHz now :D

I'll have a beer on you, thanks to all,

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Sep 14 09:46:15 MST 2010
Yes, of course it can debug pure assembler. If you spent a little bit of time reading the docs/help/forum/knowledgebase, you could save yourself a lot of time and hassle.

See:
http://lpcxpresso.code-red-tech.com/LPCXpresso/node/48
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 09:36:57 MST 2010

Quote: CodeRedSupport
You still need to provide a linker script - even for assembler. The easiest thing to do would be to let the tools generate the linker script, and place your code into the '.text' section.



Function main not defined, continue ?

Can xpresso debug pure assembler ?

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Sep 14 09:22:17 MST 2010
You still need to provide a linker script - even for assembler. The easiest thing to do would be to let the tools generate the linker script, and place your code into the '.text' section.
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 08:33:30 MST 2010

Quote: Chucky
When I chose debug in µVision it always opens the simulator.

I will try to debug in xpresso ... have to find out how it works ...

Chucky :)



Debugged blinky.c , that worked.

Created C project, removed C files, unchecked manage linker script, created asm.s file

entered program, assembled correctly

"cannot open linker script - no such file" -> no debug

Is there a way to debug real assembler code in lpcxpresso ?

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 07:46:04 MST 2010

Quote: TheFallGuy
I'm a little confused here... You say
"(I) verified they are set (using the simulator)"
Surely, you should check using the debugger and the hardware - that is the only thing that is 'correct'. A simulator is not guaranteed to match what the hardware does.

Why don't you just debug the code you have written, and see what it is doing. If you single step, and look at the peripherals in the debugger, you can see for certain what has happened.



When I chose debug in µVision it always opens the simulator.

I will try to debug in xpresso ... have to find out how it works ...

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by qili on Tue Sep 14 07:18:58 MST 2010

Quote:
it does not help me right now



it does. essentially, you have two routes ahead of you: one easier than another, and you picked the tougher one, :)

I was simply suggesting that it may speed up the process for you if you had chosen differently.
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Tue Sep 14 06:44:39 MST 2010
I'm a little confused here... You say
"(I) verified they are set (using the simulator)"
Surely, you should check using the debugger and the hardware - that is the only thing that is 'correct'. A simulator is not guaranteed to match what the hardware does.

Why don't you just debug the code you have written, and see what it is doing. If you single step, and look at the peripherals in the debugger, you can see for certain what has happened.
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 06:31:18 MST 2010

Quote: qili
that necessarily means that you have to code in a high-level language for a complex chip like ARM.

as your project grows in complexity, coding in assembly becomes unrealistic and unmanageable. Give you a quick example: I can pick up pieces of code from my library, through together a data logger that reads an analog pin, updates an lcd, stamp the data from a rtc and writes it to a eeprom, uart it out and then go back to sleep, in less than half an hour.

and it will work, with minimum modification, most of the mcus (from arm, pic, to avr).

it would be very difficult to do that in assembly.

that's why you see a very limited number of arm projects done in assembly (with reasonable amount of complexity).



I completely understand you, but it does not help me right now , LOL :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by qili on Tue Sep 14 06:13:56 MST 2010

Quote:
I'd like to use what's left as efficiently as possible ...



that necessarily means that you have to code in a high-level language for a complex chip like ARM.

as your project grows in complexity, coding in assembly becomes unrealistic and unmanageable. Give you a quick example: I can pick up pieces of code from my library, through together a data logger that reads an analog pin, updates an lcd, stamp the data from a rtc and writes it to a eeprom, uart it out and then go back to sleep, in less than half an hour.

and it will work, with minimum modification, most of the mcus (from arm, pic, to avr).

it would be very difficult to do that in assembly.

that's why you see a very limited number of arm projects done in assembly (with reasonable amount of complexity).
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 06:10:17 MST 2010

Quote: TheFallGuy
If you look at the blinky example, the first (real) thing it does is:

/* Enable AHB clock to the GPIO domain. */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

If this doesn't work, perhaps yu should read the blinky example to see what else you are not doing...



Hm, checked the manual: Reset value for GPIO in SYSAHBCLKCTRL is = 1 (enabled), however there's no harm to set it again, so I enabled the GPIO and IOCON clocks, verified they are set (using the simulator) but it made no difference, pin does not toggle :confused:

Thanks for the tip, I feel I am close to success ... maybe ...

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by JohnR on Tue Sep 14 05:25:35 MST 2010
Hi,

For what it's worth, I usually write a C version first, generate a .s file and then look to see if there is anything that can be improved.

John
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Tue Sep 14 03:51:30 MST 2010
If you look at the blinky example, the first (real) thing it does is:

/* Enable AHB clock to the GPIO domain. */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

If this doesn't work, perhaps yu should read the blinky example to see what else you are not doing...
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Tue Sep 14 03:05:20 MST 2010

Quote: TheFallGuy
I haven't tried your code, but this is going to be flashing the LED at about 1/2 the boot clock frequency. I *think* the boot clock is 4Mhz, so this will be flashing at about 2MHz - no wonder you can't see it..

How about putting a delay loop in between setting the two bits. You'll have to delay a LLOONNGG time to see anything though.



As mentioned earlier, I watch the pin output with my scope and it is flat at about 1.8V, it does not toggle. I also tried to switch it ON (forever), and then I tried to switch it OFF, however it just hangs at 1.8V

Something fundamentally must be wrong ... it works in the simulator ...

Chucky :)
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Tue Sep 14 00:25:52 MST 2010
I haven't tried your code, but this is going to be flashing the LED at about 1/2 the boot clock frequency. I *think* the boot clock is 4Mhz, so this will be flashing at about 2MHz - no wonder you can't see it..

How about putting a delay loop in between setting the two bits. You'll have to delay a LLOONNGG time to see anything though.
0 Kudos
Reply

975 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Chucky on Mon Sep 13 23:27:32 MST 2010

Quote: igorsk
Maybe you need to set up the clocks?



Hm... if the CPU can change bits to set up clocks, it should also be able to change bits for the I/O pins.

Something very simple must be going simply wrong ... I wonder what it is ...


Quote: qili
let me just say that unless you intend to use the chip for some really simple stuff (blinking an led or the likes that 8-bitters excel at), your using the assembly will be the biggest hurdle for you to fully explore the chip.



That's funny :)

I think unless you program in assembler, you cannot use the chip's potential anyway. After all this Cortex-stuff is just a poor man's ARM, no condition-field, no barrel shifter, over 50% of ARM performance gone down the drain.

I'd like to use what's left as efficiently as possible ...

Chucky :)
0 Kudos
Reply