Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Getting lnewlib-lpc (Ver 5a) uart1 interrupts to work with WINARM

Getting lnewlib-lpc (Ver 5a) uart1 interrupts to work with WINARM

2006-04-29 by ocnek1

Hello,

Using the "polled" mode for uart1 works without any problems at all. 
But now I would like to make the uart interrupt driven.  Now when I
change the device table to the following, the uart only transmitts ONE
character and then hangs...

(NOTE: added _int to each of the com1's)

const struct device_table_entry *device_table[] = {
	&com1_int,	/* stdin  */
	&com1_int,	/* stdout */
	&com1_int,	/* stderr */
	0 };

The code has the following for the uart1 setup:

sp.baud = 115200uL;
sp.length = UART_WORD_LEN_8;
sp.parity = UART_PARITY_NONE;
sp.stop = UART_STOP_BITS_2;
irq.FIQ = 0;
irq.pri = (INT_PRIORITY)5;

void)ioctl( fileno(stdout), INTERRUPT_SETUP, &irq);
void)ioctl( fileno(stdout), UART_SETUP, &sp);


Now is there something else I need to setup??

Thanks,

J.

Re: [lpc2000] Getting lnewlib-lpc (Ver 5a) uart1 interrupts to work with WINARM

2006-04-29 by Robert Adsett

At 01:00 AM 4/29/2006 +0000, ocnek1 wrote:
>Using the "polled" mode for uart1 works without any problems at all.
>But now I would like to make the uart interrupt driven.  Now when I
>change the device table to the following, the uart only transmitts ONE
>character and then hangs...

That certainly sounds like an interrupt problem.  The first character would 
be the pump priming character.  Then you don't appear to be getting the 
transmit interrupt.

>(NOTE: added _int to each of the com1's)
>
>const struct device_table_entry *device_table[] = {
>         &com1_int,      /* stdin  */
>         &com1_int,      /* stdout */
>         &com1_int,      /* stderr */
>         0 };
>
>The code has the following for the uart1 setup:
>
>sp.baud = 115200uL;
>sp.length = UART_WORD_LEN_8;
>sp.parity = UART_PARITY_NONE;
>sp.stop = UART_STOP_BITS_2;
>irq.FIQ = 0;
>irq.pri = (INT_PRIORITY)5;
>
>void)ioctl( fileno(stdout), INTERRUPT_SETUP, &irq);
>void)ioctl( fileno(stdout), UART_SETUP, &sp);


That should do it.  What are you using for startup code?

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: Getting lnewlib-lpc (Ver 5a) uart1 interrupts to work with WINARM

2006-04-29 by ocnek1

Below are the crt0 and the .ld files that I am currently using.  So if
you spot any problems or what I would need to add that would be great!!

Thanks,

j.

/* 
 crt0.S for LPC2xxx
 - based on examples from R O Software
 - based on examples from newlib-lpc
 - based on an example from Anglia Designs

 collected and modified by Martin Thomas
*/

        .global _etext                  // -> .data initial values in ROM
        .global _data                   // -> .data area in RAM
        .global _edata                  // end of .data area
        .global __bss_start             // -> .bss area in RAM
        .global __bss_end__             // end of .bss area
        .global _stack                  // top of stack

// Stack Sizes
        .set  UND_STACK_SIZE, 0x00000004
        .set  ABT_STACK_SIZE, 0x00000004
        .set  FIQ_STACK_SIZE, 0x00000004
        .set  IRQ_STACK_SIZE, 0x00000080
        .set  SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
        .set  MODE_USR, 0x10            // User Mode
        .set  MODE_FIQ, 0x11            // FIQ Mode
        .set  MODE_IRQ, 0x12            // IRQ Mode
        .set  MODE_SVC, 0x13            // Supervisor Mode
        .set  MODE_ABT, 0x17            // Abort Mode
        .set  MODE_UND, 0x1B            // Undefined Mode
        .set  MODE_SYS, 0x1F            // System Mode

        .equ  I_BIT, 0x80               // when I bit is set, IRQ is
disabled
        .equ  F_BIT, 0x40               // when F bit is set, FIQ is
disabled

        .text
	.arm
	.section .init, "ax"

        .code 32
        .align 2

        .global _boot
        .func   _boot
_boot:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
        b     _start                    // reset - _start
        ldr   pc,_undf                  // undefined - _undf
        ldr   pc,_swi                   // SWI - _swi
        ldr   pc,_pabt                  // program abort - _pabt
        ldr   pc,_dabt                  // data abort - _dabt
        nop                             // reserved
        ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC
        ldr   pc,_fiq                   // FIQ - _fiq

#if 0
// Use this group for production
_undf:  .word _reset                    // undefined - _reset
_swi:   .word _reset                    // SWI - _reset
_pabt:  .word _reset                    // program abort - _reset
_dabt:  .word _reset                    // data abort - _reset
_irq:   .word _reset                    // IRQ - _reset
_fiq:   .word _reset                    // FIQ - _reset

