Recent

Author Topic: Integrate AVRco Pascal into Freepascal?  (Read 7370 times)

avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #15 on: October 11, 2023, 03:04:42 pm »
Integrate AVRco Pascal into Freepascal?
With some dev effort you could integrate AvrCo compiler into Lazarus. Sources are proprietary so anything other then that is not realistic. I would never do such a thing, because I really like the existing hardware debugging in AvrCo's own IDE, and visual graphical simulator for the most of the drivers. Such a powerful simulator can not be found even now with today's most advanced IDEs for embedded development.

I just found out that the developer of the AVRco PAscal program has died and the program is now freeware.
I know Rolf was retired a few years ago when Merlin took over and compiler was released for free download. Where did you hear that Rolf died? I did not see it mentioned in E-Lab's forum. Are you sure?
As you can see at https://www.e-lab.de/AVRco/DOC_en/Release-News.txt Merlin has already added extended records and some other things. He also seams to have a plan to add some other new features that will be charged for.

"I myself do not use AVRco Pascal, but rather Mikroe Pascal."
I use AvrCo and MikroPascal for more then 20 years, but I also use Arduino/VScode, STM32CubeIDE, ESP-IDF and some others. AvrCo has nice syntax, project wizard, tons of drivers, graphical simulator, and powerful multitasking much simpler then FreeRTOS. MikroPascal has nice code portability between architectures and some exotic drivers. Both support hardware debuggers, single step and triggers. FreePascal is a relatively new player in AVR arena and can not compete in available drivers and features, but it is the only open sourced compiler where you can change whatever you wish. There is space for all of them.
« Last Edit: October 11, 2023, 03:15:53 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

coradi

  • Full Member
  • ***
  • Posts: 167
Re: Integrate AVRco Pascal into Freepascal?
« Reply #16 on: October 11, 2023, 03:29:05 pm »
I heard it yesterday in another forum from Harry, a very active member in the AVRco forum. He will certainly be active here in the coming days, I recommended Free Pascal to him. He will definitely take a look at it. It passed away a few days ago.
Amstrad Schneider CPC 6128
AVR8/ARM(STM32)

avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #17 on: October 11, 2023, 03:36:01 pm »
I've just gone looking at DocuCompiler.pdf and section 10.1 appears to indicate that the syntax is the same as FPC uses.

Not quite. AvrCo also borrowed some Modula-2 like syntax, and introduced it's own to better support multitasking and hardware access. Look at these examples:

Code: Pascal  [Select][+][-]
  1. function SetAO(const AnalogOutputNumber: byte; const NewValue: word): boolean;  // set value of a real physical analog output (PWM)
  2. begin // example:   SetAO(3, 1023)   =>   PWM3 := 100% duty cycle      (50% Duty Cycle at 10bit resolution is 511)
  3.   if ValueInRange(NewValue, 0, 1023) then
  4.     case AnalogOutputNumber of
  5.       1:      PWMport1A := NewValue; |
  6.       2:      PWMport1B := NewValue; |
  7.       3:      PWMport1C := NewValue; |
  8.     else
  9.       return(false); // AnalogOutputNumber is not valid
  10.     endcase;
  11.     return(true);    // AnalogOutputNumber is valid
  12.   else
  13.     return(false);   // NewValue duty cycle percentage is not valid
  14.   endif;
  15. end;

