comp.lang.ada
 help / color / mirror / Atom feed
* Interrupt-driven Usart not working in Ada, but in C working, why?
@ 2014-03-16 20:37 Rego, P.
  2014-03-16 22:54 ` Oliver Kleinke
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Rego, P. @ 2014-03-16 20:37 UTC (permalink / raw)


I am trying to use interrupt-driven Usart on an Atmel AVR ATmega2560 chip. 

The problem is that when I send anything to the usart, the Ada application restarts (continuously). I simplified the codes and created a C version (or the nearer of it) of the same code (because at first I thought that it could be a hw problem or a datasheet misunderstanding of me, and AVR community would not answer me if I had posted Ada code instead of C code ...). But the C code worked (i.e., the usart echo appears, and the board is not restarted), ao now I became clueless. Maybe the AVR guys could help me? Thanks.

The simplified version of the codes are

-- main.adb
with System.Machine_Code;
with AVR.USART;
with TEST;
pragma Unreferenced (TEST);

procedure Main is
   F_CPU : constant := 16_000_000;
   USART_BAUDRATE : constant := 9600;
begin
   AVR.USART.Reg_USART1.UCSRB.RXEN := True;
   AVR.USART.Reg_USART1.UCSRB.TXEN := True;
   AVR.USART.Reg_USART1.UCSRB.RXCIE := True;
   AVR.USART.Reg_USART1.UCSRC.UCSZ0 := True;
   AVR.USART.Reg_USART1.UCSRC.UCSZ1 := True;

   AVR.USART.Reg_USART1.UBRR (0) := AVR.Byte_Type ((F_CPU / (USART_BAUDRATE * 16)) - 1);
   AVR.USART.Reg_USART1.UBRR (1) := 0;

   System.Machine_Code.Asm ("sei", Volatile => True);

   loop
      null;
   end loop;
end Main;

-- test.ads
package TEST is

   USART1RX : constant String := "__vector_36";
   
   procedure Handle_Interrupt_USART1_RX;
   pragma Machine_Attribute
     (Entity         => Handle_Interrupt_USART1_RX,
      Attribute_Name => "signal");
   pragma Export
     (Convention    => C,
      Entity        => Handle_Interrupt_USART1_RX,
      External_Name => USART1RX);

end TEST;

with AVR;
with AVR.USART;

-- test.adb
package body Test is

   procedure Handle_Interrupt_USART1_RX is
      Curr_Buffer : AVR.Byte_Type;
   begin
      Curr_Buffer := AVR.USART.Reg_USART1.UDR;
      AVR.USART.Reg_USART1.UDR := Curr_Buffer;
   end Handle_Interrupt_USART1_RX;
end Test;


Given that I have mapped the Usart registers correctly on AVR.USART package (because my JtagICE said so).

The C code is
-- simple_isr_usart.c
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

int main (void){
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
	UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
	UBRR0H = (BAUD_PRESCALE >> 8);
	UBRR0L = BAUD_PRESCALE;
	sei();
	while (1) {}
}

ISR(USART0_RX_vect){
	char ReceivedByte;
	ReceivedByte = UDR0;
	UDR0 = ReceivedByte;
}


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-16 20:37 Interrupt-driven Usart not working in Ada, but in C working, why? Rego, P.
@ 2014-03-16 22:54 ` Oliver Kleinke
  2014-03-17  0:21   ` Rego, P.
  2014-03-16 23:09 ` Oliver Kleinke
  2014-03-17 12:17 ` rrr.eee.27
  2 siblings, 1 reply; 12+ messages in thread
From: Oliver Kleinke @ 2014-03-16 22:54 UTC (permalink / raw)


Am Sun, 16 Mar 2014 13:37:45 -0700 (PDT)
schrieb "Rego, P." <pvrego@gmail.com>:

> I am trying to use interrupt-driven Usart on an Atmel AVR ATmega2560
> chip. 

Which compiler/version?

If you're using the GNU toolchain then you can use "(avr-)objdump -S"
to generate an assembly listing that's interspersed with source code.
(Compile with debugging symbols '-g'.)

You can then compare the disassembly of both programs.

> Given that I have mapped the Usart registers correctly on AVR.USART
> package (because my JtagICE said so).

Code?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-16 20:37 Interrupt-driven Usart not working in Ada, but in C working, why? Rego, P.
  2014-03-16 22:54 ` Oliver Kleinke
