A preview of the auto generated AVR controller files have been prepared.
Your ImportATDF automation tool does a very nice job.
Note that there were some name clashes of different identifiers, hence I used s_ and m_ as prefixes for set element and bitmask names respectively.
I still don't like e_ and m_ prefixes with underscores but I can live with them since it is pretty much subjective. What I really don't like is that it seams that you have decided to use such c-ish habbit all over. Here are some examples:
uart_init1(...);
fpc_shr_qword(...);
fpc_div_mod_word(...);
spi_transfer(...);
Huh, so many underscores and low cases feel like using some C lib. Is it possible to make it more like we are used with FPC/LAZ/DELPHI, please?
I would also prefer single overloaded DivMod() which accepts different types instead of each being a completely separate (if they are intended for the user, after all):
procedure fpc_div_mod_byte(Dividend, Divisor: byte; out result, remainder: byte);
procedure fpc_div_mod_word(Dividend, Divisor: word; var result, remainder: word);
procedure fpc_div_mod_dword(Dividend, Divisor: dword; var result, remainder: dword);
function fpc_div_mod_qword(Dividend, Divisor: qword; out Remainder: qword): qword;
I didn't find type helpers for byte/word/dword/qword. Something like we have discussed previously. Do you have plans to add them as standard at all?
Since it is a 8-bit embedded world, assembly optimization will be needed in some of the libraries. It would be nice to decide what registers will never be used by the system and the system libraries, what registers would be used for function results, how to name register pairs, etc. I would suggest to make it compatible with AvrCo, and you can find more info in PDF already mentioned here (Section 11.2 Assembler - Keywords):
https://forum.lazarus.freepascal.org/index.php/topic,38809.msg266019.html#msg266019It would be of highest priority to look at GCC/Arduino register usage compatibility for this topic as there will be a need in the future to link to some C library. Functions to save/restore all registers or only system used ones would also be appreciated.
I am not quite sure how good would FPC optional register optimization work for AVR, and if we can force specific variables to be stored in registers (if enough free registers are available). Have you looked into this topic yet?
Pointers to internal and external ram, flash and eeprom would need to be treated somehow different. There are also AVRs with flash bigger then 64KB. Have you thought about such things yet?
How did you manage to do this in examples:
pinport: byte absolute PORTB;
It compiles on my standard FPC compiler only if I type adress $24 instead of PORTB. However I managed to overcome this issue on my side by defining const PORTBaddr = $24 in generated avr cpu unit and then using PORTBaddr instead of PORTB in both avr cpu unit and example code.
I see that all examples follow flat workflow - pretty much GCC and Arduino way. While that is not bad at all, I am very spoiled by AvrCo way of doing things so let me give you a quick insight that might be used as a potential inspiration. AvrCo allows flat program workflow extended with interrupts when needed, but it also provides SysTick, Tasks and Processes.
SysTick is a simple system interrupt (10ms by default but can be any period) extended with an optional user callback and used for system and drivers. No more constant polling for ADC readings, no more manual debouncing of inputs, manual matrix keyboard scanning, manual key autorepeat, we have various funtion timeouts, automatic 7seg and 14seg display refresh, automatic PWM or DAC output change, automatic soft and hard RTC handling with user callbacks, automatic handling of data collected from interrupt based drivers like pulse/freq counters or encoders, automatic step motor ramps, etc. Most drivers exploit SysTick so user code looks clean and without GCC like bloat we are used to. Drivers also have callbacks, and IO callbacks are specially usefull. For example, all character or graphical LCD functions are universal. There is example code for 8-9 display models, but if you want to use a not supported one, you just implement IO callbacks for your device, and positioning, drawing, text output and other functions immediatelly work out of the box. The same is for RTC and many other drivers. You can access serial and other types of communication directly like in GCC, but you can also use a interrupt based driver that stores characters into a buffer that you just need to poll to sea if there is anything to read. You might even sleep a process until data is available, since pipes and semaphores are implemented. There is also a round robin scheduler with cyclic tasks and processes with priorities.
Tasks have a predefined maximum time for running, and they are killed if that max time is somehow reached.
Processes are just temporary interrupted and they simply continue where they left on next schedule. This powerfull multitasking concept allows for example one or more communication processes, an IO task, main logic process, etc. Each as a separate identity easy to follow and develop. Only C based RTOS can match this.
Whatever path you decide to go, I really think that you have already done a very nice job. Thumbs up!