Code: Pascal  [Select][+][-]
  1. Unit OkoCommon;
  2.  
  3. interface
  4.  
  5. {.$W+}                 // enable/disable warnings for this unit
  6.  
  7. uses okoTypes, Common;
  8.  
  9. {$I HcpAlias.inc}      // include project dependent file with aliases which define com port used in HCP protocol (so we can use HcpCom unit in different projects)
  10.  
  11. type
  12. PAlarmEvent = pointer to TAlarmEvent;
  13.  
  14. const
  15.   OKO_PCB_HW_REV: string = '20140328'; // different HW revisions will be handled by IFDEFs in code
  16.  
  17.   UART2_DUMMY     : byte = %00;
  18.   UART2_MikroBUS_B: byte = %01;       UART2_GSM: byte = UART2_MikroBUS_B; // pseudo alias
  19.   UART2_MikroBUS_C: byte = %10;       UART2_BT : byte = UART2_MikroBUS_C; // pseudo alias
  20.   UART2_USB       : byte = %11;
  21.  
  22.   // pin numbers needed as a workaround to be able to not hard code get and set bit tags in IX[], but to be able to iterate through bits in a loop:
  23.   PIN_NUM_DI_1: byte = 0;
  24.   PIN_NUM_DI_2: byte = 1;
  25.   ...
  26.   PIN_NUM_DI_6: byte = 5;
  27.   //
  28.   PIN_NUM_DO_1: byte = 0;
  29.   PIN_NUM_DO_2: byte = 1;
  30.   ...
  31.   PIN_NUM_DO_6: byte = 5;
  32.  
  33.   BUZZ_TICK : word =  10;
  34.   BUZZ_SHORT: word = 100;
  35.   BUZZ_LONG : word = 500;
  36.  
  37.   ADC_AVFILTER: byte = 8; // ADC moving average filter depth
  38.  
  39.   VOLTAGE_REF_24V: word = 800; // TODO: this should hold real 24V measured voltage in the future
  40.  
  41. var
  42. {$PDATA}
  43.  
  44.   { PORTA } // use PINA0..PINA5 debouncing:
  45.   I      [@PinA]: byte;
  46.   DI     [@PORT_STABLE1]: byte;
  47.  
  48.   {$IDATA} // PORT_STABLE1 is not in $PDATA
  49.   DI_1   [@PORT_STABLE1, PIN_NUM_DI_1]: bit; // DI_1[@PinA, PIN_NUM_DI_1]: bit; // Input PIN
  50.   DI_2   [@PORT_STABLE1, PIN_NUM_DI_2]: bit; // DI_2[@PinA, PIN_NUM_DI_2]: bit; // Input PIN
  51.   DI_3   [@PORT_STABLE1, PIN_NUM_DI_3]: bit; // DI_3[@PinA, PIN_NUM_DI_3]: bit; // Input PIN
  52.   DI_4   [@PORT_STABLE1, PIN_NUM_DI_4]: bit; // DI_4[@PinA, PIN_NUM_DI_4]: bit; // Input PIN
  53.   DI_5   [@PORT_STABLE1, PIN_NUM_DI_5]: bit; // DI_5[@PinA, PIN_NUM_DI_5]: bit; // Input PIN
  54.   DI_6   [@PORT_STABLE1, PIN_NUM_DI_6]: bit; // DI_6[@PinA, PIN_NUM_DI_6]: bit; // Input PIN
  55.   SW_1   [@PORT_STABLE1, 6]: bit;            // Input PIN     DIP switch 1
  56.   SW_2   [@PORT_STABLE1, 7]: bit;            // Input PIN     DIP switch 2
  57.   {$PDATA}
  58.  
  59.   { PORTB }
  60.   CS_A   [@PortB, 0]: bit;  // Output PIN - SPI: CS_A
  61.   SCK    [@PortB, 1]: bit;      // Output PIN - SPI: Master data CLOCK OUT
  62.   MOSI   [@PortB, 2]: bit;      // Output PIN - SPI: Master data OUT
  63.   MISO   [@PinB,  3]: bit;  // Input  PIN - SPI: Master data IN
  64.   CS_B   [@PortB, 4]: bit;      // Output PIN - SPI: CS_B
  65.   PWMA   [@PortB, 5]: bit;      // Output PIN -
  66.   PWMB   [@PortB, 6]: bit;      // Output PIN -
  67.   PWMC   [@PortB, 7]: bit;      // Output PIN -
  68.  
  69.   { PORTC }
  70.   Q      [@PortC]: byte;
  71.   DO     [@PortC]: byte;
  72.   //
  73.   DO_1   [@PortC, PIN_NUM_DO_1]: bit;   Buzzer [@PortC, PIN_NUM_DO_1]: bit; // Output PIN
  74.   DO_2   [@PortC, PIN_NUM_DO_2]: bit;   // Output PIN
  75.   DO_3   [@PortC, PIN_NUM_DO_3]: bit;   // Output PIN
  76.   DO_4   [@PortC, PIN_NUM_DO_4]: bit;   // Output PIN
  77.   DO_5   [@PortC, PIN_NUM_DO_5]: bit;   // Output PIN
  78.   DO_6   [@PortC, PIN_NUM_DO_6]: bit;   // Output PIN
  79.   {$IDATA} // PORT_STABLE2 is not in $PDATA
  80.   SW_3   [@PORT_STABLE2, 6]: bit;       // Input PIN     DIP switch 3
  81.   SW_4   [@PORT_STABLE2, 7]: bit;       // Input PIN     DIP switch 4
  82.   {$PDATA}
  83.   {
  84.   SW_3   [@PinC,  6]: bit;   // Input PIN
  85.   SW_4   [@PinC,  7]: bit;   // Input PIN
  86.   }
  87.  
  88.   { PORTD }
  89.   SCL    [@PortD, 0]: bit;   // Output PIN
  90.   SDA    [@PinD,  1]: bit;   // Input PIN
  91.   RXD1   [@PinD,  2]: bit;       // Input PIN
  92.   TXD1   [@PortD, 3]: bit;   // Output PIN
  93.   CS_C   [@PortD, 4]: bit;       // Output PIN - SPI: CS_C
  94.   CS_D   [@PortD, 5]: bit;       DF_CHIP_SELECT [@PortD, 5]: bit; // for flash driver   // Output PIN - SPI: CS_D
  95.   RSTA   [@PortD, 6]: bit;       // Output PIN -
  96.   RSTB   [@PortD, 7]: bit;       // Output PIN -
  97.  
  98.   { PORTE }
  99.   RXD0   [@PinE,  0]: bit;   // Input PIN
  100.   TXD0   [@PortE, 1]: bit;   // Output PIN
  101.   AIN0   [@PinE,  2]: bit;   // Input PIN
  102.   AIN1   [@PinE,  3]: bit;   // Input PIN
  103.   INTA   [@PortE, 4]: bit;   // Output PIN -
  104.   INTB   [@PortE, 5]: bit;   // Output PIN -
  105.   INTC   [@PortE, 6]: bit;   // Output PIN -
  106.   RTCINT [@PinE,  7]: bit;   // Input PIN
  107.  
  108.   { PORTF }
  109.   ADC0   [@PinF, 0]: bit;    // Input PIN  AI_1
  110.   ADC1   [@PinF, 1]: bit;    // Input PIN  AI_2
  111.   ADC2   [@PinF, 2]: bit;    // Input PIN  AI_3
  112.   ADC3   [@PinF, 3]: bit;    // Input PIN  AI_4
  113.   ADC4   [@PinF, 4]: bit;    // Input PIN  AI_5
  114.   ADC5   [@PinF, 5]: bit;    // Input PIN  AN-A
  115.   ADC6   [@PinF, 6]: bit;    // Input PIN  AN-B
  116.   ADC7   [@PinF, 7]: bit;    // Input PIN  AN-C
  117.  
  118.   { PORTG }
  119.   RSTC   [@PortG, 0]: bit;   // Output PIN -
  120.   CBUS3  [@PinG,  1]: bit;   UsbDetect [@PinG,  1]: bit; // Input  PIN - USB Detect
  121.   SysLed [@PortG, 2]: bit;   // Output PIN - SYS LED
  122.   SEL_A  [@PortG, 3]: bit;   ComMuxA   [@PortG, 3]: bit; // Output PIN - Serial Comm Mux: SEL_A
  123.   SEL_B  [@PortG, 4]: bit;   ComMuxB   [@PortG, 4]: bit; // Output PIN - Serial Comm Mux: SEL_B
  124.  
  125. {$EEPROM}
  126.   EepromDummy: word;  // some old AVRs had a corruption bug when writing to zero location during power failure
  127.  
  128.   // eeprom write example:
  129.   // Settings.Ai[1].Alarms.LoLo.Value := 3.14;
  130.   //
  131.   Settings: TSettings, locked; // settings are sent from laptop via communication protocol and stored in eeprom
  132.  
  133. {$UDATA} // MAX 64 bytes of battery backup ram (User Device: RTCC_MCP7940)
  134.   Battery: TBattery, locked; // structure with all battery backed variables      TODO: check if locked really works with slow I2C used for RTC vars access
  135.  
  136. {$IDATA}
  137.   Runtime:  TRuntime, locked;  // structure with all runtime variables stored in ram
  138.  
  139.   ExpiredSecond: semaphore;
  140.   //ExpiredMinute: semaphore;
  141.   ExpiredHour:   semaphore;
  142.   //ExpiredDay:    semaphore;
  143.  
  144.   EvtPipe: pipe[16] of byte; // pipe with waiting events
  145.  
  146.   FilterW1  : AVfilter[0..ADC_AVFILTER-1] of word;
  147.   FilterW2  : AVfilter[0..ADC_AVFILTER-1] of word;
  148.   FilterW3  : AVfilter[0..ADC_AVFILTER-1] of word;
  149.   FilterW4  : AVfilter[0..ADC_AVFILTER-1] of word;
  150.   FilterW5  : AVfilter[0..ADC_AVFILTER-1] of word;
  151.   FilterW6  : AVfilter[0..ADC_AVFILTER-1] of word;
  152.   FilterW7  : AVfilter[0..ADC_AVFILTER-1] of word;
  153.   FilterW8  : AVfilter[0..ADC_AVFILTER-1] of word;
  154.  
  155.   nAVcnt: byte; // ADC counter ..
  156.   tShutDownTimer:  TTimer;
  157.   {$IFDEF SIMULATOR}
  158.     FakeBattery: array[0..UserPort-1] of byte;
  159.   {$ENDIF}
  160.  
  161.   ...
  162.  

Code: Pascal  [Select][+][-]
  1. program Oko;
  2.  
  3. {$I DeveloperSpecific.inc}  // each developer likes different defines, like {$DEFINE SIMULATOR}
  4.  
  5. {.$WG}                      // global Warnings on
  6.  
  7. {.$ZeroLocVars +}           // all local vars are cleared to zero when func/proc is entered (this has cleared FlashTotalPages and FlashPageSize, so we will not use it for now)
  8.  
  9. {$DEBDELAY}                 // only used in simulator - shortens mDelays by 90% (no affect on hex file)
  10.  
  11. {.$DEFINE DEBUG}            // show serial debug messages
  12.  
  13. device = mega128, VCC=3.3;
  14. {.$BOOTRST $07000}          // Reset Jump to $07000
  15.  
  16. import SysTick, SerPort, SerPort2, ADCPort, TWImaster, SPIdriver, SwitchPort1, SwitchPort2, RTClock, UserPort, PWMport1A, PWMport1B, PWMport1C, Watchdog, SysLEDblink;
  17.  
  18. from System import LongWord, LongInt, Float, Processes, StackChecks, Pipes;
  19.  
  20. from RTclock import RTCtimer{, RTCalarm};
  21.  
  22. From SysLEDblink Import FlashOnce; // this is optional
  23.  
  24. define
  25.   ProcClock      = 7372800;                 // Hertz
  26.   SysTick        = 10, Timer2;              // msec
  27.   StackSize      = 150, iData;
  28.   FrameSize      = 150, iData;
  29.  
  30.   WatchDog       = msec2000;                // msec32, msec64, msec125, msec250, msec1000, msec2000
  31.  
  32.   SerPort        = 9600, Stop1;             // Baud, StopBits|Parity
  33.   RxBuffer       = 16, iData;
  34.   TxBuffer       = 16, iData;
  35.  
  36.   SerPort2       = 38400, Stop1, parEven;   // change speed to 115200, 230400 or 460800 (for 921600 we would need higher crystal)
  37.   RxBuffer2      = 64, iData;               // changed from 255 to 64 to improve process freeze
  38.   TxBuffer2      = 128, iData;              // changed from 255 to 128 to improve process freeze
  39.  
  40.   ADCchans       = 8, iData;
  41.   ADCpresc       = 128;
  42.  
  43.   TWIpresc       = TWI_BR400;
  44.  
  45.   SysLedBlink    = 50; // SysTicks
  46.   SysLedBlink0   = PortC, 0, high; // Buzzer
  47.   SysLedBlink1   = PortC, 1, high; // Green LED
  48.   SysLedBlink2   = PortC, 2, high; // Red LED
  49.   SysLedBlink3   = PortC, 3, high; //
  50.   SysLedBlink4   = PortC, 4, high; //
  51.   SysLedBlink5   = PortC, 5, high; //
  52.  
  53.   SPIpresc       = 0;
  54.   SPIOrder       = LSB;
  55.   SPICPOL        = 0;
  56.   SPICPHA        = 0;
  57.   SPI_SS         = false;                   // don't use SS pin as chip select
  58.  
  59.   Scheduler      = iData;
  60.   SwitchPort1    = PinA;                    // debouncing input pins: PA.0 .. PA.7
  61.   SwitchPMask1   = %11111111;               // debounce only these bits
  62.   PolarityP1     = %00000000;               // active level: false
  63.   SwitchPort2    = PinC;                    // debouncing input pins: PC.6 .. PC.7
  64.   SwitchPMask2   = %11000000;               // debounce only these bits
  65.   PolarityP2     = %00000000;               // active level: false
  66.   Debounce       = 3;                       // debounce every 3 SysTicks
  67.  
  68.   RTclock        = iData, DateTime;         // Time or DateTime
  69.   RTCtimer       = 1;                       // 1..8 Channels
  70.   RTCsource      = SysTick{[, adj]};        // SysTick must be >= 1 when selected as RTC source, it must be integer, and (1000 mod SysTick) must be 0.
  71.  
  72.   UserPort       = 64;                      // define Mem expansion size
  73.   PWMpresc1      = 256;                     // prescaler timer1
  74.   PWMres1        = 10;                      // resolution timer1
  75.   PWMmode1       = fast, positive;          // optional
  76.  
  77.   FlashChkSum    = ProgEnd;                 // generate flash checksum at the end of code
  78.  
  79. define_usr // user defined global constants visible in whole program (it is better to use included units)
  80.   MyGlobalConst  = 1;
  81.  
  82. uses
  83.   okoTypes, okoCommon, okoTest, okoTags, okoMuxCom, HcpCom, Common, DriverFlash, DriverRTC, okoRT, okoSysTime, okoJSON, okoInterrupts;
  84.  
  85. implementation
  86.  
  87.  
  88. {$IDATA}
  89.  
  90. {--------------------------------------------------------------}
  91. { Type Declarations }
  92.  
  93.  
  94. {--------------------------------------------------------------}
  95. { Const Declarations }
  96. const
  97.  
  98. {--------------------------------------------------------------}
  99. { Var Declarations }
  100. {$IDATA}
  101. var
  102.   ProcessFreezeCnt: byte;
  103.   TotalFreezeCnt: word;
  104.  
  105.   //mydt: TDateTime;
  106.  
  107. {--------------------------------------------------------------}
  108. { functions }
  109.  
  110. procedure Init;
  111. begin
  112.   // Init ports
  113.   DDRA :=  %00000000;  // All input pins
  114.   DDRB :=  %11110111;  // Pin B3 (MISO) - input pin
  115.   DDRC :=  %00111111;  // Pin C7,C6 - input pins
  116.   DDRD :=  %11111001;  // Pin D2,D1 - input pins
  117.   DDRE :=  %01110001;  // Pin E7,E3,E2,E0 - input pins
  118.   DDRF :=  %00000000;  // All input pins
  119.   DDRG :=  %00011101;  // Pin G1 (CBUS3) - input pins
  120.  
  121.   PORTA := %11000000;  // Pin A7:A6 - PullUp if PUD=0
  122.   PORTC := %11000000;  // Pin C7:C6 - PullUp if PUD=0
  123.   PORTG := %00000010;  // Pin G1 - PullUp if PUD=0
  124.  
  125.   CS_A := 1;           // CS_D must be initially 1 for flash memory chip access
  126.   CS_B := 1;           //
  127.   CS_C := 1;           //
  128.   CS_D := 1;           //
  129.  
  130.   PWMport1A := 0;      // PWM-A
  131.   PWMport1B := 0;      // PWM-B
  132.   PWMport1C := 0;      // PWM-C
  133.  
  134.   // init interrupt Analog Comparator (AC)
  135.   SFIOR := SFIOR and %11110111; // bit 3: connect AIN1(-) input (disable ADC Mux)
  136.  
  137.   ACSR  := ACSR and %00111011; // bit 7: 0, AC enabled
  138.                                // bit 6: 0, Connect AIN0(+)
  139.                                // bit 5: -, N/A
  140.                                // bit 4: -, Analog Comparator Interrupt Flag Set/Clear by hardware
  141.                                // bit 3: -
  142.                                // bit 2: 0, Analog Comparator Input Capture Disable
  143.                                // bit 1: -, ACIS1 Comparator Interrupt on Output Edge.
  144.                                // bit 0: -, ACIS0 (0)Falling/(1)Rising Output Edge.
  145.  
  146.   ACSR := ACSR  or  %00001011; // bit 7: -
  147.                                // bit 6: -
  148.                                // bit 5: -
  149.                                // bit 4: -
  150.                                // bit 3: 1, Analog Comparator Interrupt Flag enabled
  151.                                // bit 2: -                               // bit 1:
  152.                                // bit 1: 1, ACIS1 Comparator Interrupt on Output Edge.
  153.                                // bit 0: 1, ACIS0 (0)Falling/(1)Rising Output Edge.
  154.  
  155. end Init;
  156.  
  157. {$IFDEF SIMULATOR}
  158. procedure InitSim;
  159. begin
  160.   Runtime.DO[1].Value := true;                              // MX11
  161.   Runtime.DO[2].Value := false;                             // MX12
  162.   Settings.AI[7].Active := false;                           // MX5107
  163.   Settings.AI[8].Active := false;                           // MX5108
  164.   Settings.AO[2].Active := false;                           // MX5302
  165.   Settings.AO[3].Active := true;                            // MX5303
  166.   Settings.General.OverwriteOldEvents := false;             // MX5001
  167.   Settings.BT.Active := false;
  168.   Settings.GPS.Active := false;
  169.   Settings.GSM.Active := false;
  170.   Settings.InsideTemp[1].Active := false;
  171.   Settings.InsideTemp[2].Active := false;
  172.  
  173.   Runtime.General.PowerUp.Moment.Year     := 11;            // MB101
  174.   Runtime.General.PowerUp.Moment.Month    := 02;            // MB102
  175.   Runtime.General.PowerUp.Moment.Day      := 12;            // MB103
  176.   Runtime.General.PowerUp.Moment.Hour     := 19;            // MB104
  177.   Runtime.General.PowerUp.Moment.Minute   := 30;            // MB105
  178.   Runtime.General.PowerUp.Moment.Second   := 25;            // MB106
  179.   Runtime.General.PowerUp.Moment.LeapYear := true;          // MX108
  180.  
  181.   Settings.GPS.TimeZone := -7;                              // MS5001
  182.  
  183.   Runtime.DO[1].Stat.CurrentHour.OnCount := 3210;           // MW2001
  184.   Settings.General.HcpComm.TimeoutTicks := 59876;           // MW5001
  185.  
  186.   Runtime.AO[1].Eng.Value := 1.23;                          // QF11
  187.   Runtime.AO[2].Eng.Value := 2.34;                          // QF12
  188.   Runtime.AO[3].Eng.Value := 3.14;                          // QF13
  189.   Runtime.AO[3].Eng.Stat.CurrentHour.AvgValue := 123.4567;  // MF2053
  190.   Settings.AO[1].Alarm.Treshold := 987.654321;              // MF7041
  191.  
  192.   Battery.EventPages.FirstPage := 2;                        // must be <> 0 in order for HCP read page command to work in simulator
  193.   Battery.EventPages.LastPage  := 5;
  194.   Battery.BoardStat.TotalSeconds := 1000000;                // running days shown in statistics
  195.  
  196.   //DisableInts;
  197.   RtcSetYear(13);   RtcSetMonth(12);    RtcSetDay(31);      // 2013.12.31
  198.   RtcSetHour(23);   RtcSetMinute(59);   RtcSetSecond(0);    // 23:59:00
  199.   RtcSetWeekDay(1);                                         // Tuesday
  200.   //EnableInts;  // no need to enable interrupts here since Start_Processes called later will do that for us
  201.  
  202.   // Runtime.General.PowerUp.Tick := 1234567890;            // MD1
  203.  
  204.   {if StrToDateTime('20141124T185959Z', mydt) then
  205.     WriteLn(SerOutHcp, '1: ' + DateTimeToStr(mydt, tzDoNotShowTimeZoneChar));
  206.   endif;
  207.   if StrToDateTime('20141024T185859', mydt) then
  208.     WriteLn(SerOutHcp, '2: ' + DateTimeToStr(mydt, tzShowTimeZoneChar));
  209.   endif;}
  210. end InitSim;
  211. {$ENDIF}
  212.  
  213. procedure CheckFrameAndStack;
  214. const
  215.   BAD_RESULT: integer = -1; //$FFFF
  216. var
  217.   i: byte;
  218. begin
  219.   if CheckStackValid(Main_Proc)  = BAD_RESULT then Runtime.General.Processes[IDX_MAIN      ].Stack.Valid := false; endif;
  220.   if CheckStackValid(HcpComm)    = BAD_RESULT then Runtime.General.Processes[IDX_HCP_COMM  ].Stack.Valid := false; endif;
  221.   if CheckStackValid(MuxComm)    = BAD_RESULT then Runtime.General.Processes[IDX_MUX_COMM  ].Stack.Valid := false; endif;
  222.   if CheckStackValid(RT_Data)    = BAD_RESULT then Runtime.General.Processes[IDX_RT_DATA   ].Stack.Valid := false; endif;
  223.   if CheckStackValid(RT_Second)  = BAD_RESULT then Runtime.General.Processes[IDX_RT_SECOND ].Stack.Valid := false; endif;
  224.   if CheckStackValid(RT_Hour)    = BAD_RESULT then Runtime.General.Processes[IDX_RT_HOUR   ].Stack.Valid := false; endif;
  225.   if CheckStackValid(RT_Actions) = BAD_RESULT then Runtime.General.Processes[IDX_RT_ACTIONS].Stack.Valid := false; endif;
  226.  
  227.   if CheckFrameValid(Main_Proc)  = BAD_RESULT then Runtime.General.Processes[IDX_MAIN      ].Frame.Valid := false; endif;
  228.   if CheckFrameValid(HcpComm)    = BAD_RESULT then Runtime.General.Processes[IDX_HCP_COMM  ].Frame.Valid := false; endif;
  229.   if CheckFrameValid(MuxComm)    = BAD_RESULT then Runtime.General.Processes[IDX_MUX_COMM  ].Frame.Valid := false; endif;
  230.   if CheckFrameValid(RT_Data)    = BAD_RESULT then Runtime.General.Processes[IDX_RT_DATA   ].Frame.Valid := false; endif;
  231.   if CheckFrameValid(RT_Second)  = BAD_RESULT then Runtime.General.Processes[IDX_RT_SECOND ].Frame.Valid := false; endif;
  232.   if CheckFrameValid(RT_Hour)    = BAD_RESULT then Runtime.General.Processes[IDX_RT_HOUR   ].Frame.Valid := false; endif;
  233.   if CheckFrameValid(RT_Actions) = BAD_RESULT then Runtime.General.Processes[IDX_RT_ACTIONS].Frame.Valid := false; endif;
  234.  
  235.   for i := 1 to NUMBER_OF_PROCESSES do
  236.     Runtime.General.PowerUp.StackFrameCorrupted := Runtime.General.PowerUp.StackFrameCorrupted or (not Runtime.General.Processes[i].Stack.Valid) or (not Runtime.General.Processes[i].Frame.Valid);
  237.   endfor;
  238.  
  239.   if Runtime.General.PowerUp.StackFrameCorrupted then // if stack/frame was corrupted at least once since power up
  240.     Buzz(1000); // TODO: in production buzzer should not be heard - save event instead
  241.   endif;
  242. end;
  243.  
  244. {--------------------------------------------------------------}
  245. { Main Program }
  246. ...
  247.  

Code: Pascal  [Select][+][-]
  1. process MuxComm(40, 40: iData);
  2. begin
  3.   if GetStackFree(MuxComm) < Runtime.General.Processes[IDX_MUX_COMM].Stack.MinFree then
  4.     Runtime.General.Processes[IDX_MUX_COMM].Stack.MinFree := GetStackFree(MuxComm);
  5.   endif;
  6.   if GetFrameFree(MuxComm) < Runtime.General.Processes[IDX_MUX_COMM].Frame.MinFree then
  7.     Runtime.General.Processes[IDX_MUX_COMM].Frame.MinFree := GetFrameFree(MuxComm);
  8.   endif;
  9.   Inc(Runtime.General.Processes[IDX_MUX_COMM].ScanCnt);
  10.  
  11.   Schedule; // do not waste any more systicks dedicated with priority by passing the control to the scheduler (goto next process)
  12. end MuxComm;

Code: Pascal  [Select][+][-]
  1. type
  2.   TFIFOBuff = record
  3.     Buff: pointer to byte;
  4.     Size: byte;
  5.     AddPtr: byte;
  6.     RmvPtr: byte;
  7.     function AddByte(const AByte: byte): boolean;
  8.     function RemoveByte(var AByte: byte): boolean;
  9.     procedure AssignBuffer(const ABuff: pointer to byte; const ASize: byte);
  10.     function Full: boolean;
  11.     function Empty: boolean;
  12.   end;