@ 2014-03-16 23:09 ` Oliver Kleinke
  2014-03-17  0:32   ` Rego, P.
  2014-03-17 12:17 ` rrr.eee.27
  2 siblings, 1 reply; 12+ messages in thread
From: Oliver Kleinke @ 2014-03-16 23:09 UTC (permalink / raw)


Am Sun, 16 Mar 2014 13:37:45 -0700 (PDT)
schrieb "Rego, P." <pvrego@gmail.com>:

> The problem is that when I send anything to the usart, the Ada
> application restarts (continuously).

This usually happens if you either blow the stack/heap or the PC
(program counter) overflows (reset/power on vector is at 0), e.g., if
the compiler optimizes away your main loop.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-16 22:54 ` Oliver Kleinke
@ 2014-03-17  0:21   ` Rego, P.
  2014-03-17 14:08     ` Oliver Kleinke
  0 siblings, 1 reply; 12+ messages in thread
From: Rego, P. @ 2014-03-17  0:21 UTC (permalink / raw)


On Sunday, March 16, 2014 10:54:24 PM UTC, Oliver Kleinke wrote:
> Which compiler/version?
> If you're using the GNU toolchain then you can use "(avr-)objdump -S"
> to generate an assembly listing that's interspersed with source code.
> (Compile with debugging symbols '-g'.)
> You can then compare the disassembly of both programs.

`avr-gcc --version` answers me
avr-gcc (GCC) 4.5.4 20120510 for GNAT GPL 2012 (20120509)

I put the complete Ada objectdump part at http://is.gd/au08Fs. And the C part got from .lss in Atmel Studio I put in http://is.gd/qKpAuk.

Anyway, the handle parts in both assemblies give, for the Ada part:

   procedure Handle_Interrupt_USART1_RX is
    2e84:	1f 92       	push	r1
    2e86:	0f 92       	push	r0
    2e88:	0f b6       	in	r0, 0x3f	; 63
    2e8a:	0f 92       	push	r0
    2e8c:	00 90 5b 00 	lds	r0, 0x005B
    2e90:	0f 92       	push	r0
    2e92:	11 24       	eor	r1, r1
    2e94:	2f 93       	push	r18
    2e96:	8f 93       	push	r24
    2e98:	9f 93       	push	r25
    2e9a:	ef 93       	push	r30
    2e9c:	ff 93       	push	r31
    2e9e:	df 93       	push	r29
    2ea0:	cf 93       	push	r28
    2ea2:	0f 92       	push	r0
    2ea4:	cd b7       	in	r28, 0x3d	; 61
    2ea6:	de b7       	in	r29, 0x3e	; 62
      Curr_Buffer : AVR.Byte_Type;
   begin
      Curr_Buffer := AVR.USART.Reg_USART1.UDR;
    2ea8:	88 ec       	ldi	r24, 0xC8	; 200
    2eaa:	90 e0       	ldi	r25, 0x00	; 0
    2eac:	fc 01       	movw	r30, r24
    2eae:	86 81       	ldd	r24, Z+6	; 0x06
    2eb0:	89 83       	std	Y+1, r24	; 0x01
      AVR.USART.Reg_USART1.UDR := Curr_Buffer;
    2eb2:	88 ec       	ldi	r24, 0xC8	; 200
    2eb4:	90 e0       	ldi	r25, 0x00	; 0
    2eb6:	29 81       	ldd	r18, Y+1	; 0x01
    2eb8:	fc 01       	movw	r30, r24
    2eba:	26 83       	std	Z+6, r18	; 0x06
   end Handle_Interrupt_USART1_RX;
    2ebc:	00 00       	nop
    2ebe:	0f 90       	pop	r0
    2ec0:	cf 91       	pop	r28
    2ec2:	df 91       	pop	r29
    2ec4:	ff 91       	pop	r31
    2ec6:	ef 91       	pop	r30
    2ec8:	9f 91       	pop	r25
    2eca:	8f 91       	pop	r24
    2ecc:	2f 91       	pop	r18
    2ece:	0f 90       	pop	r0
    2ed0:	00 92 5b 00 	sts	0x005B, r0
    2ed4:	0f 90       	pop	r0
    2ed6:	0f be       	out	0x3f, r0	; 63
    2ed8:	0f 90       	pop	r0
    2eda:	1f 90       	pop	r1
    2edc:	18 95       	reti

