Recent

Author Topic: Embedded avr writeln to serial port  (Read 2342 times)

diego bertotti

  • Full Member
  • ***
  • Posts: 101
Embedded avr writeln to serial port
« on: June 10, 2019, 01:50:38 am »
hi

i try to write to avr serial port using writeln, but it dont work.

in fpc documentation say about write funciton, if it used without specify output file, then stdout will be used.

I think stdout, in avr embedded, must be....serial port!, but dont work.

i can compile, have no errors!

¿whats wrong?

Code: Pascal  [Select][+][-]
  1. s:= 'Hello World';
  2. Write(s);
  3.  

and assembles was:
Code: Pascal  [Select][+][-]
  1. #  CPU AVR5
  2. # [260] s:= 'Hello World';
  3.         ldi     r24,lo8(U_sPsENCODER_ss_S)
  4.         ldi     r25,hi8(U_sPsENCODER_ss_S)
  5.         ldi     r20,lo8(_sENCODERs_Ld2)
  6.         ldi     r21,hi8(_sENCODERs_Ld2)
  7.         ldi     r22,-1
  8.         mov     r23,r1
  9.         call    fpc_shortstr_to_shortstr
  10. # [261] Write( s);
  11.         call    fpc_get_output
  12.         movw    r2,r24
  13.         ldi     r18,lo8(U_sPsENCODER_ss_S)
  14.         ldi     r19,hi8(U_sPsENCODER_ss_S)
  15.         movw    r20,r2
  16.         mov     r22,r1
  17.         mov     r23,r1
  18.         mov     r24,r1
  19.         mov     r25,r1
  20.         call    fpc_write_text_shortstr
  21.         call    fpc_iocheck
  22.         movw    r24,r2
  23.         call    fpc_write_end
  24.         call    fpc_iocheck
  25.  

who konws !!!

where can i found documentation specific about avr embedded?

thanks

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Embedded avr writeln to serial port
« Reply #1 on: June 10, 2019, 01:08:18 pm »
I think stdout, in avr embedded, must be....serial port!, but dont work.

I don't think that could work like that. The compiler would have to set up the UART, which is different for different devices. Also which UART settings should be used... occupying port -pins...

Perhaps you can redirect the StdOut and forward it to the serial port.

Quote
where can i found documentation specific about avr embedded?
There's not too much documentation.

You probably already found that:
http://wiki.freepascal.org/AVR_Programming

A tutorial in German:
http://wiki.freepascal.org/AVR_Embedded_Tutorial/de

Project wizard:
https://github.com/kupferstecher/LazPackageEmbeddedAVR

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Embedded avr writeln to serial port
« Reply #2 on: June 10, 2019, 01:39:04 pm »
The syntax should probably be something like:
Code: Pascal  [Select][+][-]
  1. write(PortID,'Hello, World');
since a single AVR can address more than one port.I believe PortID can be the actual address, but I have no AVR or docs available ATM.
« Last Edit: June 10, 2019, 01:41:47 pm by Thaddy »
Specialize a type, not a var.

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Embedded avr writeln to serial port
« Reply #3 on: June 10, 2019, 02:44:04 pm »
I just tried to redirect the StdOut. The following works for me on STM32, but I believe the code works also for AVR.

usage:

Code: Pascal  [Select][+][-]
  1. uses
  2.   uStdOutRedirect;
  3. begin
  4.    StdOutRedirectInit;
  5.    write('Hallo');
  6. end;

Unit uStdOutRedirect:
Code: Pascal  [Select][+][-]
  1. unit uStdOutRedirect;
  2.  
  3. {$mode objfpc}
  4.  
  5. INTERFACE
  6.  
  7.   Procedure StdOutRedirectInit;
  8.  
  9.  
  10. IMPLEMENTATION
  11.  
  12. Uses
  13.   consoleio, uUART;
  14.  
  15. function WriteToUART(ACh: char; AUserData: pointer): boolean; forward;
  16. function EmptyWrite(ACh: char; AUserData: pointer): boolean; forward;
  17. function EmptyRead(var ACh: char; AUserData: pointer): boolean; forward;
  18.  
  19.  
  20. Procedure StdOutRedirectInit;
  21. begin
  22.   OpenIO(StdOut,@WriteToUART,@EmptyRead,fmOutput,nil);
  23.  
  24.   //OpenIO(Input, @EmptyWrite, @EmptyRead, fmInput, nil);
  25.   //OpenIO(Output, @EmptyWrite, @EmptyRead, fmOutput, nil);
  26.   //OpenIO(ErrOutput, @EmptyWrite, @EmptyRead, fmOutput, nil);
  27.   //OpenIO(StdOut, @EmptyWrite, @EmptyRead, fmOutput, nil);
  28.   //OpenIO(StdErr, @EmptyWrite, @EmptyRead, fmOutput, nil);
  29. end;
  30.  
  31. function WriteToUART(ACh: char; AUserData: pointer): boolean;
  32.   begin
  33.     UART.SendChar(ACh);
  34.     Result:=true;
  35.   end;
  36.  
  37. function EmptyWrite(ACh: char; AUserData: pointer): boolean;
  38. begin Result:=true; end;
  39.  
  40. function EmptyRead(var ACh: char; AUserData: pointer): boolean;
  41. begin
  42.     Result:=true;
  43.     ACh:=#0;
  44. end;
  45.  
  46. end.