« Last Edit: October 12, 2023, 01:54:28 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #18 on: October 11, 2023, 03:38:49 pm »
I heard it yesterday in another forum from Harry, a very active member in the AVRco forum.
I am so sad to hear this. It is such a loss. I knew Rolf for a long, long time.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

coradi

  • Full Member
  • ***
  • Posts: 167
Re: Integrate AVRco Pascal into Freepascal?
« Reply #19 on: October 12, 2023, 09:22:55 am »
@Monkey
Haha, definitely not. That is not an option.
Amstrad Schneider CPC 6128
AVR8/ARM(STM32)

MarkMLl

  • Hero Member
  • *****
  • Posts: 8134
Re: Integrate AVRco Pascal into Freepascal?
« Reply #20 on: October 12, 2023, 09:57:39 am »
I've just gone looking at DocuCompiler.pdf and section 10.1 appears to indicate that the syntax is the same as FPC uses.

Not quite. AvrCo also borrowed some Modula-2 like syntax, and introduced it's own to better support multitasking and hardware access.

But the unit syntax, which was what OP appears to be asking about, is more or less the same. It doesn't have completely separate .itf files, or rely entirely on include files etc.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12000
  • FPC developer.
Re: Integrate AVRco Pascal into Freepascal?
« Reply #21 on: October 12, 2023, 10:40:48 am »
I've just gone looking at DocuCompiler.pdf and section 10.1 appears to indicate that the syntax is the same as FPC uses.