#else
// Use this group for development
_undf:  .word __undf                    // undefined
_swi:   .word __swi                     // SWI
_pabt:  .word __pabt                    // program abort
_dabt:  .word __dabt                    // data abort
_irq:   .word __irq                     // IRQ
_fiq:   .word __fiq                     // FIQ

__undf: b     .                         // undefined
__swi:  b     .                         // SWI
__pabt: b     .                         // program abort
__dabt: b     .                         // data abort
__irq:  b     .                         // IRQ
__fiq:  b     .                         // FIQ
#endif
        .size _boot, . - _boot
        .endfunc


// Setup the operating mode & stack.
// ---------------------------------
        .global _start, start, _mainCRTStartup
        .func   _start

_start:
start:
_mainCRTStartup:

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------------------------------------------
        ldr   r0,=_stack
        msr   CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
        mov   sp,r0
        sub   r0,r0,#UND_STACK_SIZE
        msr   CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
        mov   sp,r0
        sub   r0,r0,#ABT_STACK_SIZE
        msr   CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
        mov   sp,r0
        sub   r0,r0,#FIQ_STACK_SIZE
        msr   CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
        mov   sp,r0
        sub   r0,r0,#IRQ_STACK_SIZE
        msr   CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
        mov   sp,r0
        sub   r0,r0,#SVC_STACK_SIZE
        msr   CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
        mov   sp,r0

// Copy initialized data to its execution address in RAM
// -----------------------------------------------------
#ifdef ROM_RUN
        ldr   r1,=_etext                // -> ROM data start
        ldr   r2,=_data                 // -> data start
        ldr   r3,=_edata                // -> end of data
1:      cmp   r2,r3                     // check if data to move
        ldrlo r0,[r1],#4                // copy it
        strlo r0,[r2],#4
        blo   1b                        // loop until done
#endif
// Clear .bss
// ----------
        mov   r0,#0                     // get a zero
        ldr   r1,=__bss_start           // -> bss start
        ldr   r2,=__bss_end__           // -> bss end
2:      cmp   r1,r2                     // check if data to clear
        strlo r0,[r1],#4                // clear 4 bytes
        blo   2b                        // loop until done
		
/*
   Call C++ constructors (for objects in "global scope")
   ctor loop added by Martin Thomas 4/2005 
   based on a Anglia Design example-application for ST ARM
*/

		LDR 	r0, =__ctors_start__
		LDR 	r1, =__ctors_end__
ctor_loop:
		CMP 	r0, r1
		BEQ 	ctor_end
		LDR 	r2, [r0], #4
		STMFD 	sp!, {r0-r1}
		MOV 	lr, pc
		MOV 	pc, r2
		LDMFD 	sp!, {r0-r1}
		B 		ctor_loop
ctor_end:

// Call main program: main(0)
// --------------------------
        mov   r0,#0                     // no arguments (argc = 0)
        mov   r1,r0
        mov   r2,r0
        mov   fp,r0                     // null frame pointer
        mov   r7,r0                     // null frame pointer for thumb
        ldr   r10,=main
        mov   lr,pc

/* Enter the C code, use BX instruction so as to never return */
/* use BLX (?) main if you want to use c++ destructors below */

        bx    r10                       // enter main()

/* "global object"-dtors are never called and it should not be 
   needed since there is no OS to exit to. */
/* Call destructors */
#		LDR		r0, =__dtors_start__
#		LDR		r1, =__dtors_end__
dtor_loop:
#		CMP		r0, r1
#		BEQ		dtor_end
#		LDR		r2, [r0], #4
#		STMFD	sp!, {r0-r1}
#		MOV		lr, pc
#		MOV		pc, r2
#		LDMFD	sp!, {r0-r1}
#		B		dtor_loop
dtor_end:
   
        .size   _start, . - _start
        .endfunc

        .global _reset, reset, exit, abort
        .func   _reset