The UART has to be set up seperately, in my example the data is sent with the UART.SendChar procedure.

« Last Edit: June 10, 2019, 04:21:43 pm by kupferstecher »

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Embedded avr writeln to serial port
« Reply #4 on: June 10, 2019, 03:16:39 pm »
Note that on AVR it is a good idea to compile in {$I-} state.
Specialize a type, not a var.

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Embedded avr writeln to serial port
« Reply #5 on: June 10, 2019, 04:27:10 pm »
Thaddy, the {$I-} switch only is needed, if IO-Checks are enabled for the project, right? (-Ci command line option).

diego bertotti

  • Full Member
  • ***
  • Posts: 101
Re: Embedded avr writeln to serial port
« Reply #6 on: June 10, 2019, 04:40:26 pm »
hi

thanks for reply

i see if a use write function, ucontroller hangs!, and work fine witout write function

i see assembler and i found "call    fpc_iocheck" then i try without checking io result using {$I-}

now uc dont hang, but i can see nothing on serial port.

really, i can see data in serial port, but this data was writed on serial port by my own pascal routine
« Last Edit: June 10, 2019, 04:44:23 pm by diego bertotti »

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Embedded avr writeln to serial port
« Reply #7 on: June 10, 2019, 04:45:40 pm »
Thaddy, the {$I-} switch only is needed, if IO-Checks are enabled for the project, right? (-Ci command line option).
The assembler code showed it was in {$I+} state, hence  the fpc_io_check calls which have quite some overhead, both in time and code, especially in loops.
Specialize a type, not a var.

diego bertotti

  • Full Member
  • ***
  • Posts: 101
Re: Embedded avr writeln to serial port
« Reply #8 on: June 10, 2019, 07:42:34 pm »
kupferstecher, i don't found uUART unit!

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: Embedded avr writeln to serial port
« Reply #9 on: June 10, 2019, 09:05:24 pm »
@Thaddy:
 OK, I thought you mean my code.

@diego:
As said, I tested with a STM32, not with AVR.

But here you go, the UART code for an ATMega32. The register names may be different in your device. Also make sure the frequency setting is correct: const f_CPU.

Code: Pascal  [Select][+][-]
  1. unit uUART;
  2.  
  3. {$mode objfpc}{$H-}
  4. {$goto on}
  5.  
  6. INTERFACE
  7.  
  8. Const
  9.   f_CPU = 4000000; //Hertz
  10.   Baud  = 115200;
  11.  
  12. Type TUART = object
  13.   private
  14.     RecvValue: Byte;
  15.   public
  16.     Procedure Init;
  17.     Procedure BusyWait;
  18.     Procedure SendChar(CharVal: Char);inline;
  19.     Procedure SendString(InString: ShortString);
  20. end;
  21.  
  22. var
  23.   UART: TUART;
  24.  
  25.    
  26. //################################################################
  27. IMPLEMENTATION
  28.  
  29. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  30. procedure TUART.Init;
  31. Const
  32.   UBRR_VAL   = ((F_CPU+BAUD*8) div (BAUD*16)-1); //rounding
  33. begin
  34.   //Baudrate
  35.   UBRRL:= byte(UBRR_VAL);
  36.   UBRRH:= byte(UBRR_VAL div 256);
  37.   //bits, parity etc.
  38.   UCSRC:= (1 shl URSEL) or (1 shl UCSZ2) or (1 shl UCSZ); //8 bit, 1 stop bit, no parity
  39.   //UART aktivieren
  40.   UCSRB:= (1 shl TXEN)   //TX aktivieren (Senden)
  41.        or (1 shl RXEN)   //RX aktivieren (Empfangen)
  42.        or (1 shl RXCIE); //Interrupt bei Empfang
  43.  
  44.   //Enable Interrupts
  45.   asm sei end;
  46.  
  47. end;
  48.  
  49. //-------------------------------------------------------------------
  50. Procedure TUART.BusyWait;
  51. begin
  52.   while (UCSRA and (1 shl UDRE)) = 0 do;
  53.  
  54. end;
  55.  
  56. //-------------------------------------------------------------------
  57. Procedure TUART.SendChar(CharVal: Char);inline;
  58. begin
  59.   BusyWait;
  60.   UDR:= Byte(CharVal);    
  61. end;
  62.  
  63. //-------------------------------------------------------------------
  64. Procedure TUART.SendString(InString: ShortString);
  65. var
  66.   ii:Integer;
  67. begin
  68.  
  69.   for ii:= 1 to length(InString) do begin
  70.     BusyWait;
  71.     UDR:= Byte(InString[ii]);  
  72.   end;//do
  73.  
  74. end;
  75.  
  76. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  77. //++ Interrupt for each received byte
  78. Procedure UARTReceive_ISR;Alias: 'USART__RXC_ISR'; Interrupt; Public;
  79. begin
  80.   //UART.Send(UDR); //Echo...
  81.  
  82.   UART.RecvValue:= UDR;
  83.  
  84. end;
  85.  
  86. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  87. end.

EDIT: Don't forget to call  UART.Init; before you try to send something.
« Last Edit: June 10, 2019, 09:07:45 pm by kupferstecher »

 

TinyPortal © 2005-2018