Not quite. AvrCo also borrowed some Modula-2 like syntax,

Pointer to, the | for the cases, import and from import and maybe RETURN (though that could also have come from somewhere else and gains parameters).

But I also see Basic   (endcase/endif), and random syntax (define and process keyword), or maybe that is a bit verilog like.

and introduced it's own to better support multitasking and hardware access. Look at these examples:

It has architecture dependent port syntax and some common tricks for cooperative multitasking/RTOS and probably also interrupt routines. All on par for an embedded dialect, but "better"? .... Opinions may vary :-)

For a non architecture specific compiler, it would be nicer to hide away the port,bit syntax using some attribute system, to keep it away from the main parser.

p.s. I use MP Lab X mostly nowadays.  Afaik it also support Atmel, but I use it for dspic (XC16).  But my codebase was in C from the start.


avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #22 on: October 13, 2023, 02:51:33 am »
and introduced it's own to better support multitasking and hardware access. Look at these examples:

It has architecture dependent port syntax and some common tricks for cooperative multitasking/RTOS and probably also interrupt routines. All on par for an embedded dialect, but "better"?
Well, although I prefer it I did not say AvrCo syntax was better then Modula-2, I said that AvrCo "introduced it's own to better support multitasking and hardware access", in the context that AvrCo creator felt that some novelties could ease embedded development or could improve readability. And I do appreciate them, although I am aware that someone else might not like them at all, and that's fine. I like that every if must have an endif so I can put anything in between without having to check begin/end/else, I like that I can treat any bit as an actual boolean (var MyLed[@PortB, 2]: bit;) since it is so nice to look at MyLed := true in the embedded code, I like that at any place in the code I can change storage of the following variables to registers, ram, flash, eeprom, etc with a simple define ({$IDATA}, or {$PDATA} and others), I like that many provided drivers do their job inside of a systick, I like that many drivers (like graphic lcd) are generic and support most common types but you can easily support new ones without writing everything from the scratch (so AvrCo drawing routines also support your new lcd out of the box), I like extended records, I like it's multitasking which is not as customizable like FreeRTOS but provides much cleaner and simpler but still powerful features, and many, many other things. All these things help embedded pascal still look like pascal we love with a clean and easy to read syntax, and not like pascal translated from embedded C.

Btw, AvrCo started as PicCo for 16F84 and friends  :-[
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12000
  • FPC developer.
Re: Integrate AVRco Pascal into Freepascal?
« Reply #23 on: October 13, 2023, 11:02:39 am »
I specifically talked about how I would do the PORT/LAT access differently.

As for the multitasking that is harder to evaluate how generic that is, I only see a process keyword with numeric parameters. The define seems to be macros (shudder)

p.s. I only used 18F for about three years before I moved on to 16-bit.

avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #24 on: October 13, 2023, 03:33:45 pm »
As for the multitasking that is harder to evaluate how generic that is, I only see a process keyword with numeric parameters. The define seems to be macros (shudder)
If interested, multitasking details can be found in compiler manual pdf which can be downloaded from https://www.e-lab.de/AVRco/index_en.html, chapters "5 Multi-Tasking Programming" and "4.16 Multi-Task Functions".
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12000
  • FPC developer.
Re: Integrate AVRco Pascal into Freepascal?
« Reply #25 on: October 13, 2023, 03:54:43 pm »
As for the multitasking that is harder to evaluate how generic that is, I only see a process keyword with numeric parameters. The define seems to be macros (shudder)
If interested, multitasking details can be found in compiler manual pdf which can be downloaded from https://www.e-lab.de/AVRco/index_en.html, chapters "5 Multi-Tasking Programming" and "4.16 Multi-Task Functions".

I read through it, but it is more or less the basic embedded RTOS. I had to implement something like this in uni on an Hitachi 8051 derivate. It has a few things more than I did in this 9 week course, like the process/task difference(processes are more easily suppressed than tasks?) and the pipe functionality are new.
So slightly more expanded than a basic concept, but nothing spectacular.  Of course the language support makes it look nicer here and there, but that is more make-up than functionality.

Anyway, when I moved from PIC18 to dspic, I tried to change my embedded work from polling to event driven (using periphery that is interrupt or DMA driven), so the whole RTOS concept got less relevant, because there were less things to poll.


avra

  • Hero Member
  • *****
  • Posts: 2532
    • Additional info
Re: Integrate AVRco Pascal into Freepascal?
« Reply #26 on: October 13, 2023, 04:17:10 pm »
It has a few things more than I did in this 9 week course, like the process/task difference(processes are more easily suppressed than tasks?) and the pipe functionality are new.
Processes are basically forever loops with their own stack and frame which can be interrupted anywhere by interrupts or other processes and will continue where they stopped in the next scheduler round. Tasks are cyclic procedures called by a scheduler which are not interrupted by processes but can not last longer then a systick. Nice thing about processes is that if needed they can sleep and wait for a semaphore or pipe (usually populated by interrupt or DMA peripheral). Unlike FreeRTOS there is no idle time when you use processes, unless you explicitly create a process just for that.
« Last Edit: October 13, 2023, 04:27:47 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

 

TinyPortal © 2005-2018