_reset:
reset:
exit:
abort:
#if 0
// Disable interrupts, then force a hardware reset by driving P23 low
// -------------------------------------------------------------------
        mrs   r0,cpsr                   // get PSR
        orr   r0,r0,#I_BIT|F_BIT        // disable IRQ and FIQ
        msr   cpsr,r0                   // set up status register

        ldr   r1,=(PS_BASE)             // PS Base Address
        ldr   r0,=(PS_PIO)              // PIO Module
        str   r0,[r1,#PS_PCER_OFF]      // enable its clock
        ldr   r1,=(PIO_BASE)            // PIO Base Address
        ldr   r0,=(1<<23)               // P23
        str   r0,[r1,#PIO_PER_OFF]      // make sure pin is contolled
by PIO
        str   r0,[r1,#PIO_CODR_OFF]     // set the pin low
        str   r0,[r1,#PIO_OER_OFF]      // make it an output
#endif
        b     .                         // loop until reset

        .size _reset, . - _reset
        .endfunc

        .end
//****************************************************************

AND

/***********************************************************************/
/*  ROM.ld:  Linker Script File                                        */
/***********************************************************************/
ENTRY(_boot)
STACK_SIZE = 0x400;

/* Memory Definitions */
MEMORY
{
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 512k
  RAM (rw) : ORIGIN = 0x40000000, LENGTH = 32k
}

/* Section Definitions */
SECTIONS
{
  /* first section is .text which is used for code */
   .text :
  {
	/* *crt0.o (.text) */           /* Startup code */
	KEEP(*(.init))             /* Startup code from .init-section */
	*(.text .text.*)           /* remaining code */
	*(.gnu.linkonce.t.*)
	*(.glue_7)
	*(.glue_7t)
	*(.gcc_except_table)
	*(.rodata)                 /* read-only data (constants) */
	*(.rodata*)
	*(.gnu.linkonce.r.*)
  } > ROM
  
  /***** old: 
  .text :
  {
    *crt0.o (.text)            
    *(.text)                   
    *(.rodata)                 
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
  } > ROM 
  *****/

  . = ALIGN(4);
  
	/* .ctors .dtors are used for c++ constructors/destructors */
	/* added by Martin Thomas 4/2005 based on Anglia Design example */
	.ctors :
	{
		PROVIDE(__ctors_start__ = .);
		KEEP(*(SORT(.ctors.*)))
		KEEP(*(.ctors))
		PROVIDE(__ctors_end__ = .);
	} >ROM
	
	.dtors :
	{
		PROVIDE(__dtors_start__ = .); 
		KEEP(*(SORT(.dtors.*)))
		KEEP(*(.dtors))
		PROVIDE(__dtors_end__ = .);
	} >ROM
  
    . = ALIGN(4);
	/* mthomas - end */
   
  _etext = . ;
  PROVIDE (etext = .);

  /* .data section which is used for initialized data */
  .data : AT (_etext)
  {
    _data = .;
    *(.data)
	*(.data.*)
	*(.gnu.linkonce.d*)
	SORT(CONSTRUCTORS) /* mt 4/2005 */
	. = ALIGN(4);
	*(.fastrun) /* !!!! "RAM-Function" example */
  } > RAM
 
  . = ALIGN(4);
  _edata = . ;
  PROVIDE (edata = .);

  /* .bss section which is used for uninitialized data */
  .bss (NOLOAD) :
  {
    __bss_start = . ;
    __bss_start__ = . ;
    *(.bss)
	*(.gnu.linkonce.b*)
    *(COMMON)
    . = ALIGN(4);
  } > RAM

  . = ALIGN(4);
  __bss_end__ = . ;
  PROVIDE (__bss_end = .);

  .stack ALIGN(256) :
  {
    . += STACK_SIZE;
    PROVIDE (_stack = .);
  } > RAM

  _end = . ;
  PROVIDE (end = .);

  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
}

Re: [lpc2000] Re: Getting lnewlib-lpc (Ver 5a) uart1 interrupts to work with WINARM

2006-04-29 by Robert Adsett

At 04:50 AM 4/29/06 +0000, ocnek1 wrote:
>Below are the crt0 and the .ld files that I am currently using.  So if
>you spot any problems or what I would need to add that would be great!!
<snip>

>         .equ  I_BIT, 0x80               // when I bit is set, IRQ is disabled
>         .equ  F_BIT, 0x40               // when F bit is set, FIQ is disabled

<snip>

>// Runtime Interrupt Vectors
>// -------------------------
>Vectors:
>         b     _start                    // reset - _start
>         ldr   pc,_undf                  // undefined - _undf
>         ldr   pc,_swi                   // SWI - _swi
>         ldr   pc,_pabt                  // program abort - _pabt
>         ldr   pc,_dabt                  // data abort - _dabt
>         nop                             // reserved
>         ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC
>         ldr   pc,_fiq                   // FIQ - _fiq

The fiq will need modifying if you ever use it.

<snip>
>// Initialize Interrupt System
>// - Set stack location for each mode
>// - Leave in System Mode with Interrupts Disabled

The above comment is key

>// -----------------------------------------------
>         ldr   r0,=_stack
>         msr   CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
>         mov   sp,r0
>         sub   r0,r0,#UND_STACK_SIZE
>         msr   CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
>         mov   sp,r0
>         sub   r0,r0,#ABT_STACK_SIZE
>         msr   CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
>         mov   sp,r0
>         sub   r0,r0,#FIQ_STACK_SIZE
>         msr   CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
>         mov   sp,r0
>         sub   r0,r0,#IRQ_STACK_SIZE
>         msr   CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
>         mov   sp,r0
>         sub   r0,r0,#SVC_STACK_SIZE
>         msr   CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
>         mov   sp,r0

The interrupts are being left disabled.


You have to turn on the interrupts.  A couple of possibilities.

         Write an interrupt enable routine and enable interrupts in your 
program
         Modify the startup so you enter system mode with interrupts 
enabled.  This may the easiest, from the look of the code all you have to 
do is remove the bits that disable interrupts.
         Use the startup code supplied with newlib.

I think the second option is probably your best.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.