and for the C part:
ISR(USART1_RX_vect)
{
 114:	1f 92       	push	r1
 116:	0f 92       	push	r0
 118:	0f b6       	in	r0, 0x3f	; 63
 11a:	0f 92       	push	r0
 11c:	11 24       	eor	r1, r1
 11e:	0b b6       	in	r0, 0x3b	; 59
 120:	0f 92       	push	r0
 122:	8f 93       	push	r24
 124:	ef 93       	push	r30
 126:	ff 93       	push	r31
	char ReceivedByte;
	ReceivedByte = UDR1;
 128:	ee ec       	ldi	r30, 0xCE	; 206
 12a:	f0 e0       	ldi	r31, 0x00	; 0
 12c:	80 81       	ld	r24, Z
	UDR1 = ReceivedByte;
 12e:	80 83       	st	Z, r24
 130:	ff 91       	pop	r31
 132:	ef 91       	pop	r30
 134:	8f 91       	pop	r24
 136:	0f 90       	pop	r0
 138:	0b be       	out	0x3b, r0	; 59
 13a:	0f 90       	pop	r0
 13c:	0f be       	out	0x3f, r0	; 63
 13e:	0f 90       	pop	r0
 140:	1f 90       	pop	r1
 142:	18 95       	reti

> > Given that I have mapped the Usart registers correctly on AVR.USART
> > package (because my JtagICE said so).
> Code?

Basically (you can also access the complete from ... http://is.gd/X9qVns),

   type USART_Control_And_Register_Status_Register_A_Type is
      record
         MPCM : Boolean; -- Multi-processor Communication Mode
         U2X  : Boolean; -- Double the USART Transmission Speed
         UPE  : Boolean; -- USART Parity Error
         DOR  : Boolean; -- Data OverRun
         FE   : Boolean; -- Frame Error
         UDRE : Boolean; -- USART Data Register Empty
         TXC  : Boolean; -- USART Transmit Complete
         RXC  : Boolean; -- USART Receive Complete
      end record;
   pragma Pack (USART_Control_And_Register_Status_Register_A_Type);
   for USART_Control_And_Register_Status_Register_A_Type'Size use
     BYTE_SIZE;

   type USART_Control_And_Register_Status_Register_B_Type is
      record
         TXB8  : Boolean; -- Transmit Data Bit 8
         RXB8  : Boolean; -- Receive Data Bit 8
         UCSZ2 : Boolean; -- Character Size Bit 2
         TXEN  : Boolean; -- Transmitter Enable
         RXEN  : Boolean; -- Receiver Enable
         UDRIE : Boolean; -- USART Data Register Empty Interrupt Flag
         TXCIE : Boolean; -- Tx Complete Interrupt Flag
         RXCIE : Boolean; -- Rx Complete Interrupt Flag
      end record;
   pragma Pack (USART_Control_And_Register_Status_Register_B_Type);
   for USART_Control_And_Register_Status_Register_B_Type'Size use
     BYTE_SIZE;

   type USART_Control_And_Register_Status_Register_C_Type is
      record
         UCPOL : Boolean; -- Clock Polarity
         UCSZ0 : Boolean; -- Character Size Bit 0
         UCSZ1 : Boolean; -- Character Size Bit 1
         USBS  : Boolean; -- Stop Bit Select
         UPM   : Bit_Array_Type (0 .. 1); -- Parity Mode Bits
         UMSEL : Bit_Array_Type (0 .. 1); -- Mode Select
      end record;
   pragma Pack (USART_Control_And_Register_Status_Register_C_Type);
   for USART_Control_And_Register_Status_Register_C_Type'Size use
     BYTE_SIZE;

   type USART_Type is
      record
         UCSRA : USART_Control_And_Register_Status_Register_A_Type;
         UCSRB : USART_Control_And_Register_Status_Register_B_Type;
         UCSRC : USART_Control_And_Register_Status_Register_C_Type;
         Spare : Spare_Type (0 .. 7);
         UBRR  : Byte_Array_Type (0 .. 1); -- USART Baud Rate Register L/H Bytes
         UDR   : Byte_Type; -- USART I/O Data Register
      end record;
   pragma Pack (USART_Type);
   for USART_Type'Size use 7 * BYTE_SIZE;

...and ...
   Reg_USART1 : USART_Type;
   for Reg_USART1'Address use System'To_Address (16#C8#);

when I do &Reg_USART1.<***> from the debugger it points correctly to each register position given by datasheet. For example, &Reg_USART1.UCSRA points me to
(gdb) &avr.usart.reg_usart1.ucsra
$2 = (access avr.usart.usart_control_and_register_status_register_a_type) 0x8000c8.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-16 23:09 ` Oliver Kleinke
@ 2014-03-17  0:32   ` Rego, P.
  0 siblings, 0 replies; 12+ messages in thread
From: Rego, P. @ 2014-03-17  0:32 UTC (permalink / raw)


On Sunday, March 16, 2014 8:09:16 PM UTC-3, Oliver Kleinke wrote:

> > The problem is that when I send anything to the usart, the Ada
> > application restarts (continuously).
> This usually happens if you either blow the stack/heap or the PC
> (program counter) overflows (reset/power on vector is at 0), e.g., if
> the compiler optimizes away your main loop.

I have a feeling that I did not blow the ram, mainly because the problem does not happen in a simpler board as ATmega328P (ATmega2560 has 8KB SRAM, while the last has only 2K). Also I am using -O for optimization.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-16 20:37 Interrupt-driven Usart not working in Ada, but in C working, why? Rego, P.
  2014-03-16 22:54 ` Oliver Kleinke
  2014-03-16 23:09 ` Oliver Kleinke
@ 2014-03-17 12:17 ` rrr.eee.27
  2014-03-17 20:28   ` Rego, P.
  2 siblings, 1 reply; 12+ messages in thread
From: rrr.eee.27 @ 2014-03-17 12:17 UTC (permalink / raw)


On Sunday, March 16, 2014 9:37:45 PM UTC+1, Rego, P. wrote:
> I am trying to use interrupt-driven Usart on an Atmel AVR ATmega2560 chip. 

AVR-Ada has both polled and interrupt driven UART packages. Both work at least on atmega328. I never tried ATmega2560.

As far as I remember one of the two versions exhibited a bug in the FSF-gnat of the time (gcc-4.5 or gcc-4.6). It was fixed in a later gcc release (4.7.1?).  You also might try a more recent gcc version.

Rolf

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-17  0:21   ` Rego, P.
@ 2014-03-17 14:08     ` Oliver Kleinke
  2014-03-24 14:36       ` rrr.eee.27
  0 siblings, 1 reply; 12+ messages in thread
From: Oliver Kleinke @ 2014-03-17 14:08 UTC (permalink / raw)


Am Sun, 16 Mar 2014 17:21:58 -0700 (PDT)
schrieb "Rego, P." <pvrego@gmail.com>:

> I put the complete Ada objectdump part at http://is.gd/au08Fs. And
> the C part got from .lss in Atmel Studio I put in http://is.gd/qKpAuk.

The interrupt vector table in the disassembly is total garbage, the
vector for your ISR is not even generated.
The IV at 0x90 points to 0x2f46 <__bad_interrupt> which contains
this instruction:

00002f46 <__bad_interrupt>:
    2f46:	0c 94 00 00 	jmp	0 ; 0x0 <__vectors>

So there you have your reset. I guess you should follow Rolf's advice
and try a newer gcc.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-17 12:17 ` rrr.eee.27
@ 2014-03-17 20:28   ` Rego, P.
  2014-03-18 14:08     ` Oliver Kleinke
  0 siblings, 1 reply; 12+ messages in thread
From: Rego, P. @ 2014-03-17 20:28 UTC (permalink / raw)


On Monday, March 17, 2014 9:17:33 AM UTC-3, rrr.e...@gmail.com wrote:
> AVR-Ada has both polled and interrupt driven UART packages. Both work at least on atmega328. I never tried ATmega2560.

Yes, I also tried with ATmega328P and fully worked.

> As far as I remember one of the two versions exhibited a bug in the FSF-gnat of the time (gcc-4.5 or gcc-4.6). It was fixed in a later gcc release (4.7.1?).  You also might try a more recent gcc version.

That means I would have to build the cross-compiler, right? (it takes off the fun of using gnat-gpl-2012-avr-windows-bin.exe installer :)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-17 20:28   ` Rego, P.
@ 2014-03-18 14:08     ` Oliver Kleinke
  2014-03-21  2:52       ` Rego, P.
  0 siblings, 1 reply; 12+ messages in thread
From: Oliver Kleinke @ 2014-03-18 14:08 UTC (permalink / raw)


Am Mon, 17 Mar 2014 13:28:13 -0700 (PDT)
schrieb "Rego, P." <pvrego@gmail.com>:

> On Monday, March 17, 2014 9:17:33 AM UTC-3, rrr.e...@gmail.com wrote:
> > AVR-Ada has both polled and interrupt driven UART packages. Both
> > work at least on atmega328. I never tried ATmega2560.
> 
> Yes, I also tried with ATmega328P and fully worked.
> 
> > As far as I remember one of the two versions exhibited a bug in the
> > FSF-gnat of the time (gcc-4.5 or gcc-4.6). It was fixed in a later
> > gcc release (4.7.1?).  You also might try a more recent gcc version.
> 
> That means I would have to build the cross-compiler, right? (it takes
> off the fun of using gnat-gpl-2012-avr-windows-bin.exe installer :)

Here's a script/instructions to build a cross-compiler:
http://arduino.ada-language.com/automating-avr-gnat-and-avr-ada-installation.html



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-18 14:08     ` Oliver Kleinke
@ 2014-03-21  2:52       ` Rego, P.
  2014-03-24 14:28         ` rrr.eee.27
  0 siblings, 1 reply; 12+ messages in thread
From: Rego, P. @ 2014-03-21  2:52 UTC (permalink / raw)


On Tuesday, March 18, 2014 11:08:54 AM UTC-3, Oliver Kleinke wrote:
> Here's a script/instructions to build a cross-compiler:
> http://arduino.ada-language.com/automating-avr-gnat-and-avr-ada-installation.html

Thanks!
I started to build gcc on a virtual machine running Windows XP with cygwin. But at some point of the gcc build I got several messages like

ada/a-except.o: In function `ada__exceptions__exception_message':
/cygdrive/f/Cross/gcc-obj-4.7.2/gcc/../../gcc-4.7.2/gcc/ada/a-except.adb:609: undefined reference to `__gnat_rcheck_CE_Explicit_Raise'

followed by
collect2: error: ld returned 1 exit status
../../gcc-4.7.2/gcc/ada/gcc-interface/Make-lang.in:553: recipe for target 'gnat1.exe' failed
make[3]: *** [gnat1.exe] Error 1
make[3]: Leaving directory '/cygdrive/f/Cross/gcc-obj-4.7.2/gcc'
Makefile:4101: recipe for target 'all-stage1-gcc' failed
make[2]: *** [all-stage1-gcc] Error 2
make[2]: Leaving directory '/cygdrive/f/Cross/gcc-obj-4.7.2'
Makefile:16443: recipe for target 'stage1-bubble' failed
make[1]: *** [stage1-bubble] Error 2
make[1]: Leaving directory '/cygdrive/f/Cross/gcc-obj-4.7.2'
Makefile:16747: recipe for target 'bootstrap' failed
make: *** [bootstrap] Error 2
ERROR: gcc: make bootstrap

Would you know what could fix it?

Regards.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-21  2:52       ` Rego, P.
@ 2014-03-24 14:28         ` rrr.eee.27
  0 siblings, 0 replies; 12+ messages in thread
From: rrr.eee.27 @ 2014-03-24 14:28 UTC (permalink / raw)


On Friday, March 21, 2014 3:52:06 AM UTC+1, Rego, P. wrote:
> Would you know what could fix it? Regards.

If you don't know exactly what you're doing, don't try to bootstrap on Cygwin. You can way too easily mix up the cygwin and the pure windows tools that end in problems as above. If you start delving into building the cross toolchain, try it in a Linux environment first.

Regards
     Rolf



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interrupt-driven Usart not working in Ada, but in C working, why?
  2014-03-17 14:08     ` Oliver Kleinke
@ 2014-03-24 14:36       ` rrr.eee.27
  0 siblings, 0 replies; 12+ messages in thread
From: rrr.eee.27 @ 2014-03-24 14:36 UTC (permalink / raw)


On Monday, March 17, 2014 3:08:11 PM UTC+1, Oliver Kleinke wrote:
> 00002f46 <__bad_interrupt>: 
>     2f46: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 

> So there you have your reset. 
> I guess you should follow Rolf's advice and try a newer gcc.

No, you don't need a newer compiler, you need a better link script.
Copy one of the existing linker scripts in your local work space and correct it there according to the data sheet.

Alternatively you might try rebuildig the avr-libc (V1.8.0) which includes newer binutils and link scripts

best regards
     Rolf

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2014-03-24 14:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-16 20:37 Interrupt-driven Usart not working in Ada, but in C working, why? Rego, P.
2014-03-16 22:54 ` Oliver Kleinke
2014-03-17  0:21   ` Rego, P.
2014-03-17 14:08     ` Oliver Kleinke
2014-03-24 14:36       ` rrr.eee.27
2014-03-16 23:09 ` Oliver Kleinke
2014-03-17  0:32   ` Rego, P.
2014-03-17 12:17 ` rrr.eee.27
2014-03-17 20:28   ` Rego, P.
2014-03-18 14:08     ` Oliver Kleinke
2014-03-21  2:52       ` Rego, P.
2014-03-24 14:28         ` rrr.eee.27

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox