5 Copyright (C) 2012-2015, Molnar Karoly <molnarkaroly@users.sf.net>
7 This file is part of SDCC.
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any damages
11 arising from the use of this software.
13 Permission is granted to anyone to use this software for any purpose,
14 including commercial applications, and to alter it and redistribute it
15 freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you must not
18 claim that you wrote the original software. If you use this software
19 in a product, an acknowledgment in the product documentation would be
20 appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and must not be
23 misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source distribution.
27 ================================================================================
29 cinc2h.pl (common-inc2h.pl)
31 This program parse the gpasm header (p1xxx.inc) files and creates
32 from them the SDCC header and device library files. In addition it
33 needs the gpprocessor.c file also. These is included in the source
34 package of gputils. Mode of download of the latest source:
36 http://gputils.sourceforge.net/#Download
38 The program is available on request provide assistance: cinc2h.pl -h
40 -------------------------------------------------
42 Steps to add a new target device to SDCC/PIC16:
43 (Following Raphael Neider <rneider AT web.de>)
45 1. Create the picDEVICE.c and picDEVICE.h from pDEVICE.inc using
46 ./cinc2h.pl -p 18f4520 -cb -cp -gp "path/to/gputils_source" -o "path/to/output"
48 2. mv picDEVICE.h $SDCC/device/non-free/include/pic16
49 3. mv picDEVICE.c $SDCC/device/non-free/lib/pic16/libdev
52 (a) adjust $SDCC/device/lib/pic16/libio/*.ignore
53 if the device does not support ADC, I2C, or USART
56 * SDCC/scripts/pic18fam-h-gen.pl
57 * SDCC/device/include/pic16/adc.h (if required)
58 * SDCC/device/include/pic16/usart.h (if required)
59 * SDCC/device/lib/pic16/libio/*/* (if required)
60 to add the new device to the appropriate I/O style
61 and implement new styles (if required).
63 Having modified pic18fam-h-gen.pl, you need to run the
64 script to generate pic18fam.h.gen, which in turn must
65 then replace your .../include/pic16/pic18fam.h to take
66 effect; see pic18fam-h-gen.pl for usage information.
67 6. edit $SDCC/device/include/pic16/pic18fregs.h
68 7. edit $SDCC/device/include/pic16/pic16devices.txt
69 8. run cd $SDCC/device/non-free/lib/pic16 && sh update.sh
70 to regenerate .../libdev/Makefile.am and processors.ac
72 The file format of steps 6 and 7 is self explanatory, in most
73 if not all cases you can copy and paste another device's records
74 and adjust them to the newly added device.
76 -------------------------------------------------
78 Steps to add a new target device to SDCC/PIC14:
80 1. Create the picDEVICE.c and picDEVICE.h from pDEVICE.inc using
81 ./cinc2h.pl -p 16f1503 -cb -cp -gp "path/to/gputils_source" -o "path/to/output"
83 2. mv picDEVICE.h $SDCC/device/non-free/include/pic14
84 3. mv picDEVICE.c $SDCC/device/non-free/lib/pic14/libdev
85 4. add DEVICE to $SDCC/device/non-free/lib/pic14/libdev/devices.txt
86 (The names of the enhanced devices the "# enhanced cores" line
89 5. edit $SDCC/device/include/pic14/pic14devices.txt
91 The file format of step 5 is self explanatory, in most if not all
92 cases you can copy and paste another device's records and adjust
93 them to the newly added device.
100 no if $] >= 5.018, warnings
=> "experimental::smartmatch"; # perl 5.16
101 use 5.12.0; # when (regex)
102 use File
::Path
'make_path';
103 use feature
'switch'; # Starting from 5.10.1.
104 use POSIX
qw(strftime);
106 use constant FALSE
=> 0;
107 use constant TRUE
=> 1;
109 use constant ST_NONE
=> 0;
110 use constant ST_REG_ADDR
=> 1;
111 use constant ST_REG1_DEF
=> 2;
112 use constant ST_REG2_DEF
=> 3;
113 use constant ST_RAM_DEF
=> 4;
114 use constant ST_CONFIG_DEF
=> 5;
115 use constant ST_DEVID_DEF
=> 6;
116 use constant ST_IDLOC_DEF
=> 7;
118 use constant DIST_ADDRSIZE
=> 32;
119 use constant DIST_BITSIZE
=> 32;
120 use constant DIST_DEFSIZE
=> 32;
121 use constant DIST_COMSIZE
=> 32;
123 my $PROGRAM = 'cinc2h.pl';
127 my $gputils_path = "$ENV{HOME}/svn_snapshots/gputils/gputils";
128 my $gp_header_path = '';
129 my $gpprocessor_c = 'gpprocessor.c';
132 my $name_filter = qr/10l?f\d+[a-z]*|1[26]((c(e|r)?)|hv)\d+[a-z]*|1[268]l?f\d+([a-z]*|[a-z]+\d+[a-z]*)/;
133 my $header_name_filter = 'p${name_filter}.inc';
135 my $p14_out_path = 'pic14';
136 my $p16_out_path = 'pic16';
140 my $is_pic16 = FALSE
;
146 my $create_bitfields = FALSE
;
147 my $emit_legacy_names = FALSE
;
148 my $no_timestamp = FALSE
;
150 my $section = '//' . ('=' x
78);
152 my $btype_t = "${btail}_t";
154 # Here those names to be entered that are defective.
158 my %correction_of_names =
160 OPTION
=> 'OPTION_REG'
163 # At some processors there is such register name, that is different
164 # from what the other processors in used. This is a replacement table.
166 my %register_aliases =
171 #-----------------------------------------------
174 The structure of one element of the @registers array:
177 NAME => '', The name of register.
178 ADDRESS => 0, The address of register.
179 NEED_PREFIX => 0, Indicates if in front the name of bits necessary an prefix.
180 BITNAMES => [ The bits of register.
181 [], The names of 0th bit.
188 [] The names of 7th bit.
196 'ADCS' => { This the descriptor of the ADCS field.
197 ADDRESSES => [], Physical start addresses of bits of the field.
198 INDEXES => [], Bit indexes of bits of the field (ADCS2 -> '2').
199 WIDTH => 0 So many bit the width of the bit-field.
212 #-----------------------------------------------
214 # References of registers according to name of registers.
215 my %reg_refs_by_names = ();
217 # References of registers according to name of bits of registers.
218 # With help of recognizable the repetitive bit names.
219 my %reg_refs_by_bits = ();
221 #-----------------------------------------------
224 The structure of one element of the @configs array:
227 NAME => '', The name of config.
228 ADDRESS => 0, The address of config.
229 OPTIONS => [ The options of config.
246 #-----------------------------------------------
258 my $device_registers = '';
259 my $full_bitdefs = '';
260 my $legacy_names = '';
262 ################################################################################
263 ################################################################################
264 ################################################################################
265 ################################################################################
269 return ($_[0] =~ /([^\/]+)$/) ?
$1 : '';
272 #-------------------------------------------------------------------------------
276 die "This option \"$_[0]\" requires a parameter.\n" if ($_[1] > $#ARGV);
279 #-------------------------------------------------------------------------------
285 return hex($1) if ($Str =~ /^H'([[:xdigit:]]+)'$/io);
286 return hex($1) if ($Str =~ /^0x([[:xdigit:]]+)$/io);
287 return int($Str) if ($Str =~ /^-?\d+$/o);
289 die "str2int(): This string not integer: \"$Str\"";
292 #-------------------------------------------------------------------------------
297 my $al = $_[1] - length($text);
299 # One space will surely becomes behind it.
300 $al = 1 if ($al < 1);
302 return ($text . ' ' x
$al);
305 #-------------------------------------------------------------------------------
309 return if (pop(@_) > $verbose);
310 foreach (@_) { print $_; }
314 #-------------------------------------------------------------------------------
318 foreach (@_) { print $out_handler $_; }
321 #-------------------------------------------------------------------------------
326 print $out_handler "\n";
329 #-------------------------------------------------------------------------------
331 sub versionCompare
($$)
333 my ($Str1, $Str2) = @_;
335 if ((${$Str1} =~ /^\d/o) && (${$Str2} =~ /^\d/o))
337 # $Str1 number and $Str2 number
338 return (int(${$Str1}) <=> int(${$Str2}));
341 return (${$Str1} cmp ${$Str2});
344 #-------------------------------------------------------------------------------
348 my @a_s = ($_[0] =~ /(\d+|\D+)/go);
349 my @b_s = ($_[1] =~ /(\d+|\D+)/go);
350 my ($i, $k, $end, $ret);
371 for ($i = 0; $i < $end; ++$i)
373 $k = versionCompare
(\
$a_s[$i], \
$b_s[$i]);
375 return $k if ($k != 0);
381 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
382 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
383 #@@@@@@@@@@@@@ @@@@@@@@@@@@
384 #@@@@@@@@@@@@ Load all definitions, which will find in the header. @@@@@@@@@@@
385 #@@@@@@@@@@@@@ @@@@@@@@@@@@
386 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
387 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
389 # If the $Word included in a list then it will replace.
394 my $corr = $correction_of_names{$Word};
398 Log
("$Word --> $corr ($mcu)", 7);
405 #-------------------------------------------------------------------------------
407 # Adds to the list the $Name register.
411 my ($Name, $Address) = @_;
413 if (defined($reg_refs_by_names{$Name}))
415 die "The \"$Name\" register has been included on the list. ($mcu)\n";
419 NAME
=> correct_name
($Name),
421 NEED_PREFIX
=> FALSE
,
426 push(@registers, $reg);
427 $reg_refs_by_names{$Name} = $reg;
431 #-------------------------------------------------------------------------------
433 # Cuts the unnecessary prefix or suffix.
435 sub bit_filtration
($$)
437 my ($Regname, $Bits) = @_;
439 for (my $i = 0; $i < 8; ++$i)
441 my $array = $Bits->[$i];
443 next if (! defined($array));
452 # Operation: 'C1OUT_CMCON' --> 'C1OUT'
455 $changed += ($_ =~ s/^${Regname}_|_${Regname}$//);
456 $changed += ($_ =~ s/^(\d+)$/bit_$1/o);
457 push(@
{$new_bits}, $_);
460 $Bits->[$i] = $new_bits if ($changed);
464 #-------------------------------------------------------------------------------
466 # Tries the $Bit insert into a bitfield of the $Register.
468 sub bitfield_preparation
($$$)
470 my ($Register, $Bit, $Address) = @_;
471 my $fields = $Register->{BITFIELDS
};
473 $fields = $Register->{BITFIELDS
} = {} if (! defined($fields));
477 if ($Bit =~ /(\d+)$/op)
479 my $flname = ${^PREMATCH
};
482 if (! defined($fields->{$flname}))
484 # Creates a new field.
486 Log
("BIT first : $flname\[$Address\] = '$flidx'", 7);
487 $fields->{$flname} = {
488 ADDRESSES
=> [ $Address ],
495 # The bit inserts into an existing field.
497 Log
("BIT remaining: $flname\[$Address\] = '$flidx'", 7);
498 push(@
{$fields->{$flname}->{ADDRESSES
}}, $Address);
501 $fields->{$flname}->{INDEXES
}->[$Address] = $flidx;
505 #-------------------------------------------------------------------------------
507 # If can, classifies the $Bits into a field.
509 sub bitfield_registration
($$)
511 my ($Register, $Bits) = @_;
513 for (my $i = 0; $i < 8; ++$i)
515 my $array = $Bits->[$i];
517 next if (! defined($array));
519 Log
("bitfield_registration() -- $i", 8);
522 bitfield_preparation
($Register, $_, $i);
527 #-------------------------------------------------------------------------------
529 # In the $Queue are in register's names.
530 # Assigns to these the contents of $Bits.
534 my ($Queue, $Bits) = @_;
536 return if ((scalar(@
{$Queue}) == 0) || (scalar(@
{$Bits}) == 0));
540 next if ($_ eq 'and'); # This here easiest to filter out.
542 my $name = correct_name
($_);
543 my $reg = $reg_refs_by_names{$name};
547 Log
("The $name register is not directly be reached or does not exist. ($mcu)", 2);
548 $reg = new_register
($name, -1);
551 bit_filtration
($name, $Bits);
552 bitfield_registration
($reg, $Bits);
553 $reg->{BITNAMES
} = [ @
{$Bits} ];
560 #-------------------------------------------------------------------------------
562 # Finds the $Name in the $Bits.
566 my ($Bits, $Name) = @_;
568 return FALSE
if (! defined($Bits));
570 for (my $i = 0; $i < 8; ++$i)
572 my $array = $Bits->[$i];
574 next if (! defined($array));
578 return TRUE
if ($_ eq $Name);
585 #-------------------------------------------------------------------------------
587 # Adds to the list the $Name config byte/word.
589 sub add_conf_word
($$)
591 my ($Name, $Address) = @_;
593 my $conf = $conf_names{$Name};
597 # The $Name config byte/word still unknown, but there are related words.
599 # If the $Name config byte/word are defined later than
600 # the associated bits, then this section is executed.
603 $conf->{ADDRESS
} = $Address if ($conf->{ADDRESS
} < 0 && $Address >= 0);
607 # The $Name config byte/word still unknown and there are no related words.
615 push(@configs, $conf);
616 $conf_names{$Name} = $conf;
620 #-------------------------------------------------------------------------------
622 sub add_conf_options
($$)
624 my ($Queue, $Options) = @_;
626 return if ((scalar(@
{$Queue}) == 0) || (scalar(@
{$Options}) == 0));
630 my $conf = $conf_names{$_};
632 die "This config unknown: \"$_\" ($mcu)\n" if (! defined($conf));
634 $conf->{OPTIONS
} = [ @
{$Options} ];
641 #-------------------------------------------------------------------------------
643 # Reads the entire content of the $File.
645 sub read_content_from_header
($)
648 my ($state, $name, $addr);
652 open(IN
, '<', $File) || die "Can not open the $File header file!\n";
658 foreach (grep(! /^\s*$/o, <IN
>))
666 Log
("#### \"$line\"", 8);
672 Log
(":::: ST_NONE ($line) ($mcu)", 4);
674 $state = ST_REG_ADDR
if ($line =~ /^;-+\s*Register\s+Files\s*-+$/io);
679 Log
(":::: ST_REG_ADDR ($line) ($mcu)", 4);
681 if ($line =~ /^;-+\s*(.+)Bits\s*-+$/io)
683 # ;----- STKPTR Bits --------------------------------------------------------
684 # ;----- UIR/UIE Bits -------------------------------------------------------
685 # ;----- TXSTA, TXSTA1 and TXSTA2 Bits --------------------------------------
688 # Therefore need the queue because more register names can be on one line.
690 @queue = ($1 =~ /([^\s,\/]+)/go
);
691 $state = ST_REG1_DEF
;
693 elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io) #'
698 new_register
($1, str2int
($2));
700 } # when (ST_REG_ADDR)
704 Log
(":::: ST_REG1_DEF ($line) ($mcu)", 4);
706 if ($line =~ /^;\s*I\/O\s
+Pin\s
+Name\s
+Definitions?
$/io
)
708 # ; I/O Pin Name Definitions
711 Log
("1 +++ add_reg_bits()", 6);
712 add_reg_bits
(\
@queue, \
@array);
713 $state = ST_REG2_DEF
;
715 elsif ($line =~ /^;\s*RAM\s+Definitions?$/io)
721 Log
("2 +++ add_reg_bits()", 6);
722 add_reg_bits
(\
@queue, \
@array);
725 elsif ($line =~ /^;-+\s*(.+)Bits\s*-+$/io)
729 Log
("3 +++ add_reg_bits()", 6);
730 add_reg_bits
(\
@queue, \
@array);
732 # Therefore need the queue because more register names can be on one line.
734 @queue = ($name =~ /([^\s,\/]+)/go
);
736 elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io) #'
741 push(@
{$array[str2int
($2)]}, $1);
743 } # when (ST_REG1_DEF)
747 Log
(":::: ST_REG2_DEF ($line) ($mcu)", 4);
749 if ($line =~ /^;\s*RAM\s+Definitions?$/io)
755 Log
("4 +++ add_reg_bits()", 6);
756 add_reg_bits
(\
@queue, \
@array);
759 elsif ($line =~ /^;-+\s*([^-]+)\s*-+$/io)
763 Log
("5 +++ add_reg_bits()", 6);
764 add_reg_bits
(\
@queue, \
@array);
766 # Therefore need the queue because more register names can be on one line.
768 @queue = ($name =~ /([^\s,\/]+)/go
);
770 elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)$/io) #'
775 push(@
{$array[int($2)]}, $1);
777 } # when (ST_REG2_DEF)
781 Log
(":::: ST_RAM_DEF ($line) ($mcu)", 4);
783 $state = ST_CONFIG_DEF
if ($line =~ /^;\s*Configuration\s+Bits$/io);
788 Log
(":::: ST_CONFIG_DEF ($line) ($mcu)", 4);
790 if ($line =~ /^_(DEVID\d*)\s+EQU\s+([\w']+)$/io) #'
792 add_conf_options
(\
@queue, \
@array);
794 Log
("DEVID: $line", 6);
795 push(@devids, { NAME
=> $1, ADDRESS
=> str2int
($2) });
796 $state = ST_DEVID_DEF
;
798 elsif ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io) #'
800 add_conf_options
(\
@queue, \
@array);
802 Log
("IDLOC: $line", 6);
803 push(@idlocs, { NAME
=> $1, ADDRESS
=> str2int
($2) });
804 $state = ST_IDLOC_DEF
;
806 elsif ($line =~ /^_(CONFIG\d*\w*)\s+EQU\s+([\w']+)$/io) #'
808 Log
("CONFIG: $line", 6);
809 add_conf_word
(uc($1), str2int
($2));
811 elsif ($line =~ /^;\s*-+\s*(Config\d*\w*)\s+Options\s*-+$/io)
815 Log
("1. Config: $line", 6);
816 add_conf_options
(\
@queue, \
@array);
817 add_conf_word
($name, -1);
820 elsif ($line =~ /^;\s*-+\s*Config\s+Word(\d+)\s+Options\s*-+$/io ||
821 $line =~ /^;\s*Configuration\s+Byte\s+(\d+[HL])\s+Options$/io)
823 my $name = "CONFIG$1";
825 Log
("2. Config: $line", 6);
826 add_conf_options
(\
@queue, \
@array);
827 add_conf_word
($name, 0);
830 elsif ($line =~ /^(\w+)\s+EQU\s+([\w']+)(.+)?$/io) #'
832 my ($name, $value) = ($1, str2int
($2));
838 $expl =~ s/\s*;\s*//;
841 Log
("Config option: $line", 6);
842 push(@array, { NAME
=> $name, VALUE
=> $value, EXPLANATION
=> $expl });
844 } # when (ST_CONFIG_DEF)
848 Log
(":::: ST_DEVID_DEF ($line) ($mcu)", 4);
850 if ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io) #'
852 Log
("IDLOC: $line", 6);
853 push(@idlocs, { NAME
=> $1, ADDRESS
=> str2int
($2) });
854 $state = ST_IDLOC_DEF
;
856 elsif ($line =~ /^_(DEVID\d*)\s+EQU\s+([\w']+)$/io) #'
858 Log
("DEVID: $line", 6);
859 push(@devids, { NAME
=> $1, ADDRESS
=> str2int
($2) });
865 Log
(":::: ST_IDLOC_DEF ($line) ($mcu)", 4);
867 if ($line =~ /^_(IDLOC\d*)\s+EQU\s+([\w']+)$/io) #'
869 Log
("IDLOC: $line", 6);
870 push(@idlocs, { NAME
=> $1, ADDRESS
=> str2int
($2) });
874 } # foreach (grep(! /^\s*$/o, <IN>))
876 add_conf_options
(\
@queue, \
@array);
880 return if (! scalar(@registers));
882 # Within the array sorts by address the registers.
884 @registers = sort {$a->{ADDRESS
} <=> $b->{ADDRESS
}} @registers;
887 #-------------------------------------------------------------------------------
889 # Reads the bounds of config area from the gpprocesor.c file.
891 sub extract_config_area
($$)
893 my ($Conf_start, $Conf_end) = @_;
895 open(LIB
, '<', $gpproc_path) || die "extract_config_area(): Can not open. -> \"$gpproc_path\"\n";
897 # static struct px pics[] = {
898 # { PROC_CLASS_PIC12E , "__12F529T39A" , { "pic12f529t39a" , "p12f529t39a" , "12f529t39a" }, 0xE529, 3, 8, 0x00E0, { 0x07, 0x0F }, 0x06F, { -1, -1 }, 0x00FF, 0x0005FF, 0x000600, { -1, -1 }, { 0x000640, 0x000643 }, { 0x000FFF, 0x000FFF }, { 0x000600, 0x00063F }, 0x0FF0, "p12f529t39a.inc" , "12f529t39a_g.lkr" , 0 },
899 # { PROC_CLASS_PIC14E , "__16LF1517" , { "pic16lf1517" , "p16lf1517" , "16lf1517" }, 0xA517, 4, 32, 0x0F80, { 0x70, 0x7F }, -1, { 0x2000, 0x21EF }, 0x0FFF, 0x001FFF, 0x002000, { -1, -1 }, { 0x008000, 0x008003 }, { 0x008007, 0x008008 }, { -1, -1 }, 0x3F80, "p16lf1517.inc" , "16lf1517_g.lkr" , 0 },
901 my $in_table = FALSE
;
909 $in_table = TRUE
if (/^\s*static\s+struct\s+px\s+pics\[\s*\]\s*=\s*\{\s*$/io);
911 elsif (/\{\s*PROC_CLASS_\w+\s*,\s*"\w+"\s*,\s*\{\s*"\w+"\s*,\s*"\w+"\s*,\s*"(\w+)"\s*}\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*[\w-]+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\S+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\S+\s*,\s*\S+\s*,\s*\S+\s*,\s*\{\s*\S+\s*,\s*\S+\s*\}\s*,\s*{\s*\S+\s*,\s*\S+\s*\}\s*,\s*{\s*(\S+)\s*,\s*(\S+)\s*\}\s*,\s*{\s*\S+\s*,\s*\S+\s*\}\s*,\s*\w+\s*,\s*\"?[\.\w]+\"?\s*,\s*\"?[\.\w]+\"?\s*,\s*\d+\s*\}/iop)
913 my ($name, $c_start, $c_end) = ($1, $2, $3);
915 if ($short_mcu_name eq $name)
917 ${$Conf_start} = str2int
($c_start);
918 ${$Conf_end} = str2int
($c_end);
931 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
932 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
933 #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@
934 #@@@@@@@@@@@@@@@@@@@@ Prints the register definitions. @@@@@@@@@@@@@@@@@@@@@@@
935 #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@
936 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
937 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
939 # A bit may be more than one name. This procedure counts that how
940 # many the most of name.
942 sub max_count_of_names_of_bit
($)
947 for (my $i = 0; $i < 8; ++$i)
949 my $array = $Bits->[$i];
951 next if (! defined($array));
953 my $l = scalar(@
{$array});
955 $num = $l if ($num < $l);
961 #-------------------------------------------------------------------------------
963 # There are certain bits that have the same name in other registers
964 # also. In this case, in the definitions of bit names need apply
965 # a prefix, that allows the bits to distinguish from each other.
966 # This function this need is recorded in the affected registers.
970 foreach my $register (sort {versionSort
($a->{NAME
}, $b->{NAME
})} @registers)
972 my $bits = $register->{BITNAMES
};
974 next if (! defined($bits));
976 for (my $i = 0; $i < 8; ++$i)
978 my $array = $bits->[$i];
980 next if (! defined($array));
984 my $reg = $reg_refs_by_bits{$_};
988 Log
("The $_ bit of the $register->{NAME} register is occupied in $reg->{NAME} register. ($mcu)", 3);
989 $register->{NEED_PREFIX
} = TRUE
;
993 $reg_refs_by_bits{$_} = $register;
1000 #-------------------------------------------------------------------------------
1002 # Prints the $Index numbered $Bits of a register.
1006 my ($Bits, $Index, $Align) = @_;
1007 my $al = ' ' x
$Align;
1009 for (my $i = 0; $i < 8; ++$i)
1011 my $array = $Bits->[$i];
1013 my $bit = (defined($array) && defined($str = $array->[$Index])) ?
" $str" : '';
1015 Outl
(align
("${al}unsigned$bit", DIST_BITSIZE
), ': 1;');
1019 #-------------------------------------------------------------------------------
1021 # Prints all bits of a register.
1023 sub print_local_bitdefs
($)
1025 my $Register = $_[0];
1026 my $bits = $Register->{BITNAMES
};
1027 my $head = ($Register->{NEED_PREFIX
}) ?
"$Register->{NAME}_" : '';
1029 for (my $i = 0; $i < 8; ++$i)
1031 my $array = $bits->[$i];
1033 next if (! defined($array));
1037 Outl
(align
("#define _${head}$_", DIST_DEFSIZE
), sprintf('0x%02X', 1 << $i));
1042 #-------------------------------------------------------------------------------
1044 # Deletes the false or fragmentary bitfields.
1046 sub bitfield_filtration
($)
1048 my ($bits, $fields) = ($_[0]->{BITNAMES
}, $_[0]->{BITFIELDS
});
1050 # Does not have a bitfields.
1052 return if (! defined($fields));
1054 foreach my $field_name (keys(%{$fields}))
1056 my ($first_addr, $last_addr, $last_index);
1057 my $gr = $fields->{$field_name};
1059 Log
("bitfield_filtration() -- $field_name", 8);
1061 if (find_bit
($bits, $field_name))
1063 # The $field_name already exists in the $bits array.
1066 delete($fields->{$field_name});
1070 @
{$gr->{ADDRESSES
}} = sort {$a <=> $b} @
{$gr->{ADDRESSES
}};
1072 my ($addresses, $indexes) = ($gr->{ADDRESSES
}, $gr->{INDEXES
});
1074 $first_addr = $addresses->[0];
1076 if ((scalar(@
{$addresses}) < 2) || ($indexes->[$first_addr] != 0))
1078 # This is not field, for only one member of there is. The other
1079 # possibility is that the index of the first member is not zero.
1081 delete($fields->{$field_name});
1088 foreach (@
{$addresses})
1090 my $idx = $indexes->[$_];
1092 if ($last_addr >= 0)
1094 if ((($last_addr + 1) != $_) || (($last_index + 1) != $idx))
1096 # This bitfield is fragmented (not uniform).
1107 # This is the width of the bitfield.
1109 my $width = $last_addr - $first_addr + 1;
1111 if (($width > 0) && ($width < 8))
1113 $gr->{WIDTH
} = $width;
1117 delete($fields->{$field_name});
1119 } # foreach my $field_name (keys(%{$fields}))
1122 #-------------------------------------------------------------------------------
1124 sub print_bitfield
($$$)
1126 my ($Name, $Group, $Align) = @_;
1127 my ($addr, $width) = ($Group->{ADDRESSES
}->[0], $Group->{WIDTH
});
1128 my $al = ' ' x
$Align;
1130 Outl
(align
("${al}unsigned", DIST_BITSIZE
), ": $addr;") if ($addr > 0);
1131 Outl
(align
("${al}unsigned $Name", DIST_BITSIZE
), ": $width;");
1132 $width = 8 - ($addr + $width);
1133 Outl
(align
("${al}unsigned", DIST_BITSIZE
), ": $width;") if ($width > 0);
1136 #-------------------------------------------------------------------------------
1138 # Prints all bits of all registers.
1140 sub print_all_registers
()
1144 my ($bit_struct_num, $field_struct_num, $all_struct_num);
1145 my ($alias, $i, $r, $text, $type, $v);
1148 for ($r = 0; $r < $v;)
1150 my $reg = $registers[$r];
1153 my ($name, $addr, $bits) = ($reg->{NAME
}, $reg->{ADDRESS
}, $reg->{BITNAMES
});
1157 bitfield_filtration
($reg) if ($create_bitfields);
1159 $text = sprintf("__at(0x%04X)", $addr);
1160 $device_registers .= "$text __sfr $name;\n";
1162 $alias = $register_aliases{$name};
1163 $alias = undef if (defined($alias) && defined($reg_refs_by_names{$alias}));
1165 if (defined($bits) && (scalar(@
{$bits}) > 0))
1167 $type = "__$name$btype_t";
1168 Outl
("\n$section\n//", (' ' x
8), "$name Bits\n\nextern $text __sfr $name;");
1169 Outl
("\n#define $alias $name") if (defined($alias));
1171 $bit_struct_num = max_count_of_names_of_bit
($bits);
1173 if ($create_bitfields)
1175 $fields = $reg->{BITFIELDS
};
1176 @field_names = sort {$fields->{$a}->{ADDRESSES
}->[0] <=> $fields->{$b}->{ADDRESSES
}->[0]} keys(%{$fields});
1177 $field_struct_num = @field_names;
1178 $all_struct_num = $bit_struct_num + $field_struct_num - 1;
1182 $all_struct_num = $bit_struct_num - 1;
1185 if ($all_struct_num > 0)
1187 Outl
("\ntypedef union\n {");
1189 for ($i = 0; $i < $bit_struct_num; ++$i)
1191 Outl
(" struct\n {");
1192 print_bits
($bits, $i, 4);
1194 Outl
() if ($all_struct_num);
1198 if ($create_bitfields)
1200 for ($i = 0; $i < $field_struct_num; ++$i)
1202 my $flname = $field_names[$i];
1204 Outl
(" struct\n {");
1205 print_bitfield
($flname, $fields->{$flname}, 4);
1207 Outl
() if ($all_struct_num);
1214 Outl
("\ntypedef struct\n {");
1215 print_bits
($bits, 0, 2);
1219 Outl
("\nextern $text volatile $type $name$btail;");
1220 Outl
("\n#define $alias$btail $name$btail") if (defined($alias));
1222 print_local_bitdefs
($reg);
1223 Outl
("\n$section\n");
1225 $device_registers .= "$text volatile $type $name$btail;\n";
1226 } # if (defined($bits) && (scalar(@{$bits}) > 0))
1229 Outl
("extern $text __sfr $name;");
1230 Outl
("#define $alias $name") if (defined($alias));
1233 $device_registers .= "\n" if ($r < $v);
1235 elsif (defined($bits) && (scalar(@
{$bits}) > 0))
1237 # This is a register which can not be achieved directly, but the bits has name.
1239 Outl
("\n$section\n//", (' ' x
8), "$name Bits\n");
1240 print_local_bitdefs
($reg);
1241 Outl
("\n$section\n");
1243 } # for ($r = 0; $r < $v;)
1246 #-------------------------------------------------------------------------------
1248 sub print_configuration_words
()
1250 if (! scalar(@configs))
1254 my ($start, $end) = (-1, -1);
1256 extract_config_area
(\
$start, \
$end);
1257 return if (($start < 0) || ($end < 0));
1259 Outl
("\n$section\n//\n//", (' ' x
8), "Configuration Addresses\n//\n$section\n");
1262 while ($start <= $end)
1264 my $n = int($i / 2) + 1;
1265 my $h = ($i & 1) ?
'H' : 'L';
1267 Out
(align
("#define ${conf_head}CONFIG$n$h", DIST_BITSIZE
));
1268 Outl
(sprintf("0x%0${caddr_size}X", $start));
1273 Outl
("\n$section\n");
1277 Outl
("\n$section\n//\n//", (' ' x
8), "Configuration Bits\n//\n$section\n");
1281 Out
(align
("#define $conf_head$_->{NAME}", DIST_BITSIZE
));
1282 Outl
(sprintf("0x%0${caddr_size}X", $_->{ADDRESS
}));
1287 next if (! @
{$_->{OPTIONS
}});
1289 Outl
("\n//", ('-' x
29), " $_->{NAME} Options ", ('-' x
31), "\n");
1291 foreach (@
{$_->{OPTIONS
}})
1293 my $expl = $_->{EXPLANATION
};
1295 # Improve a spelling error: On the end of a sentence a point must be.
1296 $expl .= '.' if (($expl ne '') && ($expl !~ /\.$/o));
1298 Out
(align
("#define $_->{NAME}", DIST_BITSIZE
));
1299 Out
(align
(sprintf("0x%0${conf_size}X", $_->{VALUE
}), 8));
1300 Out
("// $expl") if (defined($expl) && ($expl ne ''));
1305 Outl
("\n$section\n");
1308 #-------------------------------------------------------------------------------
1310 sub print_devids_and_idlocs
()
1312 foreach (\
@devids, \
@idlocs)
1314 if (scalar(@
{$_}) > 0)
1318 Out
(align
("#define $conf_head$_->{NAME}", DIST_BITSIZE
));
1319 Outl
(sprintf("0x%0${caddr_size}X", $_->{ADDRESS
}));
1327 #-------------------------------------------------------------------------------
1329 sub print_license
($)
1331 print $out_handler <<EOT
1333 * This $_[0] of the $mcu MCU.
1335 * This file is part of the GNU PIC library for SDCC, originally
1336 * created by Molnar Karoly <molnarkaroly\@users.sf.net> $year.
1338 * This file is generated automatically by the $PROGRAM${time_str}.
1340 * SDCC is licensed under the GNU Public license (GPL) v2. Note that
1341 * this license covers the code to the compiler and other executables,
1342 * but explicitly does not cover any code or objects generated by sdcc.
1344 * For pic device libraries and header files which are derived from
1345 * Microchip header (.inc) and linker script (.lkr) files Microchip
1346 * requires that "The header files should state that they are only to be
1347 * used with authentic Microchip devices" which makes them incompatible
1348 * with the GPL. Pic device libraries and header files are located at
1349 * non-free/lib and non-free/include directories respectively.
1350 * Sdcc should be run with the --use-non-free command line option in
1351 * order to include non-free header files and libraries.
1353 * See http://sdcc.sourceforge.net/ for the latest information on sdcc.
1360 #-------------------------------------------------------------------------------
1362 # This procedure generates the pic14-specific information.
1364 sub make_pic14_dependent_defs
()
1366 foreach (sort {versionSort
($a->{NAME
}, $b->{NAME
})} @registers)
1368 my ($name, $bits) = ($_->{NAME
}, $_->{BITNAMES
});
1369 my $prefix = "$name$btail";
1371 if ($emit_legacy_names)
1373 $legacy_names .= align
("#define ${name}_$btail", DIST_DEFSIZE
);
1374 $legacy_names .= "$prefix\n";
1377 next if ($_->{NEED_PREFIX
} || ! defined($bits));
1379 for (my $i = 0; $i < 8; ++$i)
1381 my $array = $bits->[$i];
1383 next if (! defined($array));
1385 my $shadow = (scalar(@
{$array}) > 1) ?
", shadows bit in $prefix" : '';
1389 $full_bitdefs .= align
("#define $_", DIST_DEFSIZE
);
1390 $full_bitdefs .= align
("$prefix.$_", DIST_COMSIZE
);
1391 $full_bitdefs .= "// bit $i$shadow\n";
1395 $full_bitdefs .= "\n";
1398 $legacy_names .= "\n";
1401 #-------------------------------------------------------------------------------
1403 # Prints all informations to the header file.
1405 sub print_to_header_file
()
1407 my ($text, $name, $address, $str);
1409 print_license
('declarations');
1410 Outl
("#ifndef __${mcu}_H__\n#define __${mcu}_H__\n\n$section");
1414 $text = '#ifndef NO_ADDR_DEFINES';
1416 Outl
("//\n//\tRegister Addresses\n//\n$section\n\n$text\n");
1418 foreach (sort { $a->{ADDRESS
} <=> $b->{ADDRESS
} } @registers)
1420 ($name, $address) = ($_->{NAME
}, $_->{ADDRESS
});
1421 next if ($address < 0);
1423 $str = sprintf('0x%04X', $address);
1424 Outl
(align
("#define ${name}_ADDR", DIST_ADDRSIZE
), $str);
1427 Outl
("\n#endif // $text");
1430 Outl
("\n$section\n//\n//\tRegister Definitions\n//\n$section\n");
1432 print_all_registers
();
1433 print_configuration_words
();
1434 print_devids_and_idlocs
();
1438 make_pic14_dependent_defs
();
1441 if ($full_bitdefs ne '')
1443 $text = '#ifndef NO_BIT_DEFINES';
1444 Outl
("$text\n\n", $full_bitdefs, "#endif // $text\n");
1447 if ($emit_legacy_names)
1449 $text = '#ifndef NO_LEGACY_NAMES';
1450 Outl
("$text\n\n", $legacy_names, "#endif // $text\n");
1454 Outl
("#endif // #ifndef __${mcu}_H__");
1457 #-------------------------------------------------------------------------------
1459 # Prints name of all registers to the device file.
1461 sub print_to_device_file
()
1463 print_license
('definitions');
1464 Outl
("#include <$header_name>\n\n$section\n");
1465 Out
($device_registers) if ($device_registers ne '');
1468 #-------------------------------------------------------------------------------
1473 Usage: $PROGRAM [options]
1477 -gp <path> or --gputils-path <path>
1479 The program on this path looks for the gputils source package.
1481 -I <path> or --include <path>
1483 The program on this path looks for the headers (inc files). If this
1484 not specified, then the "header" directory in the local repository
1485 will be the default.
1487 -p <p12f1822> or --processor <p12f1822>
1489 The name of MCU. The prefix of name can be: 'p', 'pic' or nothing
1491 -o <path> or --out-path <path>
1493 Here to writes the output files. (default: "./")
1494 Attention! The program overwrites the existing files without asking.
1496 -v <level> or --verbose <level>
1498 It provides information on from the own operation.
1499 Possible value of the level between 0 and 10. (default: 0)
1501 -cb or --create-bitfields
1503 Create bit fields. In some register, can be found such bits which
1504 belong together. For example: CVR0, CVR1, CVR2, CVR3
1505 These may be useful, to merge during a common field name: CVR
1506 The compiler helps handle these bit fields. (default: no)
1508 -e or --emit-legacy-names
1510 Creates the legacy names also. (default: no)
1512 -nt or --no-timestamp
1514 There will be no timestamp in the header and device files. (default: yes)
1520 For example: $PROGRAM -p 12f1840 -cb
1525 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1526 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1527 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1528 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The main program. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1529 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1530 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1531 # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
1533 $PROGRAM = basename
($0);
1534 $gp_header_path = '';
1537 for (my $i = 0; $i < scalar(@ARGV); )
1539 my $opt = $ARGV[$i++];
1543 when (/^-(gp|-gputils-path)$/o)
1545 param_exist
($opt, $i);
1546 $gputils_path = $ARGV[$i++];
1549 when (/^-(I|-include)$/o)
1551 param_exist
($opt, $i);
1552 $gp_header_path = $ARGV[$i++];
1555 when (/^-(p|-processor)$/o)
1557 param_exist
($opt, $i);
1561 when (/^-(o|-out-path)$/o)
1563 param_exist
($opt, $i);
1564 $out_path = $ARGV[$i++];
1567 when (/^-(v|-verbose)$/o)
1569 param_exist
($opt, $i);
1570 $verbose = int($ARGV[$i++]);
1571 $verbose = 0 if (! defined($verbose) || ($verbose < 0));
1572 $verbose = 10 if ($verbose > 10);
1575 when (/^-(cb|-create-bitfields)$/o)
1577 $create_bitfields = TRUE
;
1580 when (/^-(e|-emit-legacy-names)$/o)
1582 $emit_legacy_names = TRUE
;
1585 when (/^-(nt|-no-timestamp)$/o)
1587 $no_timestamp = TRUE
;
1590 when (/^-(h|-help)$/o)
1594 } # when ('-h' || '--help')
1598 die "Miss the name of MCU!\n" if ($mcu eq '');
1599 die "This name is wrong: \"$mcu\"\n" if ($mcu !~ /^(p(ic)?)?$name_filter$/io);
1601 die "This directory - $gputils_path - not exist!" if (! -d
$gputils_path);
1603 $gp_header_path = "$gputils_path/header" if ($gp_header_path eq ''); # The default value.
1604 $gpproc_path = "$gputils_path/libgputils/$gpprocessor_c";
1607 $mcu =~ s/^p(ic)?//o;
1617 $short_mcu_name = $mcu;
1618 my $fname = "p${mcu}.inc";
1620 die "The MCU: $mcu unknown!\n" if (! -f
"$gp_header_path/$fname");
1622 $mcu = 'PIC' . uc($mcu);
1623 $header_name = lc($mcu) . '.h';
1624 $device_name = lc($mcu) . '.c';
1626 read_content_from_header
("$gp_header_path/$fname");
1628 $year = strftime
('%Y', gmtime);
1629 $time_str = strftime
(', %F %T UTC', gmtime) if (! $no_timestamp);
1631 # Creates the directory structure.
1633 my $path = ($is_pic16) ?
"$out_path/$p16_out_path" : "$out_path/$p14_out_path";
1634 my $head_dir = "$path/header";
1638 Log
("Creates the \"$head_dir\" dir.", 4);
1639 make_path
($head_dir) || die "Could not create the \"$head_dir\" dir!";
1642 my $dev_dir = "$path/device";
1646 Log
("Creates the \"$dev_dir\" dir.", 4);
1647 make_path
($dev_dir) || die "Could not create the \"$dev_dir\" dir!";
1650 # Creates the pic1xxxx.h file.
1652 my $fpath = "$head_dir/$header_name";
1653 open($out_handler, '>', $fpath) || die "Could not create the \"$fpath\" file!\n";
1654 Log
("Creates the $header_name", 1);
1655 print_to_header_file
();
1656 close($out_handler);
1658 # Creates the pic1xxxx.c file.
1660 $fpath = "$dev_dir/$device_name";
1661 open($out_handler, '>', $fpath) || die "Could not create the \"$fpath\" file!\n";
1662 Log
("Creates the $device_name", 1);
1663 print_to_device_file
();
1664 close($out